Reorganizes the network-ui code under awx/client/src/network-ui

* Moves network UI source to awx/client/src/network-ui
* Moves network ui partials to awx/ui/client/network-ui
* Renames widgets with suffix partial.svg
* Updates directives to use bundled partials
* Uses ~network-ui for loading UI component
This commit is contained in:
Ben Thomasson
2018-01-03 10:30:25 -05:00
parent f6eecad25e
commit 1c1844d889
125 changed files with 244 additions and 167 deletions

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/button.partial.svg');
function button () {
return { restrict: 'A', templateUrl};
}
exports.button = button;

View File

@@ -0,0 +1,111 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Clicked () {
this.name = 'Clicked';
}
inherits(_Clicked, _State);
var Clicked = new _Clicked();
exports.Clicked = Clicked;
function _Pressed () {
this.name = 'Pressed';
}
inherits(_Pressed, _State);
var Pressed = new _Pressed();
exports.Pressed = Pressed;
function _Disabled () {
this.name = 'Disabled';
}
inherits(_Disabled, _State);
var Disabled = new _Disabled();
exports.Disabled = Disabled;
// Begin ready state
_Ready.prototype.onMouseDown = function (controller) {
controller.changeState(Pressed);
};
_Ready.prototype.onMouseDown.transitions = ['Pressed'];
_Ready.prototype.onTouchStart = _Ready.prototype.onMouseDown;
_Ready.prototype.start = function (controller) {
controller.scope.enabled = true;
};
_Ready.prototype.onDisable = function (controller) {
controller.changeState(Disabled);
};
_Ready.prototype.onDisable.transitions = ['Disabled'];
// end ready state
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Clicked.prototype.start = function (controller) {
controller.scope.is_pressed = false;
controller.changeState(Ready);
controller.scope.callback(controller.scope);
};
_Clicked.prototype.start.transitions = ['Ready'];
_Pressed.prototype.start = function (controller) {
controller.scope.is_pressed = true;
};
_Pressed.prototype.onMouseUp = function (controller) {
controller.changeState(Clicked);
};
_Pressed.prototype.onMouseUp.transitions = ['Clicked'];
_Pressed.prototype.onTouchEnd = _Pressed.prototype.onMouseUp;
_Disabled.prototype.onEnable = function (controller) {
controller.changeState(Ready);
};
_Disabled.prototype.onEnable.transitions = ['Ready'];
_Disabled.prototype.start = function (controller) {
controller.scope.enabled = false;
};

View File

@@ -0,0 +1,14 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<rect ng-attr-class="{{button.is_pressed ? 'NetworkUI__button--button-pressed' : button.mouse_over ? 'NetworkUI__button--button-hover' : 'NetworkUI__button'}}"
x=0
y=0
ng-attr-width={{button.width}}
ng-attr-height={{button.height}}
rx=5></rect>
<text ng-attr-class="{{button.is_pressed ? 'NetworkUI__button-text--button-pressed' : button.mouse_over ? 'NetworkUI__button-text--button-hover' : 'NetworkUI__button-text'}}"
ng-attr-x="{{button.width/2}}"
ng-attr-y="{{button.height/2}}"
dy=".3em"
text-anchor="middle">{{button.name}}</text>

View File

@@ -0,0 +1,100 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _ButtonPressed () {
this.name = 'ButtonPressed';
}
inherits(_ButtonPressed, _State);
var ButtonPressed = new _ButtonPressed();
exports.ButtonPressed = ButtonPressed;
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
var i = 0;
var buttons = controller.scope.all_buttons;
var button = null;
for (i = 0; i < buttons.length; i++) {
button = buttons[i];
if (button.is_selected(controller.scope.mouseX, controller.scope.mouseY)) {
button.fsm.handle_message(msg_type, $event);
controller.changeState(ButtonPressed);
break;
}
button = null;
}
if (button === null) {
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['ButtonPressed'];
_Ready.prototype.onTouchStart = _Ready.prototype.onMouseDown;
_Ready.prototype.onMouseMove = function (controller, msg_type, $event) {
if (!controller.scope.hide_buttons) {
var i = 0;
var buttons = controller.scope.all_buttons;
var button = null;
for (i = 0; i < buttons.length; i++) {
button = buttons[i];
button.mouse_over = false;
if (button.is_selected(controller.scope.mouseX, controller.scope.mouseY)) {
button.mouse_over = true;
}
}
}
controller.delegate_channel.send(msg_type, $event);
};
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_ButtonPressed.prototype.onMouseUp = function (controller, msg_type, $event) {
var i = 0;
var buttons = controller.scope.all_buttons;
var button = null;
for (i = 0; i < buttons.length; i++) {
button = buttons[i];
button.fsm.handle_message(msg_type, $event);
}
controller.changeState(Ready);
};
_ButtonPressed.prototype.onMouseUp.transitions = ['Ready'];
_ButtonPressed.prototype.onTouchEnd = _ButtonPressed.prototype.onMouseUp;

View File

@@ -0,0 +1,14 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/chevron_left.partial.svg');
function chevronLeft () {
return {
restrict: 'A',
templateUrl,
scope: {
actionIcon: '='
}
};
}
exports.chevronLeft = chevronLeft;

View File

@@ -0,0 +1,14 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/chevron_right.partial.svg');
function chevronRight () {
return {
restrict: 'A',
templateUrl,
scope: {
actionIcon: '='
}
};
}
exports.chevronRight = chevronRight;

View File

@@ -0,0 +1,8 @@
<circle
ng-attr-class="{{actionIcon.is_pressed ? 'NetworkUI__iconBackground--pressed' : actionIcon.mouse_over ? 'NetworkUI_iconBackground--hover' : 'NetworkUI_iconBackground'}}"
class="NetworkUI_iconBackground"
cx=10 cy=9 r=16 />
<path
ng-attr-class="{{actionIcon.is_pressed ? 'NetworkUI_chevron--pressed' : actionIcon.mouse_over ? 'NetworkUI_chevron--hover' : 'NetworkUI_chevron'}}"
ng-attr-transform="scale(0.01)"
d="M1427 301l-531 531 531 531q19 19 19 45t-19 45l-166 166q-19 19-45 19t-45-19l-742-742q-19-19-19-45t19-45l742-742q19-19 45-19t45 19l166 166q19 19 19 45t-19 45z"/>

View File

@@ -0,0 +1,7 @@
<circle
ng-attr-class="{{actionIcon.is_pressed ? 'NetworkUI__iconBackground--pressed' : actionIcon.mouse_over ? 'NetworkUI_iconBackground--hover' : 'NetworkUI_iconBackground'}}"
cx=8 cy=9 r=16 />
<path
ng-attr-class="{{actionIcon.is_pressed ? 'NetworkUI_chevron--pressed' : actionIcon.mouse_over ? 'NetworkUI_chevron--hover' : 'NetworkUI_chevron'}}"
ng-attr-transform="scale(0.01)"
d="M1363 877l-742 742q-19 19-45 19t-45-19l-166-166q-19-19-19-45t19-45l531-531-531-531q-19-19-19-45t19-45l166-166q19-19 45-19t45 19l742 742q19 19 19 45t-19 45z"/>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/configuration.partial.svg');
function configuration () {
return { restrict: 'A', templateUrl};
}
exports.configuration = configuration;

View File

@@ -0,0 +1,4 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-attr-transform="translate({{item.x}}, {{item.y}}">
<path d="M100,100 h200 a20,20 0 0 1 20,20 v200 a20,20 0 0 1 -20,20 h-200 a20,20 0 0 1 -20,-20 v-200 a20,20 0 0 1 20,-20 z" fill="none" stroke="black" stroke-width="3" />
</g>

View File

@@ -0,0 +1,15 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/context_menu_button.partial.svg');
function contextMenuButton () {
return {
restrict: 'A',
templateUrl,
scope: {
contextMenuButton: '=',
contextMenu: '='
}
};
}
exports.contextMenuButton = contextMenuButton;

View File

@@ -0,0 +1,14 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/context_menu.partial.svg');
function contextMenu () {
return {
restrict: 'A',
templateUrl,
scope: {
contextMenu: '='
}
};
}
exports.contextMenu = contextMenu;

View File

@@ -0,0 +1,23 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<filter id="shadowFilter" x="0" y="0" width="102%" height="105%">
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
<feColorMatrix result = "matrixOut" in = "offOut" type = "matrix" values = "0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0"/>
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
<rect ng-attr-class="{{contextMenu.is_pressed ? 'NetworkUI__contextMenu--button-pressed' : contextMenu.mouse_over ? 'NetworkUI__contextMenu--button-hover' : 'NetworkUI__contextMenu'}}"
x=0
y=0
ng-attr-width={{contextMenu.width}}
ng-attr-height={{contextMenu.height}}
rx=5 ry=5
filter="url(#shadowFilter)">
</rect>
<g>
<g> <!-- context menu buttons -->
<g ng-repeat="button in contextMenu.buttons">
<g awx-net--context-menu-button context-menu-button="button" context-menu="contextMenu"></g>
</g>
</g> <!-- end context menu buttons -->

View File

@@ -0,0 +1,13 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<rect ng-attr-class="{{contextMenuButton.is_pressed ? 'NetworkUI__contextMenuButton-pressed' : contextMenuButton.mouse_over ? 'NetworkUI__contextMenuButton-hover' : 'NetworkUI__contextMenuButton'}}"
x= 1
ng-attr-y="{{(contextMenuButton.height * $parent.$index) + 5}}"
ng-attr-width={{contextMenuButton.width-2}}
ng-attr-height={{contextMenuButton.height}}>
</rect>
<text ng-attr-class="{{contextMenuButton.is_pressed ? 'NetworkUI__contextMenuButtonText-pressed' : contextMenuButton.mouse_over ? 'NetworkUI__contextMenuButtonText-hover' : 'NetworkUI__contextMenuButtonText'}}"
x=15
ng-attr-y="{{(contextMenuButton.height * $parent.$index) + 18}}"
dy=".3em"
text-anchor="left">{{contextMenuButton.name}}
</text>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/cursor.partial.svg');
function cursor () {
return { restrict: 'A', templateUrl};
}
exports.cursor = cursor;

View File

@@ -0,0 +1,5 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-attr-transform="translate({{cursor.x}},{{cursor.y}})" ng-attr-class="{{cursor.hidden && 'NetworkUI--hidden' || ''}}" >
<line x1="-15" y1="0" x2="15" y2="0" class="NetworkUI__cursor"/>
<line x1="0" y1="-15" x2="0" y2="15" class="NetworkUI__cursor"/>
</g>

View File

@@ -0,0 +1,9 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/debug.partial.svg');
function debug () {
return { restrict: 'A', templateUrl};
}
exports.debug = debug;

View File

@@ -0,0 +1,50 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || ''}}">
<text ng-attr-x="{{graph.right_column}}" y="35" class="NetworkUI__debug-text">view_port.x: {{view_port.x}}</text>
<text ng-attr-x="{{graph.right_column}}" y="55" class="NetworkUI__debug-text">view_port.y: {{view_port.y}}</text>
<text ng-attr-x="{{graph.right_column}}" y="75" class="NetworkUI__debug-text">view_port.width: {{view_port.width}}</text>
<text ng-attr-x="{{graph.right_column}}" y="95" class="NetworkUI__debug-text">view_port.height: {{view_port.height}}</text>
<text ng-attr-x="{{graph.right_column}}" y="115" class="NetworkUI__debug-text">width: {{graph.width}}</text>
<text ng-attr-x="{{graph.right_column}}" y="135" class="NetworkUI__debug-text">height: {{graph.height}}</text>
<text ng-attr-x="{{graph.right_column}}" y="155" class="NetworkUI__debug-text">rc: {{graph.right_column}}</text>
<text ng-attr-x="{{graph.right_column}}" y="175" class="NetworkUI__debug-text">Mouse down: {{onMouseDownResult}}</text>
<text ng-attr-x="{{graph.right_column}}" y="195" class="NetworkUI__debug-text">Mouse up: {{onMouseUpResult}}</text>
<text ng-attr-x="{{graph.right_column}}" y="215" class="NetworkUI__debug-text">Mouse move: {{onMouseMoveResult}}</text>
<text ng-attr-x="{{graph.right_column}}" y="235" class="NetworkUI__debug-text">Mouse over: {{onMouseOverResult}}</text>
<text ng-attr-x="{{graph.right_column}}" y="255" class="NetworkUI__debug-text">Mouse enter: {{onMouseEnterResult}}</text>
<text ng-attr-x="{{graph.right_column}}" y="275" class="NetworkUI__debug-text">Mouse leave: {{onMouseLeaveResult}}</text>
<text ng-attr-x="{{graph.right_column}}" y="295" class="NetworkUI__debug-text">Current scale: {{current_scale.toFixed(4)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="315" class="NetworkUI__debug-text">Pan X: {{panX.toFixed(2)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="335" class="NetworkUI__debug-text">Pan Y: {{panY.toFixed(2)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="355" class="NetworkUI__debug-text">View State: {{view_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="375" class="NetworkUI__debug-text">Mouse X: {{mouseX.toFixed(2)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="395" class="NetworkUI__debug-text">Mouse Y: {{mouseY.toFixed(2)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="415" class="NetworkUI__debug-text">Scaled X: {{scaledX.toFixed(2)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="435" class="NetworkUI__debug-text">Scaled Y: {{scaledY.toFixed(2)}}</text>
<text ng-attr-x="{{graph.right_column}}" y="455" class="NetworkUI__debug-text">Key: {{last_key}}</text>
<text ng-attr-x="{{graph.right_column}}" y="475" class="NetworkUI__debug-text">Key Code: {{last_key_code}}</text>
<text ng-attr-x="{{graph.right_column}}" y="495" class="NetworkUI__debug-text">Move State: {{move_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="515" class="NetworkUI__debug-text">Selected devices: {{selected_devices.length}}</text>
<text ng-attr-x="{{graph.right_column}}" y="535" class="NetworkUI__debug-text">Selected links: {{selected_links.length}}</text>
<text ng-attr-x="{{graph.right_column}}" y="555" class="NetworkUI__debug-text">Link State: {{link_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="575" class="NetworkUI__debug-text">Buttons State: {{buttons_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="595" class="NetworkUI__debug-text">Time State: {{time_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="615" class="NetworkUI__debug-text">Time Pointer: {{time_pointer}}</text>
<text ng-attr-x="{{graph.right_column}}" y="635" class="NetworkUI__debug-text">History: {{history.length}}</text>
<text ng-attr-x="{{graph.right_column}}" y="655" class="NetworkUI__debug-text">Touch Data: {{touch_data.xb}} {{touch_data.yb}} {{touch_data.d}}</text>
<text ng-attr-x="{{graph.right_column}}" y="675" class="NetworkUI__debug-text">Group State: {{group_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="695" class="NetworkUI__debug-text">Selected groups: {{selected_groups.length}}</text>
<text ng-attr-x="{{graph.right_column}}" y="715" class="NetworkUI__debug-text">Hotkeys State: {{hotkeys_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="735" class="NetworkUI__debug-text">Mode State: {{mode_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="755" class="NetworkUI__debug-text">Device Detail State: {{device_detail_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="775" class="NetworkUI__debug-text">Site State: {{site_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="795" class="NetworkUI__debug-text">Rack State: {{rack_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="815" class="NetworkUI__debug-text">Stream State: {{stream_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="835" class="NetworkUI__debug-text">App Toolbox State: {{app_toolbox_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="855" class="NetworkUI__debug-text">Inventory Toolbox State: {{inventory_toolbox_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="875" class="NetworkUI__debug-text">Rack Toolbox State: {{rack_toolbox_controller.state.name}}</text>
<text ng-attr-x="{{graph.right_column}}" y="895" class="NetworkUI__debug-text">Site Toolbox State: {{site_toolbox_controller.state.name}}</text>
<rect x=10 y=10 ng-attr-width="{{graph.width - 20}}" ng-attr-height="{{graph.height - 20}}" class="NetworkUI--debug"></rect>
</g>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/default.partial.svg');
function defaultd () {
return { restrict: 'A', templateUrl};
}
exports.defaultd = defaultd;

View File

@@ -0,0 +1,54 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="item.moving">
<line ng-attr-x1="{{-50 - 100}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 100}}"
ng-attr-y2="0"
class="NetworkUI--construction"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 100}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 100}}"
class="NetworkUI--construction"></line>
</g>
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></rect>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></rect>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<g class="NetworkUI__device">
<circle
cx="0"
cy="0"
ng-attr-r="{{50 + 2}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__device--selected-conflict' : item.selected ? 'NetworkUI__device--selected' : 'NetworkUI__device--remote-selected' : 'NetworkUI--hidden'}}">
</circle>
<circle
cx="0"
cy="0"
ng-attr-r="{{50}}">
</circle>
</g>
<g ng-show="item.icon || current_scale > 0.5">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__device-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="0"> {{item.name}} </text>
<text class="NetworkUI__device-text" text-anchor="middle" x="0" y="0">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/device_detail.partial.svg');
function deviceDetail () {
return { restrict: 'A', templateUrl};
}
exports.deviceDetail = deviceDetail;

View File

@@ -0,0 +1,81 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Disable () {
this.name = 'Disable';
}
inherits(_Disable, _State);
var Disable = new _Disable();
exports.Disable = Disable;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Ready.prototype.onPasteProcess = function (controller, msg_type, message) {
console.log([msg_type, message]);
var i=0;
var devices = controller.scope.devices;
var device = null;
var x = controller.scope.scaledX;
var y = controller.scope.scaledY;
var app = null;
for(i=0; i < devices.length; i++) {
device = devices[i];
if (device.is_selected(x, y)) {
console.log(device);
app = new models.Process(device.process_id_seq(),
message.process.name,
message.process.type,
controller.scope.scaledX,
controller.scope.scaledY);
app.device = device;
device.processes.push(app);
controller.scope.send_control_message(new messages.ProcessCreate(controller.scope.client_id,
app.id,
app.name,
app.type,
app.device.id,
app.x,
app.y));
break;
} else {
console.log([x,y, device.x, device.y]);
}
}
};

View File

@@ -0,0 +1,110 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-attr-transform="scale({{1/5}}) translate(-250,-250)">
<rect width=500
height=500
x=0
y=0
class="NetworkUI__group"/>
<g ng-attr-transform="translate(0,0)"
ng-attr-class="{{item.type}}"
ng-switch on="item.type">
<g ng-switch-when="router"><!-- begin router -->
<g awx-net-router></g>
</g> <!-- end router -->
<g ng-switch-when="switch"> <!-- begin switch -->
<g awx-net-switch> </g>
</g> <!-- end switch -->
<g ng-switch-when="host"> <!-- begin host -->
<g awx-net-host> </g>
</g> <!-- end host -->
<g ng-switch-default> <!-- begin default -->
<g awx-net-default></g>
</g> <!-- end default -->
<g awx-net-status-light></g>
<g awx-net-task-status></g>
</g> <!-- end transform class switch -->
<g transform="translate(0, 500)">
<g ng-repeat="interface in item.interfaces track by $index">
<g ng-attr-transform="translate({{$index * 60 + 30}}, -40)">
<g ng-if="interface.link !== null">
<line x1="0"
y1="0"
x2="0"
y2="100"
class="{{interface.link.status === null ? 'NetworkUI__link' : interface.link.status ? 'NetworkUI__link--link-pass' : 'NetworkUI__link--link-fail'}}"/>
</g>
<circle cx="0"
cy="0"
r=14
ng-attr-class="{{interface.selected ? 'NetworkUI__interface--selected' : 'NetworkUI--hidden'}}" ></circle>
<circle cx="0"
cy="0"
r=10
class="NetworkUI__interface" ></circle>
<text ng-attr-class="{{interface.selected && ! interface.edit_label ? 'NetworkUI__interface-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="-15"> {{interface.name}}</text>
<text class="NetworkUI__interface-text" text-anchor="middle" x="0" y="-15">{{interface.name}}{{interface.edit_label?'_':''}}</text>
<g ng-if="interface.remote_interface() !== null">
<circle cx="0"
cy="100"
r=14
ng-attr-class="{{interface.remote_interface().selected ? 'NetworkUI__interface--selected' : 'NetworkUI--hidden'}}" ></circle>
<circle cx="0"
cy="100"
r=10
class="NetworkUI__interface" ></circle>
</g>
<text class="NetworkUI__interface-text" text-anchor="middle" x="0" y="85">{{interface.remote_interface().name}}</text>
<g ng-repeat="item in [interface.remote_interface().device]">
<g ng-attr-transform="translate(0,100) scale(0.5) translate(0, {{item.height}})"
ng-attr-class="{{item.type}}"
ng-switch on="item.type">
<g ng-switch-when="router"><!-- begin router -->
<g awx-net-router></g>
</g> <!-- end router -->
<g ng-switch-when="switch"> <!-- begin switch -->
<g awx-net-switch> </g>
</g> <!-- end switch -->
<g ng-switch-when="host"> <!-- begin host -->
<g awx-net-host> </g>
</g> <!-- end host -->
<g ng-switch-default> <!-- begin default -->
</g> <!-- end default -->
</g> <!-- end transform class switch -->
</g> <!-- end repeat -->
</g> <!-- end transform -->
</g> <!-- end ng-repeat interface -->
</g> <!-- end transform translate -->
<g transform="translate(0, 100)">
<g ng-repeat="item in item.processes track by $index">
<g ng-attr-transform="translate({{$index * 75 + 50}}, 0) scale(0.5)">
<g awx-net-process></g>
</g> <!-- end translate -->
</g> <!-- end ng-repeat process -->
</g> <!-- end translate -->
</g> <!-- end transform scale translate -->

View File

@@ -0,0 +1,100 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var messages = require('./messages.js');
function Channel(from_controller, to_controller, tracer) {
this.tracer = tracer;
this.from_controller = from_controller;
this.to_controller = to_controller;
this.trace = false;
}
exports.Channel = Channel;
Channel.prototype.send = function(msg_type, message) {
if (this.trace && this.from_controller !== null) {
this.tracer.send_trace_message(new messages.ChannelTrace(this.from_controller.name,
this.to_controller.name,
msg_type));
}
this.to_controller.handle_message(msg_type, message);
};
function NullChannel(from_controller, tracer) {
this.tracer = tracer;
this.from_controller = from_controller;
this.trace = false;
}
NullChannel.prototype.send = function(msg_type) {
if (this.trace) {
this.tracer.send_trace_message(new messages.ChannelTrace(this.from_controller.name,
'null',
msg_type));
}
};
function FSMController (scope, name, initial_state, tracer) {
this.scope = scope;
this.name = name;
this.state = initial_state;
this.delegate_channel = new NullChannel(this, tracer);
this.tracer = tracer;
this.trace = true;
this.handling_message_type = 'start';
this.state.start(this);
this.handling_message_type = null;
}
exports.FSMController = FSMController;
FSMController.prototype.changeState = function (state) {
var old_handling_message_type;
if(this.state !== null) {
old_handling_message_type = this.handling_message_type;
this.handling_message_type = 'end';
this.state.end(this);
this.handling_message_type = old_handling_message_type;
}
if (this.trace) {
this.tracer.send_trace_message(new messages.FSMTrace(this.tracer.trace_order_seq(),
this.name,
this.state.name,
state.name,
this.handling_message_type));
}
this.state = state;
if(state !== null) {
old_handling_message_type = this.handling_message_type;
this.handling_message_type = 'start';
state.start(this);
this.handling_message_type = old_handling_message_type;
}
};
FSMController.prototype.handle_message = function(msg_type, message) {
var old_handling_message_type = this.handling_message_type;
this.handling_message_type = msg_type;
var handler_name = 'on' + msg_type;
if (typeof(this.state[handler_name]) !== "undefined") {
this.state[handler_name](this, msg_type, message);
} else {
this.default_handler(msg_type, message);
}
this.handling_message_type = old_handling_message_type;
};
FSMController.prototype.default_handler = function(msg_type, message) {
this.delegate_channel.send(msg_type, message);
};
function _State () {
}
_State.prototype.start = function () {
};
_State.prototype.end = function () {
};
var State = new _State();
exports.State = State;
exports._State = _State;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/group.partial.svg');
function group () {
return { restrict: 'A', templateUrl};
}
exports.group = group;

View File

@@ -0,0 +1,614 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
var titlecase = require('titlecase');
function _State () {
}
inherits(_State, fsm._State);
function _Resize () {
this.name = 'Resize';
}
inherits(_Resize, _State);
var Resize = new _Resize();
exports.Resize = Resize;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _CornerSelected () {
this.name = 'CornerSelected';
}
inherits(_CornerSelected, _State);
var CornerSelected = new _CornerSelected();
exports.CornerSelected = CornerSelected;
function _Selected1 () {
this.name = 'Selected1';
}
inherits(_Selected1, _State);
var Selected1 = new _Selected1();
exports.Selected1 = Selected1;
function _Selected3 () {
this.name = 'Selected3';
}
inherits(_Selected3, _State);
var Selected3 = new _Selected3();
exports.Selected3 = Selected3;
function _Move () {
this.name = 'Move';
}
inherits(_Move, _State);
var Move = new _Move();
exports.Move = Move;
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Disable () {
this.name = 'Disable';
}
inherits(_Disable, _State);
var Disable = new _Disable();
exports.Disable = Disable;
function _EditLabel () {
this.name = 'EditLabel';
}
inherits(_EditLabel, _State);
var EditLabel = new _EditLabel();
exports.EditLabel = EditLabel;
function _Selected2 () {
this.name = 'Selected2';
}
inherits(_Selected2, _State);
var Selected2 = new _Selected2();
exports.Selected2 = Selected2;
function _Placing () {
this.name = 'Placing';
}
inherits(_Placing, _State);
var Placing = new _Placing();
exports.Placing = Placing;
_State.prototype.onUnselectAll = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.delegate_channel.send(msg_type, $event);
};
_Resize.prototype.onMouseUp = function (controller, msg_type, $event) {
controller.changeState(Selected1);
controller.handle_message(msg_type, $event);
};
_Resize.prototype.onMouseUp.transitions = ['Selected1'];
_Resize.prototype.onMouseMove = function (controller) {
var groups = controller.scope.selected_groups;
var diffX = controller.scope.scaledX - controller.scope.pressedScaledX;
var diffY = controller.scope.scaledY - controller.scope.pressedScaledY;
var i = 0;
var j = 0;
var membership_old_new = [];
var previous_x1, previous_y1, previous_x2, previous_y2;
for (i = 0; i < groups.length; i++) {
previous_x1 = groups[i].x1;
previous_y1 = groups[i].y1;
previous_x2 = groups[i].x2;
previous_y2 = groups[i].y2;
if (groups[i].selected_corner === models.TOP_LEFT) {
groups[i].x1 = groups[i].x1 + diffX;
groups[i].y1 = groups[i].y1 + diffY;
}
if (groups[i].selected_corner === models.BOTTOM_RIGHT) {
groups[i].x2 = groups[i].x2 + diffX;
groups[i].y2 = groups[i].y2 + diffY;
}
if (groups[i].selected_corner === models.TOP_RIGHT) {
groups[i].x2 = groups[i].x2 + diffX;
groups[i].y1 = groups[i].y1 + diffY;
}
if (groups[i].selected_corner === models.BOTTOM_LEFT) {
groups[i].x1 = groups[i].x1 + diffX;
groups[i].y2 = groups[i].y2 + diffY;
}
membership_old_new = groups[i].update_membership(controller.scope.devices,
controller.scope.groups);
for(j = 0; j < membership_old_new[0].length; j++) {
membership_old_new[0][j].selected = false;
}
for(j = 0; j < membership_old_new[1].length; j++) {
membership_old_new[1][j].selected = true;
}
controller.scope.send_control_message(new messages.GroupMove(controller.scope.client_id,
groups[i].id,
groups[i].x1,
groups[i].y1,
groups[i].x2,
groups[i].y2,
previous_x1,
previous_y1,
previous_x2,
previous_y2));
controller.scope.send_control_message(new messages.GroupMembership(controller.scope.client_id,
groups[i].id,
membership_old_new[2]));
}
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
};
_Resize.prototype.start = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
for (i = 0; i < groups.length; i++) {
groups[i].moving = true;
}
};
_Resize.prototype.end = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
var j = 0;
for (i = 0; i < groups.length; i++) {
for(j = 0; j < groups[i].devices.length; j++) {
groups[i].devices[j].selected = false;
}
}
for (i = 0; i < groups.length; i++) {
groups[i].moving = false;
}
};
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_CornerSelected.prototype.start = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
var x = controller.scope.scaledX;
var y = controller.scope.scaledY;
for (i = 0; i < groups.length; i++) {
groups[i].selected_corner = groups[i].select_corner(x, y);
}
};
_CornerSelected.prototype.onMouseMove = function (controller) {
controller.changeState(Resize);
};
_CornerSelected.prototype.onMouseMove.transitions = ['Resize'];
_CornerSelected.prototype.onMouseUp = function (controller, msg_type, $event) {
controller.changeState(Selected1);
controller.handle_message(msg_type, $event);
};
_CornerSelected.prototype.onMouseUp.transitions = ['Selected1'];
_Selected1.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected1.prototype.onMouseMove.transitions = ['Move'];
_Selected1.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Selected1.prototype.onMouseUp.transitions = ['Selected2'];
_Selected3.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected3.prototype.onMouseMove.transitions = ['Move'];
_Selected3.prototype.onMouseUp = function (controller) {
controller.changeState(EditLabel);
};
_Selected3.prototype.onMouseUp.transitions = ['EditLabel'];
_Move.prototype.onMouseMove = function (controller) {
var groups = controller.scope.selected_groups;
var diffX = controller.scope.scaledX - controller.scope.pressedScaledX;
var diffY = controller.scope.scaledY - controller.scope.pressedScaledY;
var i = 0;
var j = 0;
var membership_old_new = [];
var previous_x1, previous_y1, previous_x2, previous_y2;
for (i = 0; i < groups.length; i++) {
previous_x1 = groups[i].x1;
previous_y1 = groups[i].y1;
previous_x2 = groups[i].x2;
previous_y2 = groups[i].y2;
groups[i].x1 = groups[i].x1 + diffX;
groups[i].y1 = groups[i].y1 + diffY;
groups[i].x2 = groups[i].x2 + diffX;
groups[i].y2 = groups[i].y2 + diffY;
membership_old_new = groups[i].update_membership(controller.scope.devices,
controller.scope.groups);
for(j = 0; j < membership_old_new[0].length; j++) {
membership_old_new[0][j].selected = false;
}
for(j = 0; j < membership_old_new[1].length; j++) {
membership_old_new[1][j].selected = true;
}
controller.scope.send_control_message(new messages.GroupMove(controller.scope.client_id,
groups[i].id,
groups[i].x1,
groups[i].y1,
groups[i].x2,
groups[i].y2,
previous_x1,
previous_y1,
previous_x2,
previous_y2));
controller.scope.send_control_message(new messages.GroupMembership(controller.scope.client_id,
groups[i].id,
membership_old_new[2]));
}
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
};
_Move.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Move.prototype.onMouseUp.transitions = ['Selected2'];
_Move.prototype.onMouseDown = function (controller) {
controller.changeState(Selected1);
};
_Move.prototype.onMouseDown.transitions = ['Selected1'];
_Move.prototype.start = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
for (i = 0; i < groups.length; i++) {
groups[i].moving = true;
}
};
_Move.prototype.end = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
var j = 0;
for (i = 0; i < groups.length; i++) {
for(j = 0; j < groups[i].devices.length; j++) {
groups[i].devices[j].selected = false;
}
}
for (i = 0; i < groups.length; i++) {
groups[i].moving = false;
}
};
_Ready.prototype.onMouseMove = function (controller, msg_type, $event) {
if (controller.scope.hide_groups) {
controller.delegate_channel.send(msg_type, $event);
return;
}
var i = 0;
for (i = 0; i < controller.scope.groups.length; i++) {
controller.scope.groups[i].update_hightlighted(controller.scope.scaledX, controller.scope.scaledY);
}
controller.delegate_channel.send(msg_type, $event);
};
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
if (controller.scope.hide_groups) {
controller.delegate_channel.send(msg_type, $event);
return;
}
//
var i = 0;
for (i = 0; i < controller.scope.groups.length; i++) {
controller.scope.groups[i].selected = false;
}
controller.scope.selected_groups = [];
for (i = 0; i < controller.scope.groups.length; i++) {
if (controller.scope.groups[i].has_corner_selected(controller.scope.scaledX, controller.scope.scaledY)) {
controller.scope.clear_selections();
if (controller.scope.selected_groups.indexOf(controller.scope.groups[i]) === -1) {
controller.scope.selected_groups.push(controller.scope.groups[i]);
}
controller.scope.groups[i].selected = true;
controller.changeState(CornerSelected);
controller.scope.pressedX = controller.scope.mouseX;
controller.scope.pressedY = controller.scope.mouseY;
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
return;
} else if (controller.scope.groups[i].is_selected(controller.scope.scaledX, controller.scope.scaledY)) {
controller.scope.clear_selections();
if (controller.scope.selected_groups.indexOf(controller.scope.groups[i]) === -1) {
controller.scope.selected_groups.push(controller.scope.groups[i]);
}
controller.scope.groups[i].selected = true;
controller.changeState(Selected1);
controller.scope.pressedX = controller.scope.mouseX;
controller.scope.pressedY = controller.scope.mouseY;
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
return;
}
}
controller.delegate_channel.send(msg_type, $event);
};
_Ready.prototype.onMouseDown.transitions = ['Selected1', 'CornerSelected'];
_Ready.prototype.onNewGroup = function (controller, msg_type, message) {
controller.scope.hide_groups = false;
controller.scope.new_group_type = message.type;
controller.changeState(Placing);
};
_Ready.prototype.onNewGroup.transitions = ['Placing'];
_Ready.prototype.onPasteGroup = function (controller, msg_type, message) {
var scope = controller.scope;
scope.hide_groups = false;
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
var group = new models.Group(controller.scope.group_id_seq(),
message.group.name,
message.group.type,
scope.scaledX,
scope.scaledY,
scope.scaledX + message.group.x2,
scope.scaledY + message.group.y2,
false);
scope.send_control_message(new messages.GroupCreate(scope.client_id,
group.id,
group.x1,
group.y1,
group.x2,
group.y2,
group.name,
group.type));
scope.groups.push(group);
scope.selected_groups.push(group);
group.selected = true;
controller.changeState(Selected2);
};
_Ready.prototype.onPasteGroup.transitions = ['Selected2'];
_EditLabel.prototype.start = function (controller) {
controller.scope.selected_groups[0].edit_label = true;
};
_EditLabel.prototype.end = function (controller) {
controller.scope.selected_groups[0].edit_label = false;
};
_EditLabel.prototype.onMouseDown = function (controller) {
controller.changeState(Ready);
};
_EditLabel.prototype.onMouseDown.transitions = ['Ready'];
_EditLabel.prototype.onKeyDown = function (controller, msg_type, $event) {
//Key codes found here:
//https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
var item = controller.scope.selected_groups[0];
var previous_name = item.name;
if ($event.keyCode === 8 || $event.keyCode === 46) { //Delete
item.name = item.name.slice(0, -1);
} else if ($event.keyCode >= 48 && $event.keyCode <=90) { //Alphanumeric
item.name += $event.key;
} else if ($event.keyCode >= 186 && $event.keyCode <=222) { //Punctuation
item.name += $event.key;
} else if ($event.keyCode === 13) { //Enter
controller.changeState(Selected2);
} else if ($event.keyCode === 32) { //Space
item.name += " ";
} else {
console.log($event.keyCode);
}
controller.scope.send_control_message(new messages.GroupLabelEdit(controller.scope.client_id,
item.id,
item.name,
previous_name));
};
_EditLabel.prototype.onKeyDown.transitions = ['Selected2'];
_Selected2.prototype.onNewGroup = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
};
_Selected2.prototype.onNewGroup.transitions = ['Ready'];
_Selected2.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.scope.pressedX = controller.scope.mouseX;
controller.scope.pressedY = controller.scope.mouseY;
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
var groups = controller.scope.selected_groups;
controller.scope.selected_groups = [];
var i = 0;
for (i = 0; i < groups.length; i++) {
if (groups[i].has_corner_selected(controller.scope.scaledX, controller.scope.scaledY)) {
controller.scope.selected_groups = [];
break;
}
else if (groups[i].is_selected(controller.scope.scaledX, controller.scope.scaledY)) {
if (controller.scope.selected_groups.indexOf(groups[i]) === -1) {
controller.scope.selected_groups.push(groups[i]);
}
}
}
if (controller.scope.selected_groups.length > 0) {
controller.changeState(Selected3);
} else {
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
}
};
_Selected2.prototype.onMouseDown.transitions = ['Ready', 'Selected3'];
_Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
if ($event.keyCode === 8) {
//Delete
controller.changeState(Ready);
var i = 0;
var index = -1;
var groups = controller.scope.selected_groups;
controller.scope.selected_groups = [];
for (i = 0; i < groups.length; i++) {
index = controller.scope.groups.indexOf(groups[i]);
if (index !== -1) {
groups[i].selected = false;
groups[i].remote_selected = false;
controller.scope.groups.splice(index, 1);
}
controller.scope.send_control_message(new messages.GroupDestroy(controller.scope.client_id,
groups[i].id,
groups[i].x1,
groups[i].y1,
groups[i].x2,
groups[i].y2,
groups[i].name));
}
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
_Placing.prototype.onMouseDown = function (controller) {
var scope = controller.scope;
var group = null;
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
scope.clear_selections();
var id = scope.group_id_seq();
group = new models.Group(id,
titlecase.toTitleCase("" + scope.new_group_type + id),
scope.new_group_type,
scope.scaledX,
scope.scaledY,
scope.scaledX,
scope.scaledY,
false);
scope.send_control_message(new messages.GroupCreate(scope.client_id,
group.id,
group.x1,
group.y1,
group.x2,
group.y2,
group.name,
group.type));
scope.groups.push(group);
scope.selected_groups.push(group);
group.selected = true;
group.selected_corner = models.BOTTOM_RIGHT;
controller.scope.new_group_type = null;
controller.changeState(Resize);
};
_Placing.prototype.onMouseDown.transitions = ['Resize'];

View File

@@ -0,0 +1,134 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="!hide_groups || item.type == 'site'">
<g ng-if="current_scale < 5">
<g ng-if="current_scale > 0.5 || item.type == 'site' || (item.type == 'rack' && current_scale > 0.1)" >
<g ng-if="item.moving">
<g ng-attr-transform="translate({{item.left_extent(scaledX)}}, {{item.top_extent(scaledY)}})">
<line x1="-100"
y1="0"
x2="+100"
y2="0"
class="NetworkUI--construction"></line>
<line x1="0"
y1="-100"
x2="0"
y2="+100"
class="NetworkUI--construction"></line>
</g>
<g ng-attr-transform="translate({{item.right_extent(scaledX)}}, {{item.top_extent(scaledY)}})">
<line x1="-100"
y1="0"
x2="+100"
y2="0"
class="NetworkUI--construction"></line>
<line x1="0"
y1="-100"
x2="0"
y2="+100"
class="NetworkUI--construction"></line>
</g>
<g ng-attr-transform="translate({{item.left_extent(scaledX)}}, {{item.bottom_extent(scaledY)}})">
<line x1="-100"
y1="0"
x2="+100"
y2="0"
class="NetworkUI--construction"></line>
<line x1="0"
y1="-100"
x2="0"
y2="+100"
class="NetworkUI--construction"></line>
</g>
<g ng-attr-transform="translate({{item.right_extent(scaledX)}}, {{item.bottom_extent(scaledY)}})">
<line x1="-100"
y1="0"
x2="+100"
y2="0"
class="NetworkUI--construction"></line>
<line x1="0"
y1="-100"
x2="0"
y2="+100"
class="NetworkUI--construction"></line>
</g>
</g>
<rect ng-attr-width="{{item.width(scaledX)}}"
ng-attr-height="{{item.height(scaledY)}}"
ng-attr-x="{{item.left_extent(scaledX)}}"
ng-attr-y="{{item.top_extent(scaledY)}}"
ng-attr-class="{{item.selected && 'NetworkUI__group--selected' || 'NetworkUI--hidden'}}"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.left_extent(scaledX)}}"
ng-attr-y="{{item.top_extent(scaledY)}}"
ng-attr-class="{{item.selected && 'NetworkUI__group--selected' || 'NetworkUI--hidden'}}"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.right_extent(scaledX) - 10}}"
ng-attr-y="{{item.top_extent(scaledY)}}"
ng-attr-class="{{item.selected && 'NetworkUI__group--selected' || 'NetworkUI--hidden'}}"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.right_extent(scaledX) - 10}}"
ng-attr-y="{{item.bottom_extent(scaledY) - 10}}"
ng-attr-class="{{item.selected && 'NetworkUI__group--selected' || 'NetworkUI--hidden'}}"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.left_extent(scaledX)}}"
ng-attr-y="{{item.bottom_extent(scaledY) - 10}}"
ng-attr-class="{{item.selected && 'NetworkUI__group--selected' || 'NetworkUI--hidden'}}"/>
<g ng-if="item.highlighted || item.selected">
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.left_extent(scaledX)}}"
ng-attr-y="{{item.top_extent(scaledY)}}"
class="NetworkUI__group"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.right_extent(scaledX) - 10}}"
ng-attr-y="{{item.top_extent(scaledY)}}"
class="NetworkUI__group"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.right_extent(scaledX) - 10}}"
ng-attr-y="{{item.bottom_extent(scaledY) - 10}}"
class="NetworkUI__group"/>
<rect ng-attr-width="10"
ng-attr-height="10"
ng-attr-x="{{item.left_extent(scaledX)}}"
ng-attr-y="{{item.bottom_extent(scaledY) - 10}}"
class="NetworkUI__group"/>
</g>
<rect ng-attr-width="{{item.width(scaledX)}}"
ng-attr-height="{{item.height(scaledY)}}"
ng-attr-x="{{item.left_extent(scaledX)}}"
ng-attr-y="{{item.top_extent(scaledY)}}"
class="NetworkUI__group"/>
<g ng-attr-transform="translate({{item.left_extent(scaledX)}},{{item.top_extent(scaledY)}})">
<g ng-if="current_scale > 0.5 || item.type == 'site' || item.type == 'rack'">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__group-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="left"
x="20"
y="32"> {{item.name}} </text>
<text class="NetworkUI__group-text" text-anchor="left" x="20" y="32">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>
<g awx-net-rack></g>
<g awx-net-site></g>
</g>
</g>
</g>
</g>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/host.partial.svg');
function host () {
return { restrict: 'A', templateUrl};
}
exports.host = host;

View File

@@ -0,0 +1,60 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="item.moving">
<line ng-attr-x1="{{-50 - 100}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 100}}"
ng-attr-y2="0"
class="NetworkUI--construction"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-15 - 100}}"
ng-attr-x2="0"
ng-attr-y2="{{15 + 100}}"
class="NetworkUI--construction"></line>
</g>
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-15 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{15 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-15}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{15 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<g class="NetworkUI__host">
<rect
x="-52"
y="-17"
ng-attr-width="{{100 + 4}}"
ng-attr-height="{{30 + 4}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__host--selected-conflict' : item.selected ? 'NetworkUI__host--selected' : 'NetworkUI__host--remote-selected' : 'NetworkUI--hidden'}}"
rx=10>
</rect>
<rect
x="-50"
y="-15"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<circle cx="30" cy="0" r=7 />
</circle>
</g>
<g ng-show="item.icon || current_scale > 0.5">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__host-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="5"> {{item.name}} </text>
<text class="NetworkUI__host-text" text-anchor="middle" x="0" y="5">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>

View File

@@ -0,0 +1,128 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var messages = require('./messages.js');
function _State () {
}
inherits(_State, fsm._State);
function _Enabled () {
this.name = 'Enabled';
}
inherits(_Enabled, _State);
var Enabled = new _Enabled();
exports.Enabled = Enabled;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Disabled () {
this.name = 'Disabled';
}
inherits(_Disabled, _State);
var Disabled = new _Disabled();
exports.Disabled = Disabled;
_Enabled.prototype.onDisable = function (controller) {
controller.changeState(Disabled);
};
_Enabled.prototype.onDisable.transitions = ['Disabled'];
_Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
var scope = controller.scope;
if ($event.key === 'c' && ($event.ctrlKey || $event.metaKey)) {
scope.first_channel.send("CopySelected", $event);
}
if ($event.key === 'l') {
scope.first_channel.send("NewLink", $event);
return;
}
if ($event.key === 'm') {
scope.first_channel.send("NewStream", $event);
}
if ($event.key === 'd') {
scope.debug.hidden = !scope.debug.hidden;
return;
}
if ($event.key === 'p') {
scope.cursor.hidden = !scope.cursor.hidden;
return;
}
if ($event.key === 'b') {
scope.hide_buttons = !scope.hide_buttons;
return;
}
if ($event.key === 'i') {
scope.hide_interfaces = !scope.hide_interfaces;
return;
}
if ($event.key === 'r') {
scope.first_channel.send("NewDevice", new messages.NewDevice("router"));
return;
}
else if ($event.key === 's') {
scope.first_channel.send("NewDevice", new messages.NewDevice("switch"));
return;
}
else if ($event.key === 'a') {
scope.first_channel.send("NewGroup", new messages.NewGroup("rack"));
return;
}
else if ($event.key === 'h') {
scope.first_channel.send("NewDevice", new messages.NewDevice("host"));
return;
}
else if ($event.key === 'g') {
scope.first_channel.send("NewGroup", new messages.NewGroup("group"));
return;
}
else if ($event.key === 'e') {
scope.first_channel.send("NewGroup", new messages.NewGroup("site"));
return;
}
else if ($event.key === '0') {
scope.panX = 0;
scope.panY = 0;
scope.current_scale = 1.0;
scope.updateScaledXY();
scope.updatePanAndScale();
}
controller.delegate_channel.send(msg_type, $event);
};
_Start.prototype.start = function (controller) {
controller.changeState(Enabled);
};
_Start.prototype.start.transitions = ['Enabled'];
_Disabled.prototype.onEnable = function (controller) {
controller.changeState(Enabled);
};
_Disabled.prototype.onEnable.transitions = ['Enabled'];

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/inventory_toolbox_clip_path.partial.svg');
function inventoryToolboxClipPath () {
return { restrict: 'A', templateUrl};
}
exports.inventoryToolboxClipPath = inventoryToolboxClipPath;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/inventory_toolbox.partial.svg');
function inventoryToolbox () {
return { restrict: 'A', templateUrl};
}
exports.inventoryToolbox = inventoryToolbox;

View File

@@ -0,0 +1,122 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<!-- begin collapsed toolbox -->
<g ng-if="overall_toolbox_collapsed">
<rect class="NetworkUI__toolbox-collapsed"
x=0
y=40
width=45
ng-attr-height={{toolbox.height}}>
</rect>
<g awx-net-chevron-right-icon
action-icon="action_icons[1]"
ng-if="overall_toolbox_collapsed"
ng-attr-transform="translate({{action_icons[1].x}}, {{action_icons[1].y}})"></g>
</g>
<!-- end collapsed toolbox -->
<g ng-if="toolbox.enabled">
<rect class="NetworkUI__toolbox"
ng-attr-x="{{toolbox.x}}"
ng-attr-y="{{toolbox.y}}"
ng-attr-width="{{toolbox.width}}"
ng-attr-height="{{toolbox.height}}"
rx=5></rect>
<text
class="NetworkUI__toolbox--title"
ng-attr-transform="translate({{toolbox.title_coordinates.x}},{{toolbox.title_coordinates.y}})">
{{toolbox.name}}
</text>
<g awx-net-chevron-left-icon
action-icon="action_icons[0]"
ng-if="toolbox.enabled"
ng-attr-transform="translate({{action_icons[0].x}}, {{action_icons[0].y}})"></g>
<g clip-path="url(#inventory-toolbox-clip-path)">
<g ng-attr-transform="translate({{toolbox.x}}, {{toolbox.y+20}})">
<g ng-repeat="item in toolbox.items track by $index"
ng-attr-transform="translate({{toolbox.width/2}},{{$index * toolbox.spacing + toolbox.spacing/2 + toolbox.scroll_offset}})"
ng-attr-class="{{item.type}}"
ng-switch on="item.type">
<g ng-switch-when="router"><!-- begin router -->
<g awx-net-router></g>
</g> <!-- end router -->
<g ng-switch-when="switch"> <!-- begin switch -->
<g awx-net-switch> </g>
</g> <!-- end switch -->
<g ng-switch-when="host"> <!-- begin host -->
<g awx-net-host> </g>
</g> <!-- end host -->
<g ng-switch-when="site"> <!-- begin site -->
<g awx-net-site-icon> </g>
</g> <!-- end site -->
<g ng-switch-when="rack"> <!-- begin rack -->
<g awx-net-rack-icon> </g>
</g> <!-- end rack -->
<g ng-switch-when="process"> <!-- begin site -->
<g awx-net-process> </g>
</g> <!-- end site -->
<g ng-switch-when="configuration"> <!-- begin site -->
<g awx-net-configuration> </g>
</g> <!-- end site -->
<g ng-switch-default> <!-- begin default -->
<g awx-net-default></g>
</g> <!-- end default -->
</g> <!-- end devices -->
</g> <!-- end transform -->
</g> <!-- end clip path -->
<rect class="NetworkUI__toolbox-bezel"
ng-attr-x="{{toolbox.x}}"
ng-attr-y="{{toolbox.y}}"
ng-attr-width="{{toolbox.width}}"
ng-attr-height="{{toolbox.height}}"
rx=5></rect>
<!-- selected item-->
<g ng-if="toolbox.selected_item != null">
<g ng-repeat="item in [toolbox.selected_item]"
ng-attr-transform="translate({{item.x}}, {{item.y}})"
ng-attr-class="{{item.type}}"
ng-switch on="item.type">
<g ng-switch-when="router"><!-- begin router -->
<g awx-net-router></g>
</g> <!-- end router -->
<g ng-switch-when="switch"> <!-- begin switch -->
<g awx-net-switch> </g>
</g> <!-- end switch -->
<g ng-switch-when="host"> <!-- begin host -->
<g awx-net-host> </g>
</g> <!-- end host -->
<g ng-switch-when="site"> <!-- begin site -->
<g awx-net-site-icon> </g>
</g> <!-- end site -->
<g ng-switch-when="rack"> <!-- begin rack -->
<g awx-net-rack-icon> </g>
</g> <!-- end rack -->
<g ng-switch-when="process"> <!-- begin site -->
<g awx-net-process> </g>
</g> <!-- end site -->
<g ng-switch-when="configuration"> <!-- begin site -->
<g awx-net-configuration> </g>
</g> <!-- end site -->
<g ng-switch-default> <!-- begin default -->
<g awx-net-default></g>
</g> <!-- end default -->
</g> <!-- end selected item -->
</g> <!-- ng-if -->
</g> <!-- ng-if toolbox.enabled -->

View File

@@ -0,0 +1,6 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<rect ng-attr-x="{{toolbox.x}}"
ng-attr-y="{{toolbox.y}}"
ng-attr-width="{{toolbox.width}}"
ng-attr-height="{{toolbox.height}}"></rect>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/layer.partial.svg');
function layer () {
return { restrict: 'A', templateUrl};
}
exports.layer = layer;

View File

@@ -0,0 +1,14 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<rect ng-attr-class="{{layer.is_pressed ? 'NetworkUI__layer--button-pressed' : layer.mouse_over ? 'NetworkUI__layer--button-hover' : 'NetworkUI__layer'}}"
x=0
y=0
ng-attr-width={{layer.width}}
ng-attr-height={{layer.height}}
rx=5></rect>
<text ng-attr-class="{{layer.is_pressed ? 'NetworkUI__layer-text--button-pressed' : layer.mouse_over ? 'NetworkUI__layer-text--button-hover' : 'NetworkUI__layer-text'}}"
ng-attr-x="{{layer.width/2}}"
ng-attr-y="{{layer.height/2}}"
dy=".3em"
text-anchor="middle">{{layer.name}}</text>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/link.partial.svg');
function link () {
return { restrict: 'A', templateUrl};
}
exports.link = link;

View File

@@ -0,0 +1,144 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Connected () {
this.name = 'Connected';
}
inherits(_Connected, _State);
var Connected = new _Connected();
exports.Connected = Connected;
function _Connecting () {
this.name = 'Connecting';
}
inherits(_Connecting, _State);
var Connecting = new _Connecting();
exports.Connecting = Connecting;
function _Selecting () {
this.name = 'Selecting';
}
inherits(_Selecting, _State);
var Selecting = new _Selecting();
exports.Selecting = Selecting;
_Ready.prototype.onNewLink = function (controller, msg_type, message) {
controller.scope.clear_selections();
controller.changeState(Selecting);
controller.delegate_channel.send(msg_type, message);
};
_Ready.prototype.onNewLink.transitions = ['Selecting'];
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Connected.prototype.start = function (controller) {
controller.scope.clear_selections();
controller.changeState(Ready);
};
_Connected.prototype.start.transitions = ['Ready'];
_Connecting.prototype.onMouseDown = function () {
};
_Connecting.prototype.onMouseUp = function (controller) {
var selected_device = controller.scope.select_items(false).last_selected_device;
var to_device_interface = null;
var from_device_interface = null;
var i = 0;
if (selected_device !== null) {
controller.scope.new_link.to_device = selected_device;
i = controller.scope.new_link.to_device.interface_seq();
to_device_interface = new models.Interface(i, "eth" + i);
controller.scope.new_link.to_device.interfaces.push(to_device_interface);
i = controller.scope.new_link.from_device.interface_seq();
from_device_interface = new models.Interface(i, "eth" + i);
controller.scope.new_link.from_device.interfaces.push(from_device_interface);
to_device_interface.link = controller.scope.new_link;
from_device_interface.link = controller.scope.new_link;
to_device_interface.device = controller.scope.new_link.to_device;
from_device_interface.device = controller.scope.new_link.from_device;
controller.scope.new_link.to_interface = to_device_interface;
controller.scope.new_link.from_interface = from_device_interface;
to_device_interface.dot();
from_device_interface.dot();
controller.scope.send_control_message(new messages.MultipleMessage(controller.scope.client_id, [
new messages.InterfaceCreate(controller.scope.client_id,
controller.scope.new_link.from_device.id,
from_device_interface.id,
from_device_interface.name),
new messages.InterfaceCreate(controller.scope.client_id,
controller.scope.new_link.to_device.id,
to_device_interface.id,
to_device_interface.name),
new messages.LinkCreate(controller.scope.client_id,
controller.scope.new_link.id,
controller.scope.new_link.from_device.id,
controller.scope.new_link.to_device.id,
from_device_interface.id,
to_device_interface.id)]));
controller.scope.new_link = null;
controller.changeState(Connected);
} else {
var index = controller.scope.links.indexOf(controller.scope.new_link);
if (index !== -1) {
controller.scope.links.splice(index, 1);
}
controller.scope.new_link = null;
controller.changeState(Ready);
}
};
_Connecting.prototype.onMouseUp.transitions = ['Ready', 'Connected'];
_Selecting.prototype.onMouseDown = function () {
};
_Selecting.prototype.onMouseUp = function (controller) {
var selected_device = controller.scope.select_items(false).last_selected_device;
if (selected_device !== null) {
controller.scope.new_link = new models.Link(controller.scope.link_id_seq(), selected_device, null, null, null, true);
controller.scope.links.push(controller.scope.new_link);
controller.changeState(Connecting);
}
};
_Selecting.prototype.onMouseUp.transitions = ['Connecting'];

View File

@@ -0,0 +1,128 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<line ng-attr-x1="{{link.from_device.x}}"
ng-attr-y1="{{link.from_device.y}}"
ng-attr-x2="{{link.to_device !== null ? link.to_device.x : scaledX}}"
ng-attr-y2="{{link.to_device !== null ? link.to_device.y : scaledY}}"
ng-attr-class="{{link.selected && 'NetworkUI__link--selected' || 'NetworkUI--hidden'}}"/>
<line ng-attr-x1="{{link.from_device.x}}"
ng-attr-y1="{{link.from_device.y}}"
ng-attr-x2="{{link.to_device !== null ? link.to_device.x : scaledX}}"
ng-attr-y2="{{link.to_device !== null ? link.to_device.y : scaledY}}"
class="{{link.status === null ? 'NetworkUI__link' : link.status ? 'NetworkUI__link--link-pass' : 'NetworkUI__link--link-fail'}}"/>
<g ng-if="!debug.hidden && current_scale > 0.5">
<line ng-if="link.to_device !== null && link.plength(scaledX, scaledY) < 100"
ng-attr-x1="{{link.pDistanceLine(scaledX, scaledY).x2}}"
ng-attr-y1="{{link.pDistanceLine(scaledX, scaledY).y2}}"
ng-attr-x2="{{scaledX}}"
ng-attr-y2="{{scaledY}}"
ng-attr-class="NetworkUI__link--debug" />
<g ng-if="link.to_device !== null" ng-attr-transform="translate({{link.to_device.x}},
{{link.to_device.y}})
rotate({{link.slope()}})
translate({{link.length()/2}}, 0)">
<circle ng-attr-cx="0"
ng-attr-cy="0"
r=10
class="NetworkUI__circle-debug" ></circle>
</g>
<g ng-if="link.to_device !== null" ng-attr-transform="translate({{link.to_device.x}},
{{link.to_device.y}})
rotate({{link.slope()}})
translate({{link.length()/2}}, 0)">
<line x1="0" y1=-20 x2=0 y2=20 class="NetworkUI__link--debug"/>
</g>
<g ng-if="link.to_device !== null" ng-attr-transform="translate({{link.to_device.x}},
{{link.to_device.y}})
rotate({{link.slope()}})
translate({{link.to_device.size}}, 0)">
<circle ng-attr-cx="0"
ng-attr-cy="0"
r=10
class="NetworkUI__circle-debug" ></circle>
</g>
<g ng-if="link.to_device !== null" ng-attr-transform="translate({{link.from_device.x}},
{{link.from_device.y}})
rotate({{link.slope()}})
translate({{-link.from_device.size}}, 0)">
<circle ng-attr-cx="0"
ng-attr-cy="0"
r=10
class="NetworkUI__circle-debug" ></circle>
</g>
</g>
<g ng-if="link.to_device !== null" ng-attr-transform="translate({{link.to_device.x}},
{{link.to_device.y}})
rotate({{link.slope()}})
translate({{link.to_device.size}}, 0)
rotate(180)
translate(-19, -9)
">
</g>
<g ng-if="(!hide_interfaces && selected_links.length === 0 && selected_interfaces.length === 0) || link.selected || link.to_interface.selected || link.from_interface.selected">
<g ng-if="current_scale > 1.0 && link.to_device !== null"
ng-attr-transform="translate({{link.from_device.x}},
{{link.from_device.y}})
rotate({{link.slope()}})
translate({{-link.length()/2}}, 0)
rotate({{-link.slope()}})
translate(0, -5)
">
<text ng-attr-class="{{link.selected && ! link.edit_label ? 'selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
font-size="8"
x="0"
y="0"> {{link.name}}</text>
<text class="NetworkUI__link-text" text-anchor="middle" x="0" y="0">{{link.name}}{{link.edit_label?'_':''}}</text>
</g>
<g ng-if="current_scale > 1.0 && link.to_device !== null"
ng-attr-transform="translate({{link.from_device.x}},
{{link.from_device.y}})
rotate({{link.slope()}})
translate({{-link.from_interface.dot_d - 25}}, 0)
rotate({{-link.slope()}})
">
<text ng-attr-class="{{link.from_interface.selected && ! link.from_interface.edit_label ? 'NetworkUI__interface-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
font-size="8"
x="0"
y="0"> {{link.from_interface.name}}</text>
<text class="NetworkUI__interface-text" text-anchor="middle" x="0" y="0">{{link.from_interface.name}}{{link.from_interface.edit_label ?'_':''}}</text>
</g>
<g ng-if="current_scale > 1.0 && link.to_device !== null"
ng-attr-transform="translate({{link.from_device.x}},
{{link.from_device.y}})
rotate({{link.slope()}})
translate({{-link.length() + link.to_interface.dot_d + 25}}, 0)
rotate({{-link.slope()}})
">
<text ng-attr-class="{{link.to_interface.selected && ! link.to_interface.edit_label ? 'NetworkUI__interface-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="0"> {{link.to_interface.name}}</text>
<text class="NetworkUI__interface-text" text-anchor="middle" x="0" y="0">{{link.to_interface.name}}{{link.to_interface.edit_label?'_':''}}</text>
</g>
<g ng-if="current_scale > 1.0 && link.to_device !== null">
<circle ng-attr-cx="{{link.from_interface.dot_x}}"
ng-attr-cy="{{link.from_interface.dot_y}}"
r=14
ng-attr-class="{{link.from_interface.selected ? 'NetworkUI__interface--selected' : 'NetworkUI--hidden'}}" ></circle>
<circle ng-attr-cx="{{link.from_interface.dot_x}}"
ng-attr-cy="{{link.from_interface.dot_y}}"
r=10
class="NetworkUI__interface" ></circle>
<circle ng-attr-cx="{{link.to_interface.dot_x}}"
ng-attr-cy="{{link.to_interface.dot_y}}"
r=14
ng-attr-class="{{link.to_interface.selected ? 'NetworkUI__interface--selected' : 'NetworkUI--hidden'}}" ></circle>
<circle ng-attr-cx="{{link.to_interface.dot_x}}"
ng-attr-cy="{{link.to_interface.dot_y}}"
r=10
class="NetworkUI__interface" ></circle>
</g>
</g> <!-- end hide_interfaces -->

View File

@@ -0,0 +1,12 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var networkUI = require('./network.ui.app.js');
var networkWidgets = require('./network.widgets.app.js');
var tablesUI = require('./tables.ui.app.js');
var tower = require('./tower.app.js');
var ngTouch = require('./ngTouch.js');
exports.networkUI = networkUI.networkUI;
exports.tablesUI = tablesUI.tablesUI;
exports.tower = tower.tower;
exports.ngTouch = ngTouch;
exports.networkWidgets = networkWidgets;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/map.partial.svg');
function map () {
return { restrict: 'A', templateUrl};
}
exports.map = map;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,446 @@
/* Copyright (c) 2017 Red Hat, Inc. */
function serialize(message) {
return JSON.stringify([message.constructor.name, message]);
}
exports.serialize = serialize;
function DeviceMove(sender, id, x, y, previous_x, previous_y) {
this.msg_type = "DeviceMove";
this.sender = sender;
this.id = id;
this.x = x;
this.y = y;
this.previous_x = previous_x;
this.previous_y = previous_y;
}
exports.DeviceMove = DeviceMove;
function DeviceCreate(sender, id, x, y, name, type) {
this.msg_type = "DeviceCreate";
this.sender = sender;
this.id = id;
this.x = x;
this.y = y;
this.name = name;
this.type = type;
}
exports.DeviceCreate = DeviceCreate;
function DeviceDestroy(sender, id, previous_x, previous_y, previous_name, previous_type) {
this.msg_type = "DeviceDestroy";
this.sender = sender;
this.id = id;
this.previous_x = previous_x;
this.previous_y = previous_y;
this.previous_name = previous_name;
this.previous_type = previous_type;
}
exports.DeviceDestroy = DeviceDestroy;
function DeviceLabelEdit(sender, id, name, previous_name) {
this.msg_type = "DeviceLabelEdit";
this.sender = sender;
this.id = id;
this.name = name;
this.previous_name = previous_name;
}
exports.DeviceLabelEdit = DeviceLabelEdit;
function DeviceSelected(sender, id) {
this.msg_type = "DeviceSelected";
this.sender = sender;
this.id = id;
}
exports.DeviceSelected = DeviceSelected;
function DeviceUnSelected(sender, id) {
this.msg_type = "DeviceUnSelected";
this.sender = sender;
this.id = id;
}
exports.DeviceUnSelected = DeviceUnSelected;
function InterfaceCreate(sender, device_id, id, name) {
this.msg_type = "InterfaceCreate";
this.sender = sender;
this.device_id = device_id;
this.id = id;
this.name = name;
}
exports.InterfaceCreate = InterfaceCreate;
function InterfaceLabelEdit(sender, id, device_id, name, previous_name) {
this.msg_type = "InterfaceLabelEdit";
this.sender = sender;
this.id = id;
this.device_id = device_id;
this.name = name;
this.previous_name = previous_name;
}
exports.InterfaceLabelEdit = InterfaceLabelEdit;
function LinkLabelEdit(sender, id, name, previous_name) {
this.msg_type = "LinkLabelEdit";
this.sender = sender;
this.id = id;
this.name = name;
this.previous_name = previous_name;
}
exports.LinkLabelEdit = LinkLabelEdit;
function LinkCreate(sender, id, from_device_id, to_device_id, from_interface_id, to_interface_id) {
this.msg_type = "LinkCreate";
this.id = id;
this.sender = sender;
this.name = '';
this.from_device_id = from_device_id;
this.to_device_id = to_device_id;
this.from_interface_id = from_interface_id;
this.to_interface_id = to_interface_id;
}
exports.LinkCreate = LinkCreate;
function LinkDestroy(sender, id, from_device_id, to_device_id, from_interface_id, to_interface_id, name) {
this.msg_type = "LinkDestroy";
this.id = id;
this.sender = sender;
this.name = name;
this.from_device_id = from_device_id;
this.to_device_id = to_device_id;
this.from_interface_id = from_interface_id;
this.to_interface_id = to_interface_id;
}
exports.LinkDestroy = LinkDestroy;
function LinkSelected(sender, id) {
this.msg_type = "LinkSelected";
this.sender = sender;
this.id = id;
}
exports.LinkSelected = LinkSelected;
function LinkUnSelected(sender, id) {
this.msg_type = "LinkUnSelected";
this.sender = sender;
this.id = id;
}
exports.LinkUnSelected = LinkUnSelected;
function Undo(sender, original_message) {
this.msg_type = "Undo";
this.sender = sender;
this.original_message = original_message;
}
exports.Undo = Undo;
function Redo(sender, original_message) {
this.msg_type = "Redo";
this.sender = sender;
this.original_message = original_message;
}
exports.Redo = Redo;
function Deploy(sender) {
this.msg_type = "Deploy";
this.sender = sender;
}
exports.Deploy = Deploy;
function Destroy(sender) {
this.msg_type = "Destroy";
this.sender = sender;
}
exports.Destroy = Destroy;
function Discover(sender) {
this.msg_type = "Discover";
this.sender = sender;
}
exports.Discover = Discover;
function Layout(sender) {
this.msg_type = "Layout";
this.sender = sender;
}
exports.Layout = Layout;
function MultipleMessage(sender, messages) {
this.msg_type = "MultipleMessage";
this.sender = sender;
this.messages = messages;
}
exports.MultipleMessage = MultipleMessage;
function Coverage(sender, coverage) {
this.msg_type = "Coverage";
this.sender = sender;
this.coverage = coverage;
}
exports.Coverage = Coverage;
function MouseEvent(sender, x, y, type) {
this.msg_type = "MouseEvent";
this.sender = sender;
this.x = x;
this.y = y;
this.type = type;
}
exports.MouseEvent = MouseEvent;
function MouseWheelEvent(sender, delta, deltaX, deltaY, type, metaKey) {
this.msg_type = "MouseWheelEvent";
this.sender = sender;
this.delta = delta;
this.deltaX = deltaX;
this.deltaY = deltaY;
this.type = type;
this.originalEvent = {metaKey: metaKey};
}
exports.MouseWheelEvent = MouseWheelEvent;
function KeyEvent(sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey) {
this.msg_type = "KeyEvent";
this.sender = sender;
this.key = key;
this.keyCode = keyCode;
this.type = type;
this.altKey = altKey;
this.shiftKey = shiftKey;
this.ctrlKey = ctrlKey;
this.metaKey = metaKey;
}
exports.KeyEvent = KeyEvent;
function TouchEvent(sender, type, touches) {
this.msg_type = "TouchEvent";
this.sender = sender;
this.type = type;
this.touches = touches;
}
exports.TouchEvent = TouchEvent;
function StartRecording(sender) {
this.msg_type = "StartRecording";
this.sender = sender;
}
exports.StartRecording = StartRecording;
function StopRecording(sender) {
this.msg_type = "StopRecording";
this.sender = sender;
}
exports.StopRecording = StopRecording;
function ViewPort(sender, scale, panX, panY) {
this.msg_type = "ViewPort";
this.sender = sender;
this.scale = scale;
this.panX = panX;
this.panY = panY;
}
exports.ViewPort = ViewPort;
function NewDevice(type) {
this.type = type;
}
exports.NewDevice = NewDevice;
function PasteDevice(device) {
this.device = device;
}
exports.PasteDevice = PasteDevice;
function PasteProcess(process) {
this.process = process;
}
exports.PasteProcess = PasteProcess;
function NewGroup(type) {
this.type = type;
}
exports.NewGroup = NewGroup;
function PasteGroup(group) {
this.group = group;
}
exports.PasteGroup = PasteGroup;
function PasteRack(group) {
this.group = group;
}
exports.PasteRack = PasteRack;
function PasteSite(group) {
this.group = group;
}
exports.PasteSite = PasteSite;
function CopySite(site) {
this.msg_type = "CopySite";
this.site = site;
}
exports.CopySite = CopySite;
function GroupMove(sender, id, x1, y1, x2, y2, previous_x1, previous_y1, previous_x2, previous_y2) {
this.msg_type = "GroupMove";
this.sender = sender;
this.id = id;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.previous_x1 = previous_x1;
this.previous_y1 = previous_y1;
this.previous_x2 = previous_x2;
this.previous_y2 = previous_y2;
}
exports.GroupMove = GroupMove;
function GroupCreate(sender, id, x1, y1, x2, y2, name, type) {
this.msg_type = "GroupCreate";
this.sender = sender;
this.id = id;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.name = name;
this.type = type;
}
exports.GroupCreate = GroupCreate;
function GroupDestroy(sender, id, previous_x1, previous_y1, previous_x2, previous_y2, previous_name, previous_type) {
this.msg_type = "GroupDestroy";
this.sender = sender;
this.id = id;
this.previous_x1 = previous_x1;
this.previous_y1 = previous_y1;
this.previous_x2 = previous_x2;
this.previous_y2 = previous_y2;
this.previous_name = previous_name;
this.previous_type = previous_type;
}
exports.GroupDestroy = GroupDestroy;
function GroupLabelEdit(sender, id, name, previous_name) {
this.msg_type = "GroupLabelEdit";
this.sender = sender;
this.id = id;
this.name = name;
this.previous_name = previous_name;
}
exports.GroupLabelEdit = GroupLabelEdit;
function GroupSelected(sender, id) {
this.msg_type = "GroupSelected";
this.sender = sender;
this.id = id;
}
exports.GroupSelected = GroupSelected;
function GroupUnSelected(sender, id) {
this.msg_type = "GroupUnSelected";
this.sender = sender;
this.id = id;
}
exports.GroupUnSelected = GroupUnSelected;
function GroupMembership(sender, id, members) {
this.msg_type = "GroupMembership";
this.sender = sender;
this.id = id;
this.members = members;
}
exports.GroupMembership = GroupMembership;
function TableCellEdit(sender, sheet, col, row, old_value, new_value) {
this.msg_type = "TableCellEdit";
this.sender = sender;
this.sheet = sheet;
this.col = col;
this.row = row;
this.old_value = old_value;
this.new_value = new_value;
}
exports.TableCellEdit = TableCellEdit;
function ProcessCreate(sender, id, name, type, device_id, x, y) {
this.msg_type = "ProcessCreate";
this.id = id;
this.name = name;
this.type = type;
this.device_id = device_id;
this.x = x;
this.y = y;
}
exports.ProcessCreate = ProcessCreate;
function StreamCreate(sender, id, from_id, to_id, label) {
this.msg_type = "StreamCreate";
this.sender = sender;
this.id = id;
this.from_id = from_id;
this.to_id = to_id;
this.label = label;
}
exports.StreamCreate = StreamCreate;
function StreamDestroy(sender, id, from_id, to_id, label) {
this.msg_type = "StreamDestroy";
this.sender = sender;
this.id = id;
this.from_id = from_id;
this.to_id = to_id;
this.label = label;
}
exports.StreamDestroy = StreamDestroy;
function StreamLabelEdit(sender, id, label, previous_label) {
this.msg_type = "StreamLabelEdit";
this.sender = sender;
this.id = id;
this.label = label;
this.previous_label = previous_label;
}
exports.StreamLabelEdit = StreamLabelEdit;
function StreamSelected(sender, id) {
this.msg_type = "StreamSelected";
this.sender = sender;
this.id = id;
}
exports.StreamSelected = StreamSelected;
function StreamUnSelected(sender, id) {
this.msg_type = "StreamUnSelected";
this.sender = sender;
this.id = id;
}
exports.StreamUnSelected = StreamUnSelected;
function FSMTrace(order, fsm_name, from_state, to_state, recv_message_type) {
this.msg_type = 'FSMTrace';
this.order = order;
this.sender = 0;
this.trace_id = 0;
this.fsm_name = fsm_name;
this.from_state = from_state;
this.to_state = to_state;
this.recv_message_type = recv_message_type;
}
exports.FSMTrace = FSMTrace;
function ChannelTrace(from_fsm, to_fsm, sent_message_type) {
this.msg_type = 'ChannelTrace';
this.sender = 0;
this.trace_id = 0;
this.from_fsm = from_fsm;
this.to_fsm = to_fsm;
this.sent_message_type = sent_message_type;
}
exports.ChannelTrace = ChannelTrace;

View File

@@ -0,0 +1,205 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var move = require('./move.js');
var group = require('./group.js');
var rack_fsm = require('./rack.fsm.js');
var site_fsm = require('./site.fsm.js');
function _State () {
}
inherits(_State, fsm._State);
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Interface () {
this.name = 'Interface';
}
inherits(_Interface, _State);
var Interface = new _Interface();
exports.Interface = Interface;
function _Site () {
this.name = 'Site';
}
inherits(_Site, _State);
var Site = new _Site();
exports.Site = Site;
function _Process () {
this.name = 'Process';
}
inherits(_Process, _State);
var Process = new _Process();
exports.Process = Process;
function _MultiSite () {
this.name = 'MultiSite';
}
inherits(_MultiSite, _State);
var MultiSite = new _MultiSite();
exports.MultiSite = MultiSite;
function _Rack () {
this.name = 'Rack';
}
inherits(_Rack, _State);
var Rack = new _Rack();
exports.Rack = Rack;
function _Device () {
this.name = 'Device';
}
inherits(_Device, _State);
var Device = new _Device();
exports.Device = Device;
_State.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
};
_Start.prototype.start = function (controller) {
controller.scope.app_toolbox_controller.handle_message('Disable', {});
controller.scope.inventory_toolbox_controller.handle_message('Disable', {});
controller.scope.rack_toolbox_controller.handle_message('Disable', {});
controller.scope.site_toolbox_controller.handle_message('Disable', {});
controller.changeState(Rack);
};
_Start.prototype.start.transitions = ['MultiSite'];
_Interface.prototype.onMouseWheel = function (controller, msg_type, $event) {
//controller.changeState(Device);
controller.delegate_channel.send(msg_type, $event);
};
_Interface.prototype.onMouseWheel.transitions = ['Device'];
_Site.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.rack_toolbox_controller.handle_message('Enable', {});
controller.scope.rack_controller.changeState(rack_fsm.Ready);
};
_Site.prototype.end = function (controller) {
controller.scope.rack_toolbox_controller.handle_message('Disable', {});
controller.scope.rack_controller.changeState(rack_fsm.Disable);
};
_Site.prototype.onMouseWheel = function (controller, msg_type, $event) {
if (controller.scope.current_scale < 0.1) {
controller.changeState(MultiSite);
} else if (controller.scope.current_scale > 0.5) {
controller.changeState(Rack);
}
controller.delegate_channel.send(msg_type, $event);
};
_Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack'];
_Process.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.delegate_channel.send(msg_type, $event);
//controller.changeState(Device);
};
_Process.prototype.onMouseWheel.transitions = ['Device'];
_MultiSite.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.site_toolbox_controller.handle_message('Enable', {});
controller.scope.site_controller.changeState(site_fsm.Ready);
};
_MultiSite.prototype.end = function (controller) {
controller.scope.site_toolbox_controller.handle_message('Disable', {});
controller.scope.site_controller.changeState(site_fsm.Disable);
};
_MultiSite.prototype.onMouseWheel = function (controller, msg_type, $event) {
if (controller.scope.current_scale > 0.1) {
controller.changeState(Site);
}
controller.delegate_channel.send(msg_type, $event);
};
_MultiSite.prototype.onMouseWheel.transitions = ['Site'];
_Device.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.app_toolbox_controller.handle_message('Enable', {});
};
_Device.prototype.end = function (controller) {
controller.scope.app_toolbox_controller.handle_message('Disable', {});
};
_Device.prototype.onMouseWheel = function (controller, msg_type, $event) {
//controller.changeState(Process);
//controller.changeState(Interface);
//controller.changeState(Site);
if (controller.scope.current_scale < 5) {
controller.changeState(Rack);
}
controller.delegate_channel.send(msg_type, $event);
};
_Device.prototype.onMouseWheel.transitions = ['Process', 'Interface', 'Rack'];
_Rack.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.inventory_toolbox_controller.handle_message('Enable', {});
controller.scope.move_controller.changeState(move.Ready);
controller.scope.group_controller.changeState(group.Ready);
};
_Rack.prototype.end = function (controller) {
controller.scope.inventory_toolbox_controller.handle_message('Disable', {});
controller.scope.move_controller.changeState(move.Disable);
controller.scope.group_controller.changeState(group.Disable);
};
_Rack.prototype.onMouseWheel = function (controller, msg_type, $event) {
if (controller.scope.current_scale < 0.5) {
controller.changeState(Site);
}
if (controller.scope.current_scale > 5) {
controller.changeState(Device);
}
controller.delegate_channel.send(msg_type, $event);
};
_Rack.prototype.onMouseWheel.transitions = ['Site', 'Device'];

View File

@@ -0,0 +1,920 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var fsm = require('./fsm.js');
var button = require('./button.js');
var util = require('./util.js');
var inherits = require('inherits');
function Device(id, name, x, y, type) {
this.id = id;
this.name = name;
this.x = x;
this.y = y;
this.height = type === "host" ? 15 : 50;
this.width = 50;
this.size = 50;
this.type = type;
this.selected = false;
this.remote_selected = false;
this.edit_label = false;
this.status = null;
this.working = false;
this.moving = false;
this.icon = false;
this.tasks = [];
this.shape = type === "router" ? "circular" : "rectangular";
this.interface_seq = util.natural_numbers(0);
this.interfaces = [];
this.process_id_seq = util.natural_numbers(0);
this.processes = [];
}
exports.Device = Device;
Device.prototype.toJSON = function () {
return {id: this.id,
name: this.name,
x: this.x,
y: this.y,
type: this.type,
interfaces: this.interfaces,
processes: this.processes};
};
Device.prototype.is_selected = function (x, y) {
return (x > this.x - this.width &&
x < this.x + this.width &&
y > this.y - this.height &&
y < this.y + this.height);
};
Device.prototype.describeArc = util.describeArc;
function Interface(id, name) {
this.id = id;
this.name = name;
this.link = null;
this.device = null;
this.edit_label = false;
this.dot_x = null;
this.dot_y = null;
}
exports.Interface = Interface;
Interface.prototype.toJSON = function () {
return {id: this.id,
name: this.name};
};
Interface.prototype.remote_interface = function () {
if (this.link === null) {
return null;
}
if (this.link.to_interface === this) {
return this.link.from_interface;
} else {
return this.link.to_interface;
}
};
Interface.prototype.is_selected = function (x, y) {
if (this.link === null || this.device === null) {
return false;
}
var d = Math.sqrt(Math.pow(x - this.device.x, 2) + Math.pow(y - this.device.y, 2));
return this.link.is_selected(x, y) && (d < this.dot_d + 30);
};
Interface.prototype.dot_distance = function () {
this.dot_d = Math.sqrt(Math.pow(this.device.x - this.dot_x, 2) + Math.pow(this.device.y - this.dot_y, 2));
};
Interface.prototype.dot = function () {
if (this.link === null || this.device === null) {
return;
}
if (this.link.to_device === null || this.link.from_device === null) {
return;
}
var p;
if (this.device.shape === "circular") {
var theta = this.link.slope_rads();
if (this.link.from_interface === this) {
theta = theta + Math.PI;
}
p = {x: this.device.x - this.device.size * Math.cos(theta),
y: this.device.y - this.device.size * Math.sin(theta)};
this.dot_x = p.x;
this.dot_y = p.y;
this.dot_distance();
return;
}
var x1;
var y1;
var x2;
var y2;
var x3;
var y3;
var x4;
var y4;
var param1;
var param2;
x3 = this.link.to_device.x;
y3 = this.link.to_device.y;
x4 = this.link.from_device.x;
y4 = this.link.from_device.y;
x1 = this.device.x - this.device.width;
y1 = this.device.y - this.device.height;
x2 = this.device.x + this.device.width;
y2 = this.device.y - this.device.height;
p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2);
param1 = util.pCase(p.x, p.y, x1, y1, x2, y2);
param2 = util.pCase(p.x, p.y, x3, y3, x4, y4);
if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) {
this.dot_x = p.x;
this.dot_y = p.y;
this.dot_distance();
return;
}
x1 = this.device.x - this.device.width;
y1 = this.device.y + this.device.height;
x2 = this.device.x + this.device.width;
y2 = this.device.y + this.device.height;
p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2);
param1 = util.pCase(p.x, p.y, x1, y1, x2, y2);
param2 = util.pCase(p.x, p.y, x3, y3, x4, y4);
if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) {
this.dot_x = p.x;
this.dot_y = p.y;
this.dot_distance();
return;
}
x1 = this.device.x + this.device.width;
y1 = this.device.y - this.device.height;
x2 = this.device.x + this.device.width;
y2 = this.device.y + this.device.height;
p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2);
param1 = util.pCase(p.x, p.y, x1, y1, x2, y2);
param2 = util.pCase(p.x, p.y, x3, y3, x4, y4);
if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) {
this.dot_x = p.x;
this.dot_y = p.y;
this.dot_distance();
return;
}
x1 = this.device.x - this.device.width;
y1 = this.device.y - this.device.height;
x2 = this.device.x - this.device.width;
y2 = this.device.y + this.device.height;
p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2);
param1 = util.pCase(p.x, p.y, x1, y1, x2, y2);
param2 = util.pCase(p.x, p.y, x3, y3, x4, y4);
if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) {
this.dot_x = p.x;
this.dot_y = p.y;
this.dot_distance();
return;
}
};
function Link(id, from_device, to_device, from_interface, to_interface) {
this.id = id;
this.from_device = from_device;
this.to_device = to_device;
this.from_interface = from_interface;
this.to_interface = to_interface;
this.selected = false;
this.remote_selected = false;
this.status = null;
this.edit_label = false;
this.name = "";
}
exports.Link = Link;
Link.prototype.toJSON = function () {
return {from_device_id: this.from_device.id,
to_device_id: this.to_device.id,
from_interface_id: this.from_interface.id,
to_interface_id: this.to_interface.id,
name: this.name};
};
Link.prototype.is_selected = function (x, y) {
// Is the distance to the mouse location less than 25 if on the label side
// or 5 on the other from the shortest line to the link?
if (this.to_device === null) {
return false;
}
var d = util.pDistance(x,
y,
this.from_device.x,
this.from_device.y,
this.to_device.x,
this.to_device.y);
if (util.cross_z_pos(x,
y,
this.from_device.x,
this.from_device.y,
this.to_device.x,
this.to_device.y)) {
return d < 10;
} else {
return d < 10;
}
};
Link.prototype.slope_rads = function () {
//Return the slope in degrees for this link.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return Math.atan2(y2 - y1, x2 - x1);
};
Link.prototype.slope = function () {
//Return the slope in degrees for this link.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI + 180;
};
Link.prototype.pDistanceLine = function (x, y) {
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return util.pDistanceLine(x, y, x1, y1, x2, y2);
};
Link.prototype.length = function () {
//Return the length of this link.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
};
Link.prototype.plength = function (x, y) {
//Return the length of this link.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return util.pDistance(x, y, x1, y1, x2, y2);
};
function ActionIcon(name, x, y, r, callback, enabled, tracer) {
this.name = name;
this.x = x;
this.y = y;
this.r = r;
this.callback = callback;
this.is_pressed = false;
this.mouse_over = false;
this.enabled = enabled;
this.fsm = new fsm.FSMController(this, "button_fsm", enabled ? button.Start : button.Disabled, tracer);
}
exports.ActionIcon = ActionIcon;
ActionIcon.prototype.is_selected = function (x, y) {
return (x > this.x - this.r &&
x < this.x + this.r &&
y > this.y - this.r &&
y < this.y + this.r);
};
function Button(name, x, y, width, height, callback, tracer) {
this.name = name;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.callback = callback;
this.is_pressed = false;
this.mouse_over = false;
this.enabled = true;
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
exports.Button = Button;
Button.prototype.is_selected = function (x, y) {
return (x > this.x &&
x < this.x + this.width &&
y > this.y &&
y < this.y + this.height);
};
function ToggleButton(name, x, y, width, height, toggle_callback, untoggle_callback, default_toggled, tracer) {
this.name = name;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.callback = this.toggle;
this.is_pressed = default_toggled;
this.toggled = default_toggled;
this.toggle_callback = toggle_callback;
this.untoggle_callback = untoggle_callback;
this.mouse_over = false;
this.enabled = true;
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
inherits(ToggleButton, Button);
exports.ToggleButton = ToggleButton;
ToggleButton.prototype.toggle = function () {
this.toggled = !this.toggled;
this.is_pressed = this.toggled;
if (this.toggled) {
this.toggle_callback();
} else {
this.untoggle_callback();
}
};
function ContextMenu(name, x, y, width, height, callback, enabled, buttons, tracer) {
this.name = name;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.callback = callback;
this.is_pressed = false;
this.mouse_over = false;
this.enabled = enabled;
this.buttons = buttons;
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
exports.ContextMenu = ContextMenu;
ContextMenu.prototype.is_selected = function (x, y) {
return (x > this.x &&
x < this.x + this.width &&
y > this.y &&
y < this.y + this.height);
};
function ContextMenuButton(name, x, y, width, height, callback, tracer) {
this.name = name;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.callback = callback;
this.is_pressed = false;
this.mouse_over = false;
this.enabled = true;
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
exports.ContextMenuButton = ContextMenuButton;
ContextMenuButton.prototype.is_selected = function (x, y) {
return (x > this.x &&
x < this.x + this.width &&
y > this.y &&
y < this.y + this.height);
};
function Task(id, name) {
this.id = id;
this.name = name;
this.status = null;
this.working = null;
}
exports.Task = Task;
Task.prototype.describeArc = util.describeArc;
function Group(id, name, type, x1, y1, x2, y2, selected) {
this.id = id;
this.name = name;
this.type = type;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.selected = selected;
this.moving = false;
this.highlighted = false;
this.fsm = null;
this.selected_corner = null;
this.devices = [];
this.links = [];
this.groups = [];
this.streams = [];
this.icon_size = type === 'site' ? 500 : 100;
}
exports.Group = Group;
Group.prototype.toJSON = function () {
return {id: this.id,
name: this.name,
type: this.type,
x1: this.x1,
y1: this.y1,
x2: this.x2,
y2: this.y2,
devices: this.devices,
links: this.links,
streams: this.streams,
groups: this.groups};
};
Group.prototype.update_hightlighted = function (x, y) {
this.highlighted = this.is_highlighted(x, y);
};
Group.prototype.is_highlighted = function (x, y) {
return (x > this.left_extent() &&
x < this.right_extent() &&
y > this.top_extent() &&
y < this.bottom_extent());
};
Group.prototype.is_icon_selected = function (x, y) {
return ((x > this.left_extent() &&
x < this.right_extent() &&
y > this.top_extent() &&
y < this.bottom_extent()) ||
(x > this.centerX() - this.icon_size &&
x < this.centerX() + this.icon_size &&
y > this.centerY() - this.icon_size &&
y < this.centerY() + this.icon_size));
};
var TOP_LEFT = 0;
exports.TOP_LEFT = TOP_LEFT;
var TOP_RIGHT = 1;
exports.TOP_RIGHT = TOP_RIGHT;
var BOTTOM_LEFT = 2;
exports.BOTTOM_LEFT = BOTTOM_LEFT;
var BOTTOM_RIGHT = 3;
exports.BOTTOM_RIGHT = BOTTOM_RIGHT;
Group.prototype.has_corner_selected = function (x, y) {
if (x > this.left_extent() &&
x < this.left_extent() + 10 &&
y > this.top_extent() &&
y < this.top_extent() + 10) {
return true;
}
if (x > this.left_extent() &&
x < this.left_extent() + 10 &&
y > this.bottom_extent() - 10 &&
y < this.bottom_extent()) {
return true;
}
if (x > this.right_extent() - 10 &&
x < this.right_extent() &&
y > this.bottom_extent() - 10 &&
y < this.bottom_extent()) {
return true;
}
if (x > this.right_extent() - 10 &&
x < this.right_extent() &&
y > this.top_extent() &&
y < this.top_extent() + 10) {
return true;
}
return false;
};
Group.prototype.corners = function () {
return [{x: this.left_extent(),
y: this.top_extent()},
{x: this.right_extent(),
y: this.top_extent()},
{x: this.left_extent(),
y: this.bottom_extent()},
{x: this.left_extent(),
y: this.bottom_extent()}];
};
Group.prototype.select_corner = function (x, y) {
var corners = [[util.distance(this.x1, this.y1, x, y), TOP_LEFT],
[util.distance(this.x2, this.y2, x, y), BOTTOM_RIGHT],
[util.distance(this.x1, this.y2, x, y), BOTTOM_LEFT],
[util.distance(this.x2, this.y1, x, y), TOP_RIGHT]];
corners.sort(function(a, b) {
return a[0] - b[0];
});
if (corners[0][0] > 30) {
return null;
}
return corners[0][1];
};
Group.prototype.is_selected = function (x, y) {
if (util.pDistance(x,
y,
this.left_extent(),
this.top_extent(),
this.left_extent(),
this.bottom_extent()) < 10) {
return true;
}
if (util.pDistance(x,
y,
this.left_extent(),
this.top_extent(),
this.right_extent(),
this.top_extent()) < 10) {
return true;
}
if (util.pDistance(x,
y,
this.left_extent(),
this.top_extent(),
this.right_extent(),
this.top_extent()) < 40 && y > this.top_extent()) {
return true;
}
if (util.pDistance(x,
y,
this.right_extent(),
this.bottom_extent(),
this.right_extent(),
this.top_extent()) < 10) {
return true;
}
if (util.pDistance(x,
y,
this.right_extent(),
this.bottom_extent(),
this.left_extent(),
this.bottom_extent()) < 10) {
return true;
}
return false;
};
Group.prototype.width = function (scaledX) {
var x2 = this.x2 !== null ? this.x2 : scaledX;
return Math.abs(this.x1 - x2);
};
Group.prototype.height = function (scaledY) {
var y2 = this.y2 !== null ? this.y2 : scaledY;
return Math.abs(this.y1 - y2);
};
Group.prototype.top_extent = function (scaledY) {
var y2 = this.y2 !== null ? this.y2 : scaledY;
return (this.y1 < y2? this.y1 : y2);
};
Group.prototype.left_extent = function (scaledX) {
var x2 = this.x2 !== null ? this.x2 : scaledX;
return (this.x1 < x2? this.x1 : x2);
};
Group.prototype.bottom_extent = function (scaledY) {
var y2 = this.y2 !== null ? this.y2 : scaledY;
return (this.y1 > y2? this.y1 : y2);
};
Group.prototype.right_extent = function (scaledX) {
var x2 = this.x2 !== null ? this.x2 : scaledX;
return (this.x1 > x2? this.x1 : x2);
};
Group.prototype.centerX = function (scaledX) {
return (this.right_extent(scaledX) + this.left_extent(scaledX)) / 2;
};
Group.prototype.centerY = function (scaledY) {
return (this.bottom_extent(scaledY) + this.top_extent(scaledY)) / 2;
};
Group.prototype.update_membership = function (devices, groups) {
var i = 0;
var y1 = this.top_extent();
var x1 = this.left_extent();
var y2 = this.bottom_extent();
var x2 = this.right_extent();
var old_devices = this.devices;
var device_ids = [];
this.devices = [];
for (i = 0; i < devices.length; i++) {
if (devices[i].x > x1 &&
devices[i].y > y1 &&
devices[i].x < x2 &&
devices[i].y < y2) {
this.devices.push(devices[i]);
device_ids.push(devices[i].id);
}
}
var old_groups = this.groups;
this.groups = [];
var group_ids = [];
for (i = 0; i < groups.length; i++) {
if (groups[i].left_extent() > x1 &&
groups[i].top_extent() > y1 &&
groups[i].right_extent() < x2 &&
groups[i].bottom_extent() < y2) {
this.groups.push(groups[i]);
group_ids.push(groups[i].id);
}
}
return [old_devices, this.devices, device_ids, old_groups, this.groups, group_ids];
};
function ToolBox(id, name, type, x, y, width, height) {
this.id = id;
this.name = name;
this.type = type;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.items = [];
this.spacing = 200;
this.scroll_offset = 0;
this.selected_item = null;
this.enabled = true;
}
exports.ToolBox = ToolBox;
function Configuration(id, name, type, x, y, content) {
this.id = id;
this.name = name;
this.type = type;
this.x = x;
this.y = y;
this.height = 50;
this.width = 50;
this.size = 50;
this.content = content;
this.selected = null;
this.enabled = true;
this.icon = false;
}
exports.Configuration = Configuration;
function Process(id, name, type, x, y) {
this.id = id;
this.name = name;
this.type = type;
this.x = x;
this.y = y;
this.height = 50;
this.width = 50;
this.size = 50;
this.selected = null;
this.enabled = true;
this.icon = false;
this.device = null;
}
exports.Process = Process;
function Stream(id, from_device, to_device, label) {
this.id = id;
this.from_device = from_device;
this.to_device = to_device;
this.selected = false;
this.remote_selected = false;
this.label = label;
this.offset = 0;
}
exports.Stream = Stream;
Stream.prototype.toJSON = function () {
return {to_device: this.to_device.id,
from_device: this.from_device.id};
};
Stream.prototype.slope_rad = function () {
//Return the slope in radians for this transition.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return Math.atan2(y2 - y1, x2 - x1) + Math.PI;
};
Stream.prototype.slope = function () {
//Return the slope in degrees for this transition.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI + 180;
};
Stream.prototype.flip_text_rotate = function () {
var slope = this.slope();
if (slope > 90 && slope < 270) {
return 180;
} else {
return 0;
}
};
Stream.prototype.flip_text_offset = function () {
var slope = this.slope();
if (slope > 90 && slope < 270) {
return 10;
} else {
return 0;
}
};
Stream.prototype.pslope = function () {
//Return the slope of a perpendicular line to this
//transition
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
var slope = (y2 - y1)/(x2 - x1);
//var intercept = - slope * x1;
var pslope = 1/slope;
return Math.atan(pslope) * 180 / Math.PI + 180;
};
Stream.prototype.perpendicular = function (x, y) {
//Find the perpendicular line through x, y to this transition.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
var slope = (y2 - y1)/(x2 - x1);
var intercept = y1 - slope * x1;
var pslope = -1/slope;
var pintercept = y - pslope * x;
var xi = (pintercept - intercept) / (slope - pslope);
var yi = pslope * xi + pintercept;
return {x1:x, y1:y, x2: xi, y2: yi};
};
Stream.prototype.is_selected = function (x, y) {
// Is the distance to the mouse location less than 25 if on the label side
// or 5 on the other from the shortest line to the transition?
console.log("is_selected");
var phi = this.slope_rad();
console.log({"phi": phi});
console.log({'x': this.from_device.x, 'y': this.from_device.y});
console.log({'x': this.to_device.x, 'y': this.to_device.y});
console.log({'x': x, 'y': y});
var p1 = util.cartesianToPolar(this.from_device.x, this.from_device.y);
var p2 = util.cartesianToPolar(this.to_device.x, this.to_device.y);
var p3 = util.cartesianToPolar(x, y);
console.log(p1);
p1.theta -= phi;
console.log(p1);
console.log(p2);
p2.theta -= phi;
console.log(p2);
p3.theta -= phi;
p1 = util.polarToCartesian_rad(0, 0, p1.r, p1.theta);
p2 = util.polarToCartesian_rad(0, 0, p2.r, p2.theta);
p3 = util.polarToCartesian_rad(0, 0, p3.r, p3.theta);
p2.y -= this.arc_offset2();
console.log(p1);
console.log(p2);
console.log(p3);
var max_x = Math.max(p1.x, p2.x);
var min_x = Math.min(p1.x, p2.x);
var max_y = Math.max(p1.y, p2.y) + 5;
var min_y = Math.min(p1.y, p2.y) - 25 ;
return p3.x > min_x && p3.x < max_x && p3.y > min_y && p3.y < max_y;
};
Stream.prototype.length = function () {
//Return the length of this transition.
var x1 = this.from_device.x;
var y1 = this.from_device.y;
var x2 = this.to_device.x;
var y2 = this.to_device.y;
return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
};
Stream.prototype.inter_length = function () {
//Return the length of this transition between states.
return this.length() - this.from_device.size - this.to_device.size;
};
Stream.prototype.arc_r = function () {
return this.inter_length();
};
Stream.prototype.arc_r2 = function () {
var offset_to_r = [2, 1, 0.75, 0.6, 0.55, 0.53, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5];
return this.length() * offset_to_r[this.offset];
};
Stream.prototype.arc_offset = function () {
var r = this.arc_r();
var offset = r - (Math.sin(this.arc_angle_rad()) * r);
return offset;
};
Stream.prototype.arc_offset2 = function () {
var r = this.arc_r2();
var theta = Math.acos((this.length() / 2) / r);
var offset = r * (1 - Math.sin(theta));
return offset;
};
Stream.prototype.arc_angle_rad = function () {
return Math.acos((this.inter_length() / 2) / this.arc_r());
};
Stream.prototype.arc_angle_tan_rad = function () {
return Math.PI/2 - Math.acos((this.inter_length() / 2) / this.arc_r());
};
Stream.prototype.arc_angle_tan = function () {
return this.arc_angle_tan_rad() * 180 / Math.PI;
};
Stream.prototype.arc_angle_tan_rad2 = function () {
var r = this.arc_r2();
var l = this.length();
var phi = this.end_arc_angle_rad();
return Math.PI/2 - Math.acos((l/2 - Math.cos(phi) * this.to_device.size) / r);
};
Stream.prototype.arc_angle_tan2 = function () {
return this.arc_angle_tan_rad2() * 180 / Math.PI;
};
Stream.prototype.end_arc_angle_rad = function () {
var r = this.arc_r2();
var l = this.length();
return Math.acos((this.to_device.size / 2) / r) - Math.acos((l/2)/r);
};
Stream.prototype.end_arc_angle = function () {
return this.end_arc_angle_rad() * 180 / Math.PI;
};
Stream.prototype.start_arc_angle_rad = function () {
return Math.acos((this.from_device.size / 2) / this.arc_r2()) - Math.acos((this.length()/2)/this.arc_r2());
};
Stream.prototype.start_arc_angle = function () {
return this.start_arc_angle_rad() * 180 / Math.PI;
};

View File

@@ -0,0 +1,547 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
var util = require('./util.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Disable () {
this.name = 'Disable';
}
inherits(_Disable, _State);
var Disable = new _Disable();
exports.Disable = Disable;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Selected2 () {
this.name = 'Selected2';
}
inherits(_Selected2, _State);
var Selected2 = new _Selected2();
exports.Selected2 = Selected2;
function _Selected3 () {
this.name = 'Selected3';
}
inherits(_Selected3, _State);
var Selected3 = new _Selected3();
exports.Selected3 = Selected3;
function _Move () {
this.name = 'Move';
}
inherits(_Move, _State);
var Move = new _Move();
exports.Move = Move;
function _Selected1 () {
this.name = 'Selected1';
}
inherits(_Selected1, _State);
var Selected1 = new _Selected1();
exports.Selected1 = Selected1;
function _EditLabel () {
this.name = 'EditLabel';
}
inherits(_EditLabel, _State);
var EditLabel = new _EditLabel();
exports.EditLabel = EditLabel;
function _Placing () {
this.name = 'Placing';
}
inherits(_Placing, _State);
var Placing = new _Placing();
exports.Placing = Placing;
_State.prototype.onUnselectAll = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.delegate_channel.send(msg_type, $event);
};
_Ready.prototype.onNewDevice = function (controller, msg_type, message) {
var scope = controller.scope;
var device = null;
var id = null;
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
scope.clear_selections();
if (message.type === "router") {
id = controller.scope.device_id_seq();
device = new models.Device(id,
"Router" + id,
scope.scaledX,
scope.scaledY,
"router");
}
else if (message.type === "switch") {
id = controller.scope.device_id_seq();
device = new models.Device(id,
"Switch" + id,
scope.scaledX,
scope.scaledY,
"switch");
}
else if (message.type === "rack") {
id = controller.scope.device_id_seq();
device = new models.Device(id,
"Rack" + id,
scope.scaledX,
scope.scaledY,
"rack");
}
else if (message.type === "host") {
id = controller.scope.device_id_seq();
device = new models.Device(id,
"Host" + id,
scope.scaledX,
scope.scaledY,
"host");
}
if (device !== null) {
scope.devices.push(device);
scope.send_control_message(new messages.DeviceCreate(scope.client_id,
device.id,
device.x,
device.y,
device.name,
device.type));
scope.selected_devices.push(device);
device.selected = true;
controller.changeState(Placing);
}
};
_Ready.prototype.onNewDevice.transitions = ['Placing'];
_Ready.prototype.onPasteDevice = function (controller, msg_type, message) {
var scope = controller.scope;
var device = null;
var intf = null;
var process = null;
var i = 0;
var c_messages = [];
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
device = new models.Device(controller.scope.device_id_seq(),
message.device.name,
scope.scaledX,
scope.scaledY,
message.device.type);
scope.devices.push(device);
c_messages.push(new messages.DeviceCreate(scope.client_id,
device.id,
device.x,
device.y,
device.name,
device.type));
for (i=0; i < message.device.interfaces.length; i++) {
intf = new models.Interface(message.device.interfaces[i].id, message.device.interfaces[i].name);
device.interfaces.push(intf);
c_messages.push(new messages.InterfaceCreate(controller.scope.client_id,
device.id,
intf.id,
intf.name));
}
for (i=0; i < message.device.processes.length; i++) {
process = new models.Process(message.device.processes[i].id,
message.device.processes[i].name,
message.device.processes[i].type, 0, 0);
process.device = device;
c_messages.push(new messages.ProcessCreate(controller.scope.client_id,
process.id,
process.name,
process.type,
process.device.id,
process.x,
process.y));
device.processes.push(process);
}
scope.selected_devices.push(device);
device.selected = true;
scope.send_control_message(new messages.MultipleMessage(controller.scope.client_id, c_messages));
controller.changeState(Selected2);
};
_Ready.prototype.onPasteDevice.transitions = ['Selected2'];
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
var last_selected = controller.scope.select_items($event.shiftKey);
if (last_selected.last_selected_device !== null) {
controller.changeState(Selected1);
} else if (last_selected.last_selected_link !== null) {
controller.changeState(Selected1);
} else if (last_selected.last_selected_interface !== null) {
controller.changeState(Selected1);
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selected1'];
_Ready.prototype.onTouchStart = _Ready.prototype.onMouseDown;
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Selected2.prototype.onNewDevice = function (controller, msg_type, message) {
controller.changeState(Ready);
controller.handle_message(msg_type, message);
};
_Selected2.prototype.onNewDevice.transitions = ['Ready'];
_Selected2.prototype.onCopySelected = function (controller) {
var devices = controller.scope.selected_devices;
var device_copy = null;
var process_copy = null;
var interface_copy = null;
var i = 0;
var j = 0;
for(i=0; i < devices.length; i++) {
device_copy = new models.Device(0, devices[i].name, 0, 0, devices[i].type);
device_copy.icon = true;
for(j=0; j < devices[i].processes.length; j++) {
process_copy = new models.Process(0, devices[i].processes[j].name, devices[i].processes[j].name, 0, 0);
device_copy.processes.push(process_copy);
}
for(j=0; j < devices[i].interfaces.length; j++) {
interface_copy = new models.Interface(devices[i].interfaces[j].id, devices[i].interfaces[j].name);
device_copy.interfaces.push(interface_copy);
}
controller.scope.inventory_toolbox.items.push(device_copy);
}
};
_Selected2.prototype.onMouseDown = function (controller, msg_type, $event) {
var last_selected = null;
if (controller.scope.selected_devices.length === 1) {
var current_selected_device = controller.scope.selected_devices[0];
var last_selected_device = controller.scope.select_items($event.shiftKey).last_selected_device;
if (current_selected_device === last_selected_device) {
controller.changeState(Selected3);
return;
}
}
if (controller.scope.selected_links.length === 1) {
var current_selected_link = controller.scope.selected_links[0];
last_selected = controller.scope.select_items($event.shiftKey);
if (current_selected_link === last_selected.last_selected_link) {
controller.changeState(Selected3);
return;
}
}
if (controller.scope.selected_interfaces.length === 1) {
var current_selected_interface = controller.scope.selected_interfaces[0];
last_selected = controller.scope.select_items($event.shiftKey);
if (current_selected_interface === last_selected.last_selected_interface) {
controller.changeState(Selected3);
return;
}
}
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
};
_Selected2.prototype.onMouseDown.transitions = ['Ready', 'Selected3'];
_Selected2.prototype.onTouchStart = _Selected2.prototype.onMouseDown;
_Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
if ($event.keyCode === 8) {
//Delete
controller.changeState(Ready);
var i = 0;
var j = 0;
var index = -1;
var devices = controller.scope.selected_devices;
var links = controller.scope.selected_links;
var all_links = controller.scope.links.slice();
controller.scope.selected_devices = [];
controller.scope.selected_links = [];
for (i = 0; i < links.length; i++) {
index = controller.scope.links.indexOf(links[i]);
if (index !== -1) {
links[i].selected = false;
links[i].remote_selected = false;
controller.scope.links.splice(index, 1);
controller.scope.send_control_message(new messages.LinkDestroy(controller.scope.client_id,
links[i].id,
links[i].from_device.id,
links[i].to_device.id,
links[i].from_interface.id,
links[i].to_interface.id,
links[i].name));
}
}
for (i = 0; i < devices.length; i++) {
index = controller.scope.devices.indexOf(devices[i]);
if (index !== -1) {
controller.scope.devices.splice(index, 1);
controller.scope.send_control_message(new messages.DeviceDestroy(controller.scope.client_id,
devices[i].id,
devices[i].x,
devices[i].y,
devices[i].name,
devices[i].type));
}
for (j = 0; j < all_links.length; j++) {
if (all_links[j].to_device === devices[i] ||
all_links[j].from_device === devices[i]) {
index = controller.scope.links.indexOf(all_links[j]);
if (index !== -1) {
controller.scope.links.splice(index, 1);
}
}
}
}
}
controller.delegate_channel.send(msg_type, $event);
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
_Selected1.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected1.prototype.onMouseMove.transitions = ['Move'];
_Selected1.prototype.onTouchMove = _Selected1.prototype.onMouseMove;
_Selected1.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Selected1.prototype.onMouseUp.transitions = ['Selected2'];
_Selected1.prototype.onTouchEnd = _Selected1.prototype.onMouseUp;
_Selected1.prototype.onMouseDown = util.noop;
_Move.prototype.start = function (controller) {
var devices = controller.scope.selected_devices;
var i = 0;
var j = 0;
for (i = 0; i < devices.length; i++) {
devices[i].moving = true;
for (j = 0; j < controller.scope.devices.length; j++) {
console.log(Math.pow(devices[i].x - controller.scope.devices[j].x, 2) +
Math.pow(devices[i].y - controller.scope.devices[j].y, 2));
if ((Math.pow(devices[i].x - controller.scope.devices[j].x, 2) +
Math.pow(devices[i].y - controller.scope.devices[j].y, 2)) < 160000) {
controller.scope.devices[j].moving = true;
}
}
}
};
_Move.prototype.end = function (controller) {
var devices = controller.scope.devices;
var i = 0;
for (i = 0; i < devices.length; i++) {
devices[i].moving = false;
}
};
_Move.prototype.onMouseMove = function (controller) {
var devices = controller.scope.selected_devices;
var groups = controller.scope.groups;
var diffX = controller.scope.scaledX - controller.scope.pressedScaledX;
var diffY = controller.scope.scaledY - controller.scope.pressedScaledY;
var i = 0;
var j = 0;
var previous_x, previous_y;
var membership_old_new;
for (i = 0; i < devices.length; i++) {
previous_x = devices[i].x;
previous_y = devices[i].y;
devices[i].x = devices[i].x + diffX;
devices[i].y = devices[i].y + diffY;
for (j = 0; j < devices[i].interfaces.length; j++) {
devices[i].interfaces[j].dot();
if (devices[i].interfaces[j].link !== null) {
devices[i].interfaces[j].link.to_interface.dot();
devices[i].interfaces[j].link.from_interface.dot();
}
}
controller.scope.send_control_message(new messages.DeviceMove(controller.scope.client_id,
devices[i].id,
devices[i].x,
devices[i].y,
previous_x,
previous_y));
}
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
//TODO: Improve the performance of this code from O(n^2) to O(n) or better
for (i = 0; i < groups.length; i++) {
membership_old_new = groups[i].update_membership(controller.scope.devices, controller.scope.groups);
controller.scope.send_control_message(new messages.GroupMembership(controller.scope.client_id,
groups[i].id,
membership_old_new[2]));
}
};
_Move.prototype.onTouchMove = _Move.prototype.onMouseMove;
_Move.prototype.onMouseUp = function (controller, msg_type, $event) {
controller.changeState(Selected1);
controller.handle_message(msg_type, $event);
};
_Move.prototype.onMouseUp.transitions = ['Selected1'];
_Move.prototype.onTouchEnd = _Move.prototype.onMouseUp;
_Move.prototype.onMouseDown = function (controller) {
controller.changeState(Selected1);
};
_Move.prototype.onMouseDown.transitions = ['Selected1'];
_Selected3.prototype.onMouseUp = function (controller) {
controller.changeState(EditLabel);
};
_Selected3.prototype.onMouseUp.transitions = ['EditLabel'];
_Selected3.prototype.onTouchEnd = function (controller) {
controller.changeState(Selected2);
};
_Selected3.prototype.onTouchEnd.transitions = ['Selected2'];
_Selected3.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected3.prototype.onMouseMove.transitions = ['Move'];
_Selected3.prototype.onTouchMove = _Selected3.prototype.onMouseMove;
_EditLabel.prototype.start = function (controller) {
controller.scope.selected_items[0].edit_label = true;
};
_EditLabel.prototype.end = function (controller) {
controller.scope.selected_items[0].edit_label = false;
};
_EditLabel.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
};
_EditLabel.prototype.onMouseDown.transitions = ['Ready'];
_EditLabel.prototype.onKeyDown = function (controller, msg_type, $event) {
//Key codes found here:
//https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
var item = controller.scope.selected_items[0];
var previous_name = item.name;
if ($event.keyCode === 8 || $event.keyCode === 46) { //Delete
item.name = item.name.slice(0, -1);
} else if ($event.keyCode >= 48 && $event.keyCode <=90) { //Alphanumeric
item.name += $event.key;
} else if ($event.keyCode >= 186 && $event.keyCode <=222) { //Punctuation
item.name += $event.key;
} else if ($event.keyCode === 13) { //Enter
controller.changeState(Selected2);
}
if (item.constructor.name === "Device") {
controller.scope.send_control_message(new messages.DeviceLabelEdit(controller.scope.client_id,
item.id,
item.name,
previous_name));
}
if (item.constructor.name === "Interface") {
controller.scope.send_control_message(new messages.InterfaceLabelEdit(controller.scope.client_id,
item.id,
item.device.id,
item.name,
previous_name));
}
if (item.constructor.name === "Link") {
controller.scope.send_control_message(new messages.LinkLabelEdit(controller.scope.client_id,
item.id,
item.name,
previous_name));
}
};
_EditLabel.prototype.onKeyDown.transitions = ['Selected2'];
_Placing.prototype.onMouseDown = function (controller) {
controller.changeState(Selected1);
};
_Placing.prototype.onMouseDown.transitions = ['Selected1'];
_Placing.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Placing.prototype.onMouseMove.transitions = ['Move'];

View File

@@ -0,0 +1,75 @@
/* Copyright (c) 2017 Red Hat, Inc. */
//console.log = function () { };
var angular = require('angular');
var NetworkUIController = require('./network.ui.controller.js');
var cursor = require('./cursor.directive.js');
var touch = require('./touch.directive.js');
var router = require('./router.directive.js');
var switchd = require('./switch.directive.js');
var host = require('./host.directive.js');
var link = require('./link.directive.js');
var stream = require('./stream.directive.js');
var rack = require('./rack.directive.js');
var rackIcon = require('./rack.icon.directive.js');
var group = require('./group.directive.js');
var site = require('./site.directive.js');
var siteIcon = require('./site.icon.directive.js');
var chevronRight = require('./chevron.right.directive.js');
var chevronLeft = require('./chevron.left.directive.js');
var contextMenu = require('./context.menu.directive.js');
var contextMenuButton = require('./context.menu.button.directive.js');
var process = require('./process.directive.js');
var configuration = require('./configuration.directive.js');
var map = require('./map.directive.js');
var deviceDetail = require('./device.detail.directive.js');
var defaultd = require('./default.directive.js');
var quadrants = require('./quadrants.directive.js');
var stencil = require('./stencil.directive.js');
var layer = require('./layer.directive.js');
var button = require('./button.directive.js');
var inventoryToolbox = require('./inventory.toolbox.directive.js');
var inventoryToolboxClipPath = require('./inventory.toolbox.clip.path.directive.js');
var statusLight = require('./status.light.directive.js');
var taskStatus = require('./task.status.directive.js');
var debug = require('./debug.directive.js');
var awxNetworkUI = require('./network.ui.directive.js');
var networkUI = angular.module('networkUI', [
'monospaced.mousewheel',
'ngTouch'
])
.controller('NetworkUIController', NetworkUIController.NetworkUIController)
.directive('awxNetCursor', cursor.cursor)
.directive('awxNetTouch', touch.touch)
.directive('awxNetDebug', debug.debug)
.directive('awxNetRouter', router.router)
.directive('awxNetSwitch', switchd.switchd)
.directive('awxNetHost', host.host)
.directive('awxNetLink', link.link)
.directive('awxNetStream', stream.stream)
.directive('awxNetRack', rack.rack)
.directive('awxNetGroup', group.group)
.directive('awxNetSite', site.site)
.directive('awxNetSiteIcon', siteIcon.siteIcon)
.directive('awxNetRackIcon', rackIcon.rackIcon)
.directive('awxNetChevronRightIcon', chevronRight.chevronRight)
.directive('awxNetChevronLeftIcon', chevronLeft.chevronLeft)
.directive('awxNetContextMenu', contextMenu.contextMenu)
.directive('awxNetContextMenuButton', contextMenuButton.contextMenuButton)
.directive('awxNetProcess', process.process)
.directive('awxNetConfiguration', configuration.configuration)
.directive('awxNetMap', map.map)
.directive('awxNetDeviceDetail', deviceDetail.deviceDetail)
.directive('awxNetDefault', defaultd.defaultd)
.directive('awxNetQuadrants', quadrants.quadrants)
.directive('awxNetStencil', stencil.stencil)
.directive('awxNetLayer', layer.layer)
.directive('awxNetButton', button.button)
.directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox)
.directive('awxNetInventoryToolboxClipPath', inventoryToolboxClipPath.inventoryToolboxClipPath)
.directive('awxNetStatusLight', statusLight.statusLight)
.directive('awxNetTaskStatus', taskStatus.taskStatus)
.directive('awxNetworkUi', awxNetworkUI.awxNetworkUI);
exports.networkUI = networkUI;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/network_ui.partial.svg');
function awxNetworkUI () {
return { restrict: 'E', templateUrl};
}
exports.awxNetworkUI = awxNetworkUI;

View File

@@ -0,0 +1,67 @@
/* Copyright (c) 2017 Red Hat, Inc. */
//console.log = function () { };
var angular = require('angular');
var NetworkWidgetsController = require('./network.widgets.controller.js');
var cursor = require('./cursor.directive.js');
var touch = require('./touch.directive.js');
var router = require('./router.directive.js');
var switchd = require('./switch.directive.js');
var host = require('./host.directive.js');
var link = require('./link.directive.js');
var stream = require('./stream.directive.js');
var rack = require('./rack.directive.js');
var rackIcon = require('./rack.icon.directive.js');
var group = require('./group.directive.js');
var site = require('./site.directive.js');
var siteIcon = require('./site.icon.directive.js');
var process = require('./process.directive.js');
var configuration = require('./configuration.directive.js');
var map = require('./map.directive.js');
var deviceDetail = require('./device.detail.directive.js');
var defaultd = require('./default.directive.js');
var quadrants = require('./quadrants.directive.js');
var stencil = require('./stencil.directive.js');
var layer = require('./layer.directive.js');
var button = require('./button.directive.js');
var inventoryToolbox = require('./inventory.toolbox.directive.js');
var inventoryToolboxClipPath = require('./inventory.toolbox.clip.path.directive.js');
var statusLight = require('./status.light.directive.js');
var taskStatus = require('./task.status.directive.js');
var debug = require('./debug.directive.js');
var awxNetworkWidgets = require('./network.widgets.directive.js');
var networkWidgets = angular.module('networkWidgets', [
'monospaced.mousewheel',
'ngTouch'
])
.controller('NetworkWidgetsController', NetworkWidgetsController.NetworkWidgetsController)
.directive('awxNetCursor', cursor.cursor)
.directive('awxNetTouch', touch.touch)
.directive('awxNetDebug', debug.debug)
.directive('awxNetRouter', router.router)
.directive('awxNetSwitch', switchd.switchd)
.directive('awxNetHost', host.host)
.directive('awxNetLink', link.link)
.directive('awxNetStream', stream.stream)
.directive('awxNetRack', rack.rack)
.directive('awxNetGroup', group.group)
.directive('awxNetSite', site.site)
.directive('awxNetSiteIcon', siteIcon.siteIcon)
.directive('awxNetRackIcon', rackIcon.rackIcon)
.directive('awxNetProcess', process.process)
.directive('awxNetConfiguration', configuration.configuration)
.directive('awxNetMap', map.map)
.directive('awxNetDeviceDetail', deviceDetail.deviceDetail)
.directive('awxNetDefault', defaultd.defaultd)
.directive('awxNetQuadrants', quadrants.quadrants)
.directive('awxNetStencil', stencil.stencil)
.directive('awxNetLayer', layer.layer)
.directive('awxNetButton', button.button)
.directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox)
.directive('awxNetInventoryToolboxClipPath', inventoryToolboxClipPath.inventoryToolboxClipPath)
.directive('awxNetStatusLight', statusLight.statusLight)
.directive('awxNetTaskStatus', taskStatus.taskStatus)
.directive('awxNetworkWidgets', awxNetworkWidgets.awxNetworkWidgets);
exports.networkWidgets = networkWidgets;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/network_widgets.partial.svg');
function awxNetworkWidgets () {
return { restrict: 'E', templateUrl};
}
exports.awxNetworkWidgets = awxNetworkWidgets;

View File

@@ -0,0 +1,124 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<div ng-controller="NetworkUIController">
<svg id="frame" class="NetworkUI"
ng-attr-height="{{graph.height}}"
ng-attr-width="{{graph.width}}"
ng-mousedown="onMouseDown($event)"
ng-mouseup="onMouseUp($event)"
ng-mouseenter="onMouseEnter($event)"
ng-mouseleave="onMouseLeave($event)"
ng-mousemove="onMouseMove($event)"
ng-mouseover="onMouseOver($event)"
ng-touchstart="onTouchStart($event)"
ng-touchmove="onTouchMove($event)"
ng-touchend="onTouchEnd($event)"
ng-tap="onTap($event)"
msd-wheel="onMouseWheel($event, $delta, $deltaX, $deltaY)">
<defs>
<filter x="0" y="0" width="1" height="1" id="selected">
<feFlood flood-color="#b3d8fd"/>
<feComposite in="SourceGraphic" operator="xor"/>
</filter>
<filter x="0" y="0" width="1" height="1" id="background">
<feFlood flood-color="#ffffff"/>
<feComposite in="SourceGraphic" operator="xor"/>
</filter>
<clipPath id="inventory-toolbox-clip-path">
<rect ng-attr-x="{{inventory_toolbox.x}}"
ng-attr-y="{{inventory_toolbox.y}}"
ng-attr-width="{{inventory_toolbox.width}}"
ng-attr-height="{{inventory_toolbox.height}}"
rx=5></rect>
</clipPath>
</defs>
<g transform="scale(1.0)" id="frame_g">
<g ng-if="current_mode == 'MultiSite'" transform="translate(-300000, -200000) scale(1000)" awx-net-map></g>
<g ng-if="!hide_links">
<g ng-if="current_scale > 0.5 && current_scale < 5">
<g ng-repeat="link in links">
<g awx-net-link></g>
</g> <!-- end ng-repeat link in links-->
</g> <!-- end ng-if current_scale -->
</g> <!-- end hide_links -->
<g ng-repeat="link in links">
<g ng-if="link.selected || link.to_interface.selected || link.from_interface.selected" link></g>
</g>
<g ng-if="current_scale > 0.5 && current_scale < 5">
<g ng-repeat="stream in streams">
<g awx-net-stream></g>
</g> <!-- end ng-repeat stream in streams-->
</g> <!-- end ng-if current_scale -->
<g ng-if="current_scale > 0.5 && current_scale < 5">
<g ng-repeat="item in devices"
ng-attr-transform="translate({{item.x}},{{item.y}})"
ng-attr-class="{{item.type}}"
ng-switch on="item.type">
<g ng-switch-when="router"><!-- begin router -->
<g awx-net-router></g>
</g> <!-- end router -->
<g ng-switch-when="switch"> <!-- begin switch -->
<g awx-net-switch> </g>
</g> <!-- end switch -->
<g ng-switch-when="host"> <!-- begin host -->
<g awx-net-host> </g>
</g> <!-- end host -->
<g ng-switch-default> <!-- begin default -->
<g awx-net-default></g>
</g> <!-- end default -->
<g awx-net-status-light></g>
</g> <!-- end devices -->
</g>
<g ng-if="current_scale >= 5">
<g ng-repeat="item in devices"
ng-attr-transform="translate({{item.x}},{{item.y}})">
<g awx-net-device-detail> </g>
</g>
</g>
<g ng-repeat="item in groups">
<g awx-net-group></g>
</g>
<g ng-attr-transform="translate({{scaledX}},{{scaledY}})" ng-attr-class="{{debug.hidden && 'hidden' || ''}} debug-cursor" >
<line x1="-5" y1="0" x2="5" y2="0"/>
<line x1="0" y1="-5" x2="0" y2="5"/>
</g>
<g awx-net-quadrants>
</g>
</g>
<g ng-repeat="toolbox in [site_toolbox, rack_toolbox, inventory_toolbox, app_toolbox]">
<g awx-net-inventory-toolbox></g>
</g>
<g ng-if="!hide_buttons">
<g> <!-- buttons -->
<g ng-repeat="button in buttons"
ng-attr-transform="translate({{button.x}},{{button.y}})">
<g awx-net-button></g>
</g>
</g> <!-- end buttons -->
<g> <!-- layers -->
<g ng-repeat="layer in layers"
ng-attr-transform="translate({{layer.x}},{{layer.y}})"
class="button">
<g awx-net-layer> </g>
</g>
</g> <!-- end layers -->
</g>
<g awx-net-context-menu
context_menu="context_menus[0]"
ng-if="context_menus[0].enabled"
ng-attr-transform="translate({{context_menus[0].x}}, {{context_menus[0].y}})">
</g>
<g awx-net-debug></g>
<g awx-net-cursor></g>
<g ng-repeat="touch in touches">
<g awx-net-touch></g>
</g>
</svg>
</div>

View File

@@ -0,0 +1,127 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<div ng-controller="NetworkWidgetsController">
<svg id="frame" class="NetworkUI"
ng-attr-height="{{graph.height}}"
ng-attr-width="{{graph.width}}"
ng-mousedown="onMouseDown($event)"
ng-mouseup="onMouseUp($event)"
ng-mouseenter="onMouseEnter($event)"
ng-mouseleave="onMouseLeave($event)"
ng-mousemove="onMouseMove($event)"
ng-mouseover="onMouseOver($event)"
ng-touchstart="onTouchStart($event)"
ng-touchmove="onTouchMove($event)"
ng-touchend="onTouchEnd($event)"
ng-tap="onTap($event)"
msd-wheel="onMouseWheel($event, $delta, $deltaX, $deltaY)">
<defs>
<filter x="0" y="0" width="1" height="1" id="selected">
<feFlood flood-color="#b3d8fd"/>
<feComposite in="SourceGraphic" operator="xor"/>
</filter>
<filter x="0" y="0" width="1" height="1" id="background">
<feFlood flood-color="#ffffff"/>
<feComposite in="SourceGraphic" operator="xor"/>
</filter>
<clipPath id="inventory-toolbox-clip-path">
<rect ng-attr-x="{{inventory_toolbox.x}}"
ng-attr-y="{{inventory_toolbox.y}}"
ng-attr-width="{{inventory_toolbox.width}}"
ng-attr-height="{{inventory_toolbox.height}}"
rx=5></rect>
</clipPath>
</defs>
<g transform="scale(1.0)" id="frame_g">
<g ng-if="current_mode == 'MultiSite'" transform="translate(-300000, -200000) scale(1000)" awx-net-map></g>
<g ng-if="!hide_links">
<g ng-if="current_scale > 0.5 && current_scale < 5">
<g ng-repeat="link in links">
<g awx-net-link></g>
</g> <!-- end ng-repeat link in links-->
</g> <!-- end ng-if current_scale -->
</g> <!-- end hide_links -->
<g ng-repeat="link in links">
<g ng-if="link.selected || link.to_interface.selected || link.from_interface.selected" link></g>
</g>
<g ng-if="current_scale > 0.5 && current_scale < 5">
<g ng-repeat="stream in streams">
<g awx-net-stream></g>
</g> <!-- end ng-repeat stream in streams-->
</g> <!-- end ng-if current_scale -->
<g ng-if="current_scale > 0.5 && current_scale < 5">
<g ng-repeat="item in devices"
ng-attr-transform="translate({{item.x}},{{item.y}})"
ng-attr-class="{{item.type}}"
ng-switch on="item.type">
<g ng-switch-when="router"><!-- begin router -->
<g awx-net-router></g>
</g> <!-- end router -->
<g ng-switch-when="switch"> <!-- begin switch -->
<g awx-net-switch> </g>
</g> <!-- end switch -->
<g ng-switch-when="host"> <!-- begin host -->
<g awx-net-host> </g>
</g> <!-- end host -->
<g ng-switch-default> <!-- begin default -->
<g awx-net-default></g>
</g> <!-- end default -->
<g awx-net-status-light></g>
<g awx-net-task-status></g>
</g> <!-- end devices -->
</g>
<g ng-if="current_scale >= 5">
<g ng-repeat="item in devices"
ng-attr-transform="translate({{item.x}},{{item.y}})">
<g awx-net-device-detail> </g>
</g>
</g>
<g ng-repeat="item in groups">
<g awx-net-group></g>
</g>
<g ng-attr-transform="translate({{scaledX}},{{scaledY}})" ng-attr-class="{{debug.hidden && 'hidden' || ''}} debug-cursor" >
<line x1="-5" y1="0" x2="5" y2="0"/>
<line x1="0" y1="-5" x2="0" y2="5"/>
</g>
<g awx-net-quadrants>
</g>
</g>
<g ng-repeat="toolbox in [site_toolbox, rack_toolbox, inventory_toolbox, app_toolbox]">
<g awx-net-inventory-toolbox></g>
</g>
<g ng-if="!hide_buttons">
<g> <!-- buttons -->
<g ng-repeat="button in buttons"
ng-attr-transform="translate({{button.x}},{{button.y}})">
<g awx-net-button></g>
</g>
</g> <!-- end buttons -->
<g> <!-- stencils -->
<g ng-repeat="stencil in stencils"
ng-attr-transform="translate({{stencil.x}},{{stencil.y}})"
class="button">
<g awx-net-stencil></g>
</g>
</g> <!-- end stencils -->
<g> <!-- layers -->
<g ng-repeat="layer in layers"
ng-attr-transform="translate({{layer.x}},{{layer.y}})"
class="button">
<g awx-net-layer> </g>
</g>
</g> <!-- end layers -->
</g>
<g awx-net-debug></g>
<g awx-net-cursor></g>
<g ng-repeat="touch in touches">
<g awx-net-touch></g>
</g>
</svg>
</div>

View File

@@ -0,0 +1,87 @@
/*
* ngTouch.js v1.0.2
* (c) 2015 Mark Topper
* License: MIT
*/
"use strict";
angular.module("ngTouch", [])
.directive("ngTouchstart", function () {
return {
controller: ["$scope", "$element", function ($scope, $element) {
$element.bind("touchstart", onTouchStart);
function onTouchStart(event) {
var method = $element.attr("ng-touchstart");
$scope.$event = event;
$scope.$apply(method);
}
}]
};
})
.directive("ngTouchmove", function () {
return {
controller: ["$scope", "$element", function ($scope, $element) {
$element.bind("touchstart", onTouchStart);
function onTouchStart(event) {
event.preventDefault();
$element.bind("touchmove", onTouchMove);
$element.bind("touchend", onTouchEnd);
}
function onTouchMove(event) {
var method = $element.attr("ng-touchmove");
$scope.$event = event;
$scope.$apply(method);
}
function onTouchEnd(event) {
event.preventDefault();
$element.unbind("touchmove", onTouchMove);
$element.unbind("touchend", onTouchEnd);
}
}]
};
})
.directive("ngTouchend", function () {
return {
controller: ["$scope", "$element", function ($scope, $element) {
$element.bind("touchend", onTouchEnd);
function onTouchEnd(event) {
var method = $element.attr("ng-touchend");
$scope.$event = event;
$scope.$apply(method);
}
}]
};
})
.directive("ngTap", function () {
return {
controller: ["$scope", "$element", function ($scope, $element) {
var moved = false;
$element.bind("touchstart", onTouchStart);
function onTouchStart() {
$element.bind("touchmove", onTouchMove);
$element.bind("touchend", onTouchEnd);
}
function onTouchMove() {
moved = true;
}
function onTouchEnd() {
$element.unbind("touchmove", onTouchMove);
$element.unbind("touchend", onTouchEnd);
if (!moved) {
var method = $element.attr("ng-tap");
$scope.$apply(method);
}
}
}]
};
});

View File

@@ -0,0 +1,36 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
function _State () {
}
inherits(_State, fsm._State);
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/process.partial.svg');
function process () {
return { restrict: 'A', templateUrl};
}
exports.process = process;

View File

@@ -0,0 +1,12 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g class="NetworkUI__process" ng-attr-transform="translate(-50, -50)">
<path ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__switch--selected-conflict' : item.selected ? 'NetworkUI__switch--selected' : 'NetworkUI__switch--remote-selected' : 'NetworkUI--hidden'}}"
d="M0,0 h100 a10,10 0 0 1 10,10 v100 a10,10 0 0 1 -10,10 h-100 a10,10 0 0 1 -10,-10 v-100 a10,10 0 0 1 10,-10 z" />
<path d="M0,0 h100 a10,10 0 0 1 10,10 v100 a10,10 0 0 1 -10,10 h-100 a10,10 0 0 1 -10,-10 v-100 a10,10 0 0 1 10,-10 z" />
</g>
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__process-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="12"> {{item.name}} </text>
<text class="NetworkUI__process-text" text-anchor="middle" x="0" y="12">{{item.name}}{{item.edit_label?'_':''}}</text>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/quadrants.partial.svg');
function quadrants () {
return { restrict: 'A', templateUrl};
}
exports.quadrants = quadrants;

View File

@@ -0,0 +1,17 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<line x1="-100000"
y1="0"
x2="100000"
y2="0"
ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || 'NetworkUI--debug'}}" />
<line x1="0"
y1="-100000"
x2="0"
y2="100000"
ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || 'NetworkUI--debug'}}" />
<rect ng-attr-x="{{view_port.x}}"
ng-attr-y="{{view_port.y}}"
ng-attr-width="{{view_port.width}}"
ng-attr-height="{{view_port.height}}"
ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || 'NetworkUI--debug'}}"
ng-attr-style="stroke-width: {{2 / current_scale}}"></rect>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/rack.partial.svg');
function rack () {
return { restrict: 'A', templateUrl};
}
exports.rack = rack;

View File

@@ -0,0 +1,513 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Disable () {
this.name = 'Disable';
}
inherits(_Disable, _State);
var Disable = new _Disable();
exports.Disable = Disable;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Selected1 () {
this.name = 'Selected1';
}
inherits(_Selected1, _State);
var Selected1 = new _Selected1();
exports.Selected1 = Selected1;
function _Selected2 () {
this.name = 'Selected2';
}
inherits(_Selected2, _State);
var Selected2 = new _Selected2();
exports.Selected2 = Selected2;
function _Selected3 () {
this.name = 'Selected3';
}
inherits(_Selected3, _State);
var Selected3 = new _Selected3();
exports.Selected3 = Selected3;
function _EditLabel () {
this.name = 'EditLabel';
}
inherits(_EditLabel, _State);
var EditLabel = new _EditLabel();
exports.EditLabel = EditLabel;
function _Move () {
this.name = 'Move';
}
inherits(_Move, _State);
var Move = new _Move();
exports.Move = Move;
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Ready.prototype.onPasteRack = function (controller, msg_type, message) {
var scope = controller.scope;
var device = null;
var intf = null;
var process = null;
var link = null;
var i = 0;
var j = 0;
var top_left_x, top_left_y;
var device_map = {};
var c_messages = [];
scope.hide_groups = false;
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
top_left_x = scope.scaledX - message.group.x2/2;
top_left_y = scope.scaledY - message.group.y2/2;
var group = new models.Group(controller.scope.group_id_seq(),
message.group.name,
message.group.type,
top_left_x,
top_left_y,
top_left_x + message.group.x2,
top_left_y + message.group.y2,
false);
c_messages.push(new messages.GroupCreate(scope.client_id,
group.id,
group.x1,
group.y1,
group.x2,
group.y2,
group.name,
group.type));
scope.groups.push(group);
for(i=0; i<message.group.devices.length;i++) {
device = new models.Device(controller.scope.device_id_seq(),
message.group.devices[i].name,
top_left_x + message.group.devices[i].x,
top_left_y + message.group.devices[i].y,
message.group.devices[i].type);
device_map[message.group.devices[i].id] = device;
device.interface_map = {};
scope.devices.push(device);
group.devices.push(device);
c_messages.push(new messages.DeviceCreate(scope.client_id,
device.id,
device.x,
device.y,
device.name,
device.type));
for (j=0; j < message.group.devices[i].interfaces.length; j++) {
intf = new models.Interface(message.group.devices[i].interfaces[j].id, message.group.devices[i].interfaces[j].name);
intf.device = device;
device.interfaces.push(intf);
device.interface_map[intf.id] = intf;
c_messages.push(new messages.InterfaceCreate(controller.scope.client_id,
device.id,
intf.id,
intf.name));
}
for (j=0; j < message.group.devices[i].processes.length; j++) {
process = new models.Process(message.group.devices[i].processes[j].id,
message.group.devices[i].processes[j].name,
message.group.devices[i].processes[j].type, 0, 0);
process.device = device;
c_messages.push(new messages.ProcessCreate(controller.scope.client_id,
process.id,
process.name,
process.type,
process.device.id,
process.x,
process.y));
device.processes.push(process);
}
}
for(i=0; i<message.group.links.length;i++) {
link = new models.Link(controller.scope.link_id_seq(),
device_map[message.group.links[i].from_device.id],
device_map[message.group.links[i].to_device.id],
device_map[message.group.links[i].from_device.id].interface_map[message.group.links[i].from_interface.id],
device_map[message.group.links[i].to_device.id].interface_map[message.group.links[i].to_interface.id]);
link.name = message.group.links[i].name;
device_map[message.group.links[i].from_device.id].interface_map[message.group.links[i].from_interface.id].link = link;
device_map[message.group.links[i].to_device.id].interface_map[message.group.links[i].to_interface.id].link = link;
device_map[message.group.links[i].from_device.id].interface_map[message.group.links[i].from_interface.id].dot();
device_map[message.group.links[i].to_device.id].interface_map[message.group.links[i].to_interface.id].dot();
scope.links.push(link);
c_messages.push(new messages.LinkCreate(controller.scope.client_id,
link.id,
link.from_device.id,
link.to_device.id,
link.from_interface.id,
link.to_interface.id));
}
scope.send_control_message(new messages.MultipleMessage(controller.scope.client_id, c_messages));
};
_Selected1.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Selected1.prototype.onMouseUp.transitions = ['Selected2'];
_Selected1.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected1.prototype.onMouseMove.transitions = ['Move'];
_Selected2.prototype.onPasteRack = function (controller, msg_type, message) {
controller.changeState(Ready);
controller.handle_message(msg_type, message);
};
_Selected2.prototype.onCopySelected = function (controller) {
var groups = controller.scope.selected_groups;
var group_copy = null;
var group = null;
var devices = null;
var device_copy = null;
var process_copy = null;
var interface_copy = null;
var link_copy = null;
var device_map = {};
var i = 0;
var j = 0;
var k = 0;
for(i=0; i < groups.length; i++) {
group = groups[i];
group_copy = new models.Group(0,
group.name,
group.type,
0,
0,
group.right_extent() - group.left_extent(),
group.bottom_extent() - group.top_extent(),
false);
group_copy.icon = true;
devices = group.devices;
for(j=0; j < devices.length; j++) {
device_copy = new models.Device(devices[j].id,
devices[j].name,
devices[j].x - group.left_extent(),
devices[j].y - group.top_extent(),
devices[j].type);
device_map[device_copy.id] = device_copy;
device_copy.icon = true;
device_copy.interface_map = {};
for(k=0; k < devices[j].processes.length; k++) {
process_copy = new models.Process(0, devices[j].processes[k].name, devices[j].processes[k].name, 0, 0);
device_copy.processes.push(process_copy);
}
for(k=0; k < devices[j].interfaces.length; k++) {
interface_copy = new models.Interface(devices[j].interfaces[k].id, devices[j].interfaces[k].name);
device_copy.interfaces.push(interface_copy);
device_copy.interface_map[interface_copy.id] = interface_copy;
}
group_copy.devices.push(device_copy);
}
group_copy.link_ids = [];
for(j=0; j < devices.length; j++) {
for(k=0; k < devices[j].interfaces.length; k++) {
if (devices[j].interfaces[k].link !== null) {
if ((devices.indexOf(devices[j].interfaces[k].remote_interface().device) !== -1) &&
(group_copy.link_ids.indexOf(devices[j].interfaces[k].link.id) === -1)) {
link_copy = new models.Link(devices[j].interfaces[k].link.id,
device_map[devices[j].interfaces[k].link.from_device.id],
device_map[devices[j].interfaces[k].link.to_device.id],
device_map[devices[j].interfaces[k].link.from_device.id].interface_map[devices[j].interfaces[k].link.from_interface.id],
device_map[devices[j].interfaces[k].link.to_device.id].interface_map[devices[j].interfaces[k].link.to_interface.id]);
link_copy.name = devices[j].interfaces[k].link.name;
group_copy.links.push(link_copy);
group_copy.link_ids.push(link_copy.id);
}
}
}
}
controller.scope.rack_toolbox.items.push(group_copy);
}
};
_Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
//controller.changeState(Ready);
controller.delegate_channel.send(msg_type, $event);
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
_Selected2.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
var groups = controller.scope.selected_groups;
var i = 0;
var selected = false;
controller.scope.selected_groups = [];
for (i = 0; i < groups.length; i++) {
if (groups[i].type !== "rack") {
continue;
}
if (groups[i].is_icon_selected(controller.scope.scaledX, controller.scope.scaledY)) {
groups[i].selected = true;
selected = true;
controller.scope.selected_groups.push(groups[i]);
}
}
if (selected) {
controller.changeState(Selected3);
} else {
for (i = 0; i < groups.length; i++) {
groups[i].selected = false;
}
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
}
};
_Selected2.prototype.onMouseDown.transitions = ['Selected3', 'Ready'];
_Selected3.prototype.onMouseUp = function (controller) {
controller.changeState(EditLabel);
};
_Selected3.prototype.onMouseUp.transitions = ['EditLabel'];
_Selected3.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected3.prototype.onMouseMove.transitions = ['Move'];
_EditLabel.prototype.start = function (controller) {
controller.scope.selected_groups[0].edit_label = true;
};
_EditLabel.prototype.end = function (controller) {
controller.scope.selected_groups[0].edit_label = false;
};
_EditLabel.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
};
_EditLabel.prototype.onMouseDown.transitions = ['Ready'];
_EditLabel.prototype.onKeyDown = function (controller, msg_type, $event) {
//Key codes found here:
//https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
var item = controller.scope.selected_groups[0];
var previous_name = item.name;
if ($event.keyCode === 8 || $event.keyCode === 46) { //Delete
item.name = item.name.slice(0, -1);
} else if ($event.keyCode >= 48 && $event.keyCode <=90) { //Alphanumeric
item.name += $event.key;
} else if ($event.keyCode >= 186 && $event.keyCode <=222) { //Punctuation
item.name += $event.key;
} else if ($event.keyCode === 13) { //Enter
controller.changeState(Selected2);
} else if ($event.keyCode === 32) { //Space
item.name += " ";
} else {
console.log($event.keyCode);
}
controller.scope.send_control_message(new messages.GroupLabelEdit(controller.scope.client_id,
item.id,
item.name,
previous_name));
};
_EditLabel.prototype.onKeyDown.transitions = ['Selected2'];
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
var groups = controller.scope.groups;
var i = 0;
var selected = false;
controller.scope.clear_selections();
for (i = 0; i < groups.length; i++) {
if (groups[i].type !== "rack") {
continue;
}
if (groups[i].is_icon_selected(controller.scope.scaledX, controller.scope.scaledY)) {
groups[i].selected = true;
selected = true;
controller.scope.selected_groups.push(groups[i]);
}
}
if (selected) {
controller.changeState(Selected1);
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selected1'];
_Move.prototype.start = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
for (i = 0; i < groups.length; i++) {
groups[i].moving = true;
}
};
_Move.prototype.end = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
var j = 0;
for (i = 0; i < groups.length; i++) {
for(j = 0; j < groups[i].devices.length; j++) {
groups[i].devices[j].selected = false;
}
}
for (i = 0; i < groups.length; i++) {
groups[i].moving = false;
}
};
_Move.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Move.prototype.onMouseUp.transitions = ['Selected2'];
_Move.prototype.onMouseMove = function (controller) {
var groups = controller.scope.selected_groups;
var devices = null;
var diffX = controller.scope.scaledX - controller.scope.pressedScaledX;
var diffY = controller.scope.scaledY - controller.scope.pressedScaledY;
var i = 0;
var j = 0;
var k = 0;
var previous_x1, previous_y1, previous_x2, previous_y2, previous_x, previous_y;
var c_messages = [];
for (i = 0; i < groups.length; i++) {
c_messages = [];
previous_x1 = groups[i].x1;
previous_y1 = groups[i].y1;
previous_x2 = groups[i].x2;
previous_y2 = groups[i].y2;
groups[i].x1 = groups[i].x1 + diffX;
groups[i].y1 = groups[i].y1 + diffY;
groups[i].x2 = groups[i].x2 + diffX;
groups[i].y2 = groups[i].y2 + diffY;
c_messages.push(new messages.GroupMove(controller.scope.client_id,
groups[i].id,
groups[i].x1,
groups[i].y1,
groups[i].x2,
groups[i].y2,
previous_x1,
previous_y1,
previous_x2,
previous_y2));
devices = groups[i].devices;
for (j = 0; j < devices.length; j++) {
previous_x = devices[j].x;
previous_y = devices[j].y;
devices[j].x = devices[j].x + diffX;
devices[j].y = devices[j].y + diffY;
for (k = 0; k < devices[j].interfaces.length; k++) {
devices[j].interfaces[k].dot();
if (devices[j].interfaces[k].link !== null) {
devices[j].interfaces[k].link.to_interface.dot();
devices[j].interfaces[k].link.from_interface.dot();
}
}
c_messages.push(new messages.DeviceMove(controller.scope.client_id,
devices[j].id,
devices[j].x,
devices[j].y,
previous_x,
previous_y));
}
controller.scope.send_control_message(new messages.MultipleMessage(controller.scope.client_id, c_messages));
}
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
};
_Move.prototype.onTouchMove = _Move.prototype.onMouseMove;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/rack_icon.partial.svg');
function rackIcon () {
return { restrict: 'A', templateUrl};
}
exports.rackIcon = rackIcon;

View File

@@ -0,0 +1,88 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="current_scale >= 0.1 && current_scale <= 0.5 && item.type == 'rack'" ng-attr-transform="translate({{item.width()/2}}, {{item.height()/2}})">
<g ng-attr-transform="scale({{1/0.5}})">
<g ng-if="item.moving">
<line ng-attr-x1="{{-50 - 100}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 100}}"
ng-attr-y2="0"
class="NetworkUI--construction"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-15 - 100}}"
ng-attr-x2="0"
ng-attr-y2="{{15 + 100}}"
class="NetworkUI--construction"></line>
</g>
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<rect
x="-52"
y="-52"
ng-attr-width="{{100 + 4}}"
ng-attr-height="{{100 + 4}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__rack--selected-conflict' : item.selected ? 'NetworkUI__rack--selected' : 'NetworkUI__rack--remote-selected' : 'NetworkUI--hidden'}}"
rx=10>
</rect>
<g class="NetworkUI__rack">
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{100}}"
rx=10
class="NetworkUI__rack-background">
</rect>
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<rect
x="-50"
y="-15"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<rect
x="-50"
y="20"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<circle cx="30" cy="-35" r=7 />
<circle cx="30" cy="0" r=7 />
<circle cx="30" cy="35" r=7 />
</circle>
</g>
</g>
<g ng-attr-transform="scale({{1/current_scale}})">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
ng-attr-y="{{180*current_scale}}"> {{item.name}} </text>
<text class="NetworkUI__rack-text" text-anchor="middle" x="0" ng-attr-y="{{180*current_scale}}">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>
</g>

View File

@@ -0,0 +1,71 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<rect
x="-52"
y="-52"
ng-attr-width="{{100 + 4}}"
ng-attr-height="{{100 + 4}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__rack--selected-conflict' : item.selected ? 'NetworkUI__rack--selected' : 'NetworkUI__rack--remote-selected' : 'NetworkUI--hidden'}}"
rx=10>
</rect>
<g class="NetworkUI__rack">
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{100}}"
rx=10
class="NetworkUI__rack-background">
</rect>
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<rect
x="-50"
y="-15"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<rect
x="-50"
y="20"
ng-attr-width="{{100}}"
ng-attr-height="{{30}}"
rx=10>
</rect>
<circle cx="30" cy="-35" r=7 />
<circle cx="30" cy="0" r=7 />
<circle cx="30" cy="35" r=7 />
</circle>
</g>
<g ng-show="item.icon || current_scale > 0.5">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="6"> {{item.name}} </text>
<text class="NetworkUI__rack-text" text-anchor="middle" x="0" y="6">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/router.partial.svg');
function router () {
return { restrict: 'A', templateUrl};
}
exports.router = router;

View File

@@ -0,0 +1,78 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="item.moving">
<line ng-attr-x1="{{-50 - 100}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 100}}"
ng-attr-y2="0"
class="NetworkUI--construction"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 100}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 100}}"
class="NetworkUI--construction"></line>
</g>
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<g class="NetworkUI__router">
<circle
cx="0"
cy="0"
ng-attr-r="{{50 + 2}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__router--selected-conflict' : item.selected ? 'NetworkUI__router--selected' : 'NetworkUI__router--remote-selected' : 'NetworkUI--hidden'}}">
</circle>
<circle
cx="0"
cy="0"
ng-attr-r="{{50}}">
</circle>
<g transform="rotate(45)">
<line ng-attr-x1="12"
ng-attr-y1="0"
ng-attr-x2="{{50-18}}"
ng-attr-y2="0"/>
<line ng-attr-x1="-12"
ng-attr-y1="0"
ng-attr-x2="{{-50+18}}"
ng-attr-y2="0"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(0) translate({{50-22}}, -20) scale(2.0)"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(180) translate({{50-22}}, -20) scale(2.0)"/>
<line ng-attr-x1="0"
ng-attr-y1="17"
ng-attr-x2="0"
ng-attr-y2="{{50-5}}"/>
<line ng-attr-x1="0"
ng-attr-y1="-17"
ng-attr-x2="0"
ng-attr-y2="{{-50+5}}"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(90) translate(-22, -20) scale(2.0)" />
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(270) translate(-22, -20) scale(2.0)"/>
</g>
</g>
<g ng-show="item.icon || current_scale > 0.5">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__router-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="0"> {{item.name}}</text>
<text class="NetworkUI__router-text" text-anchor="middle" x="0" y="0">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/site.partial.svg');
function site () {
return { restrict: 'A', templateUrl};
}
exports.site = site;

View File

@@ -0,0 +1,617 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Disable () {
this.name = 'Disable';
}
inherits(_Disable, _State);
var Disable = new _Disable();
exports.Disable = Disable;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Selected1 () {
this.name = 'Selected1';
}
inherits(_Selected1, _State);
var Selected1 = new _Selected1();
exports.Selected1 = Selected1;
function _Selected2 () {
this.name = 'Selected2';
}
inherits(_Selected2, _State);
var Selected2 = new _Selected2();
exports.Selected2 = Selected2;
function _Selected3 () {
this.name = 'Selected3';
}
inherits(_Selected3, _State);
var Selected3 = new _Selected3();
exports.Selected3 = Selected3;
function _EditLabel () {
this.name = 'EditLabel';
}
inherits(_EditLabel, _State);
var EditLabel = new _EditLabel();
exports.EditLabel = EditLabel;
function _Move () {
this.name = 'Move';
}
inherits(_Move, _State);
var Move = new _Move();
exports.Move = Move;
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Ready.prototype.onPasteSite = function (controller, msg_type, message) {
var scope = controller.scope;
var device = null;
var intf = null;
var process = null;
var link = null;
var stream = null;
var i = 0;
var j = 0;
var top_left_x, top_left_y;
var device_map = {};
var inner_group = null;
var c_messages = [];
var membership_old_new = null;
scope.hide_groups = false;
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
top_left_x = scope.scaledX - message.group.x2/2;
top_left_y = scope.scaledY - message.group.y2/2;
var group = new models.Group(controller.scope.group_id_seq(),
message.group.name,
message.group.type,
top_left_x,
top_left_y,
top_left_x + message.group.x2,
top_left_y + message.group.y2,
false);
c_messages.push(new messages.GroupCreate(scope.client_id,
group.id,
group.x1,
group.y1,
group.x2,
group.y2,
group.name,
group.type));
scope.groups.push(group);
for(i=0; i<message.group.devices.length;i++) {
device = new models.Device(controller.scope.device_id_seq(),
message.group.devices[i].name,
top_left_x + message.group.devices[i].x,
top_left_y + message.group.devices[i].y,
message.group.devices[i].type);
device_map[message.group.devices[i].id] = device;
device.interface_map = {};
scope.devices.push(device);
group.devices.push(device);
c_messages.push(new messages.DeviceCreate(scope.client_id,
device.id,
device.x,
device.y,
device.name,
device.type));
for (j=0; j < message.group.devices[i].interfaces.length; j++) {
intf = new models.Interface(message.group.devices[i].interfaces[j].id, message.group.devices[i].interfaces[j].name);
intf.device = device;
device.interfaces.push(intf);
device.interface_map[intf.id] = intf;
c_messages.push(new messages.InterfaceCreate(controller.scope.client_id,
device.id,
intf.id,
intf.name));
}
for (j=0; j < message.group.devices[i].processes.length; j++) {
process = new models.Process(message.group.devices[i].processes[j].id,
message.group.devices[i].processes[j].name,
message.group.devices[i].processes[j].type, 0, 0);
process.device = device;
c_messages.push(new messages.ProcessCreate(controller.scope.client_id,
process.id,
process.name,
process.type,
process.device.id,
process.x,
process.y));
device.processes.push(process);
}
}
for(i=0; i<message.group.links.length;i++) {
link = new models.Link(controller.scope.link_id_seq(),
device_map[message.group.links[i].from_device.id],
device_map[message.group.links[i].to_device.id],
device_map[message.group.links[i].from_device.id].interface_map[message.group.links[i].from_interface.id],
device_map[message.group.links[i].to_device.id].interface_map[message.group.links[i].to_interface.id]);
link.name = message.group.links[i].name;
device_map[message.group.links[i].from_device.id].interface_map[message.group.links[i].from_interface.id].link = link;
device_map[message.group.links[i].to_device.id].interface_map[message.group.links[i].to_interface.id].link = link;
device_map[message.group.links[i].from_device.id].interface_map[message.group.links[i].from_interface.id].dot();
device_map[message.group.links[i].to_device.id].interface_map[message.group.links[i].to_interface.id].dot();
scope.links.push(link);
c_messages.push(new messages.LinkCreate(controller.scope.client_id,
link.id,
link.from_device.id,
link.to_device.id,
link.from_interface.id,
link.to_interface.id));
}
for(i=0; i<message.group.streams.length;i++) {
stream = new models.Stream(controller.scope.stream_id_seq(),
device_map[message.group.streams[i].from_device.id],
device_map[message.group.streams[i].to_device.id],
message.group.streams[i].label);
stream.name = message.group.streams[i].name;
c_messages.push(new messages.StreamCreate(controller.scope.client_id,
stream.id,
stream.from_device.id,
stream.to_device.id,
stream.name));
scope.streams.push(stream);
}
for(i=0; i<message.group.groups.length;i++) {
inner_group = new models.Group(controller.scope.group_id_seq(),
message.group.groups[i].name,
message.group.groups[i].type,
top_left_x + message.group.groups[i].x1,
top_left_y + message.group.groups[i].y1,
top_left_x + message.group.groups[i].x2,
top_left_y + message.group.groups[i].y2,
false);
scope.groups.push(inner_group);
group.groups.push(inner_group);
c_messages.push(new messages.GroupCreate(scope.client_id,
inner_group.id,
inner_group.x1,
inner_group.y1,
inner_group.x2,
inner_group.y2,
inner_group.name,
inner_group.type));
}
for(i=0; i< group.groups.length; i++) {
membership_old_new = group.groups[i].update_membership(scope.devices, scope.groups);
c_messages.push(new messages.GroupMembership(controller.scope.client_id,
group.groups[i].id,
membership_old_new[2]));
}
membership_old_new = group.update_membership(scope.devices, scope.groups);
c_messages.push(new messages.GroupMembership(controller.scope.client_id,
group.id,
membership_old_new[2]));
scope.send_control_message(new messages.MultipleMessage(controller.scope.client_id, c_messages));
};
_Selected1.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Selected1.prototype.onMouseUp.transitions = ['Selected2'];
_Selected1.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected1.prototype.onMouseMove.transitions = ['Move'];
_Selected2.prototype.onPasteSite = function (controller, msg_type, message) {
controller.changeState(Ready);
controller.handle_message(msg_type, message);
};
_Selected2.prototype.onCopySelected = function (controller) {
var groups = controller.scope.selected_groups;
var group_copy = null;
var group = null;
var inner_group = null;
var devices = null;
var device_copy = null;
var process_copy = null;
var interface_copy = null;
var link_copy = null;
var device_map = {};
var streams = controller.scope.streams;
var stream;
var stream_copy;
var i = 0;
var j = 0;
var k = 0;
for(i=0; i < groups.length; i++) {
group = groups[i];
group_copy = new models.Group(0,
group.name,
group.type,
0,
0,
group.right_extent() - group.left_extent(),
group.bottom_extent() - group.top_extent(),
false);
group_copy.icon = true;
devices = group.devices;
for(j=0; j < devices.length; j++) {
device_copy = new models.Device(devices[j].id,
devices[j].name,
devices[j].x - group.left_extent(),
devices[j].y - group.top_extent(),
devices[j].type);
device_map[device_copy.id] = device_copy;
device_copy.icon = true;
device_copy.interface_map = {};
for(k=0; k < devices[j].processes.length; k++) {
process_copy = new models.Process(0, devices[j].processes[k].name, devices[j].processes[k].name, 0, 0);
device_copy.processes.push(process_copy);
}
for(k=0; k < devices[j].interfaces.length; k++) {
interface_copy = new models.Interface(devices[j].interfaces[k].id, devices[j].interfaces[k].name);
device_copy.interfaces.push(interface_copy);
device_copy.interface_map[interface_copy.id] = interface_copy;
}
group_copy.devices.push(device_copy);
}
group_copy.link_ids = [];
for(j=0; j < devices.length; j++) {
for(k=0; k < devices[j].interfaces.length; k++) {
if (devices[j].interfaces[k].link !== null) {
if ((devices.indexOf(devices[j].interfaces[k].remote_interface().device) !== -1) &&
(group_copy.link_ids.indexOf(devices[j].interfaces[k].link.id) === -1)) {
link_copy = new models.Link(devices[j].interfaces[k].link.id,
device_map[devices[j].interfaces[k].link.from_device.id],
device_map[devices[j].interfaces[k].link.to_device.id],
device_map[devices[j].interfaces[k].link.from_device.id].interface_map[devices[j].interfaces[k].link.from_interface.id],
device_map[devices[j].interfaces[k].link.to_device.id].interface_map[devices[j].interfaces[k].link.to_interface.id]);
link_copy.name = devices[j].interfaces[k].link.name;
group_copy.links.push(link_copy);
group_copy.link_ids.push(link_copy.id);
}
}
}
}
group_copy.stream_ids = [];
for (j=0; j<streams.length;j++) {
stream = streams[j];
if ((devices.indexOf(stream.to_device) !== -1) &&
(devices.indexOf(stream.from_device) !== -1)) {
stream_copy = new models.Stream(0, device_map[stream.from_device.id], device_map[stream.to_device.id], stream.label);
group_copy.streams.push(stream_copy);
}
}
for (j=0; j<group.groups.length;j++) {
inner_group = new models.Group(0,
group.groups[j].name,
group.groups[j].type,
group.groups[j].left_extent() - group.left_extent(),
group.groups[j].top_extent() - group.top_extent(),
group.groups[j].right_extent() - group.left_extent(),
group.groups[j].bottom_extent() - group.top_extent(),
false);
group_copy.groups.push(inner_group);
}
controller.scope.send_control_message(new messages.CopySite(group_copy));
controller.scope.site_toolbox.items.push(group_copy);
}
};
_Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
//controller.changeState(Ready);
controller.delegate_channel.send(msg_type, $event);
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
_Selected2.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
var groups = controller.scope.selected_groups;
var i = 0;
var selected = false;
controller.scope.selected_groups = [];
for (i = 0; i < groups.length; i++) {
if (groups[i].type !== "site") {
continue;
}
if (groups[i].is_icon_selected(controller.scope.scaledX, controller.scope.scaledY)) {
groups[i].selected = true;
selected = true;
controller.scope.selected_groups.push(groups[i]);
}
}
if (selected) {
controller.changeState(Selected3);
} else {
for (i = 0; i < groups.length; i++) {
groups[i].selected = false;
}
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
}
};
_Selected2.prototype.onMouseDown.transitions = ['Selected3', 'Ready'];
_Selected3.prototype.onMouseUp = function (controller) {
controller.changeState(EditLabel);
};
_Selected3.prototype.onMouseUp.transitions = ['EditLabel'];
_Selected3.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected3.prototype.onMouseMove.transitions = ['Move'];
_EditLabel.prototype.start = function (controller) {
controller.scope.selected_groups[0].edit_label = true;
};
_EditLabel.prototype.end = function (controller) {
controller.scope.selected_groups[0].edit_label = false;
};
_EditLabel.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.handle_message(msg_type, $event);
};
_EditLabel.prototype.onMouseDown.transitions = ['Ready'];
_EditLabel.prototype.onKeyDown = function (controller, msg_type, $event) {
//Key codes found here:
//https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
var item = controller.scope.selected_groups[0];
var previous_name = item.name;
if ($event.keyCode === 8 || $event.keyCode === 46) { //Delete
item.name = item.name.slice(0, -1);
} else if ($event.keyCode >= 48 && $event.keyCode <=90) { //Alphanumeric
item.name += $event.key;
} else if ($event.keyCode >= 186 && $event.keyCode <=222) { //Punctuation
item.name += $event.key;
} else if ($event.keyCode === 13) { //Enter
controller.changeState(Selected2);
} else if ($event.keyCode === 32) { //Space
item.name += " ";
} else {
console.log($event.keyCode);
}
controller.scope.send_control_message(new messages.GroupLabelEdit(controller.scope.client_id,
item.id,
item.name,
previous_name));
};
_EditLabel.prototype.onKeyDown.transitions = ['Selected2'];
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
var groups = controller.scope.groups;
var i = 0;
var selected = false;
controller.scope.clear_selections();
for (i = 0; i < groups.length; i++) {
if (groups[i].type !== "site") {
continue;
}
if (groups[i].is_icon_selected(controller.scope.scaledX, controller.scope.scaledY)) {
groups[i].selected = true;
selected = true;
controller.scope.selected_groups.push(groups[i]);
}
}
if (selected) {
controller.changeState(Selected1);
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selected1'];
_Move.prototype.start = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
for (i = 0; i < groups.length; i++) {
groups[i].moving = true;
}
};
_Move.prototype.end = function (controller) {
var groups = controller.scope.selected_groups;
var i = 0;
var j = 0;
for (i = 0; i < groups.length; i++) {
for(j = 0; j < groups[i].devices.length; j++) {
groups[i].devices[j].selected = false;
}
}
for (i = 0; i < groups.length; i++) {
groups[i].moving = false;
}
};
_Move.prototype.onMouseUp = function (controller) {
controller.changeState(Selected2);
};
_Move.prototype.onMouseUp.transitions = ['Selected2'];
_Move.prototype.onMouseMove = function (controller) {
var groups = controller.scope.selected_groups;
var devices = null;
var diffX = controller.scope.scaledX - controller.scope.pressedScaledX;
var diffY = controller.scope.scaledY - controller.scope.pressedScaledY;
var i = 0;
var j = 0;
var k = 0;
var previous_x1, previous_y1, previous_x2, previous_y2, previous_x, previous_y;
var c_messages = [];
for (i = 0; i < groups.length; i++) {
c_messages = [];
previous_x1 = groups[i].x1;
previous_y1 = groups[i].y1;
previous_x2 = groups[i].x2;
previous_y2 = groups[i].y2;
groups[i].x1 = groups[i].x1 + diffX;
groups[i].y1 = groups[i].y1 + diffY;
groups[i].x2 = groups[i].x2 + diffX;
groups[i].y2 = groups[i].y2 + diffY;
c_messages.push(new messages.GroupMove(controller.scope.client_id,
groups[i].id,
groups[i].x1,
groups[i].y1,
groups[i].x2,
groups[i].y2,
previous_x1,
previous_y1,
previous_x2,
previous_y2));
devices = groups[i].devices;
for (j = 0; j < devices.length; j++) {
previous_x = devices[j].x;
previous_y = devices[j].y;
devices[j].x = devices[j].x + diffX;
devices[j].y = devices[j].y + diffY;
for (k = 0; k < devices[j].interfaces.length; k++) {
devices[j].interfaces[k].dot();
if (devices[j].interfaces[k].link !== null) {
devices[j].interfaces[k].link.to_interface.dot();
devices[j].interfaces[k].link.from_interface.dot();
}
}
c_messages.push(new messages.DeviceMove(controller.scope.client_id,
devices[j].id,
devices[j].x,
devices[j].y,
previous_x,
previous_y));
}
for (j = 0; j < groups[i].groups.length; j++) {
previous_x1 = groups[i].groups[j].x1;
previous_y1 = groups[i].groups[j].y1;
previous_x2 = groups[i].groups[j].x2;
previous_y2 = groups[i].groups[j].y2;
groups[i].groups[j].x1 = groups[i].groups[j].x1 + diffX;
groups[i].groups[j].y1 = groups[i].groups[j].y1 + diffY;
groups[i].groups[j].x2 = groups[i].groups[j].x2 + diffX;
groups[i].groups[j].y2 = groups[i].groups[j].y2 + diffY;
c_messages.push(new messages.GroupMove(controller.scope.client_id,
groups[i].groups[j].id,
groups[i].groups[j].x1,
groups[i].groups[j].y1,
groups[i].groups[j].x2,
groups[i].groups[j].y2,
previous_x1,
previous_y1,
previous_x2,
previous_y2));
}
controller.scope.send_control_message(new messages.MultipleMessage(controller.scope.client_id, c_messages));
}
controller.scope.pressedScaledX = controller.scope.scaledX;
controller.scope.pressedScaledY = controller.scope.scaledY;
};
_Move.prototype.onTouchMove = _Move.prototype.onMouseMove;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/site_icon.partial.svg');
function siteIcon () {
return { restrict: 'A', templateUrl};
}
exports.siteIcon = siteIcon;

View File

@@ -0,0 +1,91 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="current_scale <= 0.1 && item.type == 'site'" ng-attr-transform="translate({{item.width()/2}}, {{item.height()/2}})">
<g ng-attr-transform="scale({{1/(0.1)}})">
<g ng-if="item.moving">
<line ng-attr-x1="{{-50 - 100}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 100}}"
ng-attr-y2="0"
class="NetworkUI--construction"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-15 - 100}}"
ng-attr-x2="0"
ng-attr-y2="{{15 + 100}}"
class="NetworkUI--construction"></line>
</g>
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<rect
x="-52"
y="-52"
ng-attr-width="{{100 + 4}}"
ng-attr-height="{{100 + 4}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__site--selected-conflict' : item.selected ? 'NetworkUI__site--selected' : 'NetworkUI__site--remote-selected' : 'NetworkUI--hidden'}}"
rx=10>
</rect>
<g class="NetworkUI__site">
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{100}}"
rx=10
class="NetworkUI__site-background">
</rect>
<rect class="NetworkUI__site--network" x=-42 y=60 width="80" height="10" rx=5 />
<rect class="NetworkUI__site--network" x=-42 y=30 width="10" height="40" rx=5 />
<rect class="NetworkUI__site--network" x=-5 y=30 width="10" height="40" rx=5 />
<rect class="NetworkUI__site--network" x=32 y=30 width="10" height="40" rx=5 />
<rect
x="-50"
y="-40"
ng-attr-width="{{25}}"
ng-attr-height="{{80}}"
rx=10>
</rect>
<rect
x="-20"
y="-50"
ng-attr-width="{{40}}"
ng-attr-height="{{100}}"
rx=10>
</rect>
<rect
x="25"
y="-40"
ng-attr-width="{{25}}"
ng-attr-height="{{80}}"
rx=10>
</rect>
<circle cy="20" cx="-37" r=7 />
<circle cy="25" cx="0" r=10 />
<circle cy="20" cx="37" r=7 />
</g>
</g>
<g ng-attr-transform="scale({{1/current_scale}})">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__group-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
ng-attr-x="0"
ng-attr-y="{{1200*current_scale}}"> {{item.name}} </text>
<text class="NetworkUI__group-text" text-anchor="middle" x="0" ng-attr-y="{{1200*current_scale}}">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>
</g>

View File

@@ -0,0 +1,72 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<rect
x="-52"
y="-52"
ng-attr-width="{{100 + 4}}"
ng-attr-height="{{100 + 4}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__site--selected-conflict' : item.selected ? 'NetworkUI__site--selected' : 'NetworkUI__site--remote-selected' : 'NetworkUI--hidden'}}"
rx=10>
</rect>
<g class="NetworkUI__site">
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{100}}"
rx=10
class="NetworkUI__site-background">
</rect>
<rect class="NetworkUI__site--network" x=-42 y=60 width="80" height="10" rx=5 />
<rect class="NetworkUI__site--network" x=-42 y=30 width="10" height="40" rx=5 />
<rect class="NetworkUI__site--network" x=-5 y=30 width="10" height="40" rx=5 />
<rect class="NetworkUI__site--network" x=32 y=30 width="10" height="40" rx=5 />
<rect
x="-50"
y="-40"
ng-attr-width="{{25}}"
ng-attr-height="{{80}}"
rx=10>
</rect>
<rect
x="-20"
y="-50"
ng-attr-width="{{40}}"
ng-attr-height="{{100}}"
rx=10>
</rect>
<rect
x="25"
y="-40"
ng-attr-width="{{25}}"
ng-attr-height="{{80}}"
rx=10>
</rect>
<circle cy="20" cx="-37" r=7 />
<circle cy="25" cx="0" r=10 />
<circle cy="20" cx="37" r=7 />
</g>
</g>
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__group-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
ng-attr-x="0"
ng-attr-y="100"> {{item.name}} </text>
<text class="NetworkUI__group-text" text-anchor="middle" x="0" y="100">{{item.name}}{{item.edit_label?'_':''}}</text>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/status_light.partial.svg');
function statusLight () {
return { restrict: 'A', templateUrl};
}
exports.statusLight = statusLight;

View File

@@ -0,0 +1,11 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="item.working">
<path ng-attr-transform="translate({{-item.width}}, {{-item.height}}) rotate({{frame/3}})" class="NetworkUI__status-path" ng-attr-d="{{item.describeArc(0, 0, 10, 0, 270)}}"/>
</g>
<g ng-if="!item.working">
<circle ng-attr-cx="{{-item.width}}"
ng-attr-cy="{{-item.height}}"
r=10
ng-attr-class="{{item.status === null ? 'NetworkUI--hidden' : item.status ? 'NetworkUI__status--pass': 'NetworkUI__status--fail'}}">
</circle>
</g>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/stencil.partial.svg');
function stencil () {
return { restrict: 'A', templateUrl};
}
exports.stencil = stencil;

View File

@@ -0,0 +1,14 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<rect ng-attr-class="{{stencil.is_pressed ? 'NetworkUI__stencil--button-pressed' : stencil.mouse_over ? 'NetworkUI__stencil--button-hover' : 'NetworkUI__stencil'}}"
x=0
y=0
ng-attr-width={{stencil.width}}
ng-attr-height={{stencil.height}}
rx=5></rect>
<text ng-attr-class="{{stencil.is_pressed ? 'NetworkUI__stencil-text--button-pressed' : stencil.mouse_over ? 'NetworkUI__stencil-text--button-hover' : 'NetworkUI__stencil-text'}}"
ng-attr-x="{{stencil.width/2}}"
ng-attr-y="{{stencil.height/2}}"
dy=".3em"
text-anchor="middle">{{stencil.name}}</text>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/stream.partial.svg');
function stream () {
return { restrict: 'A', templateUrl};
}
exports.stream = stream;

View File

@@ -0,0 +1,116 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var models = require('./models.js');
var messages = require('./messages.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Connected () {
this.name = 'Connected';
}
inherits(_Connected, _State);
var Connected = new _Connected();
exports.Connected = Connected;
function _Connecting () {
this.name = 'Connecting';
}
inherits(_Connecting, _State);
var Connecting = new _Connecting();
exports.Connecting = Connecting;
function _Selecting () {
this.name = 'Selecting';
}
inherits(_Selecting, _State);
var Selecting = new _Selecting();
exports.Selecting = Selecting;
_Ready.prototype.onNewStream = function (controller) {
controller.scope.clear_selections();
controller.changeState(Selecting);
};
_Ready.prototype.onNewStream.transitions = ['Selecting'];
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Connected.prototype.start = function (controller) {
controller.scope.clear_selections();
controller.changeState(Ready);
};
_Connected.prototype.start.transitions = ['Ready'];
_Connecting.prototype.onMouseDown = function () {
};
_Connecting.prototype.onMouseUp = function (controller) {
var selected = controller.scope.select_items(false);
if (selected.last_selected_device !== null) {
controller.scope.new_stream.to_device = selected.last_selected_device;
controller.scope.send_control_message(new messages.StreamCreate(controller.scope.client_id,
controller.scope.new_stream.id,
controller.scope.new_stream.from_device.id,
controller.scope.new_stream.to_device.id,
''));
controller.scope.new_stream = null;
controller.scope.update_offsets();
controller.changeState(Connected);
} else {
var index = controller.scope.streams.indexOf(controller.scope.new_stream);
if (index !== -1) {
controller.scope.streams.splice(index, 1);
}
controller.scope.new_stream = null;
controller.changeState(Ready);
}
};
_Connecting.prototype.onMouseUp.transitions = ['Ready', 'Connected'];
_Selecting.prototype.onMouseDown = function () {
};
_Selecting.prototype.onMouseUp = function (controller) {
var selected = controller.scope.select_items(false);
if (selected.last_selected_device !== null) {
controller.scope.new_stream = new models.Stream(controller.scope.stream_id_seq(), selected.last_selected_device, null, '');
controller.scope.streams.push(controller.scope.new_stream);
controller.changeState(Connecting);
}
};
_Selecting.prototype.onMouseUp.transitions = ['Connecting'];

View File

@@ -0,0 +1,134 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<!-- Straight line -->
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{stream.from_device.x}}"
ng-attr-y1="{{stream.from_device.y}}"
ng-attr-x2="{{stream.to_device !== null ? stream.to_device.x : scaledX}}"
ng-attr-y2="{{stream.to_device !== null ? stream.to_device.y : scaledY}}"
class="NetworkUI--debug"></line>
</g>
<g ng-if="stream.to_device === null">
<line ng-attr-x1="{{stream.from_device.x}}"
ng-attr-y1="{{stream.from_device.y}}"
ng-attr-x2="{{stream.to_device !== null ? stream.to_device.x : scaledX}}"
ng-attr-y2="{{stream.to_device !== null ? stream.to_device.y : scaledY}}"
class="NetworkUI__stream"></line>
</g>
<!-- End Straight line -->
<!-- Large arc -->
<g ng-if="stream.to_device !== null">
<g ng-if="stream.to_device !== stream.from_device">
<g ng-attr-transform="translate({{stream.from_device.x}},
{{stream.from_device.y}})
rotate({{stream.slope()}})">
<circle ng-if="!debug.hidden"
ng-attr-cx="{{-stream.length()/2}}"
ng-attr-cy="{{-stream.arc_offset2()}}"
r=10
class="NetworkUI__circle-debug" ></circle>
<path class="NetworkUI__stream--selected" ng-if="stream.to_device !== null && stream.selected" ng-attr-d="M0 0 A {{stream.arc_r2()}} {{stream.arc_r2()}} 0 0 0 {{-stream.length()}} 0"></path>
<path class="NetworkUI__stream" ng-if="stream.to_device !== null" ng-attr-d="M0 0 A {{stream.arc_r2()}} {{stream.arc_r2()}} 0 0 0 {{-stream.length()}} 0"></path>
<line ng-if="!debug.hidden"
ng-attr-x1="{{-stream.length()/2}}"
y1=0
ng-attr-x2="{{-stream.length()/2}}"
ng-attr-y2="{{-stream.arc_offset2()}}"
class="NetworkUI--debug"></line>
<g ng-attr-transform="rotate({{stream.start_arc_angle()}})
translate(-{{stream.from_device.size}}, 0)">
<circle ng-if="!debug.hidden"
ng-attr-cx="0"
ng-attr-cy="0"
r=10
class="NetworkUI__circle-debug" ></circle>
</g>
<rect ng-if="!debug.hidden"
ng-attr-x="{{-stream.length()}}"
ng-attr-y="{{-stream.arc_offset2()}}"
ng-attr-width="{{stream.length()}}"
ng-attr-height="{{stream.arc_offset2()}}"
class="NetworkUI--debug"></rect>
</g>
</g>
</g>
<!-- End Large arc -->
<!-- Debug -->
<g ng-if="stream.to_device !== null">
<g ng-if="stream.to_device !== stream.from_device">
<g ng-if="!debug.hidden && current_scale > 0.5">
<line ng-if="stream.to_device !== null"
ng-attr-x1="{{stream.perpendicular(scaledX, scaledY).x2}}"
ng-attr-y1="{{stream.perpendicular(scaledX, scaledY).y2}}"
ng-attr-x2="{{scaledX}}"
ng-attr-y2="{{scaledY}}"
ng-attr-class="NetworkUI--debug" />
<g ng-attr-transform="translate({{stream.to_device.x}},
{{stream.to_device.y}})
rotate({{stream.slope()}})
translate({{stream.length()/2}}, 0)">
</g>
<g ng-attr-transform="translate({{stream.to_device.x}},
{{stream.to_device.y}})
rotate({{stream.slope()}})
translate({{stream.to_device.size}}, 0)">
<circle ng-attr-cx="0"
ng-attr-cy="0"
r=10
class="NetworkUI__circle-debug" ></circle>
</g>
<g ng-attr-transform="translate({{stream.from_device.x}},
{{stream.from_device.y}})
rotate({{stream.slope()}})
translate({{-stream.from_device.size}}, 0)">
<circle ng-attr-cx="0"
ng-attr-cy="0"
r=10
class="NetworkUI__circle-debug" ></circle>
</g>
</g>
</g>
</g>
<!-- End Debug -->
<!-- Arrow -->
<g ng-if="stream.to_device !== stream.from_device">
<g ng-if="stream.to_device !== null" ng-attr-transform="translate({{stream.to_device.x}},
{{stream.to_device.y}})
rotate({{stream.slope()}})
rotate({{-stream.end_arc_angle()}})
translate({{stream.to_device.size}}, 0)
rotate({{stream.end_arc_angle()}})
rotate(180)
rotate({{-stream.arc_angle_tan2()}})">
<line ng-if="!debug.hidden"
x1=0
y1=0
x2=-100
y2=0
class="NetworkUI--debug"></line>
<g transform="translate(-19, -9)">
<path ng-attr-transform="translate(-2, -3)" d="M0,0 L0,24 L24,12 z" class="{{stream.selected && 'NetworkUI__stream--arrow-selected' || 'NetworkUI--hidden'}}"/>
<path d="M0,0 L0,18 L18,9 z" class="NetworkUI__stream-arrow"/>
</g>
</g>
<!-- End Arrow -->
<!-- Text -->
<g ng-if="current_scale > 0.5 && stream.to_device !== null"
ng-attr-transform="translate({{stream.from_device.x}},
{{stream.from_device.y}})
rotate({{stream.slope()}})
translate({{-stream.length()/2}}, 0)
translate(0, {{-stream.arc_offset2()}})
translate(0, -5)
rotate({{stream.flip_text_rotate()}})
translate(0, {{stream.flip_text_offset()}})
">
<text ng-attr-class="{{stream.selected && ! stream.edit_label ? 'NetworkUI__stream-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="0"> {{stream.label}}</text>
<text class="NetworkUI__stream-text" text-anchor="middle" x="0" y="0">{{stream.label}}{{stream.edit_label?'_':''}}</text>
</g>
</g>
<!-- End Text -->

View File

@@ -0,0 +1,763 @@
/* Copyright (c) 2017 Red Hat, Inc. */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: url(/static/assets/OpenSans-Regular.ttf);
}
@font-face {
font-family: 'Open Sans';
font-style: bold;
font-weight: 600;
src: url(/static/assets/OpenSans-Bold.ttf);
}
@selected-red: #c9232c;
@selected-mango: #ff5850;
@selected-blue: #5bbddf;
@light-background: #ffffff;
@light-widget-detail: #ffffff;
@dark-widget-detail: #707070;
@widget-body: #D7D7D7;
@link: #D7D7D7;
@group: #707070;
@debug-copynot: rgb(77,200,242);
@button-body: #ffffff;
@button-text: #707070;
@button-outline: #b7b7b7;
@button-body-hover: #f2f2f2;
@button-body-pressed: #848992;
@button-text-pressed: #ffffff;
@green: #5CB85C;
@red: #D9534F;
@light-toolbox-background: #f6f6f6;
@icon-background-hover:#337AB7;
.NetworkUI {
background-color: @light-toolbox-background;
cursor: none;
}
.NetworkUI__text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__debug-text {
fill: @debug-copynot;
font-family: 'Open Sans';
}
.NetworkUI--debug {
fill-opacity: 0;
stroke: @debug-copynot;
stroke-width: 1;
}
.NetworkUI--construction {
fill-opacity: 0;
stroke: @debug-copynot;
stroke-width: 1;
}
.NetworkUI__link--selected {
stroke: @selected-blue;
stroke-width: 6;
}
.NetworkUI__link--remote-selected {
stroke: @selected-mango;
stroke-width: 6;
}
.NetworkUI__link--selected-conflict {
stroke: @selected-red;
stroke-width: 6;
}
.NetworkUI__link {
stroke: @link;
stroke-width: 2;
}
.NetworkUI__link--link-pass {
stroke: @green;
stroke-width: 2;
}
.NetworkUI__link--link-fail {
stroke: @red;
stroke-width: 2;
}
.NetworkUI__link--debug {
stroke: @debug-copynot;
stroke-width: 1;
}
.NetworkUI__cursor {
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__debug-cursor {
stroke: @debug-copynot;
stroke-width: 4;
}
.NetworkUI--hidden {
display: none;
}
.NetworkUI__router {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__router--selected {
stroke: @selected-blue;
stroke-width: 4;
}
.NetworkUI__router--remote-selected {
stroke: @selected-mango;
stroke-width: 4;
}
.NetworkUI__router--selected-conflict {
stroke: @selected-red;
stroke-width: 4;
}
.NetworkUI__router line {
stroke: @light-widget-detail;
stroke-width: 20;
}
.NetworkUI__router polygon {
fill: @light-widget-detail;
stroke: none;
}
.NetworkUI__router-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__router-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__switch {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__switch--selected {
stroke: @selected-blue;
stroke-width: 10;
}
.NetworkUI__switch--remote-selected {
stroke: @selected-mango;
stroke-width: 10;
}
.NetworkUI__switch--selected-conflict {
stroke: @selected-red;
stroke-width: 10;
}
.NetworkUI__switch line {
stroke: @light-widget-detail;
stroke-width: 20;
}
.NetworkUI__switch polygon {
fill: @light-widget-detail;
stroke: none;
}
.NetworkUI__switch-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__switch-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__rack {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__rack-background {
fill: @light-background;
stroke: @light-background;
stroke-width: 2;
}
.NetworkUI__rack--selected {
fill: @selected-blue;
stroke: @selected-blue;
stroke-width: 10;
}
.NetworkUI__rack--remote-selected {
fill: @selected-mango;
stroke: @selected-mango;
stroke-width: 10;
}
.NetworkUI__rack--selected-conflict {
fill: @selected-red;
stroke: @selected-red;
stroke-width: 10;
}
.NetworkUI__rack line {
stroke: @light-widget-detail;
stroke-width: 20;
}
.NetworkUI__rack circle {
fill: @light-widget-detail;
stroke: none;
}
.NetworkUI__rack-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__rack-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__site {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__site--network {
fill: @dark-widget-detail;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__site-background {
fill: @light-background;
stroke: @light-background;
stroke-width: 2;
}
.NetworkUI__site--selected {
fill: @selected-blue;
stroke: @selected-blue;
stroke-width: 10;
}
.NetworkUI__site--remote-selected {
fill: @selected-mango;
stroke: @selected-mango;
stroke-width: 10;
}
.NetworkUI__site--selected-conflict {
fill: @selected-red;
stroke: @selected-red;
stroke-width: 10;
}
.NetworkUI__site line {
stroke: @dark-widget-detail;
stroke-width: 10;
}
.NetworkUI__site circle {
fill: @light-widget-detail;
stroke: none;
}
.NetworkUI__site-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__site-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__button {
fill: @button-body;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__button-text {
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__button--button-pressed {
fill: @button-body-pressed;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__button-text--button-pressed {
fill: @button-text-pressed;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__button--button-hover {
fill: @button-body-hover;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__button-text--button-hover {
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__layer {
fill: @button-body;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__layer-text {
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__layer--button-pressed {
fill: @button-body-pressed;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__layer-text--button-pressed {
fill: @button-text-pressed;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__layer--button-hover {
fill: @button-body-hover;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__layer-text--button-hover {
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__stencil {
fill: @button-body;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__stencil-text {
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__stencil--button-pressed {
fill: @button-body-pressed;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__stencil-text--button-pressed {
fill: @button-text-pressed;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__stencil--button-hover {
fill: @button-body-hover;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__stencil-text--button-hover {
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__host {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__host-background {
fill: @light-background;
stroke: @light-background;
stroke-width: 2;
}
.NetworkUI__host--selected {
fill: @selected-blue;
stroke: @selected-blue;
stroke-width: 10;
}
.NetworkUI__host--remote-selected {
fill: @selected-mango;
stroke: @selected-mango;
stroke-width: 10;
}
.NetworkUI__host--selected-conflict {
fill: @selected-red;
stroke: @selected-red;
stroke-width: 10;
}
.NetworkUI__host line {
stroke: @light-widget-detail;
stroke-width: 20;
}
.NetworkUI__host circle {
fill: @light-widget-detail;
stroke: none;
}
.NetworkUI__host-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__host-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__device {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__device-background {
fill: @light-background;
stroke: @light-background;
stroke-width: 2;
}
.NetworkUI__device--selected {
fill: @selected-blue;
stroke: @selected-blue;
stroke-width: 10;
}
.NetworkUI__device--remote-selected {
fill: @selected-mango;
stroke: @selected-mango;
stroke-width: 10;
}
.NetworkUI__device--selected-conflict {
fill: @selected-red;
stroke: @selected-red;
stroke-width: 10;
}
.NetworkUI__device line {
stroke: @light-widget-detail;
stroke-width: 20;
}
.NetworkUI__device-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__device-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__status {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__status--pass {
fill: @green;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__status--fail {
fill: @red;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__status-path {
fill: none;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__circle-debug {
fill: @debug-copynot;
}
.NetworkUI__interface {
fill: @dark-widget-detail;
}
.NetworkUI__interface--selected {
fill: @selected-blue;
}
.NetworkUI__interface-text {
fill: @button-text;
font-size: 8px;
font-family: 'Open Sans';
}
.NetworkUI__interface-text--selected {
font-size: 8px;
font-family: 'Open Sans';
}
.NetworkUI__link-text {
fill: @button-text;
font-size: 8px;
font-family: 'Open Sans';
}
.NetworkUI__touch {
stroke: @debug-copynot;
fill: none;
}
.NetworkUI__group--selected {
stroke: @selected-blue;
stroke-width: 6;
fill: none;
}
.NetworkUI__group--remote-selected {
stroke: @selected-mango;
stroke-width: 6;
fill: none;
}
.NetworkUI__group--selected-conflict {
stroke: @selected-red;
stroke-width: 6;
fill: none;
}
.NetworkUI__group {
stroke: @group;
stroke-width: 2;
fill: none;
}
.NetworkUI__group--debug {
stroke: @debug-copynot;
stroke-width: 1;
fill: none;
}
.NetworkUI__group-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__group-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__location-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__toolbox {
stroke: none;
fill: @light-background;
}
.NetworkUI__toolbox-collapsed{
fill: @light-background;
stroke: @button-outline;
stroke-width: 1;
rx: 0;
stroke-dasharray: calc(~"100vh - 40px");
stroke-dashoffset: -45;
}
.NetworkUI__toolbox-bezel {
stroke: @button-outline;
stroke-width: 1;
fill: none;
rx: 0;
stroke-dasharray: calc(~"100vh - 40px");
stroke-dashoffset: -200;
}
.NetworkUI__process {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__process-background {
fill: @light-background;
stroke: @light-background;
stroke-width: 2;
}
.NetworkUI__process--selected {
fill: @selected-blue;
stroke: @selected-blue;
stroke-width: 10;
}
.NetworkUI__process--remote-selected {
fill: @selected-mango;
stroke: @selected-mango;
stroke-width: 10;
}
.NetworkUI__process--selected-conflict {
fill: @selected-red;
stroke: @selected-red;
stroke-width: 10;
}
.NetworkUI__process path {
fill: @widget-body;
stroke: @dark-widget-detail;
stroke-width: 2;
}
.NetworkUI__process-text {
fill: @button-text;
font-family: 'Open Sans';
}
.NetworkUI__process-text--selected {
font-family: 'Open Sans';
}
.NetworkUI__stream {
fill: none;
stroke: @dark-widget-detail;
}
.NetworkUI__stream-arrow {
fill: @dark-widget-detail;
stroke: @dark-widget-detail;
}
.NetworkUI__stream--selected {
fill: none;
stroke: @selected-blue;
stroke-width: 6;
}
.NetworkUI__stream-arrow--selected {
fill: @selected-blue;
stroke: @selected-blue;
}
.NetworkUI__stream-text {
fill: @button-text;
font-size: 8px;
font-family: 'Open Sans';
}
.NetworkUI_chevron{
fill: @button-body-pressed;
}
.NetworkUI_chevron--hover{
cursor: pointer;
fill: white;
}
.NetworkUI_iconBackground{
fill:@button-body;
}
.NetworkUI_iconBackground--hover{
fill:@icon-background-hover;
}
.NetworkUI__toolbox--title{
fill: @dark-widget-detail;
text-transform: uppercase;
font-size: 14px;
font-weight: bold;
}
.NetworkUI__contextMenu{
fill: @light-background;
stroke: @button-outline;
stroke-width: 1;
}
.NetworkUI__contextMenuButton{
fill: @light-background;
}
.NetworkUI__contextMenuButtonText{
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__contextMenuButtonText-hover{
fill: @button-text;
font-family: 'Open Sans';
font-size: 14px;
}
.NetworkUI__contextMenuButton-hover,
.NetworkUI__contextMenuButton-pressed{
fill:@button-body-hover;
}

View File

@@ -0,0 +1,250 @@
/**
* @license svg-crowbar
* (c) 2013 The New York Times
* License: MIT
*/
function svg_crowbar () {
var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
window.URL = (window.URL || window.webkitURL);
var body = document.body;
var prefix = {
xmlns: "http://www.w3.org/2000/xmlns/",
xlink: "http://www.w3.org/1999/xlink",
svg: "http://www.w3.org/2000/svg"
};
initialize();
function initialize() {
var documents = [window.document],
SVGSources = [],
iframes = document.querySelectorAll("iframe"),
objects = document.querySelectorAll("object");
[].forEach.call(iframes, function(el) {
try {
if (el.contentDocument) {
documents.push(el.contentDocument);
}
} catch(err) {
console.log(err);
}
});
[].forEach.call(objects, function(el) {
try {
if (el.contentDocument) {
documents.push(el.contentDocument);
}
} catch(err) {
console.log(err);
}
});
documents.forEach(function(doc) {
var styles = getStyles(doc);
var newSources = getSources(doc, styles);
// because of prototype on NYT pages
for (var i = 0; i < newSources.length; i++) {
SVGSources.push(newSources[i]);
}
});
if (SVGSources.length > 1) {
createPopover(SVGSources);
} else if (SVGSources.length > 0) {
download(SVGSources[0]);
} else {
alert("The Crowbar couldnt find any SVG nodes.");
}
}
function createPopover(sources) {
cleanup();
sources.forEach(function(s1) {
sources.forEach(function(s2) {
if (s1 !== s2) {
if ((Math.abs(s1.top - s2.top) < 38) && (Math.abs(s1.left - s2.left) < 38)) {
s2.top += 38;
s2.left += 38;
}
}
});
});
var buttonsContainer = document.createElement("div");
body.appendChild(buttonsContainer);
buttonsContainer.setAttribute("class", "svg-crowbar");
buttonsContainer.style["z-index"] = 1e7;
buttonsContainer.style.position = "absolute";
buttonsContainer.style.top = 0;
buttonsContainer.style.left = 0;
var background = document.createElement("div");
body.appendChild(background);
background.setAttribute("class", "svg-crowbar");
background.style.background = "rgba(255, 255, 255, 0.7)";
background.style.position = "fixed";
background.style.left = 0;
background.style.top = 0;
background.style.width = "100%";
background.style.height = "100%";
sources.forEach(function(d, i) {
var buttonWrapper = document.createElement("div");
buttonsContainer.appendChild(buttonWrapper);
buttonWrapper.setAttribute("class", "svg-crowbar");
buttonWrapper.style.position = "absolute";
buttonWrapper.style.top = (d.top + document.body.scrollTop) + "px";
buttonWrapper.style.left = (document.body.scrollLeft + d.left) + "px";
buttonWrapper.style.padding = "4px";
buttonWrapper.style["border-radius"] = "3px";
buttonWrapper.style.color = "white";
buttonWrapper.style["text-align"] = "center";
buttonWrapper.style["font-family"] = "'Helvetica Neue'";
buttonWrapper.style.background = "rgba(0, 0, 0, 0.8)";
buttonWrapper.style["box-shadow"] = "0px 4px 18px rgba(0, 0, 0, 0.4)";
buttonWrapper.style.cursor = "move";
buttonWrapper.textContent = "SVG #" + i + ": " + (d.id ? "#" + d.id : "") + (d.class ? "." + d.class : "");
var button = document.createElement("button");
buttonWrapper.appendChild(button);
button.setAttribute("data-source-id", i);
button.style.width = "150px";
button.style["font-size"] = "12px";
button.style["line-height"] = "1.4em";
button.style.margin = "5px 0 0 0";
button.textContent = "Download";
button.onclick = function() {
// console.log(el, d, i, sources)
download(d);
};
});
}
function cleanup() {
var crowbarElements = document.querySelectorAll(".svg-crowbar");
[].forEach.call(crowbarElements, function(el) {
el.parentNode.removeChild(el);
});
}
function getSources(doc, styles) {
var svgInfo = [],
svgs = doc.querySelectorAll("svg");
styles = (styles === undefined) ? "" : styles;
[].forEach.call(svgs, function (svg) {
svg.setAttribute("version", "1.1");
var defsEl = document.createElement("defs");
svg.insertBefore(defsEl, svg.firstChild); //TODO .insert("defs", ":first-child")
// defsEl.setAttribute("class", "svg-crowbar");
var styleEl = document.createElement("style");
defsEl.appendChild(styleEl);
styleEl.setAttribute("type", "text/css");
// removing attributes so they aren't doubled up
svg.removeAttribute("xmlns");
svg.removeAttribute("xlink");
// These are needed for the svg
if (!svg.hasAttributeNS(prefix.xmlns, "xmlns")) {
svg.setAttributeNS(prefix.xmlns, "xmlns", prefix.svg);
}
if (!svg.hasAttributeNS(prefix.xmlns, "xmlns:xlink")) {
svg.setAttributeNS(prefix.xmlns, "xmlns:xlink", prefix.xlink);
}
var source = (new XMLSerializer()).serializeToString(svg).replace('</style>', '<![CDATA[' + styles + ']]></style>');
var rect = svg.getBoundingClientRect();
svgInfo.push({
top: rect.top,
left: rect.left,
width: rect.width,
height: rect.height,
class: svg.getAttribute("class"),
id: svg.getAttribute("id"),
childElementCount: svg.childElementCount,
source: [doctype + source]
});
});
return svgInfo;
}
function download(source) {
var filename = "untitled";
if (source.id) {
filename = source.id;
} else if (source.class) {
filename = source.class;
} else if (window.document.title) {
filename = window.document.title.replace(/[^a-z0-9]/gi, '-').toLowerCase();
}
var url = window.URL.createObjectURL(new Blob(source.source, { "type" : "text\/xml" }));
var a = document.createElement("a");
body.appendChild(a);
a.setAttribute("class", "svg-crowbar");
a.setAttribute("download", filename + ".svg");
a.setAttribute("href", url);
a.style.display = "none";
a.click();
setTimeout(function() {
window.URL.revokeObjectURL(url);
}, 10);
}
function getStyles(doc) {
var styles = "",
styleSheets = doc.styleSheets;
if (styleSheets) {
for (var i = 0; i < styleSheets.length; i++) {
processStyleSheet(styleSheets[i]);
}
}
function processStyleSheet(ss) {
if (ss.cssRules) {
for (var i = 0; i < ss.cssRules.length; i++) {
var rule = ss.cssRules[i];
if (rule.type === 3) {
// Import Rule
processStyleSheet(rule.styleSheet);
} else {
// hack for illustrator crashing on descendent selectors
if (rule.selectorText) {
if (rule.selectorText.indexOf(">") === -1) {
styles += "\n" + rule.cssText;
}
}
}
}
}
}
return styles;
}
}
exports.svg_crowbar = svg_crowbar;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/switch.partial.svg');
function switchd () {
return { restrict: 'A', templateUrl};
}
exports.switchd = switchd;

View File

@@ -0,0 +1,79 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-if="item.moving">
<line ng-attr-x1="{{-50 - 100}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 100}}"
ng-attr-y2="0"
class="NetworkUI--construction"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 100}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 100}}"
class="NetworkUI--construction"></line>
</g>
<g ng-if="!debug.hidden">
<line ng-attr-x1="{{-50 - 10}}"
ng-attr-y1="0"
ng-attr-x2="{{50 + 10}}"
ng-attr-y2="0"
class="NetworkUI--debug"></line>
<line ng-attr-x1="0"
ng-attr-y1="{{-50 - 10}}"
ng-attr-x2="0"
ng-attr-y2="{{50 + 10}}"
class="NetworkUI--debug"></line>
<rect ng-attr-x="{{-50}}"
ng-attr-y="{{-50}}"
ng-attr-width="{{50 * 2}}"
ng-attr-height="{{50 * 2}}"
class="NetworkUI--debug"></rect>
</g>
<rect
x="-52"
y="-52"
ng-attr-width="{{100 + 4}}"
ng-attr-height="{{100 + 4}}"
ng-attr-class="{{item.selected || item.remote_selected ? item.selected && item.remote_selected ? 'NetworkUI__switch--selected-conflict' : item.selected ? 'NetworkUI__switch--selected' : 'NetworkUI__switch--remote-selected' : 'NetworkUI--hidden'}}"
rx=10>
</rect>
<g class="NetworkUI__switch">
<rect
x="-50"
y="-50"
ng-attr-width="{{100}}"
ng-attr-height="{{100}}"
rx=10>
</rect>
<line ng-attr-x1="2"
ng-attr-y1="-28"
ng-attr-x2="38"
ng-attr-y2="-28"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(0) translate(28, -48) scale(2.0)"/>
<line ng-attr-x1="2"
ng-attr-y1="14"
ng-attr-x2="38"
ng-attr-y2="14"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(0) translate(28, -6) scale(2.0)"/>
<line ng-attr-x1="-2"
ng-attr-y1="28"
ng-attr-x2="-38"
ng-attr-y2="28"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(180) translate(28, -48) scale(2.0)"/>
<line ng-attr-x1="-2"
ng-attr-y1="-14"
ng-attr-x2="-38"
ng-attr-y2="-14"/>
<polygon points="0 0, 10 10, 0 20" ng-attr-transform="rotate(180) translate(28, -6) scale(2.0)"/>
</g>
<g ng-show="item.icon || current_scale > 0.5">
<text ng-attr-class="{{item.selected && ! item.edit_label ? 'NetworkUI__switch-text--selected' : 'NetworkUI--hidden'}}"
filter="url(#selected)"
text-anchor="middle"
x="0"
y="0"> {{item.name}} </text>
<text class="NetworkUI__switch-text" text-anchor="middle" x="0" y="0">{{item.name}}{{item.edit_label?'_':''}}</text>
</g>

View File

@@ -0,0 +1,16 @@
/* Copyright (c) 2017 Red Hat, Inc. */
//console.log = function () { };
var angular = require('angular');
var TablesUIController = require('./tables.ui.controller.js');
var awxTablesUI = require('./tables.ui.directive.js');
var tablesUI = angular.module('tablesUI', ['xeditable'])
.controller('TablesUIController', TablesUIController.TablesUIController)
.directive('awxTablesUi', awxTablesUI.awxTablesUI)
.run(function(editableOptions) {
editableOptions.theme = 'bs3';
editableOptions.activate = 'select';
});
exports.tablesUI = tablesUI;

View File

@@ -0,0 +1,153 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var util = require('./util.js');
var messages = require('./messages.js');
var ReconnectingWebSocket = require('reconnectingwebsocket');
var TablesUIController = function($scope, $window, $location, $timeout) {
$window.scope = $scope;
$scope.disconnected = false;
$scope.topology_id = $location.search().topology_id || 0;
if (!$scope.disconnected) {
$scope.control_socket = new ReconnectingWebSocket("ws://" + window.location.host + "/network_ui/tables?topology_id=" + $scope.topology_id,
null,
{debug: false, reconnectInterval: 300});
} else {
$scope.control_socket = {
on_message: util.noop
};
}
$scope.client_id = 0;
$scope.message_id_seq = util.natural_numbers(0);
$scope.onClientId = function(data) {
$scope.client_id = data;
};
$scope.control_socket.onmessage = function(message) {
var type_data = JSON.parse(message.data);
var type = type_data[0];
var data = type_data[1];
$scope.handle_message(type, data);
$scope.$apply();
};
$scope.control_socket.onopen = function() {
//Ignore
};
// Call onopen directly if $scope.control_socket is already open
if ($scope.control_socket.readyState === WebSocket.OPEN) {
$scope.control_socket.onopen();
}
$scope.send_control_message = function (message) {
var i = 0;
message.sender = $scope.client_id;
message.message_id = $scope.message_id_seq();
if (message.constructor.name === "MultipleMessage") {
for (i=0; i < message.messages.length; i++) {
message.messages[i].message_id = $scope.message_id_seq();
}
}
var data = messages.serialize(message);
if (!$scope.disconnected) {
$scope.control_socket.send(data);
console.log("Sent message");
} else {
console.log(data);
}
};
$scope.handle_message = function(msg_type, message) {
var handler_name = 'on' + msg_type;
if (typeof(this[handler_name]) !== "undefined") {
this[handler_name](msg_type, message);
} else {
this.default_handler(msg_type, message);
}
};
$scope.default_handler = function(msg_type, message) {
console.log([msg_type, message]);
};
// End web socket
//
//
$scope.onid = function(msg_type, message) {
console.log(["Set client_id to" , message]);
$scope.client_id = message;
};
$scope.ontopology_id = function(msg_type, message) {
console.log(["Set topology_id to" , message]);
$scope.topology_id = message;
$location.search({topology_id: message});
};
$scope.onsheet = function(msg_type, message) {
console.log("Update sheet");
console.log(message);
$scope.data = message.data;
$scope.name = message.name;
$scope.sheets.push(message.name);
$scope.sheets_by_name[message.name] = message.data;
};
$scope.onTableCellEdit = function(msg_type, message) {
if (message.sender === $scope.client_id) {
return;
}
console.log(["Updating data", message.sheet, message.row, message.col, message.new_value]);
$scope.sheets_by_name[message.sheet][message.row][message.col].value = message.new_value;
$scope.$apply();
};
$scope.user = {
name: 'world'
};
$scope.data = [];
$scope.sheets = [];
$scope.sheets_by_name = {};
console.log("Tables UI started");
$scope.$on('$destroy', function () {
console.log("Tables UI stopping");
});
$scope.updateData = function (old_data, new_data, column_index, row_index, column_name, row_name) {
console.log(['updateData', $scope.name, old_data, new_data, column_index, row_index, column_name, row_name]);
$scope.send_control_message(new messages.TableCellEdit($scope.client_id,
$scope.name,
column_index,
row_index,
old_data,
new_data));
$timeout(function () {
var q = document.querySelectorAll("#" + $scope.name + "_" + column_index + "_" + (row_index + 1));
if (q.length > 0) {
q[0].click();
}
});
};
$scope.changeSheet = function(sheet) {
$scope.name = sheet;
$scope.data = $scope.sheets_by_name[sheet];
};
};
exports.TablesUIController = TablesUIController;
console.log("Tables UI loaded");

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/tables_ui.partial.svg');
function awxTablesUI () {
return { restrict: 'E', templateUrl};
}
exports.awxTablesUI = awxTablesUI;

View File

@@ -0,0 +1,30 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<div ng-controller="TablesUIController">
<ul class="nav nav-tabs">
<li ng-repeat="sheet in sheets" role="presentation" class="{{sheet === name ? 'active': ''}}"><a href ng-click="changeSheet(sheet)">{{sheet}}</a></li>
</ul>
<table class="table table-bordered">
<colgroup>
<col ng-repeat="column_header in data[0]" style="width:10%">
</colgroup>
<thead>
<tr>
<th>
</th>
<th ng-repeat="column_header in data[0]">
{{column_header.value}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(row_index, row) in data track by $index" ng-if="$index > 0">
<th>
{{row[0].value}}
</th>
<td ng-repeat="(column_index, cell) in row track by $index" ng-if="$index > 0" buttons="no" onbeforesave="updateData(cell.value, $data, column_index, row_index, data[0][column_index-1].value, row[0].value)" editable-text="cell.value" edit-disabled="{{!cell.editable}}" ng-attr-id="{{name + '_' + column_index + '_' + row_index}}">
{{cell.value}}
</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/task_status.partial.svg');
function taskStatus () {
return { restrict: 'A', templateUrl};
}
exports.taskStatus = taskStatus;

View File

@@ -0,0 +1,16 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-attr-transform="translate({{-item.width}}, {{-item.height}})">
<g ng-repeat="task in item.tasks | limitTo: -7">
<g ng-if="task.working && current_scale > 0.5">
<path ng-attr-transform="translate({{$index * 12 + 17}}, -5 ) rotate({{frame/3}})" class="NetworkUI__status-path" ng-attr-d="{{task.describeArc(0, 0, 5, 0, 270)}}"/>
</g>
<g ng-if="!task.working && current_scale > 0.5">
<circle ng-attr-cx="{{$index * 12 + 17}}"
ng-attr-cy="-5"
r=5
ng-attr-class="{{task.status === null ? 'NetworkUI--hidden' : task.status ? 'NetworkUI__status--pass': 'NetworkUI__status--fail'}}"
</circle>
</g>
</g>
</g>

View File

@@ -0,0 +1,541 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
var messages = require('./messages.js');
var util = require('./util.js');
function _State () {
}
inherits(_State, fsm._State);
function _Past () {
this.name = 'Past';
}
inherits(_Past, _State);
var Past = new _Past();
exports.Past = Past;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Present () {
this.name = 'Present';
}
inherits(_Present, _State);
var Present = new _Present();
exports.Present = Present;
_Past.prototype.start = function (controller) {
controller.scope.time_pointer = controller.scope.history.length - 1;
};
_Past.prototype.onMessage = function(controller, msg_type, message) {
//console.log(message.data);
var type_data = JSON.parse(message.data);
var type = type_data[0];
var data = type_data[1];
if (['DeviceCreate',
'DeviceDestroy',
'DeviceMove',
'DeviceLabelEdit',
'GroupLabelEdit',
'GroupCreate',
'LinkLabelEdit',
'InterfaceLabelEdit',
'InterfaceCreate',
'LinkCreate',
'LinkDestroy'].indexOf(type) !== -1) {
controller.changeState(Present);
controller.scope.history.splice(controller.scope.time_pointer);
if (data.sender !== controller.scope.client_id) {
controller.handle_message(msg_type, message);
} else {
controller.scope.history.push(message.data);
}
} else {
controller.handle_message(type, data);
}
};
_Past.prototype.onMultipleMessage = function(controller, msg_type, message) {
var i = 0;
console.log(['MultipleMessage', message]);
if (message.sender !== controller.scope.client_id) {
for (i=0; i< message.messages.length; i++) {
controller.handle_message(message.messages[i].msg_type, message.messages[i]);
}
}
};
_Past.prototype.onDeviceSelected = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceSelected(message);
}
};
_Past.prototype.onDeviceUnSelected = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceUnSelected(message);
}
};
_Past.prototype.onUndo = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.time_pointer = Math.max(0, controller.scope.time_pointer - 1);
controller.scope.undo(message.original_message);
}
};
_Past.prototype.onRedo = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.time_pointer = Math.min(controller.scope.history.length, controller.scope.time_pointer + 1);
controller.scope.redo(message.original_message);
if (controller.scope.time_pointer === controller.scope.history.length) {
controller.changeState(Present);
}
}
};
_Past.prototype.onRedo.transitions = ['Present'];
_Past.prototype.onCoverageRequest = function(controller) {
controller.scope.send_coverage();
};
_Past.prototype.onStopRecording = function(controller) {
controller.scope.recording = false;
};
_Past.prototype.onStartReplay = function(controller) {
controller.scope.replay = true;
};
_Past.prototype.onStopReplay = function(controller) {
controller.scope.replay = false;
};
_Past.prototype.onViewPort = function(controller, msg_type, message) {
if (message.sender === controller.scope.client_id) {
return;
}
controller.scope.current_scale = message.scale;
controller.scope.panX = message.panX;
controller.scope.panY = message.panY;
controller.scope.updateScaledXY();
controller.scope.updatePanAndScale();
};
_Past.prototype.onTouchEvent = function(controller, msg_type, message) {
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
if (message.type === "touchstart") {
controller.scope.onTouchStart(message);
}
if (message.type === "touchend") {
controller.scope.onTouchEnd(message);
}
if (message.type === "touchmove") {
controller.scope.onTouchMove(message);
}
};
_Past.prototype.onMouseEvent = function(controller, msg_type, message) {
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
//console.log(message);
if (message.type === "mousemove") {
controller.scope.onMouseMove(message);
}
if (message.type === "mouseup") {
controller.scope.onMouseUp(message);
}
if (message.type === "mousedown") {
controller.scope.onMouseDown(message);
}
if (message.type === "mouseover") {
controller.scope.onMouseOver(message);
}
if (message.type === "mouseout") {
controller.scope.onMouseOver(message);
}
};
_Past.prototype.onMouseWheelEvent = function(controller, msg_type, message) {
console.log(message);
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
message.stopPropagation = util.noop;
controller.scope.onMouseWheel(message, message.delta, message.deltaX, message.deltaY);
};
_Past.prototype.onKeyEvent = function(controller, msg_type, message) {
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
//console.log(message);
if (message.type === "keydown") {
controller.scope.onKeyDown(message);
}
};
_Past.prototype.onMouseWheel = function (controller, msg_type, message) {
var $event = message[0];
var delta = message[1];
if ($event.originalEvent.metaKey) {
//console.log(delta);
if (delta < 0) {
this.undo(controller);
} else if (delta > 0) {
this.redo(controller);
}
} else {
controller.delegate_channel.send(msg_type, message);
}
};
_Past.prototype.onMouseWheel.transitions = ['Present'];
_Past.prototype.onKeyDown = function(controller, msg_type, $event) {
//console.log($event);
if ($event.key === 'z' && $event.metaKey && ! $event.shiftKey) {
this.undo(controller);
return;
} else if ($event.key === 'z' && $event.ctrlKey && ! $event.shiftKey) {
this.undo(controller);
return;
} else if ($event.key === 'Z' && $event.metaKey && $event.shiftKey) {
this.redo(controller);
return;
} else if ($event.key === 'Z' && $event.ctrlKey && $event.shiftKey) {
this.redo(controller);
return;
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Past.prototype.onKeyDown.transitions = ['Present'];
_Past.prototype.undo = function(controller) {
//controller.changeState(Past);
controller.scope.time_pointer = Math.max(0, controller.scope.time_pointer - 1);
if (controller.scope.time_pointer >= 0) {
var change = controller.scope.history[controller.scope.time_pointer];
var type_data = JSON.parse(change);
controller.scope.send_control_message(new messages.Undo(controller.scope.client_id,
type_data));
controller.scope.undo(type_data);
}
};
_Past.prototype.redo = function(controller) {
if (controller.scope.time_pointer < controller.scope.history.length) {
var change = controller.scope.history[controller.scope.time_pointer];
var type_data = JSON.parse(change);
controller.scope.send_control_message(new messages.Redo(controller.scope.client_id,
type_data));
controller.scope.redo(type_data);
controller.scope.time_pointer = Math.min(controller.scope.history.length, controller.scope.time_pointer + 1);
if (controller.scope.time_pointer === controller.scope.history.length) {
controller.changeState(Present);
}
} else {
controller.changeState(Present);
}
};
_Start.prototype.start = function (controller) {
controller.changeState(Present);
};
_Start.prototype.start.transitions = ['Present'];
_Present.prototype.onMessage = function(controller, msg_type, message) {
//console.log(message.data);
var type_data = JSON.parse(message.data);
var type = type_data[0];
var data = type_data[1];
if (['DeviceCreate',
'DeviceDestroy',
'DeviceMove',
'DeviceLabelEdit',
'GroupLabelEdit',
'GroupCreate',
'InterfaceCreate',
'InterfaceLabelEdit',
'LinkCreate',
'LinkDestroy',
'LinkLabelEdit',
'Snapshot'].indexOf(type) !== -1) {
controller.scope.history.push(message.data);
}
controller.handle_message(type, data);
};
_Present.prototype.onMultipleMessage = function(controller, msg_type, message) {
var i = 0;
console.log(['MultipleMessage', message]);
if (message.sender !== controller.scope.client_id) {
for (i = 0; i< message.messages.length; i++) {
controller.handle_message(message.messages[i].msg_type, message.messages[i]);
}
}
};
_Present.prototype.onDeviceStatus = function(controller, msg_type, message) {
controller.scope.onDeviceStatus(message);
};
_Present.prototype.onTaskStatus = function(controller, msg_type, message) {
controller.scope.onTaskStatus(message);
};
_Present.prototype.onFacts = function(controller, msg_type, message) {
controller.scope.onFacts(message);
};
_Present.prototype.onDeviceCreate = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceCreate(message);
}
};
_Present.prototype.onGroupCreate = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onGroupCreate(message);
}
};
_Present.prototype.onInterfaceCreate = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onInterfaceCreate(message);
}
};
_Present.prototype.onLinkCreate = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onLinkCreate(message);
}
};
_Present.prototype.onDeviceMove = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceMove(message);
}
};
_Present.prototype.onDeviceDestroy = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceDestroy(message);
}
};
_Present.prototype.onLinkDestroy = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onLinkDestroy(message);
}
};
_Present.prototype.onDeviceLabelEdit = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceLabelEdit(message);
}
};
_Present.prototype.onGroupLabelEdit = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onGroupLabelEdit(message);
}
};
_Present.prototype.onLinkLabelEdit = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onLinkLabelEdit(message);
}
};
_Present.prototype.onInterfaceLabelEdit = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onInterfaceLabelEdit(message);
}
};
_Present.prototype.onDeviceSelected = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceSelected(message);
}
};
_Present.prototype.onDeviceUnSelected = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onDeviceUnSelected(message);
}
};
_Present.prototype.onUndo = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.time_pointer = Math.max(0, controller.scope.time_pointer - 1);
controller.scope.undo(message.original_message);
controller.changeState(Past);
}
};
_Present.prototype.onUndo.transitions = ['Past'];
_Present.prototype.onSnapshot = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onSnapshot(message);
}
};
_Present.prototype.onToolboxItem = function(controller, msg_type, message) {
if (message.sender !== controller.scope.client_id) {
controller.scope.onToolboxItem(message);
}
};
_Present.prototype.onid = function(controller, msg_type, message) {
controller.scope.onClientId(message);
};
_Present.prototype.onTopology = function(controller, msg_type, message) {
controller.scope.onTopology(message);
};
_Present.prototype.onHistory = function(controller, msg_type, message) {
controller.scope.onHistory(message);
};
_Present.prototype.onCoverageRequest = function(controller) {
controller.scope.send_coverage();
};
_Present.prototype.onStopRecording = function(controller) {
controller.scope.recording = false;
};
_Present.prototype.onStartReplay = function(controller) {
controller.scope.replay = true;
};
_Present.prototype.onStopReplay = function(controller) {
controller.scope.replay = false;
};
_Present.prototype.onViewPort = function(controller, msg_type, message) {
if (message.sender === controller.scope.client_id) {
return;
}
controller.scope.current_scale = message.scale;
controller.scope.panX = message.panX;
controller.scope.panY = message.panY;
controller.scope.updateScaledXY();
controller.scope.updatePanAndScale();
};
_Present.prototype.onTouchEvent = function(controller, msg_type, message) {
if (!controller.scope.replay) {
return;
}
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
if (message.type === "touchstart") {
controller.scope.onTouchStart(message);
}
if (message.type === "touchend") {
controller.scope.onTouchEnd(message);
}
if (message.type === "touchmove") {
controller.scope.onTouchMove(message);
}
};
_Present.prototype.onMouseEvent = function(controller, msg_type, message) {
if (!controller.scope.replay) {
return;
}
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
//console.log(message);
if (message.type === "mousemove") {
controller.scope.onMouseMove(message);
}
if (message.type === "mouseup") {
controller.scope.onMouseUp(message);
}
if (message.type === "mousedown") {
controller.scope.onMouseDown(message);
}
if (message.type === "mouseover") {
controller.scope.onMouseOver(message);
}
};
_Present.prototype.onMouseWheelEvent = function(controller, msg_type, message) {
if (!controller.scope.replay) {
return;
}
console.log(message);
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
message.stopPropagation = util.noop;
controller.scope.onMouseWheel(message, message.delta, message.deltaX, message.deltaY);
};
_Present.prototype.onKeyEvent = function(controller, msg_type, message) {
if (!controller.scope.replay) {
return;
}
if (message.sender === controller.scope.client_id) {
return;
}
message.preventDefault = util.noop;
//console.log(message);
if (message.type === "keydown") {
controller.scope.onKeyDown(message);
}
};
_Present.prototype.onMouseWheel = function (controller, msg_type, message) {
var $event = message[0];
var delta = message[1];
if ($event.originalEvent.metaKey) {
//console.log(delta);
if (delta < 0) {
this.undo(controller);
}
} else {
controller.delegate_channel.send(msg_type, message);
}
};
_Present.prototype.onMouseWheel.transitions = ['Past'];
_Present.prototype.onKeyDown = function(controller, msg_type, $event) {
//console.log($event);
if ($event.key === 'z' && $event.metaKey && ! $event.shiftKey) {
this.undo(controller);
return;
} else if ($event.key === 'z' && $event.ctrlKey && ! $event.shiftKey) {
this.undo(controller);
return;
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Present.prototype.onKeyDown.transitions = ['Past'];
_Present.prototype.undo = function(controller) {
controller.scope.time_pointer = controller.scope.history.length - 1;
if (controller.scope.time_pointer >= 0) {
var change = controller.scope.history[controller.scope.time_pointer];
var type_data = JSON.parse(change);
controller.scope.send_control_message(new messages.Undo(controller.scope.client_id,
type_data));
controller.scope.undo(type_data);
controller.changeState(Past);
}
};

View File

@@ -0,0 +1,332 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
function _State () {
}
inherits(_State, fsm._State);
function _Dropping () {
this.name = 'Dropping';
}
inherits(_Dropping, _State);
var Dropping = new _Dropping();
exports.Dropping = Dropping;
function _Selecting () {
this.name = 'Selecting';
}
inherits(_Selecting, _State);
var Selecting = new _Selecting();
exports.Selecting = Selecting;
function _Selected () {
this.name = 'Selected';
}
inherits(_Selected, _State);
var Selected = new _Selected();
exports.Selected = Selected;
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Scrolling () {
this.name = 'Scrolling';
}
inherits(_Scrolling, _State);
var Scrolling = new _Scrolling();
exports.Scrolling = Scrolling;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Move () {
this.name = 'Move';
}
inherits(_Move, _State);
var Move = new _Move();
exports.Move = Move;
function _OffScreen () {
this.name = 'OffScreen';
}
inherits(_OffScreen, _State);
var OffScreen = new _OffScreen();
exports.OffScreen = OffScreen;
function _OffScreen2 () {
this.name = 'OffScreen2';
}
inherits(_OffScreen2, _State);
var OffScreen2 = new _OffScreen2();
exports.OffScreen2 = OffScreen2;
function _Disabled () {
this.name = 'Disabled';
}
inherits(_Disabled, _State);
var Disabled = new _Disabled();
exports.Disabled = Disabled;
_Dropping.prototype.start = function (controller) {
var i = 0;
var toolbox = controller.toolbox;
console.log(["Dropping", toolbox.selected_item]);
for(i = 0; i < toolbox.items.length; i++) {
toolbox.items[i].selected = false;
}
controller.dropped_action(toolbox.selected_item);
if (controller.remove_on_drop) {
var dindex = toolbox.items.indexOf(toolbox.selected_item);
if (dindex !== -1) {
toolbox.items.splice(dindex, 1);
}
}
toolbox.selected_item = null;
controller.changeState(Ready);
};
_Dropping.prototype.start.transitions = ['Ready'];
_Selected.prototype.onMouseMove = function (controller) {
controller.changeState(Move);
};
_Selected.prototype.onMouseMove.transitions = ['Move'];
_Selected.prototype.onMouseUp = function (controller) {
var i = 0;
var toolbox = controller.toolbox;
for(i = 0; i < toolbox.items.length; i++) {
toolbox.items[i].selected = false;
}
toolbox.selected_item = null;
controller.changeState(Ready);
};
_Selected.prototype.onMouseUp.transitions = ['Ready'];
_Selecting.prototype.onMouseDown = function (controller) {
var i = 0;
var toolbox = controller.toolbox;
var scope = controller.scope;
var selected_item = Math.floor((controller.scope.mouseY - toolbox.y - toolbox.scroll_offset) / toolbox.spacing);
for(i = 0; i < toolbox.items.length; i++) {
toolbox.items[i].selected = false;
}
if (selected_item >= 0 && selected_item < toolbox.items.length) {
toolbox.items[selected_item].selected = true;
toolbox.selected_item = toolbox.items[selected_item];
scope.pressedX = scope.mouseX;
scope.pressedY = scope.mouseY;
scope.pressedScaledX = scope.scaledX;
scope.pressedScaledY = scope.scaledY;
toolbox.selected_item.x = toolbox.x + toolbox.width/2;
toolbox.selected_item.y = selected_item * toolbox.spacing + toolbox.y + toolbox.scroll_offset + toolbox.spacing/2;
controller.scope.clear_selections();
controller.scope.first_channel.send("UnselectAll", {});
controller.changeState(Selected);
} else {
toolbox.selected_item = null;
controller.changeState(Ready);
}
};
_Selecting.prototype.onMouseDown.transitions = ['Selected', 'Ready'];
_Ready.prototype.onEnable = function () {
};
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
if(controller.toolbox.enabled &&
controller.scope.mouseX > controller.toolbox.x &&
controller.scope.mouseY > controller.toolbox.y &&
controller.scope.mouseX < controller.toolbox.x + controller.toolbox.width &&
controller.scope.mouseY < controller.toolbox.y + controller.toolbox.height) {
controller.changeState(Selecting);
controller.handle_message(msg_type, $event);
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selecting'];
_Ready.prototype.onMouseWheel = function (controller, msg_type, $event) {
if(controller.toolbox.enabled &&
controller.scope.mouseX > controller.toolbox.x &&
controller.scope.mouseY > controller.toolbox.y &&
controller.scope.mouseX < controller.toolbox.x + controller.toolbox.width &&
controller.scope.mouseY < controller.toolbox.y + controller.toolbox.height) {
controller.changeState(Scrolling);
controller.handle_message(msg_type, $event);
} else {
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
_Ready.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(OffScreen);
controller.delegate_channel.send(msg_type, message);
};
_Ready.prototype.onToggleToolbox.transitions = ['OffScreen'];
_Ready.prototype.onDisable = function (controller) {
controller.changeState(Disabled);
};
_Ready.prototype.onDisable.transitions = ['Disabled'];
_Scrolling.prototype.onMouseWheel = function (controller, msg_type, $event) {
var delta = $event[1];
controller.toolbox.scroll_offset += -1 * delta;
controller.toolbox.scroll_offset = Math.min(controller.toolbox.scroll_offset, 0);
controller.toolbox.scroll_offset = Math.max(controller.toolbox.scroll_offset, -1 * controller.toolbox.spacing * controller.toolbox.items.length + controller.toolbox.height);
controller.changeState(Ready);
};
_Scrolling.prototype.onMouseWheel.transitions = ['Ready'];
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Move.prototype.onMouseUp = function (controller) {
controller.changeState(Dropping);
};
_Move.prototype.onMouseUp.transitions = ['Dropping'];
_Move.prototype.onMouseMove = function (controller) {
var diffX = controller.scope.mouseX - controller.scope.pressedX;
var diffY = controller.scope.mouseY - controller.scope.pressedY;
controller.toolbox.selected_item.x += diffX;
controller.toolbox.selected_item.y += diffY;
controller.scope.pressedX = controller.scope.mouseX;
controller.scope.pressedY = controller.scope.mouseY;
};
_OffScreen.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(Ready);
controller.delegate_channel.send(msg_type, message);
};
_OffScreen.prototype.onToggleToolbox.transitions = ['Ready'];
_OffScreen.prototype.start = function (controller) {
controller.toolbox.enabled = false;
};
_OffScreen.prototype.end = function (controller) {
controller.toolbox.enabled = true;
};
_OffScreen.prototype.onDisable = function (controller) {
controller.changeState(OffScreen2);
};
_OffScreen.prototype.onDisable.transitions = ['OffScreen2'];
_OffScreen2.prototype.onEnable = function (controller) {
controller.changeState(OffScreen);
};
_OffScreen2.prototype.onEnable.transitions = ['OffScreen'];
_OffScreen2.prototype.onDisable = function () {
};
_OffScreen2.prototype.start = function (controller) {
controller.toolbox.enabled = false;
};
_OffScreen2.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(Disabled);
controller.delegate_channel.send(msg_type, message);
};
_OffScreen2.prototype.onToggleToolbox.transitions = ['Disabled'];
_Disabled.prototype.onDisable = function () {
};
_Disabled.prototype.onEnable = function (controller) {
controller.changeState(Ready);
};
_Disabled.prototype.onEnable.transitions = ['Ready'];
_Disabled.prototype.start = function (controller) {
if(controller.toolbox !== undefined){
controller.toolbox.enabled = false;
}
};
_Disabled.prototype.end = function (controller) {
controller.toolbox.enabled = true;
};
_Disabled.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(OffScreen2);
controller.delegate_channel.send(msg_type, message);
};
_Disabled.prototype.onToggleToolbox.transitions = ['OffScreen2'];

View File

@@ -0,0 +1,8 @@
/* Copyright (c) 2017 Red Hat, Inc. */
const templateUrl = require('~network-ui/touch.partial.svg');
function touch () {
return { restrict: 'A', templateUrl};
}
exports.touch = touch;

View File

@@ -0,0 +1,4 @@
<!-- Copyright (c) 2017 Red Hat, Inc. -->
<g ng-attr-transform="translate({{touch.screenX}},{{touch.screenY}})">
<circle ng-attr-class="{{touch.hidden && 'NetworkUI--hidden' || 'NetworkUI__touch'}}" cx=0 cy=0 r=40></circle>
</g>

View File

@@ -0,0 +1,34 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var angular = require('angular');
var tower = angular.module('tower', ['tablesUI', 'networkUI', 'ui.router']);
tower.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/index');
$stateProvider
.state({
name: 'index',
url: '/index',
template: '<ul><li><a href="#!/topology">Topology</a></li><li><a href="#!/tables">Tables</a></li></ul>'
});
$stateProvider
.state({
name: 'topology',
url: '/topology',
template: "<awx-network-ui></awx-network-ui>"
});
$stateProvider
.state({
name: 'tables',
url: '/tables',
template: "<awx-tables-ui></awx-tables-ui>"
});
});
exports.tower = tower;

View File

@@ -0,0 +1,222 @@
/* Copyright (c) 2017 Red Hat, Inc. */
Array.prototype.extend = function (other_array) {
/* you should include a test to check whether other_array really is an array */
var i = 0;
for (i = 0; i < other_array.length; i++) {
this.push(other_array[i]);
}
};
var math = require('mathjs');
function noop () {
}
exports.noop = noop;
function natural_numbers (start) {
var counter = start;
return function () {return counter += 1;};
}
exports.natural_numbers = natural_numbers;
function distance (x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
exports.distance = distance;
// polarToCartesian
// @wdebeaum, @opsb
// from http://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
// describeArc
// @wdebeaum, @opsb
// from http://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle
function describeArc(x, y, radius, startAngle, endAngle){
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(" ");
return d;
}
exports.describeArc = describeArc;
function pDistanceLine(x, y, x1, y1, x2, y2) {
//Code from http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
//Joshua
// Find the dot product of two vectors <A, B>, <C, D>
// Divide by the length squared of <C, D>
// Use scalar project to find param
//
var A = x - x1;
var B = y - y1;
var C = x2 - x1;
var D = y2 - y1;
var dot = A * C + B * D;
var len_sq = C * C + D * D;
var param = -1;
if (len_sq !== 0) {
//in case of 0 length line
param = dot / len_sq;
}
var xx, yy;
//Find a point xx, yy where the projection and the <C, D> vector intersect.
//If less than 0 use x1, y1 as the closest point.
//If less than 1 use x2, y2 as the closest point.
//If between 0 and 1 use the projection intersection xx, yy
if (param < 0) {
xx = x1;
yy = y1;
}
else if (param > 1) {
xx = x2;
yy = y2;
}
else {
xx = x1 + param * C;
yy = y1 + param * D;
}
return {x1:x, y1:y, x2: xx, y2: yy};
}
exports.pDistanceLine = pDistanceLine;
function pDistance(x, y, x1, y1, x2, y2) {
//Code from http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
//Joshua
// Find the dot product of two vectors <A, B>, <C, D>
// Divide by the length squared of <C, D>
// Use scalar project to find param
//
var A = x - x1;
var B = y - y1;
var C = x2 - x1;
var D = y2 - y1;
var dot = A * C + B * D;
var len_sq = C * C + D * D;
var param = -1;
if (len_sq !== 0) {
//in case of 0 length line
param = dot / len_sq;
}
var xx, yy;
//Find a point xx, yy where the projection and the <C, D> vector intersect.
//If less than 0 use x1, y1 as the closest point.
//If less than 1 use x2, y2 as the closest point.
//If between 0 and 1 use the projection intersection xx, yy
if (param < 0) {
xx = x1;
yy = y1;
}
else if (param > 1) {
xx = x2;
yy = y2;
}
else {
xx = x1 + param * C;
yy = y1 + param * D;
}
var dx = x - xx;
var dy = y - yy;
return Math.sqrt(dx * dx + dy * dy);
}
exports.pDistance = pDistance;
function cross_z_pos(x, y, x1, y1, x2, y2) {
var A = x - x1;
var B = y - y1;
var C = x2 - x1;
var D = y2 - y1;
return math.cross([A, B, 0], [C, D, 0])[2] > 0;
}
exports.cross_z_pos = cross_z_pos;
function intersection (x1, y1, x2, y2, x3, y3, x4, y4) {
//Find the point where lines through x1, y1, x2, y2 and x3, y3, x4, y4 intersect.
//
var Aslope;
var Aintercept;
var Bslope;
var Bintercept;
if ((x2 - x1) !== 0 && (x4 - x3) !== 0) {
Aslope = (y2 - y1)/(x2 - x1);
Aintercept = y1 - Aslope * x1;
Bslope = (y4 - y3)/(x4 - x3);
Bintercept = y3 - Bslope * x3;
var xi = (Bintercept - Aintercept) / (Aslope - Bslope);
var yi = Bslope * xi + Bintercept;
return {x: xi, y: yi};
}
if ((x2 - x1) === 0 && (x4 - x3) === 0) {
return {x: null, y: null};
}
if ((x2 - x1) === 0) {
Bslope = (y4 - y3)/(x4 - x3);
Bintercept = y3 - Bslope * x3;
return {x: x1, y: Bslope * x1 + Bintercept};
}
if ((x4 - x3) === 0) {
Aslope = (y2 - y1)/(x2 - x1);
Aintercept = y1 - Aslope * x1;
return {x: x3, y: Aslope * x3 + Aintercept};
}
}
exports.intersection = intersection;
function pCase(x, y, x1, y1, x2, y2) {
//Code from http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
//Joshua
// Find the dot product of two vectors <A, B>, <C, D>
// Divide by the length squared of <C, D>
// Use scalar project to find param
//
var A = x - x1;
var B = y - y1;
var C = x2 - x1;
var D = y2 - y1;
var dot = A * C + B * D;
var len_sq = C * C + D * D;
var param = -1;
if (len_sq !== 0) {
//in case of 0 length line
param = dot / len_sq;
}
return param;
}
exports.pCase = pCase;

View File

@@ -0,0 +1,177 @@
/* Copyright (c) 2017 Red Hat, Inc. */
var inherits = require('inherits');
var fsm = require('./fsm.js');
function _State () {
}
inherits(_State, fsm._State);
function _Ready () {
this.name = 'Ready';
}
inherits(_Ready, _State);
var Ready = new _Ready();
exports.Ready = Ready;
function _Start () {
this.name = 'Start';
}
inherits(_Start, _State);
var Start = new _Start();
exports.Start = Start;
function _Scale () {
this.name = 'Scale';
}
inherits(_Scale, _State);
var Scale = new _Scale();
exports.Scale = Scale;
function _Pressed () {
this.name = 'Pressed';
}
inherits(_Pressed, _State);
var Pressed = new _Pressed();
exports.Pressed = Pressed;
function _Pan () {
this.name = 'Pan';
}
inherits(_Pan, _State);
var Pan = new _Pan();
exports.Pan = Pan;
_Ready.prototype.onMouseDown = function (controller) {
controller.scope.pressedX = controller.scope.mouseX;
controller.scope.pressedY = controller.scope.mouseY;
controller.scope.lastPanX = controller.scope.panX;
controller.scope.lastPanY = controller.scope.panY;
controller.changeState(Pressed);
};
_Ready.prototype.onMouseDown.transitions = ['Pressed'];
_Ready.prototype.onTouchStart = function (controller, msg_type, event) {
if (event.touches.length === 2) {
controller.scope.lastPanX = controller.scope.panX;
controller.scope.lastPanY = controller.scope.panY;
controller.scope.lastScale = controller.scope.current_scale;
var x1 = event.touches[0].screenX;
var y1 = event.touches[0].screenY;
var x2 = event.touches[1].screenX;
var y2 = event.touches[1].screenY;
var d = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
var xb = (x2 + x1) / 2;
var yb = (y2 + y1) / 2;
controller.scope.touch_data = {x1: x1,
y1: y1,
x2: x2,
y2: y2,
d: d,
xb: xb,
yb: yb};
controller.changeState(Pressed);
}
};
_Ready.prototype.onTouchStart.transitions = ['Pressed'];
_Ready.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Scale);
controller.handle_message(msg_type, $event);
};
_Ready.prototype.onMouseWheel.transitions = ['Scale'];
_Start.prototype.start = function (controller) {
controller.changeState(Ready);
};
_Start.prototype.start.transitions = ['Ready'];
_Scale.prototype.onMouseWheel = function (controller, msg_type, message) {
var delta = message[1];
var new_scale = Math.max(0.001, Math.min(100, (controller.scope.current_scale + delta / (100 / controller.scope.current_scale))));
var new_panX = controller.scope.mouseX - new_scale * ((controller.scope.mouseX - controller.scope.panX) / controller.scope.current_scale);
var new_panY = controller.scope.mouseY - new_scale * ((controller.scope.mouseY - controller.scope.panY) / controller.scope.current_scale);
controller.scope.updateScaledXY();
controller.scope.current_scale = new_scale;
controller.scope.panX = new_panX;
controller.scope.panY = new_panY;
controller.scope.updatePanAndScale();
controller.changeState(Ready);
};
_Scale.prototype.onMouseWheel.transitions = ['Ready'];
_Pressed.prototype.onMouseUp = function (controller) {
controller.changeState(Ready);
};
_Pressed.prototype.onMouseUp.transitions = ['Ready'];
_Pressed.prototype.onTouchEnd = _Pressed.prototype.onMouseUp;
_Pressed.prototype.onMouseMove = function (controller, msg_type, $event) {
controller.changeState(Pan);
controller.handle_message(msg_type, $event);
};
_Pressed.prototype.onMouseMove.transitions = ['Pan'];
_Pressed.prototype.onTouchMove = _Pressed.prototype.onMouseMove;
_Pan.prototype.onMouseMove = function (controller) {
controller.scope.panX = (controller.scope.mouseX - controller.scope.pressedX) + controller.scope.lastPanX;
controller.scope.panY = (controller.scope.mouseY - controller.scope.pressedY) + controller.scope.lastPanY;
controller.scope.updateScaledXY();
controller.scope.updatePanAndScale();
};
_Pan.prototype.onTouchMove = function (controller, msg_type, event) {
if (event.touches.length === 2) {
var x1 = event.touches[0].screenX;
var y1 = event.touches[0].screenY;
var x2 = event.touches[1].screenX;
var y2 = event.touches[1].screenY;
var d = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
var xb = (x2 + x1) / 2;
var yb = (y2 + y1) / 2;
var delta = d - controller.scope.touch_data.d;
controller.scope.panX = (xb - controller.scope.touch_data.xb) + controller.scope.lastPanX;
controller.scope.panY = (yb - controller.scope.touch_data.yb) + controller.scope.lastPanY;
controller.scope.updateScaledXY();
var new_scale = Math.max(0.1, Math.min(10, (controller.scope.lastScale + delta / 100)));
var new_panX = xb - new_scale * ((xb - controller.scope.panX) / controller.scope.lastScale);
var new_panY = yb - new_scale * ((yb - controller.scope.panY) / controller.scope.lastScale);
controller.scope.current_scale = new_scale;
controller.scope.panX = new_panX;
controller.scope.panY = new_panY;
controller.scope.updatePanAndScale();
}
};
_Pan.prototype.onMouseUp = function (controller) {
controller.changeState(Ready);
};
_Pan.prototype.onMouseUp.transitions = ['Ready'];
_Pan.prototype.onTouchEnd = _Pan.prototype.onMouseUp;