remove the network UI
@@ -19,7 +19,6 @@
|
||||
</head>
|
||||
|
||||
<body data-user-agent="{{userAgent}}">
|
||||
<div ui-view="networking" ng-class="{'NetworkingUIView' : vm.networkUIisOpen}"></div>
|
||||
<at-layout>
|
||||
<bread-crumb></bread-crumb>
|
||||
<toast></toast>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="at-Layout-side"
|
||||
ng-class="{'at-Layout-side--expanded': vm.isExpanded && layoutVm.isLoggedIn}" ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing && layoutVm.currentState !== 'inventories.edit.networking'">
|
||||
ng-class="{'at-Layout-side--expanded': vm.isExpanded && layoutVm.isLoggedIn}" ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
|
||||
<div class="at-Layout-sideNavItem at-Layout-sideNavToggle" ng-click="vm.toggleExpansion()"
|
||||
ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing && layoutVm.currentState !== 'inventories.edit.networking'">
|
||||
ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
|
||||
<i class="fa fa-bars"></i>
|
||||
</div>
|
||||
<ng-transclude></ng-transclude>
|
||||
|
||||
@@ -166,9 +166,3 @@
|
||||
* the transition.
|
||||
*/
|
||||
@import '_resets';
|
||||
|
||||
/**
|
||||
* Network Visualization Style
|
||||
*
|
||||
*/
|
||||
@import '../../src/network-ui/style.less';
|
||||
|
||||
@@ -42,8 +42,6 @@ import atLibComponents from '~components';
|
||||
import atLibModels from '~models';
|
||||
import atLibServices from '~services';
|
||||
|
||||
import networkUI from '~network-ui/network.ui.app';
|
||||
|
||||
start.bootstrap(() => {
|
||||
angular.bootstrap(document.body, ['awApp']);
|
||||
});
|
||||
@@ -89,7 +87,6 @@ angular
|
||||
users.name,
|
||||
projects.name,
|
||||
scheduler.name,
|
||||
networkUI.name,
|
||||
|
||||
'Utilities',
|
||||
'templates',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*************************************************/
|
||||
|
||||
|
||||
export default ['i18n', 'awxNetStrings' , function(i18n, awxNetStrings) {
|
||||
export default ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'inventories',
|
||||
@@ -117,13 +117,6 @@ export default ['i18n', 'awxNetStrings' , function(i18n, awxNetStrings) {
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!inventory.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
network: {
|
||||
label: awxNetStrings.get('feature.ACTION_BUTTON'),
|
||||
ngClick: 'goToGraph(inventory)',
|
||||
awToolTip: awxNetStrings.get('feature.ACTION_BUTTON'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!inventory.pending_deletion'
|
||||
},
|
||||
"delete": {
|
||||
label: i18n._('Delete'),
|
||||
ngClick: "deleteInventory(inventory.id, inventory.name)",
|
||||
|
||||
@@ -107,15 +107,6 @@ function InventoriesList($scope,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.goToGraph = function(inventory){
|
||||
if(inventory.kind && inventory.kind === 'smart') {
|
||||
$state.go('inventories.editSmartInventory.networking', {smartinventory_id: inventory.id, inventory_name: inventory.name});
|
||||
}
|
||||
else {
|
||||
$state.go('inventories.edit.networking', {inventory_id: inventory.id, inventory_name: inventory.name});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.editInventory = function (inventory, reload) {
|
||||
const goOptions = reload ? { reload: true } : null;
|
||||
if(inventory.kind && inventory.kind === 'smart') {
|
||||
|
||||
@@ -46,7 +46,6 @@ import groupNestedGroupsAssociateRoute from './related/groups/related/nested-gro
|
||||
import nestedHostsAssociateRoute from './related/groups/related/nested-hosts/group-nested-hosts-associate.route';
|
||||
import nestedHostsAddRoute from './related/groups/related/nested-hosts/group-nested-hosts-add.route';
|
||||
import hostCompletedJobsRoute from '~features/jobs/routes/hostCompletedJobs.route.js';
|
||||
import networkUIRoute from '../../network-ui/network.ui.route.js';
|
||||
|
||||
export default
|
||||
angular.module('inventory', [
|
||||
@@ -295,9 +294,6 @@ angular.module('inventory', [
|
||||
let relatedHostCompletedJobs = _.cloneDeep(hostCompletedJobsRoute);
|
||||
relatedHostCompletedJobs.name = 'inventories.edit.hosts.edit.completed_jobs';
|
||||
|
||||
let smartInvNetworkUI = _.cloneDeep(networkUIRoute);
|
||||
smartInvNetworkUI.name = 'inventories.editSmartInventory.networking';
|
||||
|
||||
return Promise.all([
|
||||
standardInventoryAdd,
|
||||
standardInventoryEdit,
|
||||
@@ -346,9 +342,7 @@ angular.module('inventory', [
|
||||
stateExtender.buildDefinition(nestedHostsAssociateRoute),
|
||||
stateExtender.buildDefinition(nestedGroupsAdd),
|
||||
stateExtender.buildDefinition(nestedHostsAddRoute),
|
||||
stateExtender.buildDefinition(relatedHostCompletedJobs),
|
||||
stateExtender.buildDefinition(networkUIRoute),
|
||||
stateExtender.buildDefinition(smartInvNetworkUI)
|
||||
stateExtender.buildDefinition(relatedHostCompletedJobs)
|
||||
])
|
||||
};
|
||||
});
|
||||
|
||||
@@ -95,10 +95,6 @@ function SmartInventoryEdit($scope, $location,
|
||||
});
|
||||
};
|
||||
|
||||
$scope.goToGraph = function(){
|
||||
$state.go('inventories.editSmartInventory.networking', {smartinventory_id: $scope.inventory_obj.id, inventory_name: $scope.inventory_obj.name});
|
||||
};
|
||||
|
||||
$scope.formCancel = function() {
|
||||
$state.go('inventories');
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['i18n', 'awxNetStrings', function(i18n, awxNetStrings) {
|
||||
export default ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: i18n._('NEW SMART INVENTORY'),
|
||||
@@ -156,14 +156,6 @@ export default ['i18n', 'awxNetStrings', function(i18n, awxNetStrings) {
|
||||
skipGenerator: true,
|
||||
ngClick: "$state.go('inventories.editSmartInventory.completed_jobs')"
|
||||
}
|
||||
},
|
||||
relatedButtons: {
|
||||
network: {
|
||||
ngClick: 'goToGraph()',
|
||||
label: awxNetStrings.get('feature.ACTION_BUTTON'),
|
||||
class: 'Form-primaryButton',
|
||||
ngShow: "$state.is('inventories.editSmartInventory')"
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -99,10 +99,6 @@ function InventoriesEdit($scope, $location,
|
||||
});
|
||||
};
|
||||
|
||||
$scope.goToGraph = function(){
|
||||
$state.go('inventories.edit.networking', {inventory_id: $scope.inventory_obj.id, inventory_name: $scope.inventory_obj.name});
|
||||
};
|
||||
|
||||
$scope.formCancel = function() {
|
||||
$state.go('inventories');
|
||||
};
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
* @description This form is for adding/editing an inventory
|
||||
*/
|
||||
|
||||
export default ['i18n', 'awxNetStrings',
|
||||
function(i18n, awxNetStrings) {
|
||||
export default ['i18n',
|
||||
function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: i18n._('NEW INVENTORY'),
|
||||
@@ -174,12 +174,6 @@ function(i18n, awxNetStrings) {
|
||||
}
|
||||
},
|
||||
relatedButtons: {
|
||||
network: {
|
||||
ngClick: 'goToGraph()',
|
||||
ngShow: "$state.is('inventories.edit')",
|
||||
label: awxNetStrings.get('feature.ACTION_BUTTON'),
|
||||
class: 'Form-primaryButton'
|
||||
},
|
||||
remediate_inventory: {
|
||||
ngClick: 'remediateInventory(id, insights_credential)',
|
||||
ngShow: "is_insights && mode !== 'add' && canRemediate && ($state.is('inventories.edit') || $state.is('inventories.edit.hosts'))",
|
||||
|
||||
1
awx/ui/client/src/network-ui/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/extracted
|
||||
@@ -1,951 +0,0 @@
|
||||
|
||||
|
||||
Getting Started With Network UI Development
|
||||
===========================================
|
||||
|
||||
|
||||
**Introduction**
|
||||
|
||||
The Networking UI component of AWX works differently from the rest of the AWX
|
||||
web UI to support high-scale interactive graphical design of networking
|
||||
topologies.
|
||||
|
||||
The Networking UI is a virtual graphical canvas where graphical elements are
|
||||
drawn upon. This canvas supports panning (scrolling horizontally and
|
||||
vertically) and scaling (zooming in and out), dynamic changing of modes, and
|
||||
other features that would be very difficult or impossible to implement with
|
||||
standard HTML events and rendering.
|
||||
|
||||
This interface is more like computer graphics than it is building a styled text
|
||||
document with interactive components. A good grasp of Cartesian coordinates,
|
||||
trigonometry, and analytic geometry are useful when working with this code.
|
||||
|
||||
* See: <https://en.wikipedia.org/wiki/Analytic_geometry>
|
||||
|
||||
**Design choices**
|
||||
|
||||
Certain design choices were made to make the UI performant and scale to a large
|
||||
number of nodes in a diagram. These include the use of simple ES5 functions for
|
||||
better performance over more advanced functions. For instance C-style for-loops
|
||||
were many times faster than implementations of `forEach` or iterators which make
|
||||
function calls during each iteration. This basic ES5 style should be followed
|
||||
throughout the implementation of the Network UI.
|
||||
|
||||
**AngularJS**
|
||||
|
||||
The Networking UI component uses AngularJS 1.6.x for part of the rendering pipeline
|
||||
but it is not a normal AngularJS web application. AngularJS makes use of
|
||||
data-binding and watchers which I found do not scale to the number of elements
|
||||
we are trying to support in the Networking UI. The Networking UI only uses
|
||||
AngularJS for SVG rendering (using AngularJS templates) which does scale
|
||||
sufficiently.
|
||||
|
||||
|
||||
**AngularJS Controllers**
|
||||
|
||||
Instead of creating many AngularJS controllers and directives the networking UI
|
||||
uses one big controller to hold the state of the entire UI. Normally this is
|
||||
an anti-pattern in AngularJS. Here is was necessary to scale to a large number
|
||||
of on-screen elements.
|
||||
|
||||
**AngularJS Directives**
|
||||
|
||||
* See: <https://docs.angularjs.org/guide/directive>
|
||||
|
||||
AngularJS directives are used in the networking UI application using the element
|
||||
matching style and the `templateUrl` option to include a template. A majority of
|
||||
the directives are defined in `network.ui.app.js`.
|
||||
|
||||
* See: [network.ui.app.js](network.ui.app.js)
|
||||
```
|
||||
.directive('awxNetDeviceDetail', deviceDetail.deviceDetail)
|
||||
```
|
||||
|
||||
* See: [device.detail.directive.js](device.detail.directive.js)
|
||||
```
|
||||
function deviceDetail () {
|
||||
return { restrict: 'A', templateUrl: '/static/network_ui/widgets/device_detail.html' };
|
||||
}
|
||||
```
|
||||
|
||||
**AngularJS Templates**
|
||||
|
||||
* See: <https://docs.angularjs.org/guide/templates>
|
||||
|
||||
Normal AngularJS templates are used with the networking UI controller.
|
||||
The templates can be found in `/widgets`. Child
|
||||
scopes are created for sub-templates using the `ng-repeat` directive.
|
||||
|
||||
In this example the `awx-net-link` directive expects a Link model to be
|
||||
passed to it. The Link model is defined in the `models.js` file.
|
||||
|
||||
* See: [link.directive.js](link.directive.js)
|
||||
* See: [link.partial.svg](link.partial.svg)
|
||||
|
||||
* See: [network_ui.html](network_ui.partial.svg)
|
||||
```
|
||||
<g ng-repeat="link in links">
|
||||
<g awx-net-link></g>
|
||||
</g>
|
||||
```
|
||||
|
||||
* See: [models.js](models.js)
|
||||
```
|
||||
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 = "";
|
||||
}
|
||||
```
|
||||
|
||||
The following example sets the toolbox.selected_item value to the variable
|
||||
item which the directives used in the child scope expect to be set.
|
||||
|
||||
* See: [inventory_toolbox.html](inventory_toolbox.partial.svg)
|
||||
```
|
||||
<g ng-repeat="item in [toolbox.selected_item]">
|
||||
```
|
||||
|
||||
|
||||
**DOM (Document Object Model)**
|
||||
|
||||
No state is stored in or attached to the DOM. All state is stored in
|
||||
javascript objects attached to the network ui controller.
|
||||
|
||||
Direct DOM manipulation should not be used in the network UI unless absolutely
|
||||
necessary. JQuery should not be used. The DOM is generated through the use of
|
||||
AngularJS templates.
|
||||
|
||||
**SVG (Scalable Vector Graphics)**
|
||||
|
||||
* See: <https://developer.mozilla.org/en-US/docs/Web/SVG>
|
||||
|
||||
The network UI is built as one large SVG element (the SVG canvas) with other
|
||||
graphical elements (lines, circles, rectangles, paths, and text) absolutely
|
||||
positioned within the outer most SVG element. The browser is not involved with
|
||||
layout of the elements within the SVG. Each "widget" in the network UI needs
|
||||
to track or calculate its own position on the SVG canvas. The z-level of the
|
||||
elements are determined by the draw order on the canvas which is defined
|
||||
in `network_ui.partial.svg`. Elements drawn first will be hidden behind
|
||||
elements drawn later.
|
||||
|
||||
|
||||
|
||||
**Rendering Pipeline**
|
||||
|
||||
Event -> Javscript objects -> AngularJS templates -> SVG
|
||||
|
||||
AngularJS is used to render the SVG inside the SVG canvas using directives
|
||||
and templates. AngularJS is also used to schedule when the SVG canvas will
|
||||
be updated. When an input event comes from the user, or an event is received
|
||||
over the websocket, javascript objects will be updated according the the network
|
||||
UI code. Then AngularJS will be notified that it needs to update the templates
|
||||
either automatically for some events or explicitly using `$scope.$apply();` if
|
||||
not handled automatically by AngularJS. The templates will render to SVG and be
|
||||
included in the DOM for the rest of the AWX UI.
|
||||
|
||||
Because the networking UI does not use watchers nor data-binding features of
|
||||
AngularJS events flow in one way from event to javascript to angular to SVG.
|
||||
Events do not flow backwards through this pipeline.
|
||||
|
||||
Clicking on an SVG element will not send the event to that SVG element directly
|
||||
from the browser. It must be routed through the network UI code first.
|
||||
|
||||
|
||||
**SVG Primer**
|
||||
|
||||
SVG uses tags to define graphical elements just like HTML uses tags to define
|
||||
text documents. Commonly use tags include g, circle, rect, path, and text.
|
||||
SVG elements are absolutely positioned within an SVG canvas. The group tag, g,
|
||||
is similar to the div tag in HTML. Text in SVG must be contained in the text
|
||||
tag and cannot be outside tags as in HTML.
|
||||
|
||||
* See: <https://developer.mozilla.org/en-US/docs/Web/SVG/Element>
|
||||
|
||||
Each tag that describes a visual element requires X and Y coordinates as input
|
||||
to position that element. These coordinates are relative to position of the SVG
|
||||
canvas. The network UI uses the entire page height and width for the SVG canvas
|
||||
so that the position on the SVG on the canvas is the same as the position on
|
||||
the page.
|
||||
|
||||
|
||||
SVG supports graphical transformations on several tags to allow relative
|
||||
positioning of sub-elements which makes calculating the X and Y positions
|
||||
easier. The network UI uses transformations often for this purpose.
|
||||
Transformations that are often used here are the translate, scale, and rotate
|
||||
transforms. Translate moves the origin of the coordinate system to a new point
|
||||
for the sub-elements. Scale multiplies the size of the units in a coordinate
|
||||
system by some factor. Rotate performs a rotation about the origin by some
|
||||
number of degrees. These functions are converted to a matrix operation on the
|
||||
coordinate system which can be efficiently applied. It is often useful to use
|
||||
the transforms to simplify the calculations of X and Y coordinates instead of
|
||||
calculating those values in Javascript. Also these transforms make developing
|
||||
widgets much easier since we only need to keep up with a single point for the
|
||||
widget and all other points can be relatively positioned from that point.
|
||||
Hard-coding positions in widget development is the normal case since transforms
|
||||
can change the size and position of the widget when the widget is applied to
|
||||
the canvas. Only when necessary should we calculate positions of parts of a
|
||||
widget in javascript.
|
||||
|
||||
* See: <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform>
|
||||
|
||||
|
||||
SVG paths are a mini-language for defining graphics operations in one tag. It
|
||||
is often used to create shapes that are more complex than lines, rectangles,
|
||||
and circles. It is very useful for defining arcs.
|
||||
|
||||
* See: <https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths>
|
||||
|
||||
**SVG and CSS**
|
||||
|
||||
CSS and SVG work really nicely together for setting style, colors, and fonts in SVG.
|
||||
The SVG uses different attributes for setting colors than does HTML elements.
|
||||
Most SVG elements use `stroke` and `fill` to define the colors and `stroke-width`
|
||||
to define the width of lines and curves. The attributes `font-family` and `font-size`
|
||||
are used to set the font for text elements in SVG. The network UI uses the Less
|
||||
CSS compiler and BEM naming conventions to simplify and organize CSS.
|
||||
|
||||
* See: [style.less](style.less)
|
||||
* See: <http://lesscss.org/>
|
||||
* See: <http://getbem.com/introduction/>
|
||||
|
||||
**Events**
|
||||
|
||||
All mouse and keyboard events are captured by the outer most element of the
|
||||
network UI. Mouse movements, mouse clicks, and key presses are all routed by
|
||||
the network UI code and not by the browser. This is done to implement
|
||||
interactions with the virtual graphical canvas that are not supported by the
|
||||
browser. "Simple" things like buttons and text fields have to be handled by
|
||||
the network UI code instead of relying on the browser to route the mouse click
|
||||
to the appropriate object.
|
||||
|
||||
|
||||
The following code captures all the mouse movements, mouse clicks, mouse wheel,
|
||||
and touch events and sends them to the corresponding network UI controller functions.
|
||||
|
||||
* See: [network_ui.partial.svg](network_ui.partial.svg#L3)
|
||||
|
||||
```
|
||||
<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)">
|
||||
```
|
||||
|
||||
|
||||
Key events are captured by the following code:
|
||||
|
||||
* See: [network.ui.controller.js](network.ui.controller.js)
|
||||
|
||||
```
|
||||
$document.bind("keydown", $scope.onKeyDown);
|
||||
```
|
||||
|
||||
**Event Processing**
|
||||
|
||||
This code works as an event processing pipeline where the source of the events
|
||||
may be mouse clicks, keystrokes, or messages from the server over the
|
||||
websocket. This allows the appropriate processor to handle each event in turn
|
||||
or delegate the message to another processor.
|
||||
|
||||
The following diagram documents the pipeline processors that handle the events.
|
||||
Events are injected into to the pipeline at `Start` and travel through the
|
||||
pipeline along the arrows. Events may be handled at a node in the pipeline,
|
||||
passed along to the next node, discarded, or transformed into another message
|
||||
and sent along the pipeline. For instance `hotkeys_fsm` generates new and
|
||||
different type of events based on key presses that are injected at the
|
||||
beginning of the pipeline.
|
||||
|
||||

|
||||
|
||||
|
||||
**Describing Behavior with Finite State Machines**
|
||||
|
||||
To implement complex UI interactions predictably and correctly is a tough
|
||||
problem. Often the problem is solved by creating a large library of generic
|
||||
reusable components that are rigorously tested and hardened by a large group of
|
||||
developers over a period of several years. Eventually the myriad bugs are
|
||||
hammered out at great expense. Only then can the UI components be reliably
|
||||
used. This code does not follow that approach.
|
||||
|
||||
The workflows this code supports require very specific UI components that are
|
||||
not found in generic libraries. The interactions we want to support are not
|
||||
available in generic libraries. This code develops from scratch only the
|
||||
components that are necessary to implement the workflows of designing and
|
||||
operating networks of devices.
|
||||
|
||||
This code defines those elements using finite state machines to process the
|
||||
events from user input and other software components. Programming with finite
|
||||
state machines allows us to define formally complex behavior that would
|
||||
normally be informally defined by branches, functions, object interactions, and
|
||||
object inheritance. Formal definition eliminates much of the unexpected
|
||||
behavior that causes defects in the software.
|
||||
|
||||
* See: <https://en.wikipedia.org/wiki/Finite-state_machine>
|
||||
|
||||
Finite state machines can be represented as a directed graph of labeled nodes and labeled edges
|
||||
which can be both be represented visually and in machine readable code.
|
||||
|
||||
The network UI uses finite state machines to describe what happens when the software receives
|
||||
an input.
|
||||
|
||||
**Link FSM**
|
||||
|
||||

|
||||
|
||||
For example the link FSM describes how to connect devices with links. The FSM
|
||||
diagram above maps out the states and events that will select a device to connect and another
|
||||
device to connect to. FSMs traditionally start in the `Start` state. We get a free transition
|
||||
to the `Ready` state by handling the special event called `start` and changing state to `Ready`.
|
||||
Then when the `NewLink` event is received from a hot key or button click the FSM changes
|
||||
state to the `Selecting` state. On a `MouseUp` event the FSM changes to the the `Connecting` state
|
||||
if the mouse is over a device icon otherwise it stays in the `Selecting` state. In the `Connecting`
|
||||
state the FSM changes to the `Connected` state when it receives a `MouseUp` event and the
|
||||
mouse is over another device otherwise it goes back to the `Ready` state since the user cancelled
|
||||
the connecting operation. Finally in the `Connected` state the FSM changes to the `Ready` state
|
||||
for free using the `start` event so that the user can connect another set of devices.
|
||||
|
||||
* See: [designs/link.yml](designs/link.yml)
|
||||
* See: [link.js](link.js)
|
||||
|
||||
The link FSM diagram has an equivalent machine readable representation in `designs/link.yml`. This
|
||||
representation is useful for comparing the current implementation in `link.js` to the design to see if they
|
||||
are out-of-sync. If they are out-of-sync either the design or the implementation can be updated depending
|
||||
on if you are changing the design or implementation first.
|
||||
|
||||
Tools are provided to facilitate the design-first and the implementation-first workflows.
|
||||
|
||||
**Design-First Workflow**
|
||||
|
||||
In the design-first workflow, first change the design and then update the
|
||||
implementation to match. In this workflow we use the
|
||||
[fsm-designer-svg](https://github.com/benthomasson/fsm-designer-svg) tool to
|
||||
change the FSM diagram, then export the FSM to a file, then generate a skeleton
|
||||
of the javascript code that implements the FSM. Then development of the logic
|
||||
inside the event handlers can begin with a clear understanding of the state of
|
||||
the system and what that event handler should do.
|
||||
|
||||
Use `tools/fsm_generate_diffs.py` to generate the new skeleton code:
|
||||
|
||||
```
|
||||
./tools/fsm_generate_diffs.py designs/link.yml ./link.js
|
||||
```
|
||||
|
||||
This will print out code for additional states or transitions needed in the implementation.
|
||||
Copy those lines into the implementation code and fill out the event handler functions.
|
||||
|
||||
|
||||
**Implementation-First Workflow**
|
||||
|
||||
In the implementation-first workflow, first change the code and then update the
|
||||
design to reflect the changes. This workflow is useful when the design doesn't
|
||||
survive its impact with reality and the code adds additional requirements to
|
||||
the design. Often in usabilty testing we find that we forgot to consider
|
||||
handling a certain interaction or user input in a state. We can quickly add
|
||||
that transition to the code and test it out. Once confirmed that the interaction
|
||||
is correct we can update the design and run `./tools/fsm-diff` to make sure the two
|
||||
are in sync.
|
||||
|
||||
|
||||
Use `./extract.js` and `tools/fsm-diff` to compare the implementation to the design
|
||||
and add any additional transitions to the FSM design.
|
||||
|
||||
```
|
||||
./extract.js link.js > ./extracted/link.yml
|
||||
./tools/fsm-diff designs/link.yml extracted/link.yml
|
||||
```
|
||||
|
||||
|
||||
**Validating That Design Matches Implementation**
|
||||
|
||||
Use the `make extract` and `make diff` Makefile targets to do a mass extact of the
|
||||
FSMs from the implementation and a mass comparison against the designs. Take
|
||||
note of any differences between design and implementation and update the appropriate
|
||||
files as outlined in the workflows above.
|
||||
|
||||
```
|
||||
make extract; make diff
|
||||
```
|
||||
|
||||
|
||||
**Finite State Machine Implementation**
|
||||
|
||||
The implementation of a finite state machine in the network UI is split into
|
||||
two parts: the declaration of the states and the event-handlers which may cause
|
||||
FSM transitions using `controller.changeState`.
|
||||
|
||||
**FSM States**
|
||||
|
||||
* See: <https://en.wikipedia.org/wiki/Flyweight_pattern>
|
||||
* See: <https://en.wikipedia.org/wiki/Singleton_pattern>
|
||||
|
||||
States are implemented using an object-oriented style in ES5 using the
|
||||
flyweight and singleton patterns. This means that the state objects store no
|
||||
information on themselves and that there is only one instance of each state
|
||||
class. All states should provide a `start` and `end` function which will be
|
||||
called when a FSM state is entered and exited respectively. Subclassing
|
||||
[fsm.State](fsm.js#L36) will provide empty `start` and `end` functions that
|
||||
can be overridden as necessary.
|
||||
|
||||
* See: [fsm.js](fsm.js#L2)
|
||||
|
||||
The state variable is stored on another object called an FSMController (which
|
||||
should not be confused with an AngularJS controller). The FSMController holds
|
||||
all the state for each FSM instance. If you need more than one copy of an FSM
|
||||
(for buttons for instance) use more than one instance of FSMController and
|
||||
pass the same FSM starting state to their constructor e.g. `button.Start`.
|
||||
Variables other than `state` should not be stored on the FSMController. A
|
||||
special variable named `scope` is useful for that. The scope can be used
|
||||
to hold arbitrary data that the FSM code will use in addition to the messages
|
||||
in the event handlers. In the network UI often the `scope` is a reference
|
||||
to the network UI AngularJS controller's scope. In the case of a button
|
||||
the scope is a reference to the `Button` model.
|
||||
|
||||
* See: [models.js](models.js#302)
|
||||
|
||||
The following code creates a new instance of `FSMController` using the
|
||||
`Button` model as the scope and the `button.Start` state as the initial
|
||||
state.
|
||||
|
||||
```
|
||||
this.fsm = new fsm.FSMController(this, button.Start, null);
|
||||
```
|
||||
|
||||
* See: [link.js](link.js#L40)
|
||||
|
||||
This code block defines the `_Selecting` class in ES5 style and uses the
|
||||
`inherits` NPM module to define that the class is a subclass of `_State`. We
|
||||
also create a single instance (a singleton) of this class named `Selecting`.
|
||||
|
||||
```
|
||||
function _Selecting () {
|
||||
this.name = 'Selecting';
|
||||
}
|
||||
inherits(_Selecting, _State);
|
||||
var Selecting = new _Selecting();
|
||||
exports.Selecting = Selecting;
|
||||
```
|
||||
|
||||
**FSM Event Handlers and Transitions**
|
||||
|
||||
After all the states are defined the event handlers for those state classes can be defined.
|
||||
We do this to prevent forward references in the file.
|
||||
|
||||
* See: [link.js](link.js#L134)
|
||||
|
||||
In this code we define an event handler for the `MouseUp` event on the `Selecting` state. This
|
||||
code should select a single device if the mouse is over that device. It should store
|
||||
that device somewhere and change to the `Connecting` state. The code below creates a new
|
||||
`Link` model and stores the `selected_device` in that object. The `new_link` object is
|
||||
stored in the `controller.scope` for later use in the FSM. Finally the event handler changes
|
||||
state using `controller.changeState` to change the state of the FSM to `Connecting`.
|
||||
|
||||
Event handlers must start with the prefix of `on` and a suffix of the name of the messsage
|
||||
type. The special functions `start` and `end` do not follow this rule nor do
|
||||
they receive a message.
|
||||
|
||||
The event handler must also define its `transitions` as a list so that `./extract.js` can
|
||||
find them.
|
||||
|
||||
```
|
||||
_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'];
|
||||
|
||||
```
|
||||
|
||||
**FSM Designs**
|
||||
|
||||
All the finite state machines for the network UI have been designed using the
|
||||
[fsm-designer-svg](https://github.com/benthomasson/fsm-designer-svg) tool
|
||||
and their designs are stored in the `designs` directory.
|
||||
|
||||
* See: [designs/README.md](designs/README.md)
|
||||
|
||||
|
||||
**Data Models**
|
||||
|
||||
There are two types of data structures used in the network UI: messages and
|
||||
models. Models are used for long-lived data that is used to render the UI
|
||||
whereas messages are used for ephemeral data that is passed from one part of
|
||||
the system to another. Models may be unpacked or serialized into messages that
|
||||
are sent to other FSMControllers in the client or sent over a websocket to the
|
||||
server.
|
||||
|
||||
* See: [models.js](models.js)
|
||||
|
||||
The models defined in [models.js](models.js) are:
|
||||
|
||||
* Device - a networking device i.e. a router, a switch, or a host
|
||||
* Interface - a networking interface
|
||||
* Link - a connection between interfaces
|
||||
* Button - a UI button
|
||||
* ToggleButton - a togglable UI button
|
||||
* Task - a playbook task
|
||||
* Group - a grouping of devices
|
||||
* ToolBox - a UI element for holding things that can be placed on the virtual canvas
|
||||
* Configuration - a configuration for a device
|
||||
* Process - an application running on a device
|
||||
* Stream - a flow of data between applications
|
||||
|
||||
|
||||
**Message Types**
|
||||
|
||||
Message types define the structure of the data that is passed between the server
|
||||
and the client and between different parts of the client. This provides a known and
|
||||
well defined data structure that can be counted up on the code.
|
||||
|
||||
* See: [messages.js](messages.js)
|
||||
|
||||
The messages defined are [messages.js](messages.js):
|
||||
|
||||
* DeviceMove - Device has changed x,y position
|
||||
* DeviceCreate - A device was created
|
||||
* DeviceDestroy - A device was destroyed
|
||||
* DeviceLabelEdit - The label of a device was changed
|
||||
* DeviceSelected - A device was selected
|
||||
* DeviceUnSelected - A device was unselected
|
||||
* InterfaceCreate - An interface was created
|
||||
* InterfaceLabelEdit - The label of an interface was changed
|
||||
* LinkLabelEdit - The label of a link was changed
|
||||
* LinkCreate - A link was created
|
||||
* LinkDestroy - A link was destroyed
|
||||
* LinkSelected - A link was selected
|
||||
* LinkUnSelected - A link was unselected
|
||||
* Undo - Undo the last operation
|
||||
* Redo - Redo the last undone operation
|
||||
* Deploy - Call the deploy playbook
|
||||
* Destroy - Call the destroy playbook
|
||||
* Discover - Call the discover playbook
|
||||
* Layout - Call the layout function
|
||||
* MultipleMessage - A collection of messages that should be handled together
|
||||
* Coverage - A coverage report
|
||||
* MouseEvent - A generic mouse event
|
||||
* MouseWheelEvent - A mouse wheel event
|
||||
* KeyEvent - A key press event
|
||||
* TouchEvent - A touch screen event
|
||||
* StartRecording - Start recording user interactions
|
||||
* StopRecording - Stop recording user interactions
|
||||
* ViewPort - Update the view port onto the virtual canvas
|
||||
* NewDevice - Request for a new device
|
||||
* PasteDevice - Paste a device from a toolbox
|
||||
* PasteProcess - Paste a process from a toolbox
|
||||
* NewGroup - Request for a new group
|
||||
* PasteGroup - Paste a group from a toolbox
|
||||
* PasteRack - Paste a rack from a toolbox
|
||||
* PasteSite - Paste a site from a toolbox
|
||||
* CopySite - Copy a stie to a toolbox
|
||||
* GroupMove - A group has changed its x, y coordinates
|
||||
* GroupCreate - A new group was created
|
||||
* GroupDestroy - A group was destroyed
|
||||
* GroupLabelEdit - The label for a group was changed
|
||||
* GroupSelected - A group was selected
|
||||
* GroupUnSelected - A group was unselected
|
||||
* GroupMembership - The device membership of a group changed
|
||||
* TableCellEdit - A table cell was chaged
|
||||
* ProcessCreate - A new process was created
|
||||
* StreamCreate - A new stream was created
|
||||
* StreamDestroy - A stream was destroyed
|
||||
* StreamLabelEdit - The label of a stream was changed
|
||||
* StreamSelected - A stream was selected
|
||||
* StreamUnSelected - A stream was unselected
|
||||
|
||||
|
||||
Widget Development
|
||||
==================
|
||||
|
||||
When developing a new UI widget follow this process:
|
||||
|
||||
For a widget named `new widget` do this:
|
||||
|
||||
* Add a template in `widgets` for the new widget with name `new_widget.html`
|
||||
* Add a directive that loads that template in `src` with name `new.widget.directive.js`
|
||||
* Register the directive with the network UI application in `src/network.ui.app.js` using name `awxNetNewWidget`
|
||||
* Add a tag that loads the directive into an existing template in `widgets`. If you are not sure add it to `widgets/network_ui.html`.
|
||||
* Test that the directive is loaded when the page renders in a browser
|
||||
* Iterate on the template for the new widget until the UI look matches the mockup
|
||||
* Design the interaction behavior using [fsm-designer-svg](https://github.com/benthomasson/fsm-designer-svg)
|
||||
* Export the FSM design to `designs` in a file named `designs/new_widget.yml`
|
||||
* Create a new empty FSM implementation file in `src` named `src/new.wiget.fsm.js`
|
||||
* Use the `./tools/fsm_generate_diffs.py` tool to generate the skeleton for the new FSM implementation
|
||||
* Decide if you need any new data structures for your UI widget. If so, add them to `src/models.js`.
|
||||
* Decide if you need any new messages to communicate between the UI and the server or between pieces of the UI.
|
||||
If so, add them to `src/messages.js`
|
||||
* Add the FSM implementation to a FSMController in `src/network.ui.controller.js`
|
||||
* Write the logic in the event handlers to update the models, send any messages, and change states according to the design.
|
||||
* Test the interaction manually in a browser
|
||||
* Iterate on changing the event handlers until the desired interaction is acheived
|
||||
* Update the design to match the implementation
|
||||
|
||||
**Widget Development Example**
|
||||
|
||||
This example follows development of the inventory toolbox widget.
|
||||
|
||||
* Add a template in `widgets` for the new widget with name [inventory_toolbox.partial.svg](inventory_toolbox.partial.svg)
|
||||
|
||||
```
|
||||
<!-- Copyright (c) 2017 Red Hat, Inc. -->
|
||||
|
||||
<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>
|
||||
...
|
||||
</g> <!-- ng-if toolbox.enabled -->
|
||||
```
|
||||
|
||||
* Add a directive that loads that template in `src/network-ui` with name [inventory.toolbox.directive.js](inventory.toolbox.directive.js)
|
||||
|
||||
```
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
function inventoryToolbox () {
|
||||
return { restrict: 'A', templateUrl: '/static/network_ui/widgets/inventory_toolbox.html' };
|
||||
}
|
||||
exports.inventoryToolbox = inventoryToolbox;
|
||||
```
|
||||
|
||||
|
||||
* Register the directive with the network UI application in [network.ui.app.js](network.ui.app.js#L61) using name `awxNetInventoryToolbox`
|
||||
|
||||
```
|
||||
...
|
||||
var inventoryToolbox = require('./inventory.toolbox.directive.js');
|
||||
...
|
||||
.directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox)
|
||||
...
|
||||
```
|
||||
|
||||
* Add a tag that loads the directive into an existing template in `src/network-ui` in [network_ui.partial.svg](network_ui.partial.svg#L94)
|
||||
|
||||
```
|
||||
<g awx-net-inventory-toolbox></g>
|
||||
```
|
||||
|
||||
* Test that the directive is loaded when the page renders in a browser
|
||||
* Iterate on the template for the new widget until the UI look matches the mockup
|
||||
* Design the interaction behavior using [fsm-designer-svg](https://github.com/benthomasson/fsm-designer-svg)
|
||||
|
||||

|
||||
|
||||
* Export the FSM design to `designs` in a file named `designs/toolbox.yml`
|
||||
|
||||
```
|
||||
finite_state_machine_id: 14
|
||||
name: toolbox
|
||||
states:
|
||||
- id: 2
|
||||
label: Selected
|
||||
x: 1180
|
||||
y: 959
|
||||
- id: 6
|
||||
label: Move
|
||||
x: 1409
|
||||
y: 741
|
||||
- id: 3
|
||||
label: Ready
|
||||
x: 892
|
||||
y: 429
|
||||
- id: 4
|
||||
label: Scrolling
|
||||
x: 567
|
||||
y: 431
|
||||
- id: 5
|
||||
label: Start
|
||||
x: 892
|
||||
y: 216
|
||||
- id: 7
|
||||
label: Selecting
|
||||
x: 888
|
||||
y: 710
|
||||
- id: 1
|
||||
label: Dropping
|
||||
x: 1358
|
||||
y: 431
|
||||
transitions:
|
||||
- from_state: Selecting
|
||||
label: onMouseDown
|
||||
to_state: Selected
|
||||
- from_state: Selected
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selecting
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
- from_state: Dropping
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Scrolling
|
||||
label: onMouseWheel
|
||||
to_state: Ready
|
||||
- from_state: Ready
|
||||
label: onMouseWheel
|
||||
to_state: Scrolling
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selecting
|
||||
- from_state: Move
|
||||
label: onMouseUp
|
||||
to_state: Dropping
|
||||
```
|
||||
|
||||
* Create a new empty FSM implementation file in `src/network-ui` named `toolbox.fsm.js`
|
||||
|
||||
```
|
||||
touch toolbox.fsm.js
|
||||
```
|
||||
|
||||
* Use the `./tools/fsm_generate_diffs.py` tool to generate the skeleton for the new FSM implementation
|
||||
|
||||
```
|
||||
./tools/fsm_generate_diffs.py designs/toolbox.yml src/toolbox.fsm.js --append
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
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 _Selected () {
|
||||
this.name = 'Selected';
|
||||
}
|
||||
inherits(_Selected, _State);
|
||||
var Selected = new _Selected();
|
||||
exports.Selected = Selected;
|
||||
|
||||
function _Dropping () {
|
||||
this.name = 'Dropping';
|
||||
}
|
||||
inherits(_Dropping, _State);
|
||||
var Dropping = new _Dropping();
|
||||
exports.Dropping = Dropping;
|
||||
|
||||
function _Ready () {
|
||||
this.name = 'Ready';
|
||||
}
|
||||
inherits(_Ready, _State);
|
||||
var Ready = new _Ready();
|
||||
exports.Ready = Ready;
|
||||
|
||||
function _Selecting () {
|
||||
this.name = 'Selecting';
|
||||
}
|
||||
inherits(_Selecting, _State);
|
||||
var Selecting = new _Selecting();
|
||||
exports.Selecting = Selecting;
|
||||
|
||||
function _Move () {
|
||||
this.name = 'Move';
|
||||
}
|
||||
inherits(_Move, _State);
|
||||
var Move = new _Move();
|
||||
exports.Move = Move;
|
||||
|
||||
function _Scrolling () {
|
||||
this.name = 'Scrolling';
|
||||
}
|
||||
inherits(_Scrolling, _State);
|
||||
var Scrolling = new _Scrolling();
|
||||
exports.Scrolling = Scrolling;
|
||||
|
||||
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Ready'];
|
||||
|
||||
|
||||
|
||||
_Selected.prototype.onMouseMove = function (controller) {
|
||||
|
||||
controller.changeState(Move);
|
||||
|
||||
};
|
||||
_Selected.prototype.onMouseMove.transitions = ['Move'];
|
||||
|
||||
_Selected.prototype.onMouseUp = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Selected.prototype.onMouseUp.transitions = ['Ready'];
|
||||
|
||||
|
||||
|
||||
_Dropping.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Dropping.prototype.start.transitions = ['Ready'];
|
||||
|
||||
|
||||
|
||||
_Ready.prototype.onMouseDown = function (controller) {
|
||||
|
||||
controller.changeState(Selecting);
|
||||
|
||||
};
|
||||
_Ready.prototype.onMouseDown.transitions = ['Selecting'];
|
||||
|
||||
_Ready.prototype.onMouseWheel = function (controller) {
|
||||
|
||||
controller.changeState(Scrolling);
|
||||
|
||||
};
|
||||
_Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
|
||||
|
||||
|
||||
|
||||
_Selecting.prototype.onMouseDown = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
controller.changeState(Selected);
|
||||
|
||||
};
|
||||
_Selecting.prototype.onMouseDown.transitions = ['Ready', 'Selected'];
|
||||
|
||||
|
||||
|
||||
_Move.prototype.onMouseUp = function (controller) {
|
||||
|
||||
controller.changeState(Dropping);
|
||||
|
||||
};
|
||||
_Move.prototype.onMouseUp.transitions = ['Dropping'];
|
||||
|
||||
|
||||
|
||||
_Scrolling.prototype.onMouseWheel = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Scrolling.prototype.onMouseWheel.transitions = ['Ready'];
|
||||
};
|
||||
_Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
|
||||
|
||||
|
||||
|
||||
_Selecting.prototype.onMouseDown = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
controller.changeState(Selected);
|
||||
|
||||
};
|
||||
_Selecting.prototype.onMouseDown.transitions = ['Ready', 'Selected'];
|
||||
|
||||
|
||||
|
||||
_Move.prototype.onMouseUp = function (controller) {
|
||||
|
||||
controller.changeState(Dropping);
|
||||
|
||||
};
|
||||
_Move.prototype.onMouseUp.transitions = ['Dropping'];
|
||||
|
||||
|
||||
|
||||
_Scrolling.prototype.onMouseWheel = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Scrolling.prototype.onMouseWheel.transitions = ['Ready'];
|
||||
|
||||
```
|
||||
|
||||
* Decide if you need any new data structures for your UI widget. If so, add them to [src/models.js](src/models.js#L608).
|
||||
|
||||
```
|
||||
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;
|
||||
```
|
||||
|
||||
* Decide if you need any new messages to communicate between the UI and the server or between pieces of the UI.
|
||||
If so, add them to [messages.js](messages.js#L251)
|
||||
|
||||
```
|
||||
function PasteDevice(device) {
|
||||
this.device = device;
|
||||
}
|
||||
exports.PasteDevice = PasteDevice;
|
||||
```
|
||||
|
||||
* Write the logic in the event handlers to update the models, send any messages, and change states according to the design.
|
||||
|
||||
See: [toolbox.fsm.js](toolbox.fsm.js)
|
||||
|
||||
* Add the FSM implementation to a FSMController in [network.ui.controller.js](network.ui.controller.js#L145)
|
||||
|
||||
```
|
||||
$scope.inventory_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.app_toolbox_controller);
|
||||
```
|
||||
|
||||
* Test the interaction manually in a browser
|
||||
* Iterate on changing the event handlers until the desired interaction is achieved
|
||||
* Update the design to match the implementation
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
|
||||
.PHONY: check extract
|
||||
|
||||
FSMS = animation time test mode buttons button toolbox site rack group stream link details.panel move device.detail view keybindings hotkeys null
|
||||
|
||||
|
||||
extract:
|
||||
mkdir -p extracted
|
||||
for fsm in $(FSMS); do \
|
||||
./extract.js ./$${fsm}.fsm.js > extracted/$${fsm}.yml; \
|
||||
done
|
||||
|
||||
|
||||
check: extract
|
||||
for fsm in $(FSMS); do \
|
||||
./tools/fsm-diff ../../../../network_ui/designs/$$fsm.yml extracted/$$fsm.yml; \
|
||||
./tools/copy-layout.py ../../../../network_ui/designs/$$fsm.yml extracted/$$fsm.yml; \
|
||||
done
|
||||
@@ -1,81 +0,0 @@
|
||||
/* Copyright (c) 2018 Benjamin Thomasson */
|
||||
/* Copyright (c) 2018 Red Hat, Inc. */
|
||||
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
|
||||
|
||||
function _Start () {
|
||||
this.name = 'Start';
|
||||
}
|
||||
inherits(_Start, fsm._State);
|
||||
var Start = new _Start();
|
||||
exports.Start = Start;
|
||||
|
||||
function _Completed () {
|
||||
this.name = 'Completed';
|
||||
}
|
||||
inherits(_Completed, fsm._State);
|
||||
var Completed = new _Completed();
|
||||
exports.Completed = Completed;
|
||||
|
||||
function _Cancelled () {
|
||||
this.name = 'Cancelled';
|
||||
}
|
||||
inherits(_Cancelled, fsm._State);
|
||||
var Cancelled = new _Cancelled();
|
||||
exports.Cancelled = Cancelled;
|
||||
|
||||
function _Running () {
|
||||
this.name = 'Running';
|
||||
}
|
||||
inherits(_Running, fsm._State);
|
||||
var Running = new _Running();
|
||||
exports.Running = Running;
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Running);
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Running'];
|
||||
|
||||
_Running.prototype.start = function (controller) {
|
||||
|
||||
controller.scope.interval = setInterval(function () {
|
||||
controller.scope.frame_number = controller.scope.frame_number_seq();
|
||||
if (!controller.scope.active) {
|
||||
return;
|
||||
}
|
||||
if (controller.scope.frame_number > controller.scope.steps) {
|
||||
controller.scope.fsm.handle_message('AnimationCompleted');
|
||||
return;
|
||||
}
|
||||
controller.scope.callback(controller.scope);
|
||||
controller.scope.scope.$apply();
|
||||
}, controller.scope.frame_delay);
|
||||
};
|
||||
|
||||
_Running.prototype.onAnimationCancelled = function (controller) {
|
||||
|
||||
controller.changeState(Cancelled);
|
||||
|
||||
};
|
||||
_Running.prototype.onAnimationCancelled.transitions = ['Cancelled'];
|
||||
|
||||
_Running.prototype.onAnimationCompleted = function (controller) {
|
||||
|
||||
controller.changeState(Completed);
|
||||
|
||||
};
|
||||
_Running.prototype.onAnimationCompleted.transitions = ['Completed'];
|
||||
|
||||
_Completed.prototype.start = function (controller) {
|
||||
controller.scope.active = false;
|
||||
clearInterval(controller.scope.interval);
|
||||
};
|
||||
|
||||
_Cancelled.prototype.start = function (controller) {
|
||||
controller.scope.active = false;
|
||||
clearInterval(controller.scope.interval);
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
function scale_animation (scope) {
|
||||
|
||||
var initial_height = ((1 / scope.data.current_scale) - 1);
|
||||
var height = (scope.data.end_height - initial_height) * (scope.frame_number / scope.steps) + initial_height;
|
||||
scope.data.scope.current_scale = 1 / (1 + height);
|
||||
scope.data.scope.updatePanAndScale();
|
||||
scope.data.scope.$emit('awxNet-UpdateZoomWidget', scope.data.scope.current_scale, scope.data.updateZoomBoolean);
|
||||
}
|
||||
exports.scale_animation = scale_animation;
|
||||
|
||||
function pan_animation (scope) {
|
||||
var incr_x = (scope.data.x2 - scope.data.x1) / scope.steps;
|
||||
var incr_y = (scope.data.y2 - scope.data.y1) / scope.steps;
|
||||
var v_x = incr_x * scope.frame_number + scope.data.x1;
|
||||
var v_y = incr_y * scope.frame_number + scope.data.y1;
|
||||
var p = scope.data.scope.to_pan(v_x, v_y);
|
||||
scope.data.scope.panX = p.x + scope.data.scope.graph.width/2;
|
||||
scope.data.scope.panY = p.y + scope.data.scope.graph.height/2;
|
||||
scope.data.scope.first_channel.send("PanChanged", {});
|
||||
scope.data.scope.updatePanAndScale();
|
||||
}
|
||||
exports.pan_animation = pan_animation;
|
||||
@@ -1,107 +0,0 @@
|
||||
/* 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.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'];
|
||||
|
||||
_Disabled.prototype.onEnable = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Disabled.prototype.onEnable.transitions = ['Ready'];
|
||||
|
||||
_Disabled.prototype.start = function (controller) {
|
||||
|
||||
controller.scope.enabled = false;
|
||||
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
/* 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.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'];
|
||||
@@ -1,15 +0,0 @@
|
||||
/* 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;
|
||||
@@ -1,14 +0,0 @@
|
||||
/* 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;
|
||||
@@ -1,23 +0,0 @@
|
||||
<!-- 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 -->
|
||||
@@ -1,19 +0,0 @@
|
||||
<!-- 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-show="contextMenuButton.name !=='Remove'" 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>
|
||||
<text ng-show="contextMenuButton.type ==='remove'" ng-attr-class="{{contextMenuButton.is_pressed ? 'NetworkUI__contextMenuRemoveButtonText-pressed' : contextMenuButton.mouse_over ? 'NetworkUI__contextMenuRemoveButtonText-hover' : 'NetworkUI__contextMenuRemoveButtonText'}}"
|
||||
x=15
|
||||
ng-attr-y="{{(contextMenuButton.height * $parent.$index) + 18}}"
|
||||
dy=".3em"
|
||||
text-anchor="left">{{contextMenuButton.name}}
|
||||
</text>
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/cursor.partial.svg');
|
||||
|
||||
function cursor () {
|
||||
return { restrict: 'A', templateUrl};
|
||||
}
|
||||
exports.cursor = cursor;
|
||||
@@ -1,5 +0,0 @@
|
||||
<!-- 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>
|
||||
@@ -1,20 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/debug.partial.svg');
|
||||
|
||||
function debug () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
templateUrl,
|
||||
link: function(){
|
||||
$('.NetworkUI__debug-text').each(function(index, option){
|
||||
let startingY = 15;
|
||||
let offset = 20;
|
||||
let y = startingY + (index * offset);
|
||||
option.setAttribute('y', y);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
exports.debug = debug;
|
||||
@@ -1,60 +0,0 @@
|
||||
<!-- Copyright (c) 2017 Red Hat, Inc. -->
|
||||
|
||||
|
||||
<g ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || ''}}">
|
||||
<g transform="translate(0, 100)">
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">view_port.x: {{view_port.x}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">view_port.y: {{view_port.y}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">view_port.width: {{view_port.width}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">view_port.height: {{view_port.height}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">width: {{graph.width}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">height: {{graph.height}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">rc: {{graph.right_column}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse down: {{onMouseDownResult}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse up: {{onMouseUpResult}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse move: {{onMouseMoveResult}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse over: {{onMouseOverResult}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse enter: {{onMouseEnterResult}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse leave: {{onMouseLeaveResult}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Current scale: {{current_scale.toFixed(4)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Pan X: {{panX.toFixed(2)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Pan Y: {{panY.toFixed(2)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">View State: {{view_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse X: {{mouseX.toFixed(2)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mouse Y: {{mouseY.toFixed(2)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Scaled X: {{scaledX.toFixed(2)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Scaled Y: {{scaledY.toFixed(2)}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Key: {{last_key}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Key Code: {{last_key_code}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Move State: {{move_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Move Readonly State: {{move_readonly_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Selected devices: {{selected_devices.length}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Selected links: {{selected_links.length}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Link State: {{link_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Buttons State: {{buttons_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Time State: {{time_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Time Pointer: {{time_pointer}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Group State: {{group_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Hotkeys State: {{hotkeys_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Mode State: {{mode_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Device Detail State: {{device_detail_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Site State: {{site_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Rack State: {{rack_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Stream State: {{stream_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">App Toolbox State: {{app_toolbox_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Inventory Toolbox State: {{inventory_toolbox_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Rack Toolbox State: {{rack_toolbox_controller.state.name}}</text>
|
||||
<text ng-attr-x="{{graph.right_column}}" class="NetworkUI__debug-text">Site Toolbox State: {{site_toolbox_controller.state.name}}</text>
|
||||
</g>
|
||||
<rect x=10 y=10 ng-attr-width="{{graph.width - 20}}" ng-attr-height="{{graph.height - 20}}" class="NetworkUI--debug"></rect>
|
||||
<line x1="-10000"
|
||||
ng-attr-y1="{{graph.height/2}}"
|
||||
x2="10000"
|
||||
ng-attr-y2="{{graph.height/2}}"
|
||||
ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || 'NetworkUI--debug'}}" />
|
||||
<line ng-attr-x1="{{graph.width/2}}"
|
||||
y1="-10000"
|
||||
ng-attr-x2="{{graph.width/2}}"
|
||||
y2="10000"
|
||||
ng-attr-class="{{debug.hidden && 'NetworkUI--hidden' || 'NetworkUI--debug'}}" />
|
||||
</g>
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/default.partial.svg');
|
||||
|
||||
function defaultd () {
|
||||
return { restrict: 'A', templateUrl};
|
||||
}
|
||||
exports.defaultd = defaultd;
|
||||
@@ -1,58 +0,0 @@
|
||||
<!-- Copyright (c) 2017 Red Hat, Inc. -->
|
||||
|
||||
<g transform="scale(0.75)">
|
||||
<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(#background)"
|
||||
text-anchor="middle"
|
||||
x="0"
|
||||
y="73"> <tspan x="0" dy="20" ng-repeat="chunk in item.name|chunk:25">{{chunk}}</tspan>
|
||||
</text>
|
||||
<text class="NetworkUI__device-text" filter="url(#background)" text-anchor="middle" x="0" y="73">
|
||||
<tspan x="0" dy="20" ng-repeat="chunk in item.name|chunk:25">{{chunk}}</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
@@ -1,161 +0,0 @@
|
||||
|
||||
Finite State Machine Designs
|
||||
============================
|
||||
|
||||
This directory contains the finite state machine designs that were used to
|
||||
generate the skeleton of the javascript implementations and can be used to
|
||||
check that the implementations still match the designs.
|
||||
|
||||
|
||||
**Machine Readable FSM Schema**
|
||||
|
||||
The machine readable FSM schema contains three top-level elements: `name`, `states`, and `transitions`.
|
||||
* The `name` element is a string.
|
||||
* The `states` element contains a list of `state` elements which have attributes `id`, `label`, and `x`, and `y`.
|
||||
* The `transitions` element contains a list of `transition` elements which have attributes `from_state`, `to_state`, and `label`.
|
||||
|
||||
|
||||
**Design Diagrams**
|
||||
|
||||
The diagrams below are visual representations of the finite state machine designs in this directory.
|
||||
The equivalent machine readable representations are linked as well.
|
||||
|
||||
---
|
||||
|
||||
**Null FSM**
|
||||
* See: null.yml
|
||||
|
||||
The null FSM is an FSM that ignores all events.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Button FSM**
|
||||
* See: button.yml
|
||||
|
||||
The button FSM describes how a button works. The key insight here is that a button is not
|
||||
clicked if the mouse is not over the button on both the `MouseDown` and `MouseUp` events. Moving
|
||||
the mouse off the button before `MouseUp` is not a click.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Buttons FSM**
|
||||
* See: buttons.yml
|
||||
|
||||
The buttons FSM distributes events to the buttons which each have their own FSM.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Device Detail FSM**
|
||||
* See: device_detail.yml
|
||||
|
||||
The device detail FSM describes interactions when zoomed into a device.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Group FSM**
|
||||
* See: group.yml
|
||||
|
||||
The group FSM describes how to organize multiple devices together in a group.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Hot Keys FSM**
|
||||
* See: hotkeys.yml
|
||||
|
||||
The hot keys FSM handles key events and generates new events like `NewLink` to implement
|
||||
hot keys.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Link FSM**
|
||||
* See: link.yml
|
||||
|
||||
The link FSM connects two devices together with a link.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Mode FSM**
|
||||
* See: mode.yml
|
||||
|
||||
The mode FSM controls the overall mode of the network UI application.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Move FSM**
|
||||
* See: move.yml
|
||||
|
||||
The move FSM controls placement of devices as well as editing the device labels.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Rack FSM**
|
||||
* See: rack.yml
|
||||
|
||||
The rack FSM controls organizing devices into a special group called a rack.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Site FSM**
|
||||
* See: site.yml
|
||||
|
||||
The site FSM controls organizing devices into a special group called a site.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Stream FSM**
|
||||
* See: stream.yml
|
||||
|
||||
The stream FSM controls how streams are defined between devices.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Time FSM**
|
||||
* See: time.yml
|
||||
|
||||
The time FSM controls undo/redo functionality of the network UI.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**Toolbox FSM**
|
||||
* See: toolbox.yml
|
||||
|
||||
The toolbox FSM controls the drag-and-drop toolboxes and allow placement of new devices, applications,
|
||||
racks, and sites onto the canvas.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**View FSM**
|
||||
* See: view.yml
|
||||
|
||||
The view FSM controls the panning and scaling of the the virtual canvas through clicking-and-dragging
|
||||
of the background and scrolling the mousewheel.
|
||||
|
||||

|
||||
@@ -1,29 +0,0 @@
|
||||
diagram_id: 58
|
||||
name: animation_fsm
|
||||
states:
|
||||
- id: 4
|
||||
label: Cancelled
|
||||
x: 590
|
||||
y: 602
|
||||
- id: 3
|
||||
label: Completed
|
||||
x: 225
|
||||
y: 604
|
||||
- id: 2
|
||||
label: Running
|
||||
x: 418
|
||||
y: 362
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 454
|
||||
y: 158
|
||||
transitions:
|
||||
- from_state: Running
|
||||
label: onAnimationCancelled
|
||||
to_state: Cancelled
|
||||
- from_state: Running
|
||||
label: onAnimationCompleted
|
||||
to_state: Completed
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Running
|
||||
|
Before Width: | Height: | Size: 55 KiB |
@@ -1,43 +0,0 @@
|
||||
diagram_id: 66
|
||||
name: 'button_fsm'
|
||||
finite_state_machine_id: 12
|
||||
states:
|
||||
- id: 3
|
||||
label: Clicked
|
||||
x: 331
|
||||
y: 568
|
||||
- id: 5
|
||||
label: Disabled
|
||||
x: 719
|
||||
y: 283
|
||||
- id: 4
|
||||
label: Pressed
|
||||
x: 606
|
||||
y: 563
|
||||
- id: 1
|
||||
label: Ready
|
||||
x: 471
|
||||
y: 376
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 468
|
||||
y: 170
|
||||
transitions:
|
||||
- from_state: Clicked
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Disabled
|
||||
label: onEnable
|
||||
to_state: Ready
|
||||
- from_state: Pressed
|
||||
label: onMouseUp
|
||||
to_state: Clicked
|
||||
- from_state: Ready
|
||||
label: onDisable
|
||||
to_state: Disabled
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Pressed
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 34 KiB |
@@ -1,28 +0,0 @@
|
||||
app: buttons_fsm
|
||||
finite_state_machine_id: 7
|
||||
panX: 133
|
||||
panY: 41
|
||||
scaleXY: 1
|
||||
states:
|
||||
- label: Start
|
||||
size: 100
|
||||
x: 392
|
||||
y: 88
|
||||
- label: Ready
|
||||
size: 100
|
||||
x: 392
|
||||
y: 281
|
||||
- label: ButtonPressed
|
||||
size: 100
|
||||
x: 394
|
||||
y: 491
|
||||
transitions:
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: ButtonPressed
|
||||
- from_state: ButtonPressed
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 63 KiB |
@@ -1,26 +0,0 @@
|
||||
diagram_id: 70
|
||||
finite_state_machine_id: 21
|
||||
name: diagram
|
||||
states:
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 590
|
||||
y: 233
|
||||
- id: 2
|
||||
label: Collapsed
|
||||
x: 594
|
||||
y: 490
|
||||
- id: 3
|
||||
label: Expanded
|
||||
x: 919
|
||||
y: 491
|
||||
transitions:
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Collapsed
|
||||
- from_state: Expanded
|
||||
label: onDetailsPanelClose
|
||||
to_state: Collapsed
|
||||
- from_state: Collapsed
|
||||
label: onDetailsPanel
|
||||
to_state: Expanded
|
||||
|
Before Width: | Height: | Size: 41 KiB |
@@ -1,19 +0,0 @@
|
||||
finite_state_machine_id: 19
|
||||
name: device_detail_fsm
|
||||
states:
|
||||
- id: 2
|
||||
label: Ready
|
||||
x: 517
|
||||
y: 588
|
||||
- id: 3
|
||||
label: Disable
|
||||
x: 770
|
||||
y: 455
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 507
|
||||
y: 336
|
||||
transitions:
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 113 KiB |
@@ -1,119 +0,0 @@
|
||||
diagram_id: 61
|
||||
finite_state_machine_id: 5
|
||||
name: group_fsm
|
||||
states:
|
||||
- id: 12
|
||||
label: ContextMenu
|
||||
x: 1228
|
||||
y: -74
|
||||
- id: 3
|
||||
label: CornerSelected
|
||||
x: 526
|
||||
y: 554
|
||||
- id: 8
|
||||
label: Disable
|
||||
x: 497
|
||||
y: 84
|
||||
- id: 9
|
||||
label: EditLabel
|
||||
x: 1130
|
||||
y: 112
|
||||
- id: 6
|
||||
label: Move
|
||||
x: 1297
|
||||
y: 786
|
||||
- id: 11
|
||||
label: Placing
|
||||
x: 299
|
||||
y: 300
|
||||
- id: 7
|
||||
label: Ready
|
||||
x: 733
|
||||
y: 304
|
||||
- id: 1
|
||||
label: Resize
|
||||
x: 571
|
||||
y: 911
|
||||
- id: 4
|
||||
label: Selected1
|
||||
x: 839
|
||||
y: 640
|
||||
- id: 10
|
||||
label: Selected2
|
||||
x: 1179
|
||||
y: 435
|
||||
- id: 5
|
||||
label: Selected3
|
||||
x: 1528
|
||||
y: 360
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 744
|
||||
y: 69
|
||||
transitions:
|
||||
- from_state: ContextMenu
|
||||
label: onLabelEdit
|
||||
to_state: EditLabel
|
||||
- from_state: ContextMenu
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: CornerSelected
|
||||
label: onMouseMove
|
||||
to_state: Resize
|
||||
- from_state: CornerSelected
|
||||
label: onMouseUp
|
||||
to_state: Selected1
|
||||
- from_state: EditLabel
|
||||
label: onKeyDown
|
||||
to_state: Selected2
|
||||
- from_state: EditLabel
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Move
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Move
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Placing
|
||||
label: onMouseDown
|
||||
to_state: Resize
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: CornerSelected
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Ready
|
||||
label: onNewGroup
|
||||
to_state: Placing
|
||||
- from_state: Resize
|
||||
label: onMouseUp
|
||||
to_state: Selected1
|
||||
- from_state: Selected1
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected1
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Selected2
|
||||
label: onKeyDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Selected3
|
||||
- from_state: Selected2
|
||||
label: onNewGroup
|
||||
to_state: Ready
|
||||
- from_state: Selected3
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected3
|
||||
label: onMouseUp
|
||||
to_state: ContextMenu
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 46 KiB |
@@ -1,25 +0,0 @@
|
||||
finite_state_machine_id: 1
|
||||
name: hotkeys_fsm
|
||||
states:
|
||||
- id: 2
|
||||
label: Enabled
|
||||
x: 585
|
||||
y: 396
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 585
|
||||
y: 160
|
||||
- id: 3
|
||||
label: Disabled
|
||||
x: 331
|
||||
y: 408
|
||||
transitions:
|
||||
- from_state: Enabled
|
||||
label: onDisable
|
||||
to_state: Disabled
|
||||
- from_state: Disabled
|
||||
label: onEnable
|
||||
to_state: Enabled
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Enabled
|
||||
|
Before Width: | Height: | Size: 161 KiB |
@@ -1,38 +0,0 @@
|
||||
diagram_id: 68
|
||||
finite_state_machine_id: 18
|
||||
name: diagram
|
||||
states:
|
||||
- id: 1
|
||||
label: Enabled
|
||||
x: 842
|
||||
y: 533
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 839
|
||||
y: 270
|
||||
- id: 3
|
||||
label: Disabled
|
||||
x: 1412
|
||||
y: 522
|
||||
transitions:
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Enabled
|
||||
- from_state: Disabled
|
||||
label: onBindDocument
|
||||
to_state: Enabled
|
||||
- from_state: Enabled
|
||||
label: onUnbindDocument
|
||||
to_state: Disabled
|
||||
- from_state: Disabled
|
||||
label: onDetailsPanelClose
|
||||
to_state: Enabled
|
||||
- from_state: Enabled
|
||||
label: onDetailsPanel
|
||||
to_state: Disabled
|
||||
- from_state: Enabled
|
||||
label: onSearchDropdown
|
||||
to_state: Disabled
|
||||
- from_state: Disabled
|
||||
label: onSearchDropdownClose
|
||||
to_state: Enabled
|
||||
|
Before Width: | Height: | Size: 42 KiB |
@@ -1,42 +0,0 @@
|
||||
finite_state_machine_id: 4
|
||||
name: link_fsm
|
||||
states:
|
||||
- id: 5
|
||||
label: Selecting
|
||||
x: -429
|
||||
y: 63
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 15
|
||||
y: -221
|
||||
- id: 4
|
||||
label: Connecting
|
||||
x: -429
|
||||
y: 466
|
||||
- id: 3
|
||||
label: Connected
|
||||
x: 47
|
||||
y: 453
|
||||
- id: 1
|
||||
label: Ready
|
||||
x: 26
|
||||
y: 61
|
||||
transitions:
|
||||
- from_state: Ready
|
||||
label: onNewLink
|
||||
to_state: Selecting
|
||||
- from_state: Selecting
|
||||
label: onMouseUp
|
||||
to_state: Connecting
|
||||
- from_state: Connecting
|
||||
label: onMouseUp
|
||||
to_state: Connected
|
||||
- from_state: Connecting
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
- from_state: Connected
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 53 KiB |
@@ -1,96 +0,0 @@
|
||||
diagram_id: 68
|
||||
finite_state_machine_id: 9
|
||||
name: mode_fsm
|
||||
states:
|
||||
- id: 7
|
||||
label: Device
|
||||
x: 558
|
||||
y: 821
|
||||
- id: 2
|
||||
label: Interface
|
||||
x: 340
|
||||
y: 1053
|
||||
- id: 5
|
||||
label: MultiSite
|
||||
x: 569
|
||||
y: -88
|
||||
- id: 4
|
||||
label: Process
|
||||
x: 833
|
||||
y: 1051
|
||||
- id: 6
|
||||
label: Rack
|
||||
x: 571
|
||||
y: 486
|
||||
- id: 3
|
||||
label: Site
|
||||
x: 564
|
||||
y: 201
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 568
|
||||
y: -379
|
||||
transitions:
|
||||
- from_state: Device
|
||||
label: onMouseWheel
|
||||
to_state: Process
|
||||
- from_state: Device
|
||||
label: onMouseWheel
|
||||
to_state: Rack
|
||||
- from_state: Device
|
||||
label: onMouseWheel
|
||||
to_state: Interface
|
||||
- from_state: Device
|
||||
label: onScaleChanged
|
||||
to_state: Interface
|
||||
- from_state: Device
|
||||
label: onScaleChanged
|
||||
to_state: Rack
|
||||
- from_state: Device
|
||||
label: onScaleChanged
|
||||
to_state: Process
|
||||
- from_state: Interface
|
||||
label: onMouseWheel
|
||||
to_state: Device
|
||||
- from_state: Interface
|
||||
label: onScaleChanged
|
||||
to_state: Device
|
||||
- from_state: MultiSite
|
||||
label: onMouseWheel
|
||||
to_state: Site
|
||||
- from_state: MultiSite
|
||||
label: onScaleChanged
|
||||
to_state: Site
|
||||
- from_state: Process
|
||||
label: onMouseWheel
|
||||
to_state: Device
|
||||
- from_state: Process
|
||||
label: onScaleChanged
|
||||
to_state: Device
|
||||
- from_state: Rack
|
||||
label: onMouseWheel
|
||||
to_state: Site
|
||||
- from_state: Rack
|
||||
label: onMouseWheel
|
||||
to_state: Device
|
||||
- from_state: Rack
|
||||
label: onScaleChanged
|
||||
to_state: Site
|
||||
- from_state: Rack
|
||||
label: onScaleChanged
|
||||
to_state: Device
|
||||
- from_state: Site
|
||||
label: onMouseWheel
|
||||
to_state: MultiSite
|
||||
- from_state: Site
|
||||
label: onMouseWheel
|
||||
to_state: Rack
|
||||
- from_state: Site
|
||||
label: onScaleChanged
|
||||
to_state: MultiSite
|
||||
- from_state: Site
|
||||
label: onScaleChanged
|
||||
to_state: Rack
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: MultiSite
|
||||
|
Before Width: | Height: | Size: 329 KiB |
|
Before Width: | Height: | Size: 148 KiB |
@@ -1,65 +0,0 @@
|
||||
diagram_id: 91
|
||||
name: diagram
|
||||
states:
|
||||
- id: 0
|
||||
label: ContextMenu
|
||||
x: 826
|
||||
y: 1008
|
||||
- id: 1
|
||||
label: Disable
|
||||
x: 914
|
||||
y: 115
|
||||
- id: 5
|
||||
label: Ready
|
||||
x: 702
|
||||
y: 327
|
||||
- id: 6
|
||||
label: Selected1
|
||||
x: 397
|
||||
y: 332
|
||||
- id: 7
|
||||
label: Selected2
|
||||
x: 268
|
||||
y: 735
|
||||
- id: 8
|
||||
label: Selected3
|
||||
x: 225
|
||||
y: 1021
|
||||
- id: 9
|
||||
label: Start
|
||||
x: 704
|
||||
y: 128
|
||||
transitions:
|
||||
- from_state: ContextMenu
|
||||
label: onDetailsPanel
|
||||
to_state: Selected2
|
||||
- from_state: ContextMenu
|
||||
label: onMouseDown
|
||||
to_state: Selected2
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Selected1
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Selected2
|
||||
label: onKeyDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Selected3
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected3
|
||||
label: ''
|
||||
to_state: Selected3
|
||||
- from_state: Selected3
|
||||
label: onMouseMove
|
||||
to_state: Selected2
|
||||
- from_state: Selected3
|
||||
label: onMouseUp
|
||||
to_state: ContextMenu
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
@@ -1,107 +0,0 @@
|
||||
diagram_id: 87
|
||||
name: move
|
||||
states:
|
||||
- id: 8
|
||||
label: ContextMenu
|
||||
x: 826
|
||||
y: 1008
|
||||
- id: 0
|
||||
label: Disable
|
||||
x: 914
|
||||
y: 115
|
||||
- id: 6
|
||||
label: EditLabel
|
||||
x: 765
|
||||
y: 684
|
||||
- id: 4
|
||||
label: Move
|
||||
x: 118
|
||||
y: 594
|
||||
- id: 5
|
||||
label: Placing
|
||||
x: 263
|
||||
y: 89
|
||||
- id: 2
|
||||
label: Ready
|
||||
x: 702
|
||||
y: 327
|
||||
- id: 3
|
||||
label: Selected1
|
||||
x: 397
|
||||
y: 332
|
||||
- id: 7
|
||||
label: Selected2
|
||||
x: 268
|
||||
y: 735
|
||||
- id: 9
|
||||
label: Selected3
|
||||
x: 361
|
||||
y: 961
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 704
|
||||
y: 128
|
||||
transitions:
|
||||
- from_state: ContextMenu
|
||||
label: onDetailsPanel
|
||||
to_state: Selected2
|
||||
- from_state: ContextMenu
|
||||
label: onLabelEdit
|
||||
to_state: EditLabel
|
||||
- from_state: ContextMenu
|
||||
label: onMouseDown
|
||||
to_state: Selected2
|
||||
- from_state: EditLabel
|
||||
label: onKeyDown
|
||||
to_state: Selected2
|
||||
- from_state: EditLabel
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Move
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Move
|
||||
label: onMouseUp
|
||||
to_state: Selected1
|
||||
- from_state: Placing
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Placing
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Ready
|
||||
label: onNewDevice
|
||||
to_state: Placing
|
||||
- from_state: Ready
|
||||
label: onPasteDevice
|
||||
to_state: Selected2
|
||||
- from_state: Selected1
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected1
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Selected2
|
||||
label: onKeyDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Selected3
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onNewDevice
|
||||
to_state: Ready
|
||||
- from_state: Selected3
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected3
|
||||
label: onMouseUp
|
||||
to_state: ContextMenu
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 32 KiB |
@@ -1,15 +0,0 @@
|
||||
finite_state_machine_id: 17
|
||||
name: null_fsm
|
||||
states:
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 391
|
||||
y: 132
|
||||
- id: 2
|
||||
label: Ready
|
||||
x: 402
|
||||
y: 346
|
||||
transitions:
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 141 KiB |
@@ -1,233 +0,0 @@
|
||||
channels:
|
||||
- from_fsm: buttons_fsm
|
||||
from_fsm_id: 7
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: button_fsm
|
||||
to_fsm_id: 12
|
||||
type: ''
|
||||
- from_fsm: buttons_fsm
|
||||
from_fsm_id: 7
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: toolbox_fsm
|
||||
to_fsm_id: 14
|
||||
type: ''
|
||||
- from_fsm: details_panel_fsm
|
||||
from_fsm_id: 21
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: move_fsm
|
||||
to_fsm_id: 3
|
||||
type: ''
|
||||
- from_fsm: device_detail_fsm
|
||||
from_fsm_id: 19
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: view_fsm
|
||||
to_fsm_id: 2
|
||||
type: ''
|
||||
- from_fsm: group_fsm
|
||||
from_fsm_id: 5
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: stream_fsm
|
||||
to_fsm_id: 20
|
||||
type: ''
|
||||
- from_fsm: hotkeys_fsm
|
||||
from_fsm_id: 1
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: null_fsm
|
||||
to_fsm_id: 17
|
||||
type: ''
|
||||
- from_fsm: keybindings_fsm
|
||||
from_fsm_id: 18
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: hotkeys_fsm
|
||||
to_fsm_id: 1
|
||||
type: ''
|
||||
- from_fsm: link_fsm
|
||||
from_fsm_id: 4
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: details_panel_fsm
|
||||
to_fsm_id: 21
|
||||
type: ''
|
||||
- from_fsm: mode_fsm
|
||||
from_fsm_id: 9
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: time_fsm
|
||||
to_fsm_id: 8
|
||||
type: ''
|
||||
- from_fsm: move_fsm
|
||||
from_fsm_id: 3
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: device_detail_fsm
|
||||
to_fsm_id: 19
|
||||
type: ''
|
||||
- from_fsm: rack_fsm
|
||||
from_fsm_id: 6
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: group_fsm
|
||||
to_fsm_id: 5
|
||||
type: ''
|
||||
- from_fsm: site_fsm
|
||||
from_fsm_id: 22
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: rack_fsm
|
||||
to_fsm_id: 6
|
||||
type: ''
|
||||
- from_fsm: stream_fsm
|
||||
from_fsm_id: 20
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: link_fsm
|
||||
to_fsm_id: 4
|
||||
type: ''
|
||||
- from_fsm: test_fsm
|
||||
from_fsm_id: 23
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: mode_fsm
|
||||
to_fsm_id: 9
|
||||
type: ''
|
||||
- from_fsm: time_fsm
|
||||
from_fsm_id: 8
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: buttons_fsm
|
||||
to_fsm_id: 7
|
||||
type: ''
|
||||
- from_fsm: toolbox_fsm
|
||||
from_fsm_id: 14
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: site_fsm
|
||||
to_fsm_id: 22
|
||||
type: ''
|
||||
- from_fsm: view_fsm
|
||||
from_fsm_id: 2
|
||||
inbox: ''
|
||||
outbox: ''
|
||||
to_fsm: keybindings_fsm
|
||||
to_fsm_id: 18
|
||||
type: ''
|
||||
diagram_id: 85
|
||||
fsms:
|
||||
- id: 12
|
||||
name: button_fsm
|
||||
x1: -2438
|
||||
x2: -3026
|
||||
y1: -934
|
||||
y2: -1532
|
||||
- id: 7
|
||||
name: buttons_fsm
|
||||
x1: -2650
|
||||
x2: -2850
|
||||
y1: -16
|
||||
y2: -619
|
||||
- id: 21
|
||||
name: details_panel_fsm
|
||||
x1: 5669
|
||||
x2: 5140
|
||||
y1: -64
|
||||
y2: -521
|
||||
- id: 19
|
||||
name: device_detail_fsm
|
||||
x1: 7667
|
||||
x2: 7214
|
||||
y1: -110
|
||||
y2: -562
|
||||
- id: 5
|
||||
name: group_fsm
|
||||
x1: 3685
|
||||
x2: 2256
|
||||
y1: 278
|
||||
y2: -906
|
||||
- id: 1
|
||||
name: hotkeys_fsm
|
||||
x1: 9692
|
||||
x2: 9281
|
||||
y1: -124
|
||||
y2: -549
|
||||
- id: 18
|
||||
name: keybindings_fsm
|
||||
x1: 9223
|
||||
x2: 8370
|
||||
y1: -71
|
||||
y2: -614
|
||||
- id: 4
|
||||
name: link_fsm
|
||||
x1: 5080
|
||||
x2: 4436
|
||||
y1: 154
|
||||
y2: -732
|
||||
- id: 9
|
||||
name: mode_fsm
|
||||
x1: -3760
|
||||
x2: -4453
|
||||
y1: 192
|
||||
y2: -1439
|
||||
- id: 3
|
||||
name: move_fsm
|
||||
x1: 6968
|
||||
x2: 5813
|
||||
y1: 146
|
||||
y2: -935
|
||||
- id: 17
|
||||
name: null_fsm
|
||||
x1: 10125
|
||||
x2: 9925
|
||||
y1: -129
|
||||
y2: -543
|
||||
- id: 6
|
||||
name: rack_fsm
|
||||
x1: 2214
|
||||
x2: 1047
|
||||
y1: 127
|
||||
y2: -753
|
||||
- id: 22
|
||||
name: site_fsm
|
||||
x1: 964
|
||||
x2: -190
|
||||
y1: 128
|
||||
y2: -768
|
||||
- id: 20
|
||||
name: stream_fsm
|
||||
x1: 4376
|
||||
x2: 3868
|
||||
y1: 56
|
||||
y2: -643
|
||||
- id: 23
|
||||
name: test_fsm
|
||||
x1: -4569
|
||||
x2: -5140
|
||||
y1: 72
|
||||
y2: -863
|
||||
- id: 8
|
||||
name: time_fsm
|
||||
x1: -3122
|
||||
x2: -3693
|
||||
y1: -69
|
||||
y2: -553
|
||||
- id: 14
|
||||
name: toolbox_fsm
|
||||
x1: -680
|
||||
x2: -1722
|
||||
y1: 265
|
||||
y2: -904
|
||||
- id: 2
|
||||
name: view_fsm
|
||||
x1: 8311
|
||||
x2: 7734
|
||||
y1: -25
|
||||
y2: -684
|
||||
name: diagram
|
||||
states: []
|
||||
transitions: []
|
||||
|
Before Width: | Height: | Size: 102 KiB |
@@ -1,83 +0,0 @@
|
||||
diagram_id: 65
|
||||
finite_state_machine_id: 6
|
||||
name: rack_fsm
|
||||
states:
|
||||
- id: 9
|
||||
label: ContextMenu
|
||||
x: 898
|
||||
y: 1016
|
||||
- id: 2
|
||||
label: Disable
|
||||
x: 760
|
||||
y: 468
|
||||
- id: 7
|
||||
label: EditLabel
|
||||
x: 600
|
||||
y: 934
|
||||
- id: 8
|
||||
label: Move
|
||||
x: -69
|
||||
y: 861
|
||||
- id: 1
|
||||
label: Ready
|
||||
x: 532
|
||||
y: 560
|
||||
- id: 4
|
||||
label: Selected1
|
||||
x: 214
|
||||
y: 566
|
||||
- id: 5
|
||||
label: Selected2
|
||||
x: 220
|
||||
y: 810
|
||||
- id: 6
|
||||
label: Selected3
|
||||
x: 249
|
||||
y: 1047
|
||||
- id: 3
|
||||
label: Start
|
||||
x: 582
|
||||
y: 334
|
||||
transitions:
|
||||
- from_state: ContextMenu
|
||||
label: onLabelEdit
|
||||
to_state: EditLabel
|
||||
- from_state: ContextMenu
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: EditLabel
|
||||
label: onKeyDown
|
||||
to_state: Selected2
|
||||
- from_state: EditLabel
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Move
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Selected1
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected1
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Selected2
|
||||
label: onKeyDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Selected3
|
||||
- from_state: Selected3
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected3
|
||||
label: onMouseUp
|
||||
to_state: ContextMenu
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 104 KiB |
@@ -1,83 +0,0 @@
|
||||
diagram_id: 63
|
||||
finite_state_machine_id: 22
|
||||
name: site_fsm
|
||||
states:
|
||||
- id: 9
|
||||
label: ContextMenu
|
||||
x: 887
|
||||
y: 1031
|
||||
- id: 2
|
||||
label: Disable
|
||||
x: 760
|
||||
y: 468
|
||||
- id: 7
|
||||
label: EditLabel
|
||||
x: 600
|
||||
y: 934
|
||||
- id: 8
|
||||
label: Move
|
||||
x: -69
|
||||
y: 861
|
||||
- id: 1
|
||||
label: Ready
|
||||
x: 532
|
||||
y: 560
|
||||
- id: 4
|
||||
label: Selected1
|
||||
x: 214
|
||||
y: 566
|
||||
- id: 5
|
||||
label: Selected2
|
||||
x: 220
|
||||
y: 810
|
||||
- id: 6
|
||||
label: Selected3
|
||||
x: 249
|
||||
y: 1047
|
||||
- id: 3
|
||||
label: Start
|
||||
x: 582
|
||||
y: 334
|
||||
transitions:
|
||||
- from_state: ContextMenu
|
||||
label: onLabelEdit
|
||||
to_state: EditLabel
|
||||
- from_state: ContextMenu
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: EditLabel
|
||||
label: onKeyDown
|
||||
to_state: Selected2
|
||||
- from_state: EditLabel
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Move
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selected1
|
||||
- from_state: Selected1
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected1
|
||||
label: onMouseUp
|
||||
to_state: Selected2
|
||||
- from_state: Selected2
|
||||
label: onKeyDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected2
|
||||
label: onMouseDown
|
||||
to_state: Selected3
|
||||
- from_state: Selected3
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selected3
|
||||
label: onMouseUp
|
||||
to_state: ContextMenu
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
|
Before Width: | Height: | Size: 75 KiB |
@@ -1,42 +0,0 @@
|
||||
finite_state_machine_id: 20
|
||||
name: stream_fsm
|
||||
states:
|
||||
- id: 4
|
||||
label: Connecting
|
||||
x: 344
|
||||
y: 312
|
||||
- id: 5
|
||||
label: Selecting
|
||||
x: 311
|
||||
y: 23
|
||||
- id: 1
|
||||
label: Ready
|
||||
x: 36
|
||||
y: 28
|
||||
- id: 3
|
||||
label: Connected
|
||||
x: 55
|
||||
y: 317
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 43
|
||||
y: -188
|
||||
transitions:
|
||||
- from_state: Ready
|
||||
label: onNewStream
|
||||
to_state: Selecting
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Connected
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Connecting
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
- from_state: Connecting
|
||||
label: onMouseUp
|
||||
to_state: Connected
|
||||
- from_state: Selecting
|
||||
label: onMouseUp
|
||||
to_state: Connecting
|
||||
@@ -1,50 +0,0 @@
|
||||
diagram_id: 69
|
||||
finite_state_machine_id: 23
|
||||
name: diagram
|
||||
states:
|
||||
- id: 1
|
||||
label: Disabled
|
||||
x: 895
|
||||
y: 344
|
||||
- id: 4
|
||||
label: Loading
|
||||
x: 524
|
||||
y: 710
|
||||
- id: 5
|
||||
label: Ready
|
||||
x: 722
|
||||
y: 509
|
||||
- id: 6
|
||||
label: Reporting
|
||||
x: 926
|
||||
y: 721
|
||||
- id: 3
|
||||
label: Running
|
||||
x: 720
|
||||
y: 922
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 702
|
||||
y: 186
|
||||
transitions:
|
||||
- from_state: Disabled
|
||||
label: onEnableTest
|
||||
to_state: Ready
|
||||
- from_state: Loading
|
||||
label: start
|
||||
to_state: Running
|
||||
- from_state: Ready
|
||||
label: onDisableTest
|
||||
to_state: Disabled
|
||||
- from_state: Ready
|
||||
label: start
|
||||
to_state: Loading
|
||||
- from_state: Reporting
|
||||
label: start
|
||||
to_state: Loading
|
||||
- from_state: Running
|
||||
label: onTestCompleted
|
||||
to_state: Reporting
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Disabled
|
||||
|
Before Width: | Height: | Size: 68 KiB |
@@ -1,37 +0,0 @@
|
||||
finite_state_machine_id: 8
|
||||
name: time_fsm
|
||||
states:
|
||||
- id: 1
|
||||
label: Present
|
||||
x: 256
|
||||
y: 123
|
||||
- id: 2
|
||||
label: Start
|
||||
x: 245
|
||||
y: -161
|
||||
- id: 3
|
||||
label: Past
|
||||
x: -115
|
||||
y: 129
|
||||
transitions:
|
||||
- from_state: Past
|
||||
label: onRedo
|
||||
to_state: Present
|
||||
- from_state: Past
|
||||
label: onMouseWheel
|
||||
to_state: Present
|
||||
- from_state: Past
|
||||
label: onKeyDown
|
||||
to_state: Present
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Present
|
||||
- from_state: Present
|
||||
label: onUndo
|
||||
to_state: Past
|
||||
- from_state: Present
|
||||
label: onMouseWheel
|
||||
to_state: Past
|
||||
- from_state: Present
|
||||
label: onKeyDown
|
||||
to_state: Past
|
||||
|
Before Width: | Height: | Size: 58 KiB |
@@ -1,98 +0,0 @@
|
||||
finite_state_machine_id: 14
|
||||
name: toolbox_fsm
|
||||
states:
|
||||
- id: 9
|
||||
label: Disabled
|
||||
x: 885
|
||||
y: 141
|
||||
- id: 7
|
||||
label: OffScreen
|
||||
x: 1140
|
||||
y: 217
|
||||
- id: 1
|
||||
label: Selected
|
||||
x: 1180
|
||||
y: 959
|
||||
- id: 2
|
||||
label: Move
|
||||
x: 1409
|
||||
y: 741
|
||||
- id: 3
|
||||
label: Ready
|
||||
x: 892
|
||||
y: 429
|
||||
- id: 4
|
||||
label: Scrolling
|
||||
x: 567
|
||||
y: 431
|
||||
- id: 5
|
||||
label: Selecting
|
||||
x: 888
|
||||
y: 710
|
||||
- id: 6
|
||||
label: Dropping
|
||||
x: 1358
|
||||
y: 431
|
||||
- id: 8
|
||||
label: Start
|
||||
x: 672
|
||||
y: 196
|
||||
- id: 10
|
||||
label: OffScreen2
|
||||
x: 1115
|
||||
y: -12
|
||||
transitions:
|
||||
- from_state: Ready
|
||||
label: onDisable
|
||||
to_state: Disabled
|
||||
- from_state: OffScreen2
|
||||
label: onToggleToolbox
|
||||
to_state: Disabled
|
||||
- from_state: OffScreen2
|
||||
label: onEnable
|
||||
to_state: OffScreen
|
||||
- from_state: Ready
|
||||
label: onToggleToolbox
|
||||
to_state: OffScreen
|
||||
- from_state: Selecting
|
||||
label: onMouseDown
|
||||
to_state: Selected
|
||||
- from_state: Selected
|
||||
label: onMouseMove
|
||||
to_state: Move
|
||||
- from_state: Selecting
|
||||
label: onMouseDown
|
||||
to_state: Ready
|
||||
- from_state: Selected
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
- from_state: Dropping
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Scrolling
|
||||
label: onMouseWheel
|
||||
to_state: Ready
|
||||
- from_state: OffScreen
|
||||
label: onToggleToolbox
|
||||
to_state: Ready
|
||||
- from_state: Disabled
|
||||
label: onEnable
|
||||
to_state: Ready
|
||||
- from_state: Ready
|
||||
label: onMouseWheel
|
||||
to_state: Scrolling
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Selecting
|
||||
- from_state: Move
|
||||
label: onMouseUp
|
||||
to_state: Dropping
|
||||
- from_state: OffScreen
|
||||
label: onDisable
|
||||
to_state: OffScreen2
|
||||
- from_state: Disabled
|
||||
label: onToggleToolbox
|
||||
to_state: OffScreen2
|
||||
|
Before Width: | Height: | Size: 69 KiB |
@@ -1,45 +0,0 @@
|
||||
finite_state_machine_id: 2
|
||||
name: view_fsm
|
||||
states:
|
||||
- id: 1
|
||||
label: Start
|
||||
x: 498
|
||||
y: 175
|
||||
- id: 2
|
||||
label: Ready
|
||||
x: 506
|
||||
y: 395
|
||||
- id: 3
|
||||
label: Scale
|
||||
x: 310
|
||||
y: 626
|
||||
- id: 4
|
||||
label: Pan
|
||||
x: 741
|
||||
y: 631
|
||||
- id: 5
|
||||
label: Pressed
|
||||
x: 739
|
||||
y: 392
|
||||
transitions:
|
||||
- from_state: Scale
|
||||
label: onMouseWheel
|
||||
to_state: Ready
|
||||
- from_state: Start
|
||||
label: start
|
||||
to_state: Ready
|
||||
- from_state: Ready
|
||||
label: onMouseWheel
|
||||
to_state: Scale
|
||||
- from_state: Ready
|
||||
label: onMouseDown
|
||||
to_state: Pressed
|
||||
- from_state: Pressed
|
||||
label: onMouseMove
|
||||
to_state: Pan
|
||||
- from_state: Pressed
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
- from_state: Pan
|
||||
label: onMouseUp
|
||||
to_state: Ready
|
||||
@@ -1,62 +0,0 @@
|
||||
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 _Collapsed () {
|
||||
this.name = 'Collapsed';
|
||||
}
|
||||
inherits(_Collapsed, _State);
|
||||
var Collapsed = new _Collapsed();
|
||||
exports.Collapsed = Collapsed;
|
||||
|
||||
function _Expanded () {
|
||||
this.name = 'Expanded';
|
||||
}
|
||||
inherits(_Expanded, _State);
|
||||
var Expanded = new _Expanded();
|
||||
exports.Expanded = Expanded;
|
||||
|
||||
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller, msg_type, $event) {
|
||||
|
||||
controller.scope.$parent.vm.rightPanelIsExpanded = false;
|
||||
controller.changeState(Collapsed);
|
||||
controller.handle_message(msg_type, $event);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Collapsed'];
|
||||
|
||||
|
||||
|
||||
_Collapsed.prototype.onDetailsPanel = function (controller, msg_type, $event) {
|
||||
|
||||
controller.scope.$parent.vm.rightPanelIsExpanded = true;
|
||||
controller.changeState(Expanded);
|
||||
controller.handle_message(msg_type, $event);
|
||||
|
||||
};
|
||||
_Collapsed.prototype.onDetailsPanel.transitions = ['Expanded'];
|
||||
|
||||
|
||||
|
||||
_Expanded.prototype.onDetailsPanelClose = function (controller, msg_type, $event) {
|
||||
|
||||
controller.scope.$parent.vm.rightPanelIsExpanded = false;
|
||||
controller.scope.$parent.vm.keyPanelExpanded = false;
|
||||
controller.changeState(Collapsed);
|
||||
controller.handle_message(msg_type, $event);
|
||||
};
|
||||
_Expanded.prototype.onDetailsPanelClose.transitions = ['Collapsed'];
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
var YAML = require('yamljs');
|
||||
|
||||
function Iterator(o){
|
||||
var k=Object.keys(o);
|
||||
return {
|
||||
next:function(){
|
||||
return k.shift();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var myArgs = process.argv.slice(2);
|
||||
var implementation = require(myArgs[0]);
|
||||
var states = [];
|
||||
var transitions = [];
|
||||
var data = {states: states,
|
||||
transitions: transitions};
|
||||
|
||||
var state_iter = Iterator(implementation);
|
||||
var transition_iter = null;
|
||||
var next_state = state_iter.next();
|
||||
var next_transition = null;
|
||||
var state = null;
|
||||
var transition = null;
|
||||
var i = 0;
|
||||
while(next_state !== undefined) {
|
||||
state = implementation[next_state];
|
||||
transition_iter = Iterator(state.constructor.prototype);
|
||||
next_transition = transition_iter.next();
|
||||
while (next_transition !== undefined) {
|
||||
transition = state.constructor.prototype[next_transition];
|
||||
if (transition.transitions !== undefined) {
|
||||
for (i = 0; i < transition.transitions.length; i++) {
|
||||
transitions.push({from_state: next_state,
|
||||
to_state:transition.transitions[i],
|
||||
label:next_transition});
|
||||
}
|
||||
}
|
||||
next_transition = transition_iter.next();
|
||||
}
|
||||
states.push({label: state.name});
|
||||
next_state = state_iter.next();
|
||||
}
|
||||
|
||||
|
||||
console.log(YAML.stringify(data));
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
var YAML = require('yamljs');
|
||||
|
||||
function Iterator(o){
|
||||
var k=Object.keys(o);
|
||||
return {
|
||||
next:function(){
|
||||
return k.shift();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var myArgs = process.argv.slice(2);
|
||||
var implementation = require(myArgs[0]);
|
||||
var messages = [];
|
||||
var data = {messages: messages};
|
||||
var message_iter = Iterator(implementation);
|
||||
var field_iter = null;
|
||||
var next_message = message_iter.next();
|
||||
var next_field = null;
|
||||
var message = null;
|
||||
var message_instance = null;
|
||||
var fields = null;
|
||||
// var field = null;
|
||||
// var i = 0;
|
||||
while(next_message !== undefined) {
|
||||
message = implementation[next_message];
|
||||
try {
|
||||
message_instance = new message();
|
||||
} catch(err) {
|
||||
next_message = message_iter.next();
|
||||
continue;
|
||||
}
|
||||
fields = [];
|
||||
field_iter = Iterator(message_instance);
|
||||
next_field = field_iter.next();
|
||||
while (next_field !== undefined) {
|
||||
fields.push(next_field);
|
||||
// field = message.constructor.prototype[next_field];
|
||||
// if (field.transitions !== undefined) {
|
||||
// for (i = 0; i < field.transitions.length; i++) {
|
||||
// transitions.push({from_message: next_message,
|
||||
// to_message:field.transitions[i],
|
||||
// label:next_field});
|
||||
// }
|
||||
// }
|
||||
next_field = field_iter.next();
|
||||
}
|
||||
if(message_instance.msg_type !== null && message_instance.msg_type !== undefined) {
|
||||
messages.push({msg_type: message_instance.msg_type,
|
||||
fields: fields});
|
||||
}
|
||||
next_message = message_iter.next();
|
||||
}
|
||||
|
||||
|
||||
console.log(YAML.stringify(data));
|
||||
@@ -1,91 +0,0 @@
|
||||
/* 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) {
|
||||
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() {
|
||||
};
|
||||
|
||||
function FSMController (scope, name, initial_state, tracer, log) {
|
||||
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;
|
||||
this.log = log;
|
||||
}
|
||||
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;
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/host.partial.svg');
|
||||
|
||||
function host () {
|
||||
return { restrict: 'A', templateUrl};
|
||||
}
|
||||
exports.host = host;
|
||||
@@ -1,91 +0,0 @@
|
||||
<!-- Copyright (c) 2017 Red Hat, Inc. -->
|
||||
<g transform="scale(0.75)">
|
||||
<g ng-if="item.moving">
|
||||
<!--horizontal line -->
|
||||
<line x1="-150"
|
||||
y1="0"
|
||||
x2="150"
|
||||
y2="0"
|
||||
class="NetworkUI--construction">
|
||||
</line>
|
||||
<!-- end horizontal line -->
|
||||
|
||||
<!-- vertical line -->
|
||||
<line x1="0"
|
||||
y1="-150"
|
||||
x2="0"
|
||||
y2="150"
|
||||
class="NetworkUI--construction">
|
||||
</line>
|
||||
<!-- end vertical line -->
|
||||
</g>
|
||||
|
||||
<g ng-if="!debug.hidden">
|
||||
<!--horizontal line -->
|
||||
<line x1="-60"
|
||||
y1="0"
|
||||
x2="60"
|
||||
y2="0"
|
||||
class="NetworkUI--debug">
|
||||
</line>
|
||||
<!-- end horizontal line -->
|
||||
|
||||
<!-- vertical line -->
|
||||
<line x1="0"
|
||||
y1="-40"
|
||||
x2="0"
|
||||
y2="40"
|
||||
class="NetworkUI--debug">
|
||||
</line>
|
||||
<!-- end vertical line -->
|
||||
|
||||
<!-- debug rectangle -->
|
||||
<rect x="-50"
|
||||
y="-30"
|
||||
width="100"
|
||||
height="60"
|
||||
class="NetworkUI--debug">
|
||||
</rect>
|
||||
<!-- end debug rectangle -->
|
||||
</g>
|
||||
<g transform="translate(-50,-30)">
|
||||
<rect
|
||||
ry=20
|
||||
rx=20
|
||||
width=100
|
||||
height=60
|
||||
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__host--background'}}">
|
||||
</rect>
|
||||
<g transform="scale(2)">
|
||||
<path
|
||||
class="NetworkUI__host"
|
||||
d="M17.8,14.7c-0.3,0-0.6,0.2-0.6,0.6c0,0.3,0.2,0.6,0.6,0.6c0.3,0,0.6-0.2,0.6-0.6S18.1,14.7,17.8,14.7z"/>
|
||||
<path
|
||||
class="NetworkUI__host"
|
||||
d="M40.8,0H9.2C4.2,0,0,4.2,0,9.2v11.5C0,25.8,4.2,30,9.2,30h31.5c5.1,0,9.2-4.2,9.2-9.2V9.2
|
||||
C50,4.2,45.8,0,40.8,0z M37.8,17.9c0,1-0.8,1.8-1.8,1.8H14c-1,0-1.8-0.8-1.8-1.8V13c0-1,0.8-1.8,1.8-1.8h22c1,0,1.8,0.8,1.8,1.8
|
||||
V17.9z"/>
|
||||
<path
|
||||
class="NetworkUI__host"
|
||||
d="M36,12.5H14c-0.3,0-0.4,0.2-0.4,0.4v4.9c0,0.3,0.2,0.4,0.4,0.4h22c0.3,0,0.4-0.2,0.4-0.4v-4.9
|
||||
C36.4,12.7,36.3,12.5,36,12.5z M17.8,17.2c-1.1,0-1.9-0.9-1.9-1.9c0-1.1,0.9-1.9,1.9-1.9s1.9,0.9,1.9,1.9S18.9,17.2,17.8,17.2z
|
||||
M28.2,17.1h-0.9c-0.3,0-0.6-0.2-0.6-0.6s0.2-0.6,0.6-0.6h0.9c0.4,0,0.6,0.2,0.6,0.6C28.8,16.8,28.6,17.1,28.2,17.1z M28.2,14.9
|
||||
h-0.9c-0.3,0-0.6-0.2-0.6-0.6c0-0.4,0.2-0.6,0.6-0.6h0.9c0.4,0,0.6,0.2,0.6,0.6C28.8,14.7,28.6,14.9,28.2,14.9z M30.9,17.1H30
|
||||
c-0.3,0-0.6-0.2-0.6-0.6s0.2-0.6,0.6-0.6h0.9c0.4,0,0.6,0.2,0.6,0.6C31.5,16.8,31.3,17.1,30.9,17.1z M30.9,14.9H30
|
||||
c-0.3,0-0.6-0.2-0.6-0.6c0-0.4,0.2-0.6,0.6-0.6h0.9c0.4,0,0.6,0.2,0.6,0.6S31.3,14.9,30.9,14.9z M33.6,17.1h-0.9
|
||||
c-0.4,0-0.6-0.2-0.6-0.6s0.2-0.6,0.6-0.6h0.9c0.4,0,0.6,0.2,0.6,0.6C34.2,16.8,33.9,17.1,33.6,17.1z M33.6,14.9h-0.9
|
||||
c-0.4,0-0.6-0.2-0.6-0.6c0-0.4,0.2-0.6,0.6-0.6h0.9c0.4,0,0.6,0.2,0.6,0.6C34.2,14.7,33.9,14.9,33.6,14.9z"/>
|
||||
</g>
|
||||
</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(#background)"
|
||||
text-anchor="middle"
|
||||
x="0"
|
||||
y="50"> <tspan x="0" dy="20" ng-repeat="chunk in item.name|chunk:25">{{chunk}}</tspan>
|
||||
</text>
|
||||
<text class="NetworkUI__host-text" filter="url(#background)" text-anchor="middle" x="0" y="50">
|
||||
<tspan x="0" dy="20" ng-repeat="chunk in item.name|chunk:25">{{chunk}}</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
@@ -1,85 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.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 === 'r' && ($event.ctrlKey || $event.metaKey)) {
|
||||
location.reload();
|
||||
}
|
||||
|
||||
if ($event.key === 'd') {
|
||||
scope.debug.hidden = !scope.debug.hidden;
|
||||
return;
|
||||
}
|
||||
if ($event.key === 'i') {
|
||||
scope.hide_interfaces = !scope.hide_interfaces;
|
||||
return;
|
||||
}
|
||||
if($event.keyCode === 27){
|
||||
// 27 is the escape key
|
||||
scope.reset_fsm_state();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event.key === '0') {
|
||||
scope.jump_to_animation(0, 0, 0.7);
|
||||
}
|
||||
|
||||
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'];
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/inventory_toolbox.partial.svg');
|
||||
|
||||
function inventoryToolbox () {
|
||||
return { restrict: 'A', templateUrl};
|
||||
}
|
||||
exports.inventoryToolbox = inventoryToolbox;
|
||||
@@ -1,98 +0,0 @@
|
||||
<!-- Copyright (c) 2017 Red Hat, Inc. -->
|
||||
<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>
|
||||
|
||||
|
||||
<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-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-default> <!-- begin default -->
|
||||
<g awx-net-default></g>
|
||||
</g> <!-- end default -->
|
||||
</g> <!-- end selected item -->
|
||||
</g> <!-- ng-if -->
|
||||
</g> <!-- ng-if toolbox.enabled -->
|
||||
<text
|
||||
class="NetworkUI__toolbox--title"
|
||||
filter="url(#background)"
|
||||
ng-if="toolbox.enabled"
|
||||
ng-attr-transform="translate({{toolbox.title_coordinates.x}},{{toolbox.title_coordinates.y}})">
|
||||
{{toolbox.name}}
|
||||
</text>
|
||||
</g> <!-- ng-if !hide_menus -->
|
||||
@@ -1,93 +0,0 @@
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
|
||||
function _State () {
|
||||
}
|
||||
inherits(_State, fsm._State);
|
||||
|
||||
|
||||
function _Disabled () {
|
||||
this.name = 'Disabled';
|
||||
}
|
||||
inherits(_Disabled, _State);
|
||||
var Disabled = new _Disabled();
|
||||
exports.Disabled = Disabled;
|
||||
|
||||
function _Start () {
|
||||
this.name = 'Start';
|
||||
}
|
||||
inherits(_Start, _State);
|
||||
var Start = new _Start();
|
||||
exports.Start = Start;
|
||||
|
||||
function _Enabled () {
|
||||
this.name = 'Enabled';
|
||||
}
|
||||
inherits(_Enabled, _State);
|
||||
var Enabled = new _Enabled();
|
||||
exports.Enabled = Enabled;
|
||||
|
||||
|
||||
|
||||
|
||||
_Disabled.prototype.onBindDocument = function (controller) {
|
||||
|
||||
$(document).bind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Enabled);
|
||||
|
||||
};
|
||||
_Disabled.prototype.onBindDocument.transitions = ['Enabled'];
|
||||
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
$(document).bind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Enabled);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Enabled'];
|
||||
|
||||
|
||||
|
||||
_Enabled.prototype.onUnbindDocument = function (controller) {
|
||||
|
||||
$(document).unbind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Disabled);
|
||||
|
||||
};
|
||||
_Enabled.prototype.onUnbindDocument.transitions = ['Disabled'];
|
||||
|
||||
_Disabled.prototype.onDetailsPanelClose = function (controller) {
|
||||
|
||||
$(document).bind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Enabled);
|
||||
|
||||
};
|
||||
_Disabled.prototype.onDetailsPanelClose.transitions = ['Enabled'];
|
||||
|
||||
_Disabled.prototype.onSearchDropdownClose = function (controller) {
|
||||
|
||||
$(document).bind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Enabled);
|
||||
|
||||
};
|
||||
_Disabled.prototype.onSearchDropdownClose.transitions = ['Enabled'];
|
||||
|
||||
|
||||
|
||||
_Enabled.prototype.onDetailsPanel = function (controller) {
|
||||
|
||||
$(document).unbind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Disabled);
|
||||
|
||||
};
|
||||
_Enabled.prototype.onDetailsPanel.transitions = ['Disabled'];
|
||||
|
||||
_Enabled.prototype.onSearchDropdown = function (controller) {
|
||||
|
||||
$(document).unbind("keydown", controller.scope.onKeyDown);
|
||||
controller.changeState(Disabled);
|
||||
|
||||
};
|
||||
_Enabled.prototype.onSearchDropdown.transitions = ['Disabled'];
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/link.partial.svg');
|
||||
|
||||
function link () {
|
||||
return { restrict: 'A', templateUrl};
|
||||
}
|
||||
exports.link = link;
|
||||
@@ -1,128 +0,0 @@
|
||||
<!-- 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 ? 'NetworkUI__interface-text--selected' : 'NetworkUI--hidden'}}"
|
||||
filter="url(#background)"
|
||||
text-anchor="middle"
|
||||
font-size="8"
|
||||
x="0"
|
||||
y="0"> {{link.name}}</text>
|
||||
<text class="NetworkUI__link-text" filter="url(#background)" 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(#background)"
|
||||
text-anchor="middle"
|
||||
font-size="8"
|
||||
x="0"
|
||||
y="0"> {{link.from_interface.name}}</text>
|
||||
<text class="NetworkUI__interface-text" filter="url(#background)" 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(#background)"
|
||||
text-anchor="middle"
|
||||
x="0"
|
||||
y="0"> {{link.to_interface.name}}</text>
|
||||
<text class="NetworkUI__interface-text" filter="url(#background)" 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 -->
|
||||
@@ -1,240 +0,0 @@
|
||||
/* 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, host_id) {
|
||||
this.msg_type = "DeviceCreate";
|
||||
this.sender = sender;
|
||||
this.id = id;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.host_id = host_id;
|
||||
}
|
||||
exports.DeviceCreate = DeviceCreate;
|
||||
|
||||
function DeviceDestroy(sender, id, previous_x, previous_y, previous_name, previous_type, previous_host_id) {
|
||||
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;
|
||||
this.previous_host_id = previous_host_id;
|
||||
}
|
||||
exports.DeviceDestroy = DeviceDestroy;
|
||||
|
||||
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 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 MultipleMessage(sender, messages) {
|
||||
this.msg_type = "MultipleMessage";
|
||||
this.sender = sender;
|
||||
this.messages = messages;
|
||||
}
|
||||
exports.MultipleMessage = MultipleMessage;
|
||||
|
||||
|
||||
function MouseEvent(sender, x, y, type, trace_id) {
|
||||
this.msg_type = "MouseEvent";
|
||||
this.sender = sender;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.type = type;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.MouseEvent = MouseEvent;
|
||||
|
||||
function MouseWheelEvent(sender, delta, deltaX, deltaY, type, metaKey, trace_id) {
|
||||
this.msg_type = "MouseWheelEvent";
|
||||
this.sender = sender;
|
||||
this.delta = delta;
|
||||
this.deltaX = deltaX;
|
||||
this.deltaY = deltaY;
|
||||
this.type = type;
|
||||
this.originalEvent = {metaKey: metaKey};
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.MouseWheelEvent = MouseWheelEvent;
|
||||
|
||||
function KeyEvent(sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey, trace_id) {
|
||||
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;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.KeyEvent = KeyEvent;
|
||||
|
||||
function StartRecording(sender, trace_id) {
|
||||
this.msg_type = "StartRecording";
|
||||
this.sender = sender;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.StartRecording = StartRecording;
|
||||
|
||||
function StopRecording(sender, trace_id) {
|
||||
this.msg_type = "StopRecording";
|
||||
this.sender = sender;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.StopRecording = StopRecording;
|
||||
|
||||
function ViewPort(sender, scale, panX, panY, graph_width, graph_height, trace_id) {
|
||||
this.msg_type = "ViewPort";
|
||||
this.sender = sender;
|
||||
this.scale = scale;
|
||||
this.panX = panX;
|
||||
this.panY = panY;
|
||||
this.graph_width = graph_width;
|
||||
this.graph_height = graph_height;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.ViewPort = ViewPort;
|
||||
|
||||
function PasteDevice(device) {
|
||||
this.device = device;
|
||||
}
|
||||
exports.PasteDevice = PasteDevice;
|
||||
|
||||
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 Snapshot(sender, devices, links, inventory_toolbox, order, trace_id) {
|
||||
this.msg_type = 'Snapshot';
|
||||
this.sender = 0;
|
||||
this.devices = devices;
|
||||
this.links = links;
|
||||
this.inventory_toolbox = inventory_toolbox;
|
||||
this.order = order;
|
||||
this.trace_id = trace_id;
|
||||
}
|
||||
exports.Snapshot = Snapshot;
|
||||
|
||||
function EnableTest() {
|
||||
this.msg_type = "EnableTest";
|
||||
}
|
||||
exports.EnableTest = EnableTest;
|
||||
|
||||
function DisableTest() {
|
||||
this.msg_type = "DisableTest";
|
||||
}
|
||||
exports.DisableTest = DisableTest;
|
||||
|
||||
function StartTest() {
|
||||
this.msg_type = "StartTest";
|
||||
}
|
||||
exports.StartTest = StartTest;
|
||||
|
||||
function TestCompleted() {
|
||||
this.msg_type = "TestCompleted";
|
||||
}
|
||||
exports.TestCompleted = TestCompleted;
|
||||
|
||||
function TestResult(sender, id, name, result, date, code_under_test) {
|
||||
this.msg_type = "TestResult";
|
||||
this.sender = sender;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.result = result;
|
||||
this.date = date;
|
||||
this.code_under_test = code_under_test;
|
||||
}
|
||||
exports.TestResult = TestResult;
|
||||
|
||||
function Coverage(sender, coverage, result_id) {
|
||||
this.msg_type = "Coverage";
|
||||
this.sender = sender;
|
||||
this.coverage = coverage;
|
||||
this.result_id = result_id;
|
||||
}
|
||||
exports.Coverage = Coverage;
|
||||
@@ -1,38 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.js');
|
||||
var move = require('./move.fsm.js');
|
||||
|
||||
function _State () {
|
||||
}
|
||||
inherits(_State, fsm._State);
|
||||
|
||||
|
||||
function _Start () {
|
||||
this.name = 'Start';
|
||||
}
|
||||
inherits(_Start, _State);
|
||||
var Start = new _Start();
|
||||
exports.Start = Start;
|
||||
|
||||
function _Rack () {
|
||||
this.name = 'Rack';
|
||||
}
|
||||
inherits(_Rack, _State);
|
||||
var Rack = new _Rack();
|
||||
exports.Rack = Rack;
|
||||
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.scope.inventory_toolbox_controller.handle_message('Disable', {});
|
||||
controller.changeState(Rack);
|
||||
};
|
||||
_Start.prototype.start.transitions = ['MultiSite'];
|
||||
|
||||
|
||||
_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);
|
||||
};
|
||||
@@ -1,381 +0,0 @@
|
||||
/* Copyright (c) 2017-2018 Red Hat, Inc. */
|
||||
var fsm = require('./fsm.js');
|
||||
var button = require('./button.fsm.js');
|
||||
var util = require('./util.js');
|
||||
var animation_fsm = require('./animation.fsm.js');
|
||||
|
||||
function Device(id, name, x, y, type, host_id) {
|
||||
this.id = id;
|
||||
this.host_id = host_id ? host_id: 0;
|
||||
this.name = name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.height = type === "host" ? 20 : 37.5;
|
||||
this.width = 37.5;
|
||||
this.size = 37.5;
|
||||
this.type = type;
|
||||
this.selected = false;
|
||||
this.remote_selected = 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.interfaces_by_name = {};
|
||||
this.variables = {};
|
||||
}
|
||||
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.map(function (x) {
|
||||
return x.toJSON();
|
||||
}),
|
||||
variables: this.variables
|
||||
};
|
||||
};
|
||||
|
||||
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.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 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 = false;
|
||||
this.buttons = buttons;
|
||||
this.fsm = new fsm.FSMController(this, "button_fsm", enabled ? button.Start : button.Disabled, 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, type) {
|
||||
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.type = type;
|
||||
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 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 Test(name, event_trace, fsm_trace, pre_test_snapshot, post_test_snapshot) {
|
||||
this.name = name;
|
||||
this.event_trace = event_trace;
|
||||
this.fsm_trace = fsm_trace;
|
||||
this.pre_test_snapshot = pre_test_snapshot;
|
||||
this.post_test_snapshot = post_test_snapshot;
|
||||
}
|
||||
exports.Test = Test;
|
||||
|
||||
function TestResult(id, name, result, date, code_under_test) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.result = result;
|
||||
this.date = date;
|
||||
this.code_under_test = code_under_test;
|
||||
}
|
||||
exports.TestResult = TestResult;
|
||||
|
||||
function Animation(id, steps, data, scope, tracer, callback) {
|
||||
|
||||
this.id = id;
|
||||
this.steps = steps;
|
||||
this.active = true;
|
||||
this.frame_number_seq = util.natural_numbers(-1);
|
||||
this.frame_number = 0;
|
||||
this.data = data;
|
||||
this.data.updateZoomBoolean = data.updateZoomBoolean !== undefined ? data.updateZoomBoolean : true;
|
||||
this.callback = callback;
|
||||
this.scope = scope;
|
||||
this.interval = null;
|
||||
this.frame_delay = 17;
|
||||
this.fsm = new fsm.FSMController(this, "animation_fsm", animation_fsm.Start, tracer);
|
||||
}
|
||||
exports.Animation = Animation;
|
||||
@@ -1,397 +0,0 @@
|
||||
/* 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 _Placing () {
|
||||
this.name = 'Placing';
|
||||
}
|
||||
inherits(_Placing, _State);
|
||||
var Placing = new _Placing();
|
||||
exports.Placing = Placing;
|
||||
|
||||
|
||||
function _ContextMenu () {
|
||||
this.name = 'ContextMenu';
|
||||
}
|
||||
inherits(_ContextMenu, _State);
|
||||
var ContextMenu = new _ContextMenu();
|
||||
exports.ContextMenu = ContextMenu;
|
||||
|
||||
|
||||
_State.prototype.onUnselectAll = function (controller, msg_type, $event) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
controller.delegate_channel.send(msg_type, $event);
|
||||
};
|
||||
|
||||
_Ready.prototype.onPasteDevice = function (controller, msg_type, message) {
|
||||
|
||||
var scope = controller.scope;
|
||||
var device = null;
|
||||
var remote_device = null;
|
||||
var intf = null;
|
||||
var link = null;
|
||||
var new_link = 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,
|
||||
message.device.host_id);
|
||||
device.variables = message.device.variables;
|
||||
scope.update_links_in_vars_by_device(device.name, device.variables);
|
||||
scope.devices.push(device);
|
||||
scope.devices_by_name[message.device.name] = device;
|
||||
c_messages.push(new messages.DeviceCreate(scope.client_id,
|
||||
device.id,
|
||||
device.x,
|
||||
device.y,
|
||||
device.name,
|
||||
device.type,
|
||||
device.host_id));
|
||||
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);
|
||||
device.interfaces_by_name[message.device.interfaces[i].name] = intf;
|
||||
intf.device = device;
|
||||
c_messages.push(new messages.InterfaceCreate(controller.scope.client_id,
|
||||
device.id,
|
||||
intf.id,
|
||||
intf.name));
|
||||
}
|
||||
if (scope.links_in_vars_by_device[device.name] !== undefined) {
|
||||
for (i=0; i < scope.links_in_vars_by_device[device.name].length; i++) {
|
||||
link = scope.links_in_vars_by_device[device.name][i];
|
||||
if (device.interfaces_by_name[link.from_interface] === undefined) {
|
||||
intf = new models.Interface(device.interface_seq(), link.from_interface);
|
||||
device.interfaces.push(intf);
|
||||
device.interfaces_by_name[link.from_interface] = intf;
|
||||
intf.device = device;
|
||||
c_messages.push(new messages.InterfaceCreate(controller.scope.client_id,
|
||||
device.id,
|
||||
intf.id,
|
||||
intf.name));
|
||||
}
|
||||
if (scope.devices_by_name[link.to_device] !== undefined) {
|
||||
remote_device = scope.devices_by_name[link.to_device];
|
||||
if (remote_device.interfaces_by_name[link.to_interface] === undefined) {
|
||||
intf = new models.Interface(remote_device.interface_seq(), link.to_interface);
|
||||
remote_device.interfaces.push(intf);
|
||||
remote_device.interfaces_by_name[link.to_interface] = intf;
|
||||
intf.device = remote_device;
|
||||
c_messages.push(new messages.InterfaceCreate(controller.scope.client_id,
|
||||
remote_device.id,
|
||||
intf.id,
|
||||
intf.name));
|
||||
}
|
||||
}
|
||||
if (scope.devices_by_name[link.to_device] === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (scope.devices_by_name[link.to_device].interfaces_by_name[link.to_interface] === undefined) {
|
||||
continue;
|
||||
}
|
||||
new_link = new models.Link(scope.link_id_seq(),
|
||||
device,
|
||||
scope.devices_by_name[link.to_device],
|
||||
device.interfaces_by_name[link.from_interface],
|
||||
scope.devices_by_name[link.to_device].interfaces_by_name[link.to_interface]);
|
||||
c_messages.push(new messages.LinkCreate(controller.scope.client_id,
|
||||
new_link.id,
|
||||
new_link.from_device.id,
|
||||
new_link.to_device.id,
|
||||
new_link.from_interface.id,
|
||||
new_link.to_interface.id));
|
||||
device.interfaces_by_name[link.from_interface].link = new_link;
|
||||
scope.devices_by_name[link.to_device].interfaces_by_name[link.to_interface].link = new_link;
|
||||
scope.links.push(new_link);
|
||||
scope.updateInterfaceDots();
|
||||
}
|
||||
}
|
||||
scope.selected_devices.push(device);
|
||||
device.selected = true;
|
||||
controller.log.debug(c_messages);
|
||||
scope.$emit('awxNet-addSearchOption', device);
|
||||
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'];
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Ready'];
|
||||
|
||||
|
||||
_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.scope.first_channel.send('BindDocument', {});
|
||||
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.scope.deleteDevice();
|
||||
}
|
||||
|
||||
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.onMouseUp = function (controller) {
|
||||
|
||||
if(controller.scope.$parent.vm.rightPanelIsExpanded){
|
||||
controller.scope.onDetailsContextButton();
|
||||
}
|
||||
controller.changeState(Selected2);
|
||||
|
||||
};
|
||||
_Selected1.prototype.onMouseUp.transitions = ['Selected2'];
|
||||
|
||||
_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++) {
|
||||
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 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;
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
_Move.prototype.onMouseUp = function (controller, msg_type, $event) {
|
||||
|
||||
controller.changeState(Selected1);
|
||||
controller.handle_message(msg_type, $event);
|
||||
};
|
||||
_Move.prototype.onMouseUp.transitions = ['Selected1'];
|
||||
|
||||
_Move.prototype.onMouseDown = function (controller) {
|
||||
|
||||
controller.changeState(Selected1);
|
||||
};
|
||||
_Move.prototype.onMouseDown.transitions = ['Selected1'];
|
||||
|
||||
_Selected3.prototype.onMouseUp = function (controller, msg_type, $event) {
|
||||
let context_menu = controller.scope.context_menus[0];
|
||||
context_menu.enabled = true;
|
||||
context_menu.x = $event.x;
|
||||
context_menu.y = $event.y;
|
||||
context_menu.buttons.forEach(function(button, index){
|
||||
button.x = $event.x;
|
||||
let menuPaddingTop = 5;
|
||||
button.y = $event.y + menuPaddingTop + (button.height * index);
|
||||
});
|
||||
|
||||
controller.changeState(ContextMenu);
|
||||
};
|
||||
_Selected3.prototype.onMouseUp.transitions = ['ContextMenu'];
|
||||
|
||||
_Selected3.prototype.onMouseMove = function (controller) {
|
||||
controller.changeState(Move);
|
||||
};
|
||||
_Selected3.prototype.onMouseMove.transitions = ['Move'];
|
||||
|
||||
_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'];
|
||||
|
||||
|
||||
_ContextMenu.prototype.end = function (controller) {
|
||||
|
||||
controller.scope.removeContextMenu();
|
||||
};
|
||||
|
||||
_ContextMenu.prototype.onMouseDown = function (controller) {
|
||||
|
||||
controller.changeState(Selected2);
|
||||
|
||||
};
|
||||
_ContextMenu.prototype.onMouseDown.transitions = ['Selected2'];
|
||||
|
||||
_ContextMenu.prototype.onDetailsPanel = function (controller, msg_type, $event) {
|
||||
|
||||
controller.changeState(Selected2);
|
||||
controller.handle_message(msg_type, $event);
|
||||
};
|
||||
_ContextMenu.prototype.onDetailsPanel.transitions = ['Selected2'];
|
||||
@@ -1,177 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
var inherits = require('inherits');
|
||||
var fsm = require('./fsm.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 _Selected1 () {
|
||||
this.name = 'Selected1';
|
||||
}
|
||||
inherits(_Selected1, _State);
|
||||
var Selected1 = new _Selected1();
|
||||
exports.Selected1 = Selected1;
|
||||
|
||||
function _ContextMenu () {
|
||||
this.name = 'ContextMenu';
|
||||
}
|
||||
inherits(_ContextMenu, _State);
|
||||
var ContextMenu = new _ContextMenu();
|
||||
exports.ContextMenu = ContextMenu;
|
||||
|
||||
|
||||
_State.prototype.onUnselectAll = function (controller, msg_type, $event) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
controller.delegate_channel.send(msg_type, $event);
|
||||
};
|
||||
|
||||
|
||||
_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'];
|
||||
|
||||
_Start.prototype.start = function (controller) {
|
||||
|
||||
controller.changeState(Ready);
|
||||
|
||||
};
|
||||
_Start.prototype.start.transitions = ['Ready'];
|
||||
|
||||
|
||||
_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.scope.first_channel.send('BindDocument', {});
|
||||
controller.changeState(Ready);
|
||||
controller.handle_message(msg_type, $event);
|
||||
};
|
||||
_Selected2.prototype.onMouseDown.transitions = ['Ready', 'Selected3'];
|
||||
|
||||
|
||||
_Selected1.prototype.onMouseUp = function (controller) {
|
||||
|
||||
if(controller.scope.$parent.vm.rightPanelIsExpanded){
|
||||
controller.scope.onDetailsContextButton();
|
||||
}
|
||||
controller.changeState(Selected2);
|
||||
|
||||
};
|
||||
_Selected1.prototype.onMouseUp.transitions = ['Selected2'];
|
||||
|
||||
_Selected1.prototype.onMouseDown = util.noop;
|
||||
|
||||
_Selected3.prototype.onMouseUp = function (controller, msg_type, $event) {
|
||||
let context_menu = controller.scope.context_menus[0];
|
||||
context_menu.enabled = true;
|
||||
context_menu.x = $event.x;
|
||||
context_menu.y = $event.y;
|
||||
context_menu.buttons.forEach(function(button, index){
|
||||
button.x = $event.x;
|
||||
let menuPaddingTop = 5;
|
||||
button.y = $event.y + menuPaddingTop + (button.height * index);
|
||||
});
|
||||
|
||||
controller.changeState(ContextMenu);
|
||||
};
|
||||
_Selected3.prototype.onMouseUp.transitions = ['ContextMenu'];
|
||||
|
||||
_Selected3.prototype.onMouseMove = function (controller) {
|
||||
controller.changeState(Selected2);
|
||||
};
|
||||
_Selected3.prototype.onMouseMove.transitions = ['Selected2'];
|
||||
|
||||
_ContextMenu.prototype.end = function (controller) {
|
||||
|
||||
controller.scope.removeContextMenu();
|
||||
};
|
||||
|
||||
_ContextMenu.prototype.onMouseDown = function (controller) {
|
||||
|
||||
controller.changeState(Selected2);
|
||||
|
||||
};
|
||||
_ContextMenu.prototype.onMouseDown.transitions = ['Selected2'];
|
||||
|
||||
_ContextMenu.prototype.onDetailsPanel = function (controller, msg_type, $event) {
|
||||
|
||||
controller.changeState(Selected2);
|
||||
controller.handle_message(msg_type, $event);
|
||||
};
|
||||
_ContextMenu.prototype.onDetailsPanel.transitions = ['Selected2'];
|
||||
@@ -1,29 +0,0 @@
|
||||
.Networking-panelHeader {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.Networking-panelHeaderText {
|
||||
color: @default-interface-txt;
|
||||
flex: 1 0 auto;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.Networking-noItems{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.Networking-form{
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.Networking-saveConfirmation{
|
||||
font-weight: normal;
|
||||
color: @default-succ;
|
||||
text-align: right;
|
||||
margin-top:15px;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
['$scope', 'HostsService', 'awxNetStrings',
|
||||
function($scope, HostsService, strings){
|
||||
|
||||
function codemirror () {
|
||||
return {
|
||||
init:{}
|
||||
};
|
||||
}
|
||||
$scope.codeMirror = new codemirror();
|
||||
$scope.formClose = function(){
|
||||
$scope.$parent.$broadcast('awxNet-closeDetailsPanel');
|
||||
};
|
||||
$scope.strings = strings;
|
||||
$scope.hostPopover = `<p>${$scope.strings.get('details.HOST_POPOVER')}</p><blockquote>myserver.domain.com<br/>127.0.0.1<br />10.1.0.140:25<br />server.example.com:25</blockquote>`;
|
||||
|
||||
$scope.formSave = function(){
|
||||
var host = {
|
||||
id: $scope.item.id,
|
||||
variables: $scope.variables === '---' || $scope.variables === '{}' ? null : $scope.variables,
|
||||
name: $scope.item.name,
|
||||
description: $scope.item.description,
|
||||
enabled: $scope.item.enabled
|
||||
};
|
||||
HostsService.put(host).then(function(response){
|
||||
$scope.saveConfirmed = true;
|
||||
if(_.has(response, "data")){
|
||||
$scope.$parent.$broadcast('awxNet-hostUpdateSaved', response.data);
|
||||
}
|
||||
setTimeout(function(){
|
||||
$scope.saveConfirmed = false;
|
||||
}, 3000);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$parent.$on('awxNet-showDetails', (e, data, canAdd) => {
|
||||
if (!_.has(data, 'host_id')) {
|
||||
$scope.item = data;
|
||||
$scope.canAdd = canAdd;
|
||||
} else {
|
||||
$scope.item = data;
|
||||
}
|
||||
if ($scope.codeMirror.init) {
|
||||
$scope.codeMirror.init($scope.item.variables);
|
||||
}
|
||||
});
|
||||
}];
|
||||
@@ -1,22 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2018 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import detailsController from './details.controller';
|
||||
|
||||
const templateUrl = require('~network-ui/network-details/details.partial.html');
|
||||
|
||||
export default [
|
||||
function() {
|
||||
return {
|
||||
scope:{
|
||||
item: "=",
|
||||
canAdd: '@'
|
||||
},
|
||||
templateUrl,
|
||||
controller: detailsController,
|
||||
restrict: 'E',
|
||||
};
|
||||
}];
|
||||
@@ -1,48 +0,0 @@
|
||||
<div class="Networking-panelHeader">
|
||||
<div class="JobResults-panelHeaderText" translate="">
|
||||
DETAILS <span ng-if="!item.host_id && item.name">| {{item.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="List-noItems Networking-noItems" ng-if="!item.host_id">
|
||||
{{item.type}} DETAILS NOT AVAILABLE
|
||||
</div>
|
||||
|
||||
<div ng-show="item.host_id">
|
||||
<form class="Form Networking-form ng-pristine ng-valid ng-valid-required" name="host_form" id="host_form" autocomplete="off" novalidate="">
|
||||
<div class="form-group Form-formGroup Form-formGroup--fullWidth">
|
||||
<label class="Form-inputLabelContainer">
|
||||
<span class="Form-requiredAsterisk">*</span>
|
||||
<span class="Form-inputLabel"> {{strings.get('details.HOST_NAME')}}</span><a id="awp-name" href="" aw-pop-over="{{hostPopover}}" data-placement="right" data-tip-watch="hostPopover" data-container="body" over-title="{{strings.get('details.HOST_NAME')}}" class="help-link" data-original-title="" title="" tabindex="-1"><i class="fa fa-question-circle"></i></a>
|
||||
</label>
|
||||
<div>
|
||||
<input readonly type="text" ng-model="item.name" name="name" id="host_name" class="form-control Form-textInput Networking-input ng-pristine ng-untouched ng-valid ng-not-empty ng-valid-required" required="" ng-disabled="!(item.summary_fields.user_capabilities.edit || canAdd)">
|
||||
<div class="error ng-hide" id="host-name-required-error" ng-show="host_form.name.$dirty && host_form.name.$error.required">Please enter a value.</div>
|
||||
<div class="error api-error ng-binding" id="host-name-api-error" ng-bind="name_api_error"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--fullWidth">
|
||||
<label class="Form-inputLabelContainer">
|
||||
<span class="Form-inputLabel">{{strings.get('details.DESCRIPTION')}}</span>
|
||||
</label>
|
||||
<div>
|
||||
<input readonly type="text" ng-model="item.description" name="description" id="host_description" class="form-control Form-textInput Networking-input" ng-disabled="!(item.summary_fields.user_capabilities.edit || canAdd)">
|
||||
<div class="error api-error ng-binding" id="host-description-api-error" ng-bind="description_api_error"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group Form-formGroup Form-formGroup--fullWidth">
|
||||
<at-code-mirror
|
||||
disabled="true"
|
||||
variables="{{ item.variables }}"
|
||||
tooltip-placement="left"
|
||||
init="codeMirror.init">
|
||||
</at-code-mirror>
|
||||
</div>
|
||||
</form>
|
||||
<div class="buttons Form-buttons" id="host_controls">
|
||||
<button type="button" class="btn btn-sm Form-cancelButton" id="host_cancel_btn" ng-click="formClose()"> {{strings.get('details.CLOSE')}}</button>
|
||||
</div>
|
||||
<div class="Networking-saveConfirmation" ng-show="saveConfirmed">
|
||||
{{strings.get('details.SAVE_COMPLETE')}} <i class="fa fa-check-circle"></i>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,11 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2018 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import awxNetDetailsPanel from './details.directive';
|
||||
|
||||
export default
|
||||
angular.module('networkDetailsDirective', [])
|
||||
.directive('awxNetDetailsPanel', awxNetDetailsPanel);
|
||||
@@ -1,6 +0,0 @@
|
||||
const MODULE_NAME = 'at.features.networking';
|
||||
|
||||
angular
|
||||
.module(MODULE_NAME, []);
|
||||
|
||||
export default MODULE_NAME;
|
||||
@@ -1,215 +0,0 @@
|
||||
.NetworkingUIView{
|
||||
position:absolute;
|
||||
display:block;
|
||||
width:100vw;
|
||||
height: 100vh;
|
||||
z-index: 1101;
|
||||
}
|
||||
|
||||
.Networking-shell{
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
width:100%;
|
||||
align-items: flex-end;
|
||||
position:absolute;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
.Networking-top{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.Networking-header{
|
||||
border-top: 1px solid @at-color-panel-border;
|
||||
border-bottom: 1px solid @at-color-panel-border;
|
||||
display:flex;
|
||||
height: 40px;
|
||||
width:100%;
|
||||
background-color: @default-bg;
|
||||
}
|
||||
|
||||
.Networking-headerTitle{
|
||||
color: @default-interface-txt;
|
||||
flex: 1 0 auto;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding-left: 20px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Netowrking-headerActions{
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.Networking-headerActionItem{
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
padding-right: 20px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.Networking-toolbarIcon{
|
||||
font-size: 16px;
|
||||
height: 30px;
|
||||
min-width: 30px;
|
||||
color: @default-icon;
|
||||
background-color: inherit;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.Networking-toolbarIcon:hover{
|
||||
background-color:@default-link;
|
||||
color: @default-bg;
|
||||
}
|
||||
|
||||
.Networking-toolbarIcon--selected{
|
||||
background-color:@default-link;
|
||||
color: @default-bg;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.Networking-canvasPanel{
|
||||
width:100%
|
||||
}
|
||||
|
||||
.Networking-detailPanel{
|
||||
border-left: 1px solid @at-color-panel-border;
|
||||
border-bottom: 1px solid @at-color-panel-border;
|
||||
width:400px;
|
||||
height: calc(~"100vh - 115px");
|
||||
padding: 20px;
|
||||
color: @default-interface-txt;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
background-color: @default-bg;
|
||||
position: absolute;
|
||||
top:115px;
|
||||
right:0px;
|
||||
}
|
||||
|
||||
.Networking-toolbar{
|
||||
min-height: 40px;
|
||||
width:100%;
|
||||
background-color: @ebgrey;
|
||||
display:flex;
|
||||
flex: 1 0 auto;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid @at-color-panel-border;
|
||||
}
|
||||
|
||||
.Networking-toolbarLeftSide{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-width: 400px;
|
||||
padding-left: 20px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Networking-toolbarRightSide{
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
min-width: 500px;
|
||||
padding-right: 20px;
|
||||
height: 40px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.Networking-actionsDropDownContainer{
|
||||
height: 30px;
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
margin-top:-5px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
.Networking-searchBarContainer{
|
||||
height: 30px;
|
||||
display: flex;
|
||||
margin-top:-5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.Networking-dropDown{
|
||||
left:-2px!important;
|
||||
z-index: 1101;
|
||||
}
|
||||
|
||||
.Networking-searchButton{
|
||||
padding: 4px 10px;
|
||||
}
|
||||
|
||||
.Networking-searchButton i{
|
||||
color:@default-icon;
|
||||
}
|
||||
|
||||
|
||||
.Networking-dropdownPanelTitle{
|
||||
color: @default-stdout-txt;
|
||||
padding-left:15px;
|
||||
min-height: 30px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.Networking-keyContainer{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.Networking-keyDropDownPanel{
|
||||
width: 180px;
|
||||
padding: 10px 0px 10px 0px;
|
||||
border: 1px solid @btn-bord;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
right:0px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.Networking-keyPanelOption{
|
||||
color: @default-stdout-txt;
|
||||
padding-left:15px;
|
||||
min-height: 30px;
|
||||
font-size: 12px;
|
||||
display:flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Networking-keySymbol{
|
||||
background-color: @default-icon;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Networking-keySymbolLabel{
|
||||
font-size: 12px;
|
||||
padding-left: 15px;
|
||||
color: @default-stdout-txt;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.Networking-toolboxPanelToolbarIcon--selected{
|
||||
border-radius: 5px;
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/* eslint-disable */
|
||||
function NetworkingController (canEdit, inventory, $state, $scope, strings) {
|
||||
const vm = this || {};
|
||||
|
||||
vm.networkUIisOpen = true;
|
||||
vm.strings = strings;
|
||||
vm.panelTitle = `${strings.get('state.BREADCRUMB_LABEL')} | ${inventory.name}`;
|
||||
vm.hostDetail = {};
|
||||
vm.canEdit = canEdit;
|
||||
vm.rightPanelIsExpanded = false;
|
||||
vm.leftPanelIsExpanded = true;
|
||||
vm.keyPanelExpanded = false;
|
||||
vm.groups = [];
|
||||
$scope.devices = [];
|
||||
vm.close = () => {
|
||||
vm.networkUIisOpen = false;
|
||||
$scope.$broadcast('awxNet-closeNetworkUI');
|
||||
$state.go('inventories');
|
||||
};
|
||||
|
||||
vm.key = () => {
|
||||
vm.keyPanelExpanded = !vm.keyPanelExpanded;
|
||||
};
|
||||
|
||||
vm.hideToolbox = () => {
|
||||
vm.leftPanelIsExpanded = !vm.leftPanelIsExpanded;
|
||||
$scope.$broadcast('awxNet-hideToolbox', vm.leftPanelIsExpanded);
|
||||
};
|
||||
|
||||
$scope.$on('awxNet-instatiateSelect', (e, devices) => {
|
||||
for(var i = 0; i < devices.length; i++){
|
||||
let device = devices[i];
|
||||
let grouping;
|
||||
switch (device.type){
|
||||
case 'host':
|
||||
grouping = strings.get('search.HOST');
|
||||
break;
|
||||
case 'switch':
|
||||
grouping = strings.get('search.SWITCH');
|
||||
break;
|
||||
case 'router':
|
||||
grouping = strings.get('search.ROUTER');
|
||||
break;
|
||||
default:
|
||||
grouping = strings.get('search.UNKNOWN');
|
||||
}
|
||||
$scope.devices.push({
|
||||
value: device.id,
|
||||
text: device.name,
|
||||
label: device.name,
|
||||
id: device.id,
|
||||
type: device.type,
|
||||
group_type: grouping
|
||||
});
|
||||
}
|
||||
|
||||
$("#networking-search").select2({
|
||||
width:'400px',
|
||||
containerCssClass: 'Form-dropDown',
|
||||
placeholder: strings.get('search.SEARCH'),
|
||||
dropdownParent: $('.Networking-toolbar'),
|
||||
});
|
||||
|
||||
$("#networking-actionsDropdown").select2({
|
||||
width:'400px',
|
||||
containerCssClass: 'Form-dropDown',
|
||||
minimumResultsForSearch: -1,
|
||||
placeholder: strings.get('actions.ACTIONS'),
|
||||
dropdownParent: $('.Networking-toolbar'),
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$on('awxNet-addSearchOption', (e, device) => {
|
||||
$scope.devices.push({
|
||||
value: device.id,
|
||||
text: device.name,
|
||||
label: device.name,
|
||||
id: device.id,
|
||||
type: device.type
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$on('awxNet-editSearchOption', (e, device) => {
|
||||
for(var i = 0; i < $scope.devices.length; i++){
|
||||
if(device.id === $scope.devices[i].id){
|
||||
$scope.devices[i].text = device.name;
|
||||
$scope.devices[i].label = device.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('awxNet-removeSearchOption', (e, device) => {
|
||||
for (var i = 0; i < $scope.devices.length; i++) {
|
||||
if ($scope.devices[i].id === device.id) {
|
||||
$scope.devices.splice(i, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Handlers for actions drop down
|
||||
$('#networking-actionsDropdown').on('select2:select', (e) => {
|
||||
$scope.$broadcast('awxNet-toolbarButtonEvent', e.params.data.title);
|
||||
$("#networking-actionsDropdown").val(null).trigger('change');
|
||||
});
|
||||
|
||||
$('#networking-actionsDropdown').on('select2:open', () => {
|
||||
$('.select2-dropdown').addClass('Networking-dropDown');
|
||||
});
|
||||
|
||||
// Handlers for search dropdown
|
||||
$('#networking-search').on('select2:select', () => {
|
||||
$scope.$broadcast('awxNet-search', $scope.device);
|
||||
});
|
||||
|
||||
$('#networking-search').on('select2:open', () => {
|
||||
$('.select2-dropdown').addClass('Networking-dropDown');
|
||||
$scope.$broadcast('awxNet-SearchDropdown');
|
||||
});
|
||||
|
||||
$('#networking-search').on('select2:close', () => {
|
||||
setTimeout(function() {
|
||||
$('.select2-container-active').removeClass('select2-container-active');
|
||||
$(':focus').blur();
|
||||
}, 1);
|
||||
$scope.$broadcast('awxNet-SearchDropdownClose');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
NetworkingController.$inject = [
|
||||
'canEdit',
|
||||
'inventory',
|
||||
'$state',
|
||||
'$scope',
|
||||
'awxNetStrings',
|
||||
'CreateSelect2'
|
||||
];
|
||||
|
||||
export default NetworkingController;
|
||||
/* eslint-disable */
|
||||
@@ -1,91 +0,0 @@
|
||||
<div class="Networking-shell">
|
||||
<div class="Networking-top">
|
||||
<div class="Networking-header">
|
||||
<div class="Networking-headerTitle">{{vm.panelTitle}}</div>
|
||||
<div class="Netowrking-headerActions">
|
||||
<div class="Networking-headerActionItem">
|
||||
<button ng-click="vm.close()" type="button" class="close">
|
||||
<i class="fa fa-times-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Networking-toolbar">
|
||||
<div class="Networking-toolbarLeftSide">
|
||||
<div class="Networking-actionsDropDownContainer">
|
||||
<select id="networking-actionsDropdown"
|
||||
style="width:400px">
|
||||
<option></option>
|
||||
<option value="Export" title="Export">{{ vm.strings.get('actions.EXPORT') }} SVG</option>
|
||||
<option value="ExportYaml" title="ExportYaml">{{ vm.strings.get('actions.EXPORT') }} YAML</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Networking-toolbarRightSide">
|
||||
<div ng-if="vm.canEdit">
|
||||
<button ng-click="vm.hideToolbox()" type="button" class="Networking-toolbarIcon" ng-class="{'Networking-toolbarIcon--selected Networking-toolboxPanelToolbarIcon--selected' : vm.leftPanelIsExpanded}">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="Networking-keyContainer">
|
||||
<button ng-click="vm.key()" type="button" class="Networking-toolbarIcon" ng-class="{'Networking-toolbarIcon--selected' : vm.keyPanelExpanded}">
|
||||
<i class="fa fa-key"></i>
|
||||
</button>
|
||||
<div class="Networking-keyDropDownPanel" ng-if="vm.keyPanelExpanded">
|
||||
<div class="Networking-dropdownPanelTitle">
|
||||
{{ vm.strings.get('key.KEY') }}
|
||||
</div>
|
||||
<div class="Networking-keyPanelOption">
|
||||
<div class="Networking-keySymbol">d</div>
|
||||
<div class="Networking-keySymbolLabel">{{ vm.strings.get('key.DEBUG_MODE') }}</div>
|
||||
</div>
|
||||
<div class="Networking-keyPanelOption">
|
||||
<div class="Networking-keySymbol">i</div>
|
||||
<div class="Networking-keySymbolLabel">{{ vm.strings.get('key.HIDE_INTERFACES') }}</div>
|
||||
</div>
|
||||
<div class="Networking-keyPanelOption">
|
||||
<div class="Networking-keySymbol">0</div>
|
||||
<div class="Networking-keySymbolLabel">{{ vm.strings.get('key.RESET_ZOOM') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Networking-searchBarContainer">
|
||||
<select id="networking-search"
|
||||
ng-model="device"
|
||||
ng-options="device.label group by device.group_type for device in devices | orderBy:'label' "
|
||||
style="width:400px">
|
||||
<option></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="Networking-detailPanel" ng-show="vm.rightPanelIsExpanded">
|
||||
<awx-net-details-panel item="item"></awx-net-details-panel>
|
||||
</div>
|
||||
<div class="Networking-canvasPanel">
|
||||
<awx-network-ui></awx-network-ui>
|
||||
</div>
|
||||
<div class="Networking-zoomPanel" ng-class="{'Networking-zoomPanel--expanded' : vm.rightPanelIsExpanded}">
|
||||
<awx-net-zoom-widget></awx-net-zoom-widget>
|
||||
</div>
|
||||
<div id="alert-modal" class="modal fade">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-hide="disableButtons" data-target="#alert-modal" data-dismiss="modal" class="modal" aria-hidden="true"><i class="fa fa-times-circle"></i></button>
|
||||
<h3 id="alertHeader" ng-bind="alertHeader"></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="alert-modal-msg" class="alert" ng-bind-html="alertBody"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" ng-hide="disableButtons" data-target="#form-modal" data-dismiss="modal" id="alert_ok_btn" class="btn btn-default" translate>OK</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- modal-content -->
|
||||
</div>
|
||||
<!-- modal-dialog -->
|
||||
</div>
|
||||
@@ -1,50 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
import atFeaturesNetworking from './network-nav/main';
|
||||
import networkDetailsDirective from './network-details/main';
|
||||
import networkZoomWidget from './zoom-widget/main';
|
||||
import awxNetStrings from './network.ui.strings';
|
||||
|
||||
var NetworkUIController = require('./network.ui.controller.js');
|
||||
var cursor = require('./cursor.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 contextMenu = require('./context.menu.directive.js');
|
||||
var contextMenuButton = require('./context.menu.button.directive.js');
|
||||
var defaultd = require('./default.directive.js');
|
||||
var quadrants = require('./quadrants.directive.js');
|
||||
var inventoryToolbox = require('./inventory.toolbox.directive.js');
|
||||
var debug = require('./debug.directive.js');
|
||||
var test_results = require('./test_results.directive.js');
|
||||
var awxNetworkUI = require('./network.ui.directive.js');
|
||||
var util = require('./util.js');
|
||||
|
||||
export default
|
||||
angular.module('networkUI', [
|
||||
'monospaced.mousewheel',
|
||||
atFeaturesNetworking,
|
||||
networkDetailsDirective.name,
|
||||
networkZoomWidget.name
|
||||
])
|
||||
.filter('chunk', function () {
|
||||
return function(input, size) {
|
||||
return util.chunkSubstr(input, size);
|
||||
};
|
||||
})
|
||||
.controller('NetworkUIController', NetworkUIController.NetworkUIController)
|
||||
.directive('awxNetCursor', cursor.cursor)
|
||||
.directive('awxNetDebug', debug.debug)
|
||||
.directive('awxNetRouter', router.router)
|
||||
.directive('awxNetSwitch', switchd.switchd)
|
||||
.directive('awxNetHost', host.host)
|
||||
.directive('awxNetLink', link.link)
|
||||
.directive('awxNetContextMenu', contextMenu.contextMenu)
|
||||
.directive('awxNetContextMenuButton', contextMenuButton.contextMenuButton)
|
||||
.directive('awxNetDefault', defaultd.defaultd)
|
||||
.directive('awxNetQuadrants', quadrants.quadrants)
|
||||
.directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox)
|
||||
.directive('awxNetTestResults', test_results.test_results)
|
||||
.directive('awxNetworkUi', awxNetworkUI.awxNetworkUI)
|
||||
.service('awxNetStrings', awxNetStrings);
|
||||
@@ -1,8 +0,0 @@
|
||||
/* Copyright (c) 2017 Red Hat, Inc. */
|
||||
|
||||
const templateUrl = require('~network-ui/network_ui.partial.svg');
|
||||
|
||||
function awxNetworkUI () {
|
||||
return { restrict: 'E', templateUrl};
|
||||
}
|
||||
exports.awxNetworkUI = awxNetworkUI;
|
||||
@@ -1,34 +0,0 @@
|
||||
import { N_ } from '../i18n';
|
||||
import NetworkingController from './network-nav/network.nav.controller';
|
||||
|
||||
const networkNavTemplate = require('~network-ui/network-nav/network.nav.view.html');
|
||||
|
||||
export default {
|
||||
name: 'inventories.edit.networking',
|
||||
route: '/networking',
|
||||
ncyBreadcrumb: {
|
||||
label: N_("INVENTORIES")
|
||||
},
|
||||
views: {
|
||||
'networking@': {
|
||||
templateUrl: networkNavTemplate,
|
||||
controller: NetworkingController,
|
||||
controllerAs: 'vm'
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
inventory: ['$stateParams', 'resourceData',
|
||||
function($stateParams, resourceData){
|
||||
let inventory = {
|
||||
name: $stateParams.inventory_name || resourceData.data.name,
|
||||
id: $stateParams.inventory_id || $stateParams.smartinventory_id
|
||||
};
|
||||
return inventory;
|
||||
}],
|
||||
canEdit: ['$stateParams', 'resourceData',
|
||||
function($stateParams, resourceData){
|
||||
return resourceData.data.summary_fields.user_capabilities.edit;
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
function awxNetStrings (BaseString) {
|
||||
BaseString.call(this, 'awxNet');
|
||||
|
||||
const { t } = this;
|
||||
const ns = this.awxNet;
|
||||
|
||||
ns.feature = {
|
||||
ACTION_BUTTON: t.s('Network Visualizer')
|
||||
};
|
||||
|
||||
ns.state = {
|
||||
BREADCRUMB_LABEL: t.s('NETWORK VISUALIZER')
|
||||
};
|
||||
|
||||
ns.toolbox = {
|
||||
INVENTORY: t.s('Inventory')
|
||||
};
|
||||
|
||||
ns.actions = {
|
||||
ACTIONS: t.s('ACTIONS'),
|
||||
EXPORT: t.s('Export'),
|
||||
EXPAND_PANEL: t.s('Expand Panel'),
|
||||
COLLAPSE_PANEL: t.s('Collapse Panel')
|
||||
};
|
||||
|
||||
ns.key = {
|
||||
KEY: t.s('Key'),
|
||||
DEBUG_MODE: t.s('Debug Mode'),
|
||||
HIDE_CURSOR: t.s('Hide Cursor'),
|
||||
HIDE_BUTTONS: t.s('Hide Buttons'),
|
||||
HIDE_INTERFACES: t.s('Hide Interfaces'),
|
||||
RESET_ZOOM: t.s('Reset Zoom')
|
||||
};
|
||||
|
||||
ns.search = {
|
||||
SEARCH: t.s('SEARCH'),
|
||||
HOST: t.s('Host'),
|
||||
SWITCH: t.s('Switch'),
|
||||
ROUTER: t.s('Router'),
|
||||
UNKNOWN: t.s('Unknown')
|
||||
};
|
||||
|
||||
ns.context_menu = {
|
||||
DETAILS: t.s('Details'),
|
||||
REMOVE: t.s('Remove')
|
||||
};
|
||||
|
||||
ns.details = {
|
||||
HOST_NAME: t.s('Host Name'),
|
||||
DESCRIPTION: t.s('Description'),
|
||||
HOST_POPOVER: t.s('Provide a host name, ip address, or ip address:port. Examples include:'),
|
||||
SAVE_COMPLETE: t.s('Save Complete'),
|
||||
CLOSE: t.s('Close')
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
awxNetStrings.$inject = ['BaseStringService'];
|
||||
|
||||
export default awxNetStrings;
|
||||