diff --git a/Makefile b/Makefile index 5151046635..54d0c49be3 100644 --- a/Makefile +++ b/Makefile @@ -374,7 +374,7 @@ awx-link: sed -i "s/placeholder/$(shell git describe --long | sed 's/\./\\./g')/" /awx_devel/awx.egg-info/PKG-INFO cp /tmp/awx.egg-link /venv/awx/lib/python2.7/site-packages/awx.egg-link -TEST_DIRS ?= awx/main/tests/unit awx/main/tests/functional awx/conf/tests awx/sso/tests awx/network_ui/tests/unit +TEST_DIRS ?= awx/main/tests/unit awx/main/tests/functional awx/conf/tests awx/sso/tests # Run all API unit tests. test: @@ -389,7 +389,7 @@ test_unit: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/awx/bin/activate; \ fi; \ - py.test awx/main/tests/unit awx/conf/tests/unit awx/sso/tests/unit awx/network_ui/tests/unit + py.test awx/main/tests/unit awx/conf/tests/unit awx/sso/tests/unit test_ansible: @if [ "$(VENV_BASE)" ]; then \ diff --git a/awx/main/routing.py b/awx/main/routing.py index 79a3c84a5a..0a49f25c6c 100644 --- a/awx/main/routing.py +++ b/awx/main/routing.py @@ -1,5 +1,4 @@ from channels.routing import route -from awx.network_ui.routing import channel_routing as network_ui_routing channel_routing = [ @@ -7,6 +6,3 @@ channel_routing = [ route("websocket.disconnect", "awx.main.consumers.ws_disconnect", path=r'^/websocket/$'), route("websocket.receive", "awx.main.consumers.ws_receive", path=r'^/websocket/$'), ] - - -channel_routing += network_ui_routing diff --git a/awx/network_ui/CONTRIBUTING.md b/awx/network_ui/CONTRIBUTING.md deleted file mode 100644 index 106e5df02d..0000000000 --- a/awx/network_ui/CONTRIBUTING.md +++ /dev/null @@ -1,132 +0,0 @@ -Network UI -========== - -See [awx/ui/client/src/network-ui/CONTRIBUTING.md](../ui/client/src/network-ui/CONTRIBUTING.md) for the introduction -to the Network UI client-side development. - -Server-Side Development ------------------------ - -This document covers the Network UI server-side development. - -The Network UI is a UX driven feature to provide a graphical user -experience that fits well into the network engineer's normal workflow. Their -normal workflow includes a diagram drawn in a graphical drawing program, a -spreadsheet, and the command line interface of their network gear. Network -architects design the network on the graphical diagram and then hand off the -architecture to network operators who implement the architecture on the network -using spreadsheets to manage their data and manually converting the data into -CLI commands using their networking expertise and expertise with their physical -gear. - -The server-side code supports the persistence needed to provide this graphical -user experience of architecting a network and using that information along with -additional information (stored in vars files) to configure the network devices -using the CLI or NETCONF using Ansible playbooks and roles. - -Network UI Data Schema ----------------------- - -For the 3.3 release the persistence needed includes the position information of -the devices on the virtual canvas and the type of the devices as well as -information about the interfaces on the devices and the links connecting those -interfaces. - -These requirements determine the database schema needed for the network UI which -requires these models: Topology, Device, Interface, Link, and TopologyInventory. - -![Models](designs/models.png) - -This diagram shows the relationships between the models in the Network UI schema. - -The models are: - -* Device - a host, switch, router, or other networking device -* Interface - a connection point on a device for a link -* Link - a physical connection between two devices to their respective interfaces -* Topology - a collection of devices and links -* TopologyInventory - a mapping between topologies and Tower inventories - - -Network UI Websocket Protocol ------------------------------ - -Persistence for the network UI canvas state is implemented using an -asynchronous websocket protocol to send information from the client to the -server and vice-versa. This two-way communication was chosen to support future -features for streaming data to the canvas, broadcast messaging between clients, -and for interaction performance on the UI. - - -Messages --------- - -JSON messages are passed over the `/network_ui/topology` websocket between the -test client and the test server. The protocol that is used for all messages is -in ABNF (RFC5234): - - - message_type = 'DeviceMove' / 'DeviceCreate' / 'DeviceDestroy' / 'DeviceLabelEdit' / 'DeviceSelected' / 'DeviceUnSelected' / 'InterfaceCreate' / 'InterfaceLabelEdit' / 'LinkLabelEdit' / 'LinkCreate' / 'LinkDestroy' / 'LinkSelected' / 'LinkUnSelected' / 'MultipleMessage' / 'Snapshot' - message_data = '{' 'msg_type' ': ' message_type ', ' key-value *( ', ' key-value ) '}' - message = '[ id , ' posint ']' / '[ topology_id , ' posint ']' / '[' message_type ', ' message_data ']' - -See https://github.com/AndyA/abnfgen/blob/master/andy/json.abnf for the rest of -the JSON ABNF. - -See [designs/messages.yml](designs/messages.yml) for the allowable keys and -values for each message type. - - -Initially when the websocket is first opened the server will send four messages -to the client. These are: - -* the client id using the `id` message type. -* the topology id using the `topology` message type. -* a Topology record containing data for the canvas itself. -* a Snapshot message containing all the data of the data on the canvas. - -As the user interacts with the canvas messages will be generated by the client -and the `network_ui.consumers.Persistence` class will update the models that -represent the canvas. - - - -Persistence ------------ - -The class `awx.network_uiconsumers.Persistence` provides persistence for the Network UI canvas. -It does so by providing message handlers that handle storage of the canvas change events -into the database. Each event has a message handle with name `onX` where `X` is the name of the message -type. The handlers use the `filter/values_list`, `filter/values`, `filter/update`, and `filter/delete` -patterns to update the data in the database quickly with a constant O(1) number of queries per event -often with only one query needed. With `filter/update` and `filter/delete` all the work is done -in the database and Python never needs to instaniate and garbage collect the model objects. - -Bulk operations (`filter/values`) in `send_snapshot` are used to produce a constant number of -queries produce a snapshot when the canvas is first loaded. This method avoids creating -the model objects since it only produces dicts that are JSON serializable which are bundled -together for the `Snapshot` message type. - -This method of persistence uses Django as a database query-compiler for transforms from -the event types to the database types. Using Django in this way is very performant since -Python does very little work processing the data and when possible the data never leaves -the database. - - -Client Tracking ---------------- - -Each user session to the network UI canvas is tracked with the `client_id` param. Multiple -clients can view and interact with the network UI canvas at a time. They will see each other's -edits to the canvas in real time. This works by broadcasting the canvas change events to -all clients viewing the same topology. - -``` - # Send to all clients editing the topology - Group("topology-%s" % message.channel_session['topology_id']).send({"text": message['text']}) -``` - -API ---- - -There is no user accessible API for this feature in the 3.3 release. diff --git a/awx/network_ui/__init__.py b/awx/network_ui/__init__.py deleted file mode 100644 index ebed9407c5..0000000000 --- a/awx/network_ui/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright (c) 2017 Red Hat, Inc - diff --git a/awx/network_ui/consumers.py b/awx/network_ui/consumers.py deleted file mode 100644 index a62fe73cdb..0000000000 --- a/awx/network_ui/consumers.py +++ /dev/null @@ -1,330 +0,0 @@ -# Copyright (c) 2017 Red Hat, Inc -import channels -from channels.auth import channel_session_user, channel_session_user_from_http -from awx.network_ui.models import Topology, Device, Link, Interface -from awx.network_ui.models import TopologyInventory -from awx.main.models.inventory import Inventory -import urlparse -from django.db.models import Q -from collections import defaultdict -import logging -import uuid -import six - - -from awx.network_ui.utils import transform_dict - -import json - -logger = logging.getLogger("awx.network_ui.consumers") - - -def parse_inventory_id(data): - inventory_id = data.get('inventory_id', ['null']) - try: - inventory_id = int(inventory_id[0]) - except ValueError: - inventory_id = None - except IndexError: - inventory_id = None - except TypeError: - inventory_id = None - if not inventory_id: - inventory_id = None - return inventory_id - - -class NetworkingEvents(object): - - ''' - Provides handlers for the networking events for the topology canvas. - ''' - - def parse_message_text(self, message_text, client_id): - ''' - See the Messages of CONTRIBUTING.md for the message format. - ''' - data = json.loads(message_text) - if len(data) == 2: - message_type = data.pop(0) - message_value = data.pop(0) - if isinstance(message_value, list): - logger.warning("Message has no sender") - return None, None - if isinstance(message_value, dict) and client_id != message_value.get('sender'): - logger.warning("client_id mismatch expected: %s actual %s", client_id, message_value.get('sender')) - return None, None - return message_type, message_value - else: - logger.error("Invalid message text") - return None, None - - def handle(self, message): - ''' - Dispatches a message based on the message type to a handler function - of name onX where X is the message type. - ''' - topology_id = message.get('topology') - if topology_id is None: - logger.warning("Unsupported message %s: no topology", message) - return - client_id = message.get('client') - if client_id is None: - logger.warning("Unsupported message %s: no client", message) - return - if not message.get('can_edit'): - logger.warning("Client {0} does not have permission to edit topology {1}".format(client_id, topology_id)) - return - if 'text' not in message: - logger.warning("Unsupported message %s: no data", message) - return - message_type, message_value = self.parse_message_text(message['text'], client_id) - if message_type is None: - logger.warning("Unsupported message %s: no message type", message) - return - handler = self.get_handler(message_type) - if handler is not None: - handler(message_value, topology_id, client_id) - else: - logger.warning("Unsupported message %s: no handler", message_type) - - def get_handler(self, message_type): - return getattr(self, "on{0}".format(message_type), None) - - def onDeviceCreate(self, device, topology_id, client_id): - device = transform_dict(dict(x='x', - y='y', - name='name', - type='device_type', - id='cid', - host_id='host_id'), device) - logger.info("Device created %s", device) - d, _ = Device.objects.get_or_create(topology_id=topology_id, cid=device['cid'], defaults=device) - d.x = device['x'] - d.y = device['y'] - d.device_type = device['device_type'] - d.host_id = device['host_id'] - d.save() - (Topology.objects - .filter(pk=topology_id, device_id_seq__lt=device['cid']) - .update(device_id_seq=device['cid'])) - - def onDeviceDestroy(self, device, topology_id, client_id): - logger.info("Device removed %s", device) - Device.objects.filter(topology_id=topology_id, cid=device['id']).delete() - - def onDeviceMove(self, device, topology_id, client_id): - Device.objects.filter(topology_id=topology_id, cid=device['id']).update(x=device['x'], y=device['y']) - - def onDeviceLabelEdit(self, device, topology_id, client_id): - logger.debug("Device label edited %s", device) - Device.objects.filter(topology_id=topology_id, cid=device['id']).update(name=device['name']) - - def onInterfaceLabelEdit(self, interface, topology_id, client_id): - (Interface.objects - .filter(device__topology_id=topology_id, - cid=interface['id'], - device__cid=interface['device_id']) - .update(name=interface['name'])) - - def onLinkLabelEdit(self, link, topology_id, client_id): - logger.debug("Link label edited %s", link) - Link.objects.filter(from_device__topology_id=topology_id, cid=link['id']).update(name=link['name']) - - def onInterfaceCreate(self, interface, topology_id, client_id): - Interface.objects.get_or_create(device_id=Device.objects.get(cid=interface['device_id'], - topology_id=topology_id).pk, - cid=interface['id'], - defaults=dict(name=interface['name'])) - (Device.objects - .filter(cid=interface['device_id'], - topology_id=topology_id, - interface_id_seq__lt=interface['id']) - .update(interface_id_seq=interface['id'])) - - def onLinkCreate(self, link, topology_id, client_id): - logger.debug("Link created %s", link) - device_map = dict(Device.objects - .filter(topology_id=topology_id, cid__in=[link['from_device_id'], link['to_device_id']]) - .values_list('cid', 'pk')) - if link['from_device_id'] not in device_map: - logger.warning('Device not found') - return - if link['to_device_id'] not in device_map: - logger.warning('Device not found') - return - Link.objects.get_or_create(cid=link['id'], - name=link['name'], - from_device_id=device_map[link['from_device_id']], - to_device_id=device_map[link['to_device_id']], - from_interface_id=Interface.objects.get(device_id=device_map[link['from_device_id']], - cid=link['from_interface_id']).pk, - to_interface_id=Interface.objects.get(device_id=device_map[link['to_device_id']], - cid=link['to_interface_id']).pk) - (Topology.objects - .filter(pk=topology_id, link_id_seq__lt=link['id']) - .update(link_id_seq=link['id'])) - - def onLinkDestroy(self, link, topology_id, client_id): - logger.debug("Link deleted %s", link) - device_map = dict(Device.objects - .filter(topology_id=topology_id, cid__in=[link['from_device_id'], link['to_device_id']]) - .values_list('cid', 'pk')) - if link['from_device_id'] not in device_map: - logger.warning('Device not found') - return - if link['to_device_id'] not in device_map: - logger.warning('Device not found') - return - Link.objects.filter(cid=link['id'], - from_device_id=device_map[link['from_device_id']], - to_device_id=device_map[link['to_device_id']], - from_interface_id=Interface.objects.get(device_id=device_map[link['from_device_id']], - cid=link['from_interface_id']).pk, - to_interface_id=Interface.objects.get(device_id=device_map[link['to_device_id']], - cid=link['to_interface_id']).pk).delete() - - def onDeviceSelected(self, message_value, topology_id, client_id): - 'Ignore DeviceSelected messages' - pass - - def onDeviceUnSelected(self, message_value, topology_id, client_id): - 'Ignore DeviceSelected messages' - pass - - def onLinkSelected(self, message_value, topology_id, client_id): - 'Ignore LinkSelected messages' - pass - - def onLinkUnSelected(self, message_value, topology_id, client_id): - 'Ignore LinkSelected messages' - pass - - def onMultipleMessage(self, message_value, topology_id, client_id): - for message in message_value['messages']: - handler = self.get_handler(message['msg_type']) - if handler is not None: - handler(message, topology_id, client_id) - else: - logger.warning("Unsupported message %s", message['msg_type']) - - -networking_events_dispatcher = NetworkingEvents() - - -@channel_session_user_from_http -def ws_connect(message): - if not message.user.is_authenticated(): - logger.error("Request user is not authenticated to use websocket.") - message.reply_channel.send({"close": True}) - return - else: - message.reply_channel.send({"accept": True}) - - data = urlparse.parse_qs(message.content['query_string']) - inventory_id = parse_inventory_id(data) - try: - inventory = Inventory.objects.get(id=inventory_id) - except Inventory.DoesNotExist: - logger.error("User {} attempted connecting inventory_id {} that does not exist.".format( - message.user.id, inventory_id) - ) - message.reply_channel.send({"close": True}) - return - if message.user not in inventory.read_role: - logger.warn("User {} attempted connecting to inventory_id {} without permission.".format( - message.user.id, inventory_id - )) - message.reply_channel.send({"close": True}) - return - message.channel_session['can_edit'] = message.user in inventory.admin_role - topology_ids = list(TopologyInventory.objects.filter(inventory_id=inventory_id).values_list('pk', flat=True)) - topology_id = None - if len(topology_ids) > 0: - topology_id = topology_ids[0] - if topology_id is not None: - topology = Topology.objects.get(pk=topology_id) - else: - topology = Topology(name="topology", scale=0.7, panX=0, panY=0) - topology.save() - TopologyInventory(inventory_id=inventory_id, topology_id=topology.pk).save() - topology_id = topology.pk - message.channel_session['topology_id'] = topology_id - channels.Group("topology-%s" % topology_id).add(message.reply_channel) - client_id = six.text_type(uuid.uuid4()) - message.channel_session['client_id'] = client_id - channels.Group("client-%s" % client_id).add(message.reply_channel) - message.reply_channel.send({"text": json.dumps(["id", client_id])}) - message.reply_channel.send({"text": json.dumps(["topology_id", topology_id])}) - topology_data = transform_dict(dict(id='topology_id', - name='name', - panX='panX', - panY='panY', - scale='scale', - link_id_seq='link_id_seq', - device_id_seq='device_id_seq'), topology.__dict__) - - message.reply_channel.send({"text": json.dumps(["Topology", topology_data])}) - send_snapshot(message.reply_channel, topology_id) - - -def send_snapshot(channel, topology_id): - interfaces = defaultdict(list) - - for i in (Interface.objects - .filter(device__topology_id=topology_id) - .values()): - i = transform_dict(dict(cid='id', - device_id='device_id', - id='interface_id', - name='name'), i) - interfaces[i['device_id']].append(i) - devices = list(Device.objects.filter(topology_id=topology_id).values()) - devices = [transform_dict(dict(cid='id', - id='device_id', - device_type='device_type', - host_id='host_id', - name='name', - x='x', - y='y', - interface_id_seq='interface_id_seq'), x) for x in devices] - for device in devices: - device['interfaces'] = interfaces[device['device_id']] - - links = [dict(id=x['cid'], - name=x['name'], - from_device_id=x['from_device__cid'], - to_device_id=x['to_device__cid'], - from_interface_id=x['from_interface__cid'], - to_interface_id=x['to_interface__cid']) - for x in list(Link.objects - .filter(Q(from_device__topology_id=topology_id) | - Q(to_device__topology_id=topology_id)) - .values('cid', - 'name', - 'from_device__cid', - 'to_device__cid', - 'from_interface__cid', - 'to_interface__cid'))] - snapshot = dict(sender=0, - devices=devices, - links=links) - channel.send({"text": json.dumps(["Snapshot", snapshot])}) - - -@channel_session_user -def ws_message(message): - # Send to all clients editing the topology - if message.channel_session['can_edit']: - channels.Group("topology-%s" % message.channel_session['topology_id']).send({"text": message['text']}) - # Send to networking_events handler - networking_events_dispatcher.handle({"text": message['text'], - "topology": message.channel_session['topology_id'], - "client": message.channel_session['client_id'], - "can_edit": message.channel_session['can_edit']}) - - -@channel_session_user -def ws_disconnect(message): - if 'topology_id' in message.channel_session: - channels.Group("topology-%s" % message.channel_session['topology_id']).discard(message.reply_channel) diff --git a/awx/network_ui/docs/README.md b/awx/network_ui/docs/README.md deleted file mode 100644 index 2c8ff94bda..0000000000 --- a/awx/network_ui/docs/README.md +++ /dev/null @@ -1,8 +0,0 @@ - - -The design files in this directory are used in the database schema designer tool. - -* [models.png](models.png) - An image of the database schema design for network UI. -* [models.yml](models.yml) - Provides the main schema design for the network UI project. - -![Models](models.png) diff --git a/awx/network_ui/docs/messages.yml b/awx/network_ui/docs/messages.yml deleted file mode 100644 index 06ee3b9b75..0000000000 --- a/awx/network_ui/docs/messages.yml +++ /dev/null @@ -1,19 +0,0 @@ -messages: - - {msg_type: DeviceMove, fields: [msg_type, sender, id, x, y, previous_x, previous_y]} - - {msg_type: DeviceCreate, fields: [msg_type, sender, id, x, y, name, type, host_id]} - - {msg_type: DeviceDestroy, fields: [msg_type, sender, id, previous_x, previous_y, previous_name, previous_type, previous_host_id]} - - {msg_type: DeviceLabelEdit, fields: [msg_type, sender, id, name, previous_name]} - - {msg_type: DeviceSelected, fields: [msg_type, sender, id]} - - {msg_type: DeviceUnSelected, fields: [msg_type, sender, id]} - - {msg_type: InterfaceCreate, fields: [msg_type, sender, device_id, id, name]} - - {msg_type: InterfaceLabelEdit, fields: [msg_type, sender, id, device_id, name, previous_name]} - - {msg_type: LinkLabelEdit, fields: [msg_type, sender, id, name, previous_name]} - - {msg_type: LinkCreate, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]} - - {msg_type: LinkDestroy, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]} - - {msg_type: LinkSelected, fields: [msg_type, sender, id]} - - {msg_type: LinkUnSelected, fields: [msg_type, sender, id]} - - {msg_type: MultipleMessage, fields: [msg_type, sender, messages]} - - {msg_type: Snapshot, fields: [msg_type, sender, devices, links, order, trace_id]} - - {msg_type: id, type: int} - - {msg_type: topology_id, type: int} - - {msg_type: Topology, fields: [topology_id, name, panX, panY, scale, link_id_seq, device_id_seq]} diff --git a/awx/network_ui/docs/models.png b/awx/network_ui/docs/models.png deleted file mode 100644 index c6b22910d8..0000000000 Binary files a/awx/network_ui/docs/models.png and /dev/null differ diff --git a/awx/network_ui/docs/models.yml b/awx/network_ui/docs/models.yml deleted file mode 100644 index 3176306249..0000000000 --- a/awx/network_ui/docs/models.yml +++ /dev/null @@ -1,123 +0,0 @@ -app: awx.network_ui -external_models: [] -models: -- display: name - fields: - - name: device_id - pk: true - type: AutoField - - name: topology - ref: Topology - ref_field: topology_id - type: ForeignKey - - len: 200 - name: name - type: CharField - - name: x - type: IntegerField - - name: y - type: IntegerField - - name: id - type: IntegerField - - len: 200 - name: device_type - type: CharField - - default: 0 - name: interface_id_seq - type: IntegerField - - default: 0 - name: host_id - type: IntegerField - name: Device - x: 348 - y: 124 -- fields: - - name: link_id - pk: true - type: AutoField - - name: from_device - ref: Device - ref_field: device_id - related_name: from_link - type: ForeignKey - - name: to_device - ref: Device - ref_field: device_id - related_name: to_link - type: ForeignKey - - name: from_interface - ref: Interface - ref_field: interface_id - related_name: from_link - type: ForeignKey - - name: to_interface - ref: Interface - ref_field: interface_id - related_name: to_link - type: ForeignKey - - name: id - type: IntegerField - - len: 200 - name: name - type: CharField - name: Link - x: 731 - y: -33 -- display: name - fields: - - name: topology_id - pk: true - type: AutoField - - len: 200 - name: name - type: CharField - - name: scale - type: FloatField - - name: panX - type: FloatField - - name: panY - type: FloatField - - default: 0 - name: device_id_seq - type: IntegerField - - default: 0 - name: link_id_seq - type: IntegerField - name: Topology - x: 111 - y: 127 -- display: name - fields: - - name: interface_id - pk: true - type: AutoField - - name: device - ref: Device - ref_field: device_id - type: ForeignKey - - len: 200 - name: name - type: CharField - - name: id - type: IntegerField - name: Interface - x: 977 - y: 312 -- fields: - - name: topology_inventory_id - pk: true - type: AutoField - - name: topology - ref: Topology - ref_field: topology_id - type: ForeignKey - - name: inventory_id - type: IntegerField - name: TopologyInventory - x: -204 - y: 12 -modules: [] -view: - panX: 213.729555519212 - panY: 189.446959094643 - scaleXY: 0.69 diff --git a/awx/network_ui/migrations/0001_initial.py b/awx/network_ui/migrations/0001_initial.py deleted file mode 100644 index 07013104e1..0000000000 --- a/awx/network_ui/migrations/0001_initial.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.11 on 2018-03-23 20:43 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('main', '0027_v330_emitted_events'), - ] - - operations = [ - migrations.CreateModel( - name='Client', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ], - ), - migrations.CreateModel( - name='Device', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('name', models.CharField(blank=True, max_length=200)), - ('x', models.IntegerField()), - ('y', models.IntegerField()), - ('cid', models.IntegerField()), - ('device_type', models.CharField(blank=True, max_length=200)), - ('interface_id_seq', models.IntegerField(default=0)), - ('host', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.Host')), - ], - ), - migrations.CreateModel( - name='Interface', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('name', models.CharField(blank=True, max_length=200)), - ('cid', models.IntegerField()), - ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Device')), - ], - ), - migrations.CreateModel( - name='Link', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('cid', models.IntegerField()), - ('name', models.CharField(blank=True, max_length=200)), - ('from_device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='from_link', to='network_ui.Device')), - ('from_interface', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='from_link', to='network_ui.Interface')), - ('to_device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='to_link', to='network_ui.Device')), - ('to_interface', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='to_link', to='network_ui.Interface')), - ], - ), - migrations.CreateModel( - name='Topology', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('name', models.CharField(blank=True, max_length=200)), - ('scale', models.FloatField()), - ('panX', models.FloatField()), - ('panY', models.FloatField()), - ('device_id_seq', models.IntegerField(default=0)), - ('link_id_seq', models.IntegerField(default=0)), - ], - ), - migrations.CreateModel( - name='TopologyInventory', - fields=[ - ('id', models.AutoField(primary_key=True, serialize=False)), - ('inventory', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Inventory')), - ('topology', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Topology')), - ], - ), - migrations.AddField( - model_name='device', - name='topology', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='network_ui.Topology'), - ), - ] diff --git a/awx/network_ui/migrations/0002_delete_client.py b/awx/network_ui/migrations/0002_delete_client.py deleted file mode 100644 index fe5708fa3c..0000000000 --- a/awx/network_ui/migrations/0002_delete_client.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.11 on 2018-05-30 17:18 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('network_ui', '0001_initial'), - ] - - operations = [ - migrations.DeleteModel( - name='Client', - ), - ] diff --git a/awx/network_ui/migrations/__init__.py b/awx/network_ui/migrations/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/awx/network_ui/models.py b/awx/network_ui/models.py deleted file mode 100644 index 9712a6ce00..0000000000 --- a/awx/network_ui/models.py +++ /dev/null @@ -1,60 +0,0 @@ -from django.db import models - - -class Device(models.Model): - - id = models.AutoField(primary_key=True,) - topology = models.ForeignKey('Topology',) - name = models.CharField(max_length=200, blank=True) - x = models.IntegerField() - y = models.IntegerField() - cid = models.IntegerField() - device_type = models.CharField(max_length=200, blank=True) - interface_id_seq = models.IntegerField(default=0,) - host = models.ForeignKey('main.Host', default=None, null=True, on_delete=models.SET_NULL) - - def __unicode__(self): - return self.name - - -class Link(models.Model): - - id = models.AutoField(primary_key=True,) - from_device = models.ForeignKey('Device', related_name='from_link',) - to_device = models.ForeignKey('Device', related_name='to_link',) - from_interface = models.ForeignKey('Interface', related_name='from_link',) - to_interface = models.ForeignKey('Interface', related_name='to_link',) - cid = models.IntegerField() - name = models.CharField(max_length=200, blank=True) - - -class Topology(models.Model): - - id = models.AutoField(primary_key=True,) - name = models.CharField(max_length=200, blank=True) - scale = models.FloatField() - panX = models.FloatField() - panY = models.FloatField() - device_id_seq = models.IntegerField(default=0,) - link_id_seq = models.IntegerField(default=0,) - - def __unicode__(self): - return self.name - - -class Interface(models.Model): - - id = models.AutoField(primary_key=True,) - device = models.ForeignKey('Device',) - name = models.CharField(max_length=200, blank=True) - cid = models.IntegerField() - - def __unicode__(self): - return self.name - - -class TopologyInventory(models.Model): - - id = models.AutoField(primary_key=True,) - topology = models.ForeignKey('Topology',) - inventory = models.ForeignKey('main.Inventory') diff --git a/awx/network_ui/routing.py b/awx/network_ui/routing.py deleted file mode 100644 index 0a9d07635d..0000000000 --- a/awx/network_ui/routing.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2017 Red Hat, Inc -from channels.routing import route -from awx.network_ui.consumers import ws_connect, ws_message, ws_disconnect - -channel_routing = [ - route("websocket.connect", ws_connect, path=r"^/network_ui/topology/"), - route("websocket.receive", ws_message, path=r"^/network_ui/topology/"), - route("websocket.disconnect", ws_disconnect, path=r"^/network_ui/topology/"), -] diff --git a/awx/network_ui/tests/__init__.py b/awx/network_ui/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/awx/network_ui/tests/conftest.py b/awx/network_ui/tests/conftest.py deleted file mode 100644 index ca4f2f1cda..0000000000 --- a/awx/network_ui/tests/conftest.py +++ /dev/null @@ -1,9 +0,0 @@ -import pytest -from mock import PropertyMock - - -@pytest.fixture(autouse=True) -def _disable_database_settings(mocker): - m = mocker.patch('awx.conf.settings.SettingsWrapper.all_supported_settings', new_callable=PropertyMock) - m.return_value = [] - diff --git a/awx/network_ui/tests/functional/__init__.py b/awx/network_ui/tests/functional/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/awx/network_ui/tests/functional/test_consumers.py b/awx/network_ui/tests/functional/test_consumers.py deleted file mode 100644 index 3b6c0c38d3..0000000000 --- a/awx/network_ui/tests/functional/test_consumers.py +++ /dev/null @@ -1,246 +0,0 @@ -import mock -import logging -import json -import imp -from mock import patch -patch('channels.auth.channel_session_user', lambda x: x).start() -patch('channels.auth.channel_session_user_from_http', lambda x: x).start() - -from awx.main.models import Inventory # noqa -from awx.network_ui.consumers import parse_inventory_id, networking_events_dispatcher, send_snapshot # noqa -from awx.network_ui.models import Topology, Device, Link, Interface, TopologyInventory # noqa -import awx # noqa -import awx.network_ui # noqa -import awx.network_ui.consumers # noqa -imp.reload(awx.network_ui.consumers) - - -def test_parse_inventory_id(): - assert parse_inventory_id({}) is None - assert parse_inventory_id({'inventory_id': ['1']}) == 1 - assert parse_inventory_id({'inventory_id': ['0']}) is None - assert parse_inventory_id({'inventory_id': ['X']}) is None - assert parse_inventory_id({'inventory_id': []}) is None - assert parse_inventory_id({'inventory_id': 'x'}) is None - assert parse_inventory_id({'inventory_id': '12345'}) == 1 - assert parse_inventory_id({'inventory_id': 1}) is None - - -def test_network_events_handle_message_incomplete_message1(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle({}) - log_mock.assert_called_once_with( - 'Unsupported message %s: no topology', {}) - - -def test_network_events_handle_message_incomplete_message2(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle({'topology': [0]}) - log_mock.assert_called_once_with( - 'Unsupported message %s: no client', {'topology': [0]}) - - -def test_network_events_handle_message_incomplete_message3(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle({'topology': [1]}) - log_mock.assert_called_once_with( - 'Unsupported message %s: no client', {'topology': [1]}) - - -def test_network_events_handle_message_incomplete_message4(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle({'topology': 1, 'client': 1}) - log_mock.assert_called_once_with('Unsupported message %s: no data', { - 'client': 1, 'topology': 1}) - - -def test_network_events_handle_message_incomplete_message5(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - message = ['DeviceCreate'] - networking_events_dispatcher.handle( - {'topology': 1, 'client': 1, 'text': json.dumps(message)}) - log_mock.assert_called_once_with('Unsupported message %s: no message type', { - 'text': '["DeviceCreate"]', 'client': 1, 'topology': 1}) - - -def test_network_events_handle_message_incomplete_message6(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - message = ['DeviceCreate', []] - networking_events_dispatcher.handle( - {'topology': 1, 'client': 1, 'text': json.dumps(message)}) - log_mock.assert_has_calls([ - mock.call('Message has no sender'), - mock.call('Unsupported message %s: no message type', {'text': '["DeviceCreate", []]', 'client': 1, 'topology': 1})]) - - -def test_network_events_handle_message_incomplete_message7(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - message = ['DeviceCreate', {}] - networking_events_dispatcher.handle( - {'topology': 1, 'client': 1, 'text': json.dumps(message)}) - log_mock.assert_has_calls([ - mock.call('client_id mismatch expected: %s actual %s', 1, None), - mock.call('Unsupported message %s: no message type', {'text': '["DeviceCreate", {}]', 'client': 1, 'topology': 1})]) - - -def test_network_events_handle_message_incomplete_message8(): - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock: - message = ['Unsupported', {'sender': 1}] - networking_events_dispatcher.handle( - {'topology': 1, 'client': 1, 'text': json.dumps(message)}) - log_mock.assert_called_once_with( - 'Unsupported message %s: no handler', u'Unsupported') - - -def test_send_snapshot_empty(): - channel = mock.MagicMock() - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects'),\ - mock.patch.object(Link, 'objects'),\ - mock.patch.object(Interface, 'objects'),\ - mock.patch.object(Topology, 'objects'): - send_snapshot(channel, 1) - log_mock.assert_not_called() - channel.send.assert_called_once_with( - {'text': '["Snapshot", {"links": [], "devices": [], "sender": 0}]'}) - - -def test_send_snapshot_single(): - channel = mock.MagicMock() - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock,\ - mock.patch.object(Link, 'objects'),\ - mock.patch.object(Interface, 'objects') as interface_objects_mock: - - interface_objects_mock.filter.return_value.values.return_value = [ - dict(cid=1, device_id=1, id=1, name="eth0")] - device_objects_mock.filter.return_value.values.return_value = [ - dict(cid=1, id=1, device_type="host", name="host1", x=0, y=0, - interface_id_seq=1, host_id=1)] - send_snapshot(channel, 1) - device_objects_mock.filter.assert_called_once_with(topology_id=1) - device_objects_mock.filter.return_value.values.assert_called_once_with() - interface_objects_mock.filter.assert_called_once_with( - device__topology_id=1) - interface_objects_mock.filter.return_value.values.assert_called_once_with() - log_mock.assert_not_called() - channel.send.assert_called_once_with( - {'text': '''["Snapshot", {"links": [], "devices": [{"interface_id_seq": 1, \ -"name": "host1", "interfaces": [{"id": 1, "device_id": 1, "name": "eth0", "interface_id": 1}], \ -"device_type": "host", "host_id": 1, "y": 0, "x": 0, "id": 1, "device_id": 1}], "sender": 0}]'''}) - - -def test_ws_disconnect(): - message = mock.MagicMock() - message.channel_session = dict(topology_id=1) - message.reply_channel = 'foo' - with mock.patch('channels.Group') as group_mock: - awx.network_ui.consumers.ws_disconnect(message) - group_mock.assert_called_once_with('topology-1') - group_mock.return_value.discard.assert_called_once_with('foo') - - -def test_ws_disconnect_no_topology(): - message = mock.MagicMock() - with mock.patch('channels.Group') as group_mock: - awx.network_ui.consumers.ws_disconnect(message) - group_mock.assert_not_called() - - -def test_ws_message(): - message = mock.MagicMock() - message.channel_session = dict(topology_id=1, client_id=1) - message.__getitem__.return_value = json.dumps([]) - print (message['text']) - with mock.patch('channels.Group') as group_mock: - awx.network_ui.consumers.ws_message(message) - group_mock.assert_called_once_with('topology-1') - group_mock.return_value.send.assert_called_once_with({'text': '[]'}) - - -def test_ws_connect_unauthenticated(): - message = mock.MagicMock() - message.user.is_authenticated.return_value = False - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch.object(logger, 'error') as log_mock: - awx.network_ui.consumers.ws_connect(message) - log_mock.assert_called_once_with('Request user is not authenticated to use websocket.') - - -def test_ws_connect_new_topology(): - mock_user = mock.Mock() - message = mock.MagicMock(user=mock_user) - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch('awx.network_ui.consumers.uuid') as client_mock,\ - mock.patch('awx.network_ui.consumers.Topology') as topology_mock,\ - mock.patch('channels.Group'),\ - mock.patch('awx.network_ui.consumers.send_snapshot') as send_snapshot_mock,\ - mock.patch.object(logger, 'warning'),\ - mock.patch.object(TopologyInventory, 'objects'),\ - mock.patch.object(TopologyInventory, 'save'),\ - mock.patch.object(Topology, 'save'),\ - mock.patch.object(Topology, 'objects'),\ - mock.patch.object(Device, 'objects'),\ - mock.patch.object(Link, 'objects'),\ - mock.patch.object(Interface, 'objects'),\ - mock.patch.object(Inventory, 'objects') as inventory_objects: - client_mock.uuid4 = mock.MagicMock(return_value="777") - topology_mock.return_value = Topology( - name="topology", scale=0.7, panX=0, panY=0, pk=999) - inventory_objects.get.return_value = mock.Mock(admin_role=[mock_user]) - awx.network_ui.consumers.ws_connect(message) - message.reply_channel.send.assert_has_calls([ - mock.call({'text': '["id", "777"]'}), - mock.call({'text': '["topology_id", 999]'}), - mock.call( - {'text': '["Topology", {"scale": 1.0, "name": "topology", "device_id_seq": 0, "panY": 0, "panX": 0, "topology_id": 999, "link_id_seq": 0}]'}), - ]) - send_snapshot_mock.assert_called_once_with(message.reply_channel, 999) - - -def test_ws_connect_existing_topology(): - mock_user = mock.Mock() - message = mock.MagicMock(user=mock_user) - logger = logging.getLogger('awx.network_ui.consumers') - with mock.patch('awx.network_ui.consumers.uuid') as client_mock,\ - mock.patch('awx.network_ui.consumers.send_snapshot') as send_snapshot_mock,\ - mock.patch('channels.Group'),\ - mock.patch.object(logger, 'warning'),\ - mock.patch.object(TopologyInventory, 'objects') as topology_inventory_objects_mock,\ - mock.patch.object(TopologyInventory, 'save'),\ - mock.patch.object(Topology, 'save'),\ - mock.patch.object(Topology, 'objects') as topology_objects_mock,\ - mock.patch.object(Device, 'objects'),\ - mock.patch.object(Link, 'objects'),\ - mock.patch.object(Interface, 'objects'),\ - mock.patch.object(Inventory, 'objects') as inventory_objects: - topology_inventory_objects_mock.filter.return_value.values_list.return_value = [ - 1] - client_mock.uuid4 = mock.MagicMock(return_value="888") - topology_objects_mock.get.return_value = Topology(pk=1001, - id=1, - name="topo", - panX=0, - panY=0, - scale=1.0, - link_id_seq=1, - device_id_seq=1) - inventory_objects.get.return_value = mock.Mock(admin_role=[mock_user]) - awx.network_ui.consumers.ws_connect(message) - message.reply_channel.send.assert_has_calls([ - mock.call({'text': '["id", "888"]'}), - mock.call({'text': '["topology_id", 1001]'}), - mock.call( - {'text': '["Topology", {"scale": 1.0, "name": "topo", "device_id_seq": 1, "panY": 0, "panX": 0, "topology_id": 1001, "link_id_seq": 1}]'}), - ]) - send_snapshot_mock.assert_called_once_with(message.reply_channel, 1001) diff --git a/awx/network_ui/tests/functional/test_models.py b/awx/network_ui/tests/functional/test_models.py deleted file mode 100644 index 8d439dca22..0000000000 --- a/awx/network_ui/tests/functional/test_models.py +++ /dev/null @@ -1,54 +0,0 @@ -import pytest - -import inspect - -from awx.network_ui.models import Device, Topology, Interface, Link - -from awx.main.models import Organization, Inventory -from awx.main.tasks import delete_inventory - -from django.db.models import Model - - -def test_device(): - assert str(Device(name="foo")) == "foo" - - -def test_topology(): - assert str(Topology(name="foo")) == "foo" - - -def test_interface(): - assert str(Interface(name="foo")) == "foo" - - -@pytest.mark.django_db -def test_deletion(): - org = Organization.objects.create(name='Default') - inv = Inventory.objects.create(name='inv', organization=org) - host1 = inv.hosts.create(name='foo') - host2 = inv.hosts.create(name='bar') - topology = Topology.objects.create( - name='inv', scale=0.7, panX=0.0, panY=0.0 - ) - inv.topologyinventory_set.create(topology=topology) - device1 = topology.device_set.create(name='foo', host=host1, x=0.0, y=0.0, cid=1) - interface1 = Interface.objects.create(device=device1, name='foo', cid=2) - device2 = topology.device_set.create(name='bar', host=host2, x=0.0, y=0.0, cid=3) - interface2 = Interface.objects.create(device=device2, name='bar', cid=4) - Link.objects.create( - from_device=device1, to_device=device2, - from_interface=interface1, to_interface=interface2, - cid=10 - ) - - network_ui_models = [] - from awx.network_ui import models as network_models - for name, model in vars(network_models).items(): - if not inspect.isclass(model) or not issubclass(model, Model): - continue - network_ui_models.append(model) - - delete_inventory.run(inv.pk, None) - for cls in network_ui_models: - assert cls.objects.count() == 0, cls diff --git a/awx/network_ui/tests/functional/test_network_events.py b/awx/network_ui/tests/functional/test_network_events.py deleted file mode 100644 index d4ce60c7ae..0000000000 --- a/awx/network_ui/tests/functional/test_network_events.py +++ /dev/null @@ -1,451 +0,0 @@ -import mock -import json -import logging - -from awx.network_ui.consumers import networking_events_dispatcher -from awx.network_ui.models import Topology, Device, Link, Interface - - -def message(message): - def wrapper(fn): - fn.tests_message = message - return fn - return wrapper - - -@message('DeviceMove') -def test_network_events_handle_message_DeviceMove(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['DeviceMove', dict( - msg_type='DeviceMove', - sender=1, - id=1, - x=100, - y=100, - previous_x=0, - previous_y=0 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock: - networking_events_dispatcher.handle(message) - device_objects_mock.filter.assert_called_once_with( - cid=1, topology_id=1) - device_objects_mock.filter.return_value.update.assert_called_once_with( - x=100, y=100) - log_mock.assert_not_called() - - -@message('DeviceCreate') -def test_network_events_handle_message_DeviceCreate(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['DeviceCreate', dict(msg_type='DeviceCreate', - sender=1, - id=1, - x=0, - y=0, - name="test_created", - type='host', - host_id=None)] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Topology.objects, 'filter') as topology_objects_mock,\ - mock.patch.object(Device.objects, 'get_or_create') as device_objects_mock: - device_mock = mock.MagicMock() - filter_mock = mock.MagicMock() - device_objects_mock.return_value = [device_mock, True] - topology_objects_mock.return_value = filter_mock - networking_events_dispatcher.handle(message) - device_objects_mock.assert_called_once_with( - cid=1, - defaults={'name': u'test_created', 'cid': 1, 'device_type': u'host', - 'x': 0, 'y': 0, 'host_id': None}, - topology_id=1) - device_mock.save.assert_called_once_with() - topology_objects_mock.assert_called_once_with( - device_id_seq__lt=1, pk=1) - filter_mock.update.assert_called_once_with(device_id_seq=1) - log_mock.assert_not_called() - - -@message('DeviceLabelEdit') -def test_network_events_handle_message_DeviceLabelEdit(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['DeviceLabelEdit', dict( - msg_type='DeviceLabelEdit', - sender=1, - id=1, - name='test_changed', - previous_name='test_created' - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device.objects, 'filter') as device_objects_filter_mock: - networking_events_dispatcher.handle(message) - device_objects_filter_mock.assert_called_once_with( - cid=1, topology_id=1) - log_mock.assert_not_called() - - -@message('DeviceSelected') -def test_network_events_handle_message_DeviceSelected(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['DeviceSelected', dict( - msg_type='DeviceSelected', - sender=1, - id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle(message) - log_mock.assert_not_called() - - -@message('DeviceUnSelected') -def test_network_events_handle_message_DeviceUnSelected(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['DeviceUnSelected', dict( - msg_type='DeviceUnSelected', - sender=1, - id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle(message) - log_mock.assert_not_called() - - -@message('DeviceDestroy') -def test_network_events_handle_message_DeviceDestory(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['DeviceDestroy', dict( - msg_type='DeviceDestroy', - sender=1, - id=1, - previous_x=0, - previous_y=0, - previous_name="", - previous_type="host", - previous_host_id="1")] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock: - networking_events_dispatcher.handle(message) - device_objects_mock.filter.assert_called_once_with( - cid=1, topology_id=1) - device_objects_mock.filter.return_value.delete.assert_called_once_with() - log_mock.assert_not_called() - - -@message('InterfaceCreate') -def test_network_events_handle_message_InterfaceCreate(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['InterfaceCreate', dict( - msg_type='InterfaceCreate', - sender=1, - device_id=1, - id=1, - name='eth0' - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock,\ - mock.patch.object(Interface, 'objects') as interface_objects_mock: - device_objects_mock.get.return_value.pk = 99 - networking_events_dispatcher.handle(message) - device_objects_mock.get.assert_called_once_with(cid=1, topology_id=1) - device_objects_mock.filter.assert_called_once_with( - cid=1, interface_id_seq__lt=1, topology_id=1) - interface_objects_mock.get_or_create.assert_called_once_with( - cid=1, defaults={'name': u'eth0'}, device_id=99) - log_mock.assert_not_called() - - -@message('InterfaceLabelEdit') -def test_network_events_handle_message_InterfaceLabelEdit(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['InterfaceLabelEdit', dict( - msg_type='InterfaceLabelEdit', - sender=1, - id=1, - device_id=1, - name='new name', - previous_name='old name' - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Interface, 'objects') as interface_objects_mock: - networking_events_dispatcher.handle(message) - interface_objects_mock.filter.assert_called_once_with( - cid=1, device__cid=1, device__topology_id=1) - interface_objects_mock.filter.return_value.update.assert_called_once_with( - name=u'new name') - log_mock.assert_not_called() - - -@message('LinkLabelEdit') -def test_network_events_handle_message_LinkLabelEdit(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkLabelEdit', dict( - msg_type='LinkLabelEdit', - sender=1, - id=1, - name='new name', - previous_name='old name' - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Link, 'objects') as link_objects_mock: - networking_events_dispatcher.handle(message) - link_objects_mock.filter.assert_called_once_with( - cid=1, from_device__topology_id=1) - link_objects_mock.filter.return_value.update.assert_called_once_with( - name=u'new name') - log_mock.assert_not_called() - - -@message('LinkCreate') -def test_network_events_handle_message_LinkCreate(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkCreate', dict( - msg_type='LinkCreate', - id=1, - sender=1, - name="", - from_device_id=1, - to_device_id=2, - from_interface_id=1, - to_interface_id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock,\ - mock.patch.object(Link, 'objects') as link_objects_mock,\ - mock.patch.object(Interface, 'objects') as interface_objects_mock,\ - mock.patch.object(Topology, 'objects') as topology_objects_mock: - values_list_mock = mock.MagicMock() - values_list_mock.values_list.return_value = [(1,1), (2,2)] - interface_objects_mock.get.return_value = mock.MagicMock() - interface_objects_mock.get.return_value.pk = 7 - device_objects_mock.filter.return_value = values_list_mock - topology_objects_mock.filter.return_value = mock.MagicMock() - networking_events_dispatcher.handle(message) - device_objects_mock.filter.assert_called_once_with( - cid__in=[1, 2], topology_id=1) - values_list_mock.values_list.assert_called_once_with('cid', 'pk') - link_objects_mock.get_or_create.assert_called_once_with( - cid=1, from_device_id=1, from_interface_id=7, name=u'', - to_device_id=2, to_interface_id=7) - topology_objects_mock.filter.assert_called_once_with( - link_id_seq__lt=1, pk=1) - topology_objects_mock.filter.return_value.update.assert_called_once_with( - link_id_seq=1) - log_mock.assert_not_called() - - -@message('LinkCreate') -def test_network_events_handle_message_LinkCreate_bad_device1(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkCreate', dict( - msg_type='LinkCreate', - id=1, - sender=1, - name="", - from_device_id=1, - to_device_id=2, - from_interface_id=1, - to_interface_id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock,\ - mock.patch.object(Link, 'objects'),\ - mock.patch.object(Interface, 'objects') as interface_objects_mock,\ - mock.patch.object(Topology, 'objects') as topology_objects_mock: - values_list_mock = mock.MagicMock() - values_list_mock.values_list.return_value = [(9,1), (2,2)] - interface_objects_mock.get.return_value = mock.MagicMock() - interface_objects_mock.get.return_value.pk = 7 - device_objects_mock.filter.return_value = values_list_mock - topology_objects_mock.filter.return_value = mock.MagicMock() - networking_events_dispatcher.handle(message) - device_objects_mock.filter.assert_called_once_with( - cid__in=[1, 2], topology_id=1) - values_list_mock.values_list.assert_called_once_with('cid', 'pk') - log_mock.assert_called_once_with('Device not found') - - -@message('LinkCreate') -def test_network_events_handle_message_LinkCreate_bad_device2(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkCreate', dict( - msg_type='LinkCreate', - id=1, - sender=1, - name="", - from_device_id=1, - to_device_id=2, - from_interface_id=1, - to_interface_id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device, 'objects') as device_objects_mock,\ - mock.patch.object(Link, 'objects'),\ - mock.patch.object(Interface, 'objects') as interface_objects_mock,\ - mock.patch.object(Topology, 'objects') as topology_objects_mock: - values_list_mock = mock.MagicMock() - values_list_mock.values_list.return_value = [(1,1), (9,2)] - interface_objects_mock.get.return_value = mock.MagicMock() - interface_objects_mock.get.return_value.pk = 7 - device_objects_mock.filter.return_value = values_list_mock - topology_objects_mock.filter.return_value = mock.MagicMock() - networking_events_dispatcher.handle(message) - device_objects_mock.filter.assert_called_once_with( - cid__in=[1, 2], topology_id=1) - values_list_mock.values_list.assert_called_once_with('cid', 'pk') - log_mock.assert_called_once_with('Device not found') - - -@message('LinkDestroy') -def test_network_events_handle_message_LinkDestroy(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkDestroy', dict( - msg_type='LinkDestroy', - id=1, - sender=1, - name="", - from_device_id=1, - to_device_id=2, - from_interface_id=1, - to_interface_id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device.objects, 'filter') as device_filter_mock,\ - mock.patch.object(Link.objects, 'filter') as link_filter_mock,\ - mock.patch.object(Interface.objects, 'get') as interface_get_mock: - values_mock = mock.MagicMock() - interface_get_mock.return_value = mock.MagicMock() - interface_get_mock.return_value.pk = 7 - device_filter_mock.return_value = values_mock - values_mock.values_list.return_value = [(1,1), (2,2)] - networking_events_dispatcher.handle(message) - device_filter_mock.assert_called_once_with( - cid__in=[1, 2], topology_id=1) - values_mock.values_list.assert_called_once_with('cid', 'pk') - link_filter_mock.assert_called_once_with( - cid=1, from_device_id=1, from_interface_id=7, to_device_id=2, to_interface_id=7) - log_mock.assert_not_called() - - -@message('LinkDestroy') -def test_network_events_handle_message_LinkDestroy_bad_device_map1(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkDestroy', dict( - msg_type='LinkDestroy', - id=1, - sender=1, - name="", - from_device_id=1, - to_device_id=2, - from_interface_id=1, - to_interface_id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device.objects, 'filter') as device_filter_mock,\ - mock.patch.object(Link.objects, 'filter'),\ - mock.patch.object(Interface.objects, 'get') as interface_get_mock: - values_mock = mock.MagicMock() - interface_get_mock.return_value = mock.MagicMock() - interface_get_mock.return_value.pk = 7 - device_filter_mock.return_value = values_mock - values_mock.values_list.return_value = [(9,1), (2,2)] - networking_events_dispatcher.handle(message) - log_mock.assert_called_once_with('Device not found') - - -@message('LinkDestroy') -def test_network_events_handle_message_LinkDestroy_bad_device_map2(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkDestroy', dict( - msg_type='LinkDestroy', - id=1, - sender=1, - name="", - from_device_id=1, - to_device_id=2, - from_interface_id=1, - to_interface_id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock,\ - mock.patch.object(Device.objects, 'filter') as device_filter_mock,\ - mock.patch.object(Link.objects, 'filter'),\ - mock.patch.object(Interface.objects, 'get') as interface_get_mock: - values_mock = mock.MagicMock() - interface_get_mock.return_value = mock.MagicMock() - interface_get_mock.return_value.pk = 7 - device_filter_mock.return_value = values_mock - values_mock.values_list.return_value = [(1,1), (9,2)] - networking_events_dispatcher.handle(message) - log_mock.assert_called_once_with('Device not found') - - -@message('LinkSelected') -def test_network_events_handle_message_LinkSelected(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkSelected', dict( - msg_type='LinkSelected', - sender=1, - id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle(message) - log_mock.assert_not_called() - - -@message('LinkUnSelected') -def test_network_events_handle_message_LinkUnSelected(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['LinkUnSelected', dict( - msg_type='LinkUnSelected', - sender=1, - id=1 - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle(message) - log_mock.assert_not_called() - - -@message('MultipleMessage') -def test_network_events_handle_message_MultipleMessage_unsupported_message(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['MultipleMessage', dict( - msg_type='MultipleMessage', - sender=1, - messages=[dict(msg_type="Unsupported")] - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle(message) - log_mock.assert_called_once_with( - 'Unsupported message %s', u'Unsupported') - - -@message('MultipleMessage') -def test_network_events_handle_message_MultipleMessage(): - logger = logging.getLogger('awx.network_ui.consumers') - message_data = ['MultipleMessage', dict( - msg_type='MultipleMessage', - sender=1, - messages=[dict(msg_type="DeviceSelected")] - )] - message = {'topology': 1, 'client': 1, 'text': json.dumps(message_data)} - with mock.patch.object(logger, 'warning') as log_mock: - networking_events_dispatcher.handle(message) - log_mock.assert_not_called() diff --git a/awx/network_ui/tests/functional/test_routing.py b/awx/network_ui/tests/functional/test_routing.py deleted file mode 100644 index d1d7a741dd..0000000000 --- a/awx/network_ui/tests/functional/test_routing.py +++ /dev/null @@ -1,9 +0,0 @@ - -import awx.network_ui.routing - - -def test_routing(): - ''' - Tests that the number of routes in awx.network_ui.routing is 3. - ''' - assert len(awx.network_ui.routing.channel_routing) == 3 diff --git a/awx/network_ui/tests/functional/test_views.py b/awx/network_ui/tests/functional/test_views.py deleted file mode 100644 index 9b55ad72d4..0000000000 --- a/awx/network_ui/tests/functional/test_views.py +++ /dev/null @@ -1,65 +0,0 @@ - -import mock - -from awx.network_ui.views import topology_data, NetworkAnnotatedInterface, json_topology_data, yaml_topology_data -from awx.network_ui.models import Topology, Device, Link, Interface - - - -def test_topology_data(): - with mock.patch.object(Topology, 'objects'),\ - mock.patch.object(Device, 'objects') as device_objects_mock,\ - mock.patch.object(Link, 'objects') as link_objects_mock,\ - mock.patch.object(Interface, 'objects'),\ - mock.patch.object(NetworkAnnotatedInterface, 'filter'): - device_objects_mock.filter.return_value.order_by.return_value = [ - Device(pk=1), Device(pk=2)] - link_objects_mock.filter.return_value = [Link(from_device=Device(name='from', cid=1), - to_device=Device( - name='to', cid=2), - from_interface=Interface( - name="eth0", cid=1), - to_interface=Interface( - name="eth0", cid=1), - name="", - pk=1 - )] - data = topology_data(1) - assert len(data['devices']) == 2 - assert len(data['links']) == 1 - - -def test_json_topology_data(): - request = mock.MagicMock() - request.GET = dict(topology_id=1) - with mock.patch('awx.network_ui.views.topology_data') as topology_data_mock: - topology_data_mock.return_value = dict() - json_topology_data(request) - topology_data_mock.assert_called_once_with(1) - - -def test_yaml_topology_data(): - request = mock.MagicMock() - request.GET = dict(topology_id=1) - with mock.patch('awx.network_ui.views.topology_data') as topology_data_mock: - topology_data_mock.return_value = dict() - yaml_topology_data(request) - topology_data_mock.assert_called_once_with(1) - - -def test_json_topology_data_no_topology_id(): - request = mock.MagicMock() - request.GET = dict() - with mock.patch('awx.network_ui.views.topology_data') as topology_data_mock: - topology_data_mock.return_value = dict() - json_topology_data(request) - topology_data_mock.assert_not_called() - - -def test_yaml_topology_data_no_topology_id(): - request = mock.MagicMock() - request.GET = dict() - with mock.patch('awx.network_ui.views.topology_data') as topology_data_mock: - topology_data_mock.return_value = dict() - yaml_topology_data(request) - topology_data_mock.assert_not_called() diff --git a/awx/network_ui/urls.py b/awx/network_ui/urls.py deleted file mode 100644 index 2101eff59f..0000000000 --- a/awx/network_ui/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2017 Red Hat, Inc -from django.conf.urls import url - -from awx.network_ui import views - -app_name = 'network_ui' -urlpatterns = [ - url(r'^topology.json/?$', views.json_topology_data, name='json_topology_data'), - url(r'^topology.yaml/?$', views.yaml_topology_data, name='yaml_topology_data'), -] diff --git a/awx/network_ui/utils.py b/awx/network_ui/utils.py deleted file mode 100644 index 9b2eea6c10..0000000000 --- a/awx/network_ui/utils.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2017 Red Hat, Inc - - -def transform_dict(dict_map, d): - return {to_key: d[from_key] for from_key, to_key in dict_map.iteritems()} - diff --git a/awx/network_ui/views.py b/awx/network_ui/views.py deleted file mode 100644 index b9cd476bcc..0000000000 --- a/awx/network_ui/views.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2017 Red Hat, Inc -from django import forms -from django.http import JsonResponse, HttpResponseBadRequest, HttpResponse -from awx.network_ui.models import Topology, Device, Link, Interface -from django.db.models import Q -import yaml - -NetworkAnnotatedInterface = Interface.objects.values('name', - 'cid', - 'from_link__pk', - 'to_link__pk', - 'from_link__to_device__name', - 'to_link__from_device__name', - 'from_link__to_interface__name', - 'to_link__from_interface__name') - - -def topology_data(topology_id): - - data = dict(devices=[], - links=[]) - - topology = Topology.objects.get(pk=topology_id) - - data['name'] = topology.name - data['topology_id'] = topology_id - - links = list(Link.objects - .filter(Q(from_device__topology_id=topology_id) | - Q(to_device__topology_id=topology_id))) - - interfaces = Interface.objects.filter(device__topology_id=topology_id) - - for device in Device.objects.filter(topology_id=topology_id).order_by('name'): - interfaces = list(NetworkAnnotatedInterface.filter(device_id=device.pk).order_by('name')) - interfaces = [dict(name=x['name'], - network=x['from_link__pk'] or x['to_link__pk'], - remote_device_name=x['from_link__to_device__name'] or x['to_link__from_device__name'], - remote_interface_name=x['from_link__to_interface__name'] or x['to_link__from_interface__name'], - id=x['cid'], - ) for x in interfaces] - data['devices'].append(dict(name=device.name, - type=device.device_type, - x=device.x, - y=device.y, - id=device.cid, - interfaces=interfaces)) - - for link in links: - data['links'].append(dict(from_device=link.from_device.name, - to_device=link.to_device.name, - from_interface=link.from_interface.name, - to_interface=link.to_interface.name, - from_device_id=link.from_device.cid, - to_device_id=link.to_device.cid, - from_interface_id=link.from_interface.cid, - to_interface_id=link.to_interface.cid, - name=link.name, - network=link.pk)) - - return data - - -class TopologyForm(forms.Form): - topology_id = forms.IntegerField() - - -def json_topology_data(request): - form = TopologyForm(request.GET) - if form.is_valid(): - response = JsonResponse(topology_data(form.cleaned_data['topology_id']), - content_type='application/force-download') - response['Content-Disposition'] = 'attachment; filename="{}"'.format('topology.json') - return response - else: - return HttpResponseBadRequest(form.errors) - - -def yaml_topology_data(request): - form = TopologyForm(request.GET) - if form.is_valid(): - response = HttpResponse(yaml.safe_dump(topology_data(form.cleaned_data['topology_id']), - default_flow_style=False), - content_type='application/force-download') - response['Content-Disposition'] = 'attachment; filename="{}"'.format('topology.yaml') - return response - else: - return HttpResponseBadRequest(form.errors) - diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 818713431e..48440022d5 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -289,8 +289,7 @@ INSTALLED_APPS = ( 'awx.api', 'awx.ui', 'awx.sso', - 'solo', - 'awx.network_ui' + 'solo' ) INTERNAL_IPS = ('127.0.0.1',) diff --git a/awx/ui/build/webpack.base.js b/awx/ui/build/webpack.base.js index 633987dde0..e0e0eb383b 100644 --- a/awx/ui/build/webpack.base.js +++ b/awx/ui/build/webpack.base.js @@ -22,7 +22,6 @@ const SRC_PATH = path.join(CLIENT_PATH, 'src'); const STATIC_PATH = path.join(UI_PATH, 'static'); const TEST_PATH = path.join(UI_PATH, 'test'); const THEME_PATH = path.join(LIB_PATH, 'theme'); -const NETWORK_UI_PATH = path.join(SRC_PATH, 'network-ui'); const APP_ENTRY = path.join(SRC_PATH, 'app.js'); const VENDOR_ENTRY = path.join(SRC_PATH, 'vendor.js'); @@ -208,7 +207,6 @@ const base = { '~test': TEST_PATH, '~theme': THEME_PATH, '~ui': UI_PATH, - '~network-ui': NETWORK_UI_PATH, d3$: '~node_modules/d3/d3.min.js', 'codemirror.jsonlint$': '~node_modules/codemirror/addon/lint/json-lint.js', jquery: '~node_modules/jquery/dist/jquery.js', diff --git a/awx/ui/build/webpack.watch.js b/awx/ui/build/webpack.watch.js index 5bf1aad89c..143058077a 100644 --- a/awx/ui/build/webpack.watch.js +++ b/awx/ui/build/webpack.watch.js @@ -77,12 +77,6 @@ const watch = { target: TARGET, secure: false, ws: true - }, - { - context: '/network_ui', - target: TARGET, - secure: false, - ws: true }] } }; diff --git a/awx/ui/client/index.template.ejs b/awx/ui/client/index.template.ejs index 146d3290d7..b28c5b13ec 100644 --- a/awx/ui/client/index.template.ejs +++ b/awx/ui/client/index.template.ejs @@ -19,7 +19,6 @@ -
diff --git a/awx/ui/client/lib/components/layout/side-nav.partial.html b/awx/ui/client/lib/components/layout/side-nav.partial.html index 5786c13537..8996df899f 100644 --- a/awx/ui/client/lib/components/layout/side-nav.partial.html +++ b/awx/ui/client/lib/components/layout/side-nav.partial.html @@ -1,7 +1,7 @@
+ ng-class="{'at-Layout-side--expanded': vm.isExpanded && layoutVm.isLoggedIn}" ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
+ ng-show="layoutVm.isLoggedIn && !layoutVm.licenseIsMissing">
diff --git a/awx/ui/client/lib/theme/index.less b/awx/ui/client/lib/theme/index.less index 00cc8ddb47..29b4c987c1 100644 --- a/awx/ui/client/lib/theme/index.less +++ b/awx/ui/client/lib/theme/index.less @@ -166,9 +166,3 @@ * the transition. */ @import '_resets'; - -/** - * Network Visualization Style - * - */ -@import '../../src/network-ui/style.less'; diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 257851337d..1c908573cc 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -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', diff --git a/awx/ui/client/src/inventories-hosts/inventories/inventory.list.js b/awx/ui/client/src/inventories-hosts/inventories/inventory.list.js index 5dadf977c6..753956f802 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/inventory.list.js +++ b/awx/ui/client/src/inventories-hosts/inventories/inventory.list.js @@ -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)", diff --git a/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js b/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js index 0c085d793e..7fa200b5f3 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js +++ b/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js @@ -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') { diff --git a/awx/ui/client/src/inventories-hosts/inventories/main.js b/awx/ui/client/src/inventories-hosts/inventories/main.js index cf13eaacd5..20feecfe10 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/main.js +++ b/awx/ui/client/src/inventories-hosts/inventories/main.js @@ -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) ]) }; }); diff --git a/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/edit/smart-inventory-edit.controller.js b/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/edit/smart-inventory-edit.controller.js index be09299704..7af348d0d1 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/edit/smart-inventory-edit.controller.js +++ b/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/edit/smart-inventory-edit.controller.js @@ -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'); }; diff --git a/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js b/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js index edd6846619..01a49b008b 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js +++ b/awx/ui/client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js @@ -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')" - } } }; diff --git a/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js b/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js index 65579c96b9..8f96ae9f6f 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js @@ -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'); }; diff --git a/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js b/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js index 9219c91fe4..98f6e62998 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js +++ b/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js @@ -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'))", diff --git a/awx/ui/client/src/network-ui/.gitignore b/awx/ui/client/src/network-ui/.gitignore deleted file mode 100644 index bc3cac3dd2..0000000000 --- a/awx/ui/client/src/network-ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/extracted diff --git a/awx/ui/client/src/network-ui/CONTRIBUTING.md b/awx/ui/client/src/network-ui/CONTRIBUTING.md deleted file mode 100644 index bf3c2b3a28..0000000000 --- a/awx/ui/client/src/network-ui/CONTRIBUTING.md +++ /dev/null @@ -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: - -**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: - -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: - -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) -``` - - - -``` - -* 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) -``` - -``` - - -**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: - -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: - -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: - - -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: - -**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: -* See: - -**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) - -``` - -``` - - -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. - -![Event Pipeline](designs/pipeline.png) - - -**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: - -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** - -![Link FSM](designs/link.png) - -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: -* See: - -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) - -``` - - - - - ... - -``` - -* 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) - -``` - -``` - -* 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) - -![Toolbox](designs/toolbox.png) - -* 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 diff --git a/awx/ui/client/src/network-ui/Makefile b/awx/ui/client/src/network-ui/Makefile deleted file mode 100644 index 58991a7919..0000000000 --- a/awx/ui/client/src/network-ui/Makefile +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/animation.fsm.js b/awx/ui/client/src/network-ui/animation.fsm.js deleted file mode 100644 index dc1e737d50..0000000000 --- a/awx/ui/client/src/network-ui/animation.fsm.js +++ /dev/null @@ -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); -}; diff --git a/awx/ui/client/src/network-ui/animations.js b/awx/ui/client/src/network-ui/animations.js deleted file mode 100644 index 74ead1a423..0000000000 --- a/awx/ui/client/src/network-ui/animations.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/button.fsm.js b/awx/ui/client/src/network-ui/button.fsm.js deleted file mode 100644 index f32839ecdc..0000000000 --- a/awx/ui/client/src/network-ui/button.fsm.js +++ /dev/null @@ -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; - -}; diff --git a/awx/ui/client/src/network-ui/buttons.fsm.js b/awx/ui/client/src/network-ui/buttons.fsm.js deleted file mode 100644 index 2a01a0bd3a..0000000000 --- a/awx/ui/client/src/network-ui/buttons.fsm.js +++ /dev/null @@ -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']; diff --git a/awx/ui/client/src/network-ui/context.menu.button.directive.js b/awx/ui/client/src/network-ui/context.menu.button.directive.js deleted file mode 100644 index 8e984109cf..0000000000 --- a/awx/ui/client/src/network-ui/context.menu.button.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/context.menu.directive.js b/awx/ui/client/src/network-ui/context.menu.directive.js deleted file mode 100644 index bf92043d34..0000000000 --- a/awx/ui/client/src/network-ui/context.menu.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/context_menu.partial.svg b/awx/ui/client/src/network-ui/context_menu.partial.svg deleted file mode 100644 index 883b532c04..0000000000 --- a/awx/ui/client/src/network-ui/context_menu.partial.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/awx/ui/client/src/network-ui/context_menu_button.partial.svg b/awx/ui/client/src/network-ui/context_menu_button.partial.svg deleted file mode 100644 index 22425b7f9f..0000000000 --- a/awx/ui/client/src/network-ui/context_menu_button.partial.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - -{{contextMenuButton.name}} - -{{contextMenuButton.name}} - diff --git a/awx/ui/client/src/network-ui/cursor.directive.js b/awx/ui/client/src/network-ui/cursor.directive.js deleted file mode 100644 index 340640efb0..0000000000 --- a/awx/ui/client/src/network-ui/cursor.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/cursor.partial.svg b/awx/ui/client/src/network-ui/cursor.partial.svg deleted file mode 100644 index a0f7233bd7..0000000000 --- a/awx/ui/client/src/network-ui/cursor.partial.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/awx/ui/client/src/network-ui/debug.directive.js b/awx/ui/client/src/network-ui/debug.directive.js deleted file mode 100644 index c593f0be5b..0000000000 --- a/awx/ui/client/src/network-ui/debug.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/debug.partial.svg b/awx/ui/client/src/network-ui/debug.partial.svg deleted file mode 100644 index 8a852a9bd3..0000000000 --- a/awx/ui/client/src/network-ui/debug.partial.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - view_port.x: {{view_port.x}} - view_port.y: {{view_port.y}} - view_port.width: {{view_port.width}} - view_port.height: {{view_port.height}} - width: {{graph.width}} - height: {{graph.height}} - rc: {{graph.right_column}} - Mouse down: {{onMouseDownResult}} - Mouse up: {{onMouseUpResult}} - Mouse move: {{onMouseMoveResult}} - Mouse over: {{onMouseOverResult}} - Mouse enter: {{onMouseEnterResult}} - Mouse leave: {{onMouseLeaveResult}} - Current scale: {{current_scale.toFixed(4)}} - Pan X: {{panX.toFixed(2)}} - Pan Y: {{panY.toFixed(2)}} - View State: {{view_controller.state.name}} - Mouse X: {{mouseX.toFixed(2)}} - Mouse Y: {{mouseY.toFixed(2)}} - Scaled X: {{scaledX.toFixed(2)}} - Scaled Y: {{scaledY.toFixed(2)}} - Key: {{last_key}} - Key Code: {{last_key_code}} - Move State: {{move_controller.state.name}} - Move Readonly State: {{move_readonly_controller.state.name}} - Selected devices: {{selected_devices.length}} - Selected links: {{selected_links.length}} - Link State: {{link_controller.state.name}} - Buttons State: {{buttons_controller.state.name}} - Time State: {{time_controller.state.name}} - Time Pointer: {{time_pointer}} - Group State: {{group_controller.state.name}} - Hotkeys State: {{hotkeys_controller.state.name}} - Mode State: {{mode_controller.state.name}} - Device Detail State: {{device_detail_controller.state.name}} - Site State: {{site_controller.state.name}} - Rack State: {{rack_controller.state.name}} - Stream State: {{stream_controller.state.name}} - App Toolbox State: {{app_toolbox_controller.state.name}} - Inventory Toolbox State: {{inventory_toolbox_controller.state.name}} - Rack Toolbox State: {{rack_toolbox_controller.state.name}} - Site Toolbox State: {{site_toolbox_controller.state.name}} - - - - - diff --git a/awx/ui/client/src/network-ui/default.directive.js b/awx/ui/client/src/network-ui/default.directive.js deleted file mode 100644 index 16c469f188..0000000000 --- a/awx/ui/client/src/network-ui/default.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/default.partial.svg b/awx/ui/client/src/network-ui/default.partial.svg deleted file mode 100644 index 4484255fb9..0000000000 --- a/awx/ui/client/src/network-ui/default.partial.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - {{chunk}} - - - {{chunk}} - - - diff --git a/awx/ui/client/src/network-ui/designs/README.md b/awx/ui/client/src/network-ui/designs/README.md deleted file mode 100644 index 3a20f73bcd..0000000000 --- a/awx/ui/client/src/network-ui/designs/README.md +++ /dev/null @@ -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. - -![Null FSM](null.png) - ---- - -**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. - -![Button FSM](button.png) - ---- - -**Buttons FSM** -* See: buttons.yml - -The buttons FSM distributes events to the buttons which each have their own FSM. - -![Buttons FSM](buttons.png) - ---- - -**Device Detail FSM** -* See: device_detail.yml - -The device detail FSM describes interactions when zoomed into a device. - -![Device Detail FSM](device_detail.png) - ---- - -**Group FSM** -* See: group.yml - -The group FSM describes how to organize multiple devices together in a group. - -![Group FSM](group.png) - ---- - -**Hot Keys FSM** -* See: hotkeys.yml - -The hot keys FSM handles key events and generates new events like `NewLink` to implement -hot keys. - -![Hot Keys FSM](hotkeys.png) - ---- - -**Link FSM** -* See: link.yml - -The link FSM connects two devices together with a link. - -![Link](link.png) - ---- - -**Mode FSM** -* See: mode.yml - -The mode FSM controls the overall mode of the network UI application. - -![Mode](mode.png) - ---- - -**Move FSM** -* See: move.yml - -The move FSM controls placement of devices as well as editing the device labels. - -![Move](move.png) - ---- - -**Rack FSM** -* See: rack.yml - -The rack FSM controls organizing devices into a special group called a rack. - -![Rack](rack.png) - ---- - -**Site FSM** -* See: site.yml - -The site FSM controls organizing devices into a special group called a site. - -![Site](site.png) - ---- - -**Stream FSM** -* See: stream.yml - -The stream FSM controls how streams are defined between devices. - -![Stream](stream.png) - ---- - -**Time FSM** -* See: time.yml - -The time FSM controls undo/redo functionality of the network UI. - -![Time](time.png) - ---- - -**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. - -![Toolbox](toolbox.png) - ---- - -**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. - -![View](view.png) diff --git a/awx/ui/client/src/network-ui/designs/animation.yml b/awx/ui/client/src/network-ui/designs/animation.yml deleted file mode 100644 index c99b99dd1c..0000000000 --- a/awx/ui/client/src/network-ui/designs/animation.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/button.png b/awx/ui/client/src/network-ui/designs/button.png deleted file mode 100644 index 5a1bc7aaa1..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/button.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/button.yml b/awx/ui/client/src/network-ui/designs/button.yml deleted file mode 100644 index f037edb8f8..0000000000 --- a/awx/ui/client/src/network-ui/designs/button.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/buttons.png b/awx/ui/client/src/network-ui/designs/buttons.png deleted file mode 100644 index 8538b06614..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/buttons.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/buttons.yml b/awx/ui/client/src/network-ui/designs/buttons.yml deleted file mode 100644 index b1cc56a246..0000000000 --- a/awx/ui/client/src/network-ui/designs/buttons.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/details.panel.png b/awx/ui/client/src/network-ui/designs/details.panel.png deleted file mode 100644 index d060f3bd2f..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/details.panel.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/details.panel.yml b/awx/ui/client/src/network-ui/designs/details.panel.yml deleted file mode 100644 index 555d21c8be..0000000000 --- a/awx/ui/client/src/network-ui/designs/details.panel.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/device.detail.png b/awx/ui/client/src/network-ui/designs/device.detail.png deleted file mode 100644 index 0f11ac8ffe..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/device.detail.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/device.detail.yml b/awx/ui/client/src/network-ui/designs/device.detail.yml deleted file mode 100644 index fcb2f52eb6..0000000000 --- a/awx/ui/client/src/network-ui/designs/device.detail.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/group.png b/awx/ui/client/src/network-ui/designs/group.png deleted file mode 100644 index 5ca5ead538..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/group.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/group.yml b/awx/ui/client/src/network-ui/designs/group.yml deleted file mode 100644 index f618170553..0000000000 --- a/awx/ui/client/src/network-ui/designs/group.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/hotkeys.png b/awx/ui/client/src/network-ui/designs/hotkeys.png deleted file mode 100644 index d21ff09cc6..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/hotkeys.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/hotkeys.yml b/awx/ui/client/src/network-ui/designs/hotkeys.yml deleted file mode 100644 index 6d237bda46..0000000000 --- a/awx/ui/client/src/network-ui/designs/hotkeys.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/keybindings.png b/awx/ui/client/src/network-ui/designs/keybindings.png deleted file mode 100644 index b6a0b89a19..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/keybindings.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/keybindings.yml b/awx/ui/client/src/network-ui/designs/keybindings.yml deleted file mode 100644 index b98167e288..0000000000 --- a/awx/ui/client/src/network-ui/designs/keybindings.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/link.png b/awx/ui/client/src/network-ui/designs/link.png deleted file mode 100644 index 4058fd5519..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/link.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/link.yml b/awx/ui/client/src/network-ui/designs/link.yml deleted file mode 100644 index 7b3a7ea16c..0000000000 --- a/awx/ui/client/src/network-ui/designs/link.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/mode.png b/awx/ui/client/src/network-ui/designs/mode.png deleted file mode 100644 index b8dff5610d..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/mode.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/mode.yml b/awx/ui/client/src/network-ui/designs/mode.yml deleted file mode 100644 index b124a3d32e..0000000000 --- a/awx/ui/client/src/network-ui/designs/mode.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/move.png b/awx/ui/client/src/network-ui/designs/move.png deleted file mode 100644 index e199991c76..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/move.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/move.readonly.png b/awx/ui/client/src/network-ui/designs/move.readonly.png deleted file mode 100644 index 95db906bcd..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/move.readonly.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/move.readonly.yml b/awx/ui/client/src/network-ui/designs/move.readonly.yml deleted file mode 100644 index 6d1245d772..0000000000 --- a/awx/ui/client/src/network-ui/designs/move.readonly.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/move.yml b/awx/ui/client/src/network-ui/designs/move.yml deleted file mode 100644 index 42e42b6dfd..0000000000 --- a/awx/ui/client/src/network-ui/designs/move.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/null.png b/awx/ui/client/src/network-ui/designs/null.png deleted file mode 100644 index f095a1cad4..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/null.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/null.yml b/awx/ui/client/src/network-ui/designs/null.yml deleted file mode 100644 index 5218cfe1f7..0000000000 --- a/awx/ui/client/src/network-ui/designs/null.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/pipeline.png b/awx/ui/client/src/network-ui/designs/pipeline.png deleted file mode 100644 index c5fb2b12f7..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/pipeline.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/pipeline.yml b/awx/ui/client/src/network-ui/designs/pipeline.yml deleted file mode 100644 index 43052f2b2d..0000000000 --- a/awx/ui/client/src/network-ui/designs/pipeline.yml +++ /dev/null @@ -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: [] diff --git a/awx/ui/client/src/network-ui/designs/rack.png b/awx/ui/client/src/network-ui/designs/rack.png deleted file mode 100644 index 505cfdda6b..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/rack.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/rack.yml b/awx/ui/client/src/network-ui/designs/rack.yml deleted file mode 100644 index 3a5f7cae8c..0000000000 --- a/awx/ui/client/src/network-ui/designs/rack.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/site.png b/awx/ui/client/src/network-ui/designs/site.png deleted file mode 100644 index 72d256f552..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/site.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/site.yml b/awx/ui/client/src/network-ui/designs/site.yml deleted file mode 100644 index ab807f28d1..0000000000 --- a/awx/ui/client/src/network-ui/designs/site.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/stream.png b/awx/ui/client/src/network-ui/designs/stream.png deleted file mode 100644 index 3a00d21e97..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/stream.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/stream.yml b/awx/ui/client/src/network-ui/designs/stream.yml deleted file mode 100644 index cf12e95312..0000000000 --- a/awx/ui/client/src/network-ui/designs/stream.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/test.yml b/awx/ui/client/src/network-ui/designs/test.yml deleted file mode 100644 index 37092ab245..0000000000 --- a/awx/ui/client/src/network-ui/designs/test.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/time.png b/awx/ui/client/src/network-ui/designs/time.png deleted file mode 100644 index cec5fe69ee..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/time.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/time.yml b/awx/ui/client/src/network-ui/designs/time.yml deleted file mode 100644 index 6efaa5f38c..0000000000 --- a/awx/ui/client/src/network-ui/designs/time.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/toolbox.png b/awx/ui/client/src/network-ui/designs/toolbox.png deleted file mode 100644 index 14f676bddc..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/toolbox.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/toolbox.yml b/awx/ui/client/src/network-ui/designs/toolbox.yml deleted file mode 100644 index 99fd550b54..0000000000 --- a/awx/ui/client/src/network-ui/designs/toolbox.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/designs/view.png b/awx/ui/client/src/network-ui/designs/view.png deleted file mode 100644 index e0d7f261b2..0000000000 Binary files a/awx/ui/client/src/network-ui/designs/view.png and /dev/null differ diff --git a/awx/ui/client/src/network-ui/designs/view.yml b/awx/ui/client/src/network-ui/designs/view.yml deleted file mode 100644 index 75f3c5cb47..0000000000 --- a/awx/ui/client/src/network-ui/designs/view.yml +++ /dev/null @@ -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 diff --git a/awx/ui/client/src/network-ui/details.panel.fsm.js b/awx/ui/client/src/network-ui/details.panel.fsm.js deleted file mode 100644 index 2d8560594d..0000000000 --- a/awx/ui/client/src/network-ui/details.panel.fsm.js +++ /dev/null @@ -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']; diff --git a/awx/ui/client/src/network-ui/extract.js b/awx/ui/client/src/network-ui/extract.js deleted file mode 100755 index 79edb17f60..0000000000 --- a/awx/ui/client/src/network-ui/extract.js +++ /dev/null @@ -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)); diff --git a/awx/ui/client/src/network-ui/extract_messages.js b/awx/ui/client/src/network-ui/extract_messages.js deleted file mode 100755 index aee32413de..0000000000 --- a/awx/ui/client/src/network-ui/extract_messages.js +++ /dev/null @@ -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)); diff --git a/awx/ui/client/src/network-ui/fsm.js b/awx/ui/client/src/network-ui/fsm.js deleted file mode 100644 index 3d43531c79..0000000000 --- a/awx/ui/client/src/network-ui/fsm.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/host.directive.js b/awx/ui/client/src/network-ui/host.directive.js deleted file mode 100644 index aa0b13d3c4..0000000000 --- a/awx/ui/client/src/network-ui/host.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/host.partial.svg b/awx/ui/client/src/network-ui/host.partial.svg deleted file mode 100644 index f4bff2cb3c..0000000000 --- a/awx/ui/client/src/network-ui/host.partial.svg +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{chunk}} - - - {{chunk}} - - - diff --git a/awx/ui/client/src/network-ui/hotkeys.fsm.js b/awx/ui/client/src/network-ui/hotkeys.fsm.js deleted file mode 100644 index 410fba8ba7..0000000000 --- a/awx/ui/client/src/network-ui/hotkeys.fsm.js +++ /dev/null @@ -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']; diff --git a/awx/ui/client/src/network-ui/inventory.toolbox.directive.js b/awx/ui/client/src/network-ui/inventory.toolbox.directive.js deleted file mode 100644 index d3cfa8b65e..0000000000 --- a/awx/ui/client/src/network-ui/inventory.toolbox.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/inventory_toolbox.partial.svg b/awx/ui/client/src/network-ui/inventory_toolbox.partial.svg deleted file mode 100644 index 348c0b20e3..0000000000 --- a/awx/ui/client/src/network-ui/inventory_toolbox.partial.svg +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{toolbox.name}} - - diff --git a/awx/ui/client/src/network-ui/keybindings.fsm.js b/awx/ui/client/src/network-ui/keybindings.fsm.js deleted file mode 100644 index 3e9fcd8ee4..0000000000 --- a/awx/ui/client/src/network-ui/keybindings.fsm.js +++ /dev/null @@ -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']; diff --git a/awx/ui/client/src/network-ui/link.directive.js b/awx/ui/client/src/network-ui/link.directive.js deleted file mode 100644 index 446f56b14f..0000000000 --- a/awx/ui/client/src/network-ui/link.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/link.partial.svg b/awx/ui/client/src/network-ui/link.partial.svg deleted file mode 100644 index bd9f9f3641..0000000000 --- a/awx/ui/client/src/network-ui/link.partial.svg +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - {{link.name}} -{{link.name}}{{link.edit_label?'_':''}} - - - - {{link.from_interface.name}} -{{link.from_interface.name}}{{link.from_interface.edit_label ?'_':''}} - - - - {{link.to_interface.name}} -{{link.to_interface.name}}{{link.to_interface.edit_label?'_':''}} - - - - - - - - diff --git a/awx/ui/client/src/network-ui/messages.js b/awx/ui/client/src/network-ui/messages.js deleted file mode 100644 index 88950cee74..0000000000 --- a/awx/ui/client/src/network-ui/messages.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/mode.fsm.js b/awx/ui/client/src/network-ui/mode.fsm.js deleted file mode 100644 index 22cfeec656..0000000000 --- a/awx/ui/client/src/network-ui/mode.fsm.js +++ /dev/null @@ -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); -}; diff --git a/awx/ui/client/src/network-ui/models.js b/awx/ui/client/src/network-ui/models.js deleted file mode 100644 index 0adabdf55e..0000000000 --- a/awx/ui/client/src/network-ui/models.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/move.fsm.js b/awx/ui/client/src/network-ui/move.fsm.js deleted file mode 100644 index eaa72bab15..0000000000 --- a/awx/ui/client/src/network-ui/move.fsm.js +++ /dev/null @@ -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']; diff --git a/awx/ui/client/src/network-ui/move.readonly.fsm.js b/awx/ui/client/src/network-ui/move.readonly.fsm.js deleted file mode 100644 index aa0e1958e0..0000000000 --- a/awx/ui/client/src/network-ui/move.readonly.fsm.js +++ /dev/null @@ -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']; diff --git a/awx/ui/client/src/network-ui/network-details/details.block.less b/awx/ui/client/src/network-ui/network-details/details.block.less deleted file mode 100644 index 802e67fd3e..0000000000 --- a/awx/ui/client/src/network-ui/network-details/details.block.less +++ /dev/null @@ -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; -} diff --git a/awx/ui/client/src/network-ui/network-details/details.controller.js b/awx/ui/client/src/network-ui/network-details/details.controller.js deleted file mode 100644 index 36c05cf097..0000000000 --- a/awx/ui/client/src/network-ui/network-details/details.controller.js +++ /dev/null @@ -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 = `

${$scope.strings.get('details.HOST_POPOVER')}

myserver.domain.com
127.0.0.1
10.1.0.140:25
server.example.com:25
`; - - $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); - } - }); - }]; diff --git a/awx/ui/client/src/network-ui/network-details/details.directive.js b/awx/ui/client/src/network-ui/network-details/details.directive.js deleted file mode 100644 index d05f364390..0000000000 --- a/awx/ui/client/src/network-ui/network-details/details.directive.js +++ /dev/null @@ -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', - }; -}]; diff --git a/awx/ui/client/src/network-ui/network-details/details.partial.html b/awx/ui/client/src/network-ui/network-details/details.partial.html deleted file mode 100644 index ed30e056ad..0000000000 --- a/awx/ui/client/src/network-ui/network-details/details.partial.html +++ /dev/null @@ -1,48 +0,0 @@ -
-
- DETAILS | {{item.name}} -
-
- -
- {{item.type}} DETAILS NOT AVAILABLE -
- -
-
-
- -
- -
Please enter a value.
-
-
-
-
- -
- -
-
-
-
- - -
-
-
- -
-
- {{strings.get('details.SAVE_COMPLETE')}} -
-
diff --git a/awx/ui/client/src/network-ui/network-details/main.js b/awx/ui/client/src/network-ui/network-details/main.js deleted file mode 100644 index ffa06f41e4..0000000000 --- a/awx/ui/client/src/network-ui/network-details/main.js +++ /dev/null @@ -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); diff --git a/awx/ui/client/src/network-ui/network-nav/main.js b/awx/ui/client/src/network-ui/network-nav/main.js deleted file mode 100644 index 8561a2017d..0000000000 --- a/awx/ui/client/src/network-ui/network-nav/main.js +++ /dev/null @@ -1,6 +0,0 @@ -const MODULE_NAME = 'at.features.networking'; - -angular - .module(MODULE_NAME, []); - -export default MODULE_NAME; diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.block.less b/awx/ui/client/src/network-ui/network-nav/network.nav.block.less deleted file mode 100644 index 7bfbd778a7..0000000000 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.block.less +++ /dev/null @@ -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; -} diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js b/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js deleted file mode 100644 index b9103431a8..0000000000 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js +++ /dev/null @@ -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 */ diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.view.html b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html deleted file mode 100644 index 4efd698a90..0000000000 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.view.html +++ /dev/null @@ -1,91 +0,0 @@ -
-
-
-
{{vm.panelTitle}}
-
-
- -
-
-
-
-
-
- -
-
-
-
- -
-
- -
-
- {{ vm.strings.get('key.KEY') }} -
-
-
d
-
{{ vm.strings.get('key.DEBUG_MODE') }}
-
-
-
i
-
{{ vm.strings.get('key.HIDE_INTERFACES') }}
-
-
-
0
-
{{ vm.strings.get('key.RESET_ZOOM') }}
-
-
-
-
- -
-
-
- -
-
-
- -
-
- -
-
- -
- diff --git a/awx/ui/client/src/network-ui/network.ui.app.js b/awx/ui/client/src/network-ui/network.ui.app.js deleted file mode 100644 index 5fe046e5b0..0000000000 --- a/awx/ui/client/src/network-ui/network.ui.app.js +++ /dev/null @@ -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); diff --git a/awx/ui/client/src/network-ui/network.ui.controller.js b/awx/ui/client/src/network-ui/network.ui.controller.js deleted file mode 100644 index 1e2398dbef..0000000000 --- a/awx/ui/client/src/network-ui/network.ui.controller.js +++ /dev/null @@ -1,1475 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ -var fsm = require('./fsm.js'); -var mode_fsm = require('./mode.fsm.js'); -var hotkeys = require('./hotkeys.fsm.js'); -var toolbox_fsm = require('./toolbox.fsm.js'); -var view = require('./view.fsm.js'); -var move = require('./move.fsm.js'); -var move_readonly = require('./move.readonly.fsm.js'); -var buttons = require('./buttons.fsm.js'); -var time = require('./time.fsm.js'); -var test_fsm = require('./test.fsm.js'); -var util = require('./util.js'); -var models = require('./models.js'); -var messages = require('./messages.js'); -var animations = require('./animations.js'); -var keybindings = require('./keybindings.fsm.js'); -var details_panel_fsm = require('./details.panel.fsm.js'); -var svg_crowbar = require('./vendor/svg-crowbar.js'); -var ReconnectingWebSocket = require('reconnectingwebsocket'); - -var NetworkUIController = function($scope, - $document, - $location, - $window, - $http, - $q, - $state, - $log, - ProcessErrors, - ConfigService, - rbacUiControlService, - awxNetStrings) { - - window.scope = $scope; - - $scope.http = $http; - - $scope.api_token = ''; - $scope.disconnected = false; - $scope.tests_enabled = false; - - $scope.topology_id = 0; - // Create a web socket to connect to the backend server - - $scope.inventory_id = $scope.$parent.$resolve.inventory.id; - - var protocol = null; - - if ($location.protocol() === 'http') { - protocol = 'ws'; - } else if ($location.protocol() === 'https') { - protocol = 'wss'; - } - - $scope.initial_messages = []; - if (!$scope.disconnected) { - $scope.control_socket = new ReconnectingWebSocket(protocol + "://" + window.location.host + "/network_ui/topology/?inventory_id=" + $scope.inventory_id, - null, - {debug: false, reconnectInterval: 300}); - if ($scope.tests_enabled) { - $scope.test_socket = new ReconnectingWebSocket(protocol + "://" + window.location.host + "/network_ui/test?inventory_id=" + $scope.inventory_id, - null, - {debug: false, reconnectInterval: 300}); - } else { - $scope.test_socket = { - on_message: util.noop, - send: util.noop - }; - } - - } else { - $scope.control_socket = { - on_message: util.noop - }; - } - $scope.my_location = $location.protocol() + "://" + $location.host() + ':' + $location.port(); - $scope.client_id = 0; - $scope.test_client_id = 0; - $scope.onMouseDownResult = ""; - $scope.onMouseUpResult = ""; - $scope.onMouseEnterResult = ""; - $scope.onMouseLeaveResult = ""; - $scope.onMouseMoveResult = ""; - $scope.onMouseMoveResult = ""; - $scope.current_scale = 0.7; - $scope.current_mode = null; - $scope.panX = 0; - $scope.panY = 0; - $scope.mouseX = 0; - $scope.mouseY = 0; - $scope.scaledX = 0; - $scope.scaledY = 0; - $scope.pressedX = 0; - $scope.pressedY = 0; - $scope.pressedScaledX = 0; - $scope.pressedScaledY = 0; - $scope.lastPanX = 0; - $scope.lastPanY = 0; - $scope.selected_devices = []; - $scope.selected_links = []; - $scope.selected_interfaces = []; - $scope.selected_items = []; - $scope.new_link = null; - $scope.new_stream = null; - $scope.last_key = ""; - $scope.last_key_code = null; - $scope.last_event = null; - $scope.cursor = {'x':100, 'y': 100, 'hidden': true}; - - $scope.debug = {'hidden': true}; - $scope.hide_buttons = false; - $scope.hide_menus = false; - $scope.hide_links = false; - $scope.hide_interfaces = false; - $scope.graph = {'width': window.innerWidth, - 'right_column': 300, - 'height': window.innerHeight}; - $scope.MAX_ZOOM = 5; - $scope.MIN_ZOOM = 0.1; - $scope.device_id_seq = util.natural_numbers(0); - $scope.link_id_seq = util.natural_numbers(0); - $scope.message_id_seq = util.natural_numbers(0); - $scope.test_result_id_seq = util.natural_numbers(0); - $scope.animation_id_seq = util.natural_numbers(0); - $scope.overall_toolbox_collapsed = false; - $scope.time_pointer = -1; - $scope.frame = 0; - $scope.recording = false; - $scope.replay = false; - $scope.devices = []; - $scope.devices_by_name = {}; - $scope.links = []; - $scope.links_in_vars_by_device = {}; - $scope.tests = []; - $scope.current_tests = []; - $scope.current_test = null; - $scope.template_building = false; - $scope.version = null; - $scope.test_events = []; - $scope.test_results = []; - $scope.test_errors = []; - $scope.animations = []; - $scope.sequences = {}; - $scope.view_port = {'x': 0, - 'y': 0, - 'width': 0, - 'height': 0, - }; - $scope.trace_id_seq = util.natural_numbers(0); - $scope.trace_order_seq = util.natural_numbers(0); - $scope.trace_id = $scope.trace_id_seq(); - $scope.jump = {from_x: 0, - from_y: 0, - to_x: 0, - to_y: 0}; - $scope.canEdit = $scope.$parent.$resolve.canEdit; - $scope.strings = awxNetStrings; - $scope.send_trace_message = function (message) { - if (!$scope.recording) { - return; - } - message.sender = $scope.test_client_id; - message.trace_id = $scope.trace_id; - message.message_id = $scope.message_id_seq(); - var data = messages.serialize(message); - if (!$scope.disconnected) { - try { - $scope.test_socket.send(data); - } - catch(err) { - $scope.initial_messages.push(message); - } - } - }; - - $scope.onKeyDown = function ($event) { - if ($scope.recording) { - $scope.send_test_message(new messages.KeyEvent($scope.test_client_id, - $event.key, - $event.keyCode, - $event.type, - $event.altKey, - $event.shiftKey, - $event.ctrlKey, - $event.metaKey, - $scope.trace_id)); - } - $scope.last_event = $event; - $scope.last_key = $event.key; - $scope.last_key_code = $event.keyCode; - $scope.first_channel.send('KeyDown', $event); - $scope.$apply(); - $event.preventDefault(); - }; - - //Define the FSMs - $scope.hotkeys_controller = new fsm.FSMController($scope, "hotkeys_fsm", hotkeys.Start, $scope, $log); - $scope.keybindings_controller = new fsm.FSMController($scope, "keybindings_fsm", keybindings.Start, $scope, $log); - $scope.view_controller = new fsm.FSMController($scope, "view_fsm", view.Start, $scope, $log); - $scope.move_controller = new fsm.FSMController($scope, "move_fsm", move.Start, $scope, $log); - $scope.move_readonly_controller = new fsm.FSMController($scope, "move_readonly_fsm", move_readonly.Start, $scope, $log); - $scope.details_panel_controller = new fsm.FSMController($scope, "details_panel_fsm", details_panel_fsm.Start, $scope, $log); - $scope.buttons_controller = new fsm.FSMController($scope, "buttons_fsm", buttons.Start, $scope, $log); - $scope.time_controller = new fsm.FSMController($scope, "time_fsm", time.Start, $scope, $log); - $scope.test_controller = new fsm.FSMController($scope, "test_fsm", test_fsm.Start, $scope, $log); - - $scope.inventory_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope, $log); - - var toolboxTopMargin = $('.Networking-top').height(); - var toolboxTitleMargin = toolboxTopMargin + 35; - var toolboxHeight = $scope.graph.height - $('.Networking-top').height(); - - $scope.update_links_in_vars_by_device = function (device_name, variables) { - - var j = 0; - var link = null; - - if (variables.ansible_topology !== undefined) { - if (variables.ansible_topology.links !== undefined) { - for (j=0; j < variables.ansible_topology.links.length; j++) { - link = variables.ansible_topology.links[j]; - if (link.remote_device_name !== undefined && - link.remote_interface_name !== undefined && - link.name !== undefined) { - if ($scope.links_in_vars_by_device[device_name] === undefined) { - $scope.links_in_vars_by_device[device_name] = []; - } - if ($scope.links_in_vars_by_device[link.remote_device_name] === undefined) { - $scope.links_in_vars_by_device[link.remote_device_name] = []; - } - $scope.links_in_vars_by_device[device_name].push({ - from_interface: link.name, - to_interface: link.remote_interface_name, - from_device: device_name, - to_device: link.remote_device_name - }); - $scope.links_in_vars_by_device[link.remote_device_name].push({ - from_interface: link.remote_interface_name, - to_interface: link.name, - from_device: link.remote_device_name, - to_device: device_name - }); - } - } - } - } - }; - - $scope.for_each_page = function(url, callback, limit) { - - function rec(url, rec_limit) { - if (rec_limit <= 0) { - return; - } - $http.get(url) - .then(function(response) { - callback(response.data.results); - if (response.data.next) { - rec(response.data.next, rec_limit-1); - } - }) - .catch(({data, status}) => { - ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get host data: ' + status }); - }); - } - rec(url, limit); - }; - - //Inventory Toolbox Setup - $scope.inventory_toolbox = new models.ToolBox(0, $scope.strings.get('toolbox.INVENTORY'), 'device', 0, toolboxTopMargin, 200, toolboxHeight); - if (!$scope.disconnected) { - $scope.for_each_page('/api/v2/inventories/' + $scope.inventory_id + '/hosts/', - function(all_results) { - let hosts = all_results; - $log.debug(hosts.length); - for(var i = 0; i= 0; i--) { - if (devices[i].is_selected($scope.scaledX, $scope.scaledY)) { - devices[i].selected = true; - $scope.send_control_message(new messages.DeviceSelected($scope.client_id, devices[i].id)); - last_selected_device = devices[i]; - if ($scope.selected_items.indexOf($scope.devices[i]) === -1) { - $scope.selected_items.push($scope.devices[i]); - } - if ($scope.selected_devices.indexOf(devices[i]) === -1) { - $scope.selected_devices.push(devices[i]); - } - if (!multiple_selection) { - break; - } - } - } - - // Do not select interfaces if a device was selected - if (last_selected_device === null && !$scope.hide_interfaces) { - for (i = devices.length - 1; i >= 0; i--) { - for (j = devices[i].interfaces.length - 1; j >= 0; j--) { - if (devices[i].interfaces[j].is_selected($scope.scaledX, $scope.scaledY)) { - devices[i].interfaces[j].selected = true; - last_selected_interface = devices[i].interfaces[j]; - if ($scope.selected_interfaces.indexOf($scope.devices[i].interfaces[j]) === -1) { - $scope.selected_interfaces.push($scope.devices[i].interfaces[j]); - } - if ($scope.selected_items.indexOf($scope.devices[i].interfaces[j]) === -1) { - $scope.selected_items.push($scope.devices[i].interfaces[j]); - } - if (!multiple_selection) { - break; - } - } - } - } - } - - // Do not select links if a device was selected - if (last_selected_device === null && last_selected_interface === null) { - for (i = $scope.links.length - 1; i >= 0; i--) { - if ($scope.links[i].is_selected($scope.scaledX, $scope.scaledY)) { - $scope.links[i].selected = true; - $scope.send_control_message(new messages.LinkSelected($scope.client_id, $scope.links[i].id)); - last_selected_link = $scope.links[i]; - if ($scope.selected_items.indexOf($scope.links[i]) === -1) { - $scope.selected_items.push($scope.links[i]); - } - if ($scope.selected_links.indexOf($scope.links[i]) === -1) { - $scope.selected_links.push($scope.links[i]); - if (!multiple_selection) { - break; - } - } - } - } - } - - return {last_selected_device: last_selected_device, - last_selected_link: last_selected_link, - last_selected_interface: last_selected_interface, - }; - }; - - // Event Handlers - - $scope.normalize_mouse_event = function ($event) { - if ($event.pageX !== undefined) { - $event.x = $event.pageX; - } - if ($event.pageY !== undefined) { - $event.y = $event.pageY; - } - if ($event.originalEvent !== undefined) { - var originalEvent = $event.originalEvent; - if (originalEvent.wheelDelta !== undefined) { - $event.delta = $event.originalEvent.wheelDelta; - } - if (originalEvent.wheelDeltaX !== undefined) { - $event.deltaX = $event.originalEvent.wheelDeltaX; - } - if (originalEvent.wheelDeltaY !== undefined) { - $event.deltaY = $event.originalEvent.wheelDeltaY; - } - if (originalEvent.deltaX !== undefined) { - $event.deltaX = $event.originalEvent.deltaX; - } - if (originalEvent.deltaY !== undefined) { - $event.deltaY = $event.originalEvent.deltaY; - $event.delta = $event.originalEvent.deltaY; - } - } - }; - - $scope.onMouseDown = function ($event) { - $scope.normalize_mouse_event($event); - if ($scope.recording) { - $scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id)); - } - $scope.last_event = $event; - $scope.first_channel.send('MouseDown', $event); - $scope.onMouseDownResult = getMouseEventResult($event); - $event.preventDefault(); - }; - - $scope.onMouseUp = function ($event) { - $scope.normalize_mouse_event($event); - if ($scope.recording) { - $scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id)); - } - $scope.last_event = $event; - $scope.first_channel.send('MouseUp', $event); - $scope.onMouseUpResult = getMouseEventResult($event); - $event.preventDefault(); - }; - - $scope.onMouseLeave = function ($event) { - $scope.normalize_mouse_event($event); - if ($scope.recording) { - $scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id)); - } - $scope.onMouseLeaveResult = getMouseEventResult($event); - $event.preventDefault(); - }; - - $scope.onMouseMove = function ($event) { - $scope.normalize_mouse_event($event); - if ($scope.recording) { - $scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id)); - } - //var coords = getCrossBrowserElementCoords($event); - $scope.cursor.x = $event.x; - $scope.cursor.y = $event.y; - $scope.mouseX = $event.x; - $scope.mouseY = $event.y; - $scope.updateScaledXY(); - $scope.first_channel.send('MouseMove', $event); - $scope.onMouseMoveResult = getMouseEventResult($event); - $event.preventDefault(); - }; - - $scope.onMouseOver = function ($event) { - $scope.normalize_mouse_event($event); - if ($scope.recording) { - $scope.send_test_message(new messages.MouseEvent($scope.test_client_id, $event.x, $event.y, $event.type, $scope.trace_id)); - } - $scope.onMouseOverResult = getMouseEventResult($event); - $event.preventDefault(); - }; - - $scope.onMouseEnter = $scope.onMouseOver; - - $scope.onMouseWheel = function ($event) { - $scope.normalize_mouse_event($event); - var delta = $event.delta; - var deltaX = $event.deltaX; - var deltaY = $event.deltaY; - if ($scope.recording) { - $scope.send_test_message(new messages.MouseWheelEvent($scope.test_client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey, $scope.trace_id)); - } - $scope.last_event = $event; - $scope.first_channel.send('MouseWheel', [$event, delta, deltaX, deltaY]); - $event.preventDefault(); - }; - - // Conext Menu Button Handlers - $scope.removeContextMenu = function(){ - let context_menu = $scope.context_menus[0]; - context_menu.enabled = false; - context_menu.x = -100000; - context_menu.y = -100000; - context_menu.buttons.forEach(function(button){ - button.enabled = false; - button.x = -100000; - button.y = -100000; - }); - }; - - $scope.closeDetailsPanel = function () { - $scope.first_channel.send('DetailsPanelClose', {}); - }; - - $scope.$on('awxNet-closeDetailsPanel', $scope.closeDetailsPanel); - - $scope.onDetailsContextButton = function () { - function emitCallback(item, canAdd){ - $scope.first_channel.send('DetailsPanel', {}); - $scope.removeContextMenu(); - $scope.update_toolbox_heights(); - $scope.$emit('awxNet-showDetails', item, canAdd); - } - - // show details for devices - if ($scope.selected_devices.length === 1 && $scope.selected_devices[0].host_id === 0){ - // following block is intended for devices added in the network UI but not in Tower - emitCallback($scope.selected_devices[0]); - } - - // following block is intended for devices that are saved in the API - if ($scope.selected_devices.length === 1 && $scope.selected_devices[0].host_id !== 0){ - let host_id = $scope.selected_devices[0].host_id; - let url = `/api/v2/hosts/${host_id}/`; - let hostData = $http.get(url) - .then(function(response) { - let host = response.data; - host.host_id = host.id; - return host; - }) - .catch(({data, status}) => { - ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get host data: ' + status }); - }); - let canAdd = rbacUiControlService.canAdd('hosts') - .then(function(res) { - return res.canAdd; - }) - .catch(function() { - return false; - }); - Promise.all([hostData, canAdd]).then((values) => { - let item = values[0]; - let canAdd = values[1]; - emitCallback(item, canAdd); - }); - } - - // show details for interfaces - else if($scope.selected_interfaces.length === 1){ - emitCallback($scope.selected_interfaces[0]); - } - - // show details for links - else if($scope.selected_links.length === 1){ - emitCallback($scope.selected_links[0]); - } - - }; - - $scope.onDeviceDestroy = function(data) { - $scope.destroy_device(data); - }; - - $scope.destroy_device = function(data) { - - // Delete the device and any links connecting to the device. - var i = 0; - var j = 0; - var dindex = -1; - var lindex = -1; - var devices = $scope.devices.slice(); - var all_links = $scope.links.slice(); - for (i = 0; i < devices.length; i++) { - if (devices[i].id === data.id) { - dindex = $scope.devices.indexOf(devices[i]); - if (dindex !== -1) { - $scope.devices.splice(dindex, 1); - } - lindex = -1; - for (j = 0; j < all_links.length; j++) { - if (all_links[j].to_device === devices[i] || - all_links[j].from_device === devices[i]) { - lindex = $scope.links.indexOf(all_links[j]); - if (lindex !== -1) { - $scope.links.splice(lindex, 1); - } - } - } - } - } - }; - - $scope.deleteDevice = function(){ - var i = 0; - var j = 0; - var index = -1; - var devices = $scope.selected_devices; - var all_links = $scope.links.slice(); - $scope.selected_devices = []; - $scope.selected_links = []; - $scope.move_controller.changeState(move.Ready); - for (i = 0; i < devices.length; i++) { - index = $scope.devices.indexOf(devices[i]); - if (index !== -1) { - $scope.devices.splice(index, 1); - $scope.devices_by_name[devices[i].name] = undefined; - $scope.$emit('awxNet-removeSearchOption', devices[i]); - devices[i].x = 0; - devices[i].y = 0; - devices[i].selected = false; - devices[i].remote_selected = false; - devices[i].interfaces = []; - devices[i].interfaces_by_name = []; - $scope.inventory_toolbox.items.push(devices[i]); - $scope.send_control_message(new messages.DeviceDestroy($scope.client_id, - devices[i].id, - devices[i].x, - devices[i].y, - devices[i].name, - devices[i].type, - devices[i].host_id)); - } - for (j = 0; j < all_links.length; j++) { - if (all_links[j].to_device === devices[i] || - all_links[j].from_device === devices[i]) { - index = $scope.links.indexOf(all_links[j]); - if (index !== -1) { - $scope.links.splice(index, 1); - $scope.send_control_message(new messages.LinkDestroy($scope.client_id, - all_links[j].id, - all_links[j].from_device.id, - all_links[j].to_device.id, - all_links[j].from_interface.id, - all_links[j].to_interface.id, - all_links[j].name)); - - } - } - } - } - }; - - $scope.onDeleteContextMenu = function(){ - $scope.removeContextMenu(); - if($scope.selected_devices.length === 1){ - $scope.deleteDevice(); - } - }; - - $scope.$on('awxNet-hideToolbox', () => { - $scope.first_channel.send("ToggleToolbox", {}); - $scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed; - }); - - $scope.$on('awxNet-toolbarButtonEvent', function(e, functionName){ - $scope[`on${functionName}Button`](); - }); - - $scope.$on('awxNet-SearchDropdown', function(){ - $scope.first_channel.send('SearchDropdown', {}); - }); - - $scope.$on('awxNet-SearchDropdownClose', function(){ - $scope.first_channel.send('SearchDropdownClose', {}); - }); - - $scope.$on('awxNet-search', function(e, device){ - - var searched; - for(var i = 0; i < $scope.devices.length; i++){ - if(Number(device.id) === $scope.devices[i].id){ - searched = $scope.devices[i]; - } - } - searched.selected = true; - $scope.selected_devices.push(searched); - $scope.jump_to_animation(searched.x, searched.y, 1.0); - }); - - $scope.jump_to_animation = function(jump_to_x, jump_to_y, jump_to_scale, updateZoom) { - $scope.cancel_animations(); - var v_center = $scope.to_virtual_coordinates($scope.graph.width/2, $scope.graph.height/2); - $scope.jump.from_x = v_center.x; - $scope.jump.from_y = v_center.y; - $scope.jump.to_x = jump_to_x; - $scope.jump.to_y = jump_to_y; - var distance = util.distance(v_center.x, v_center.y, jump_to_x, jump_to_y); - var num_frames = 30 * Math.floor((1 + 4 * distance / (distance + 3000))); - var scale_animation = new models.Animation($scope.animation_id_seq(), - num_frames, - { - c: -0.1, - distance: distance, - end_height: (1.0/jump_to_scale) - 1, - current_scale: $scope.current_scale, - scope: $scope, - updateZoomBoolean: updateZoom - }, - $scope, - $scope, - animations.scale_animation); - $scope.animations.push(scale_animation); - var pan_animation = new models.Animation($scope.animation_id_seq(), - num_frames, - { - x2: jump_to_x, - y2: jump_to_y, - x1: v_center.x, - y1: v_center.y, - scope: $scope - }, - $scope, - $scope, - animations.pan_animation); - $scope.animations.push(pan_animation); - }; - - $scope.$on('awxNet-zoom', (e, zoomPercent) => { - let v_center = $scope.to_virtual_coordinates($scope.graph.width/2, $scope.graph.height/2); - let scale = Math.pow(10, (zoomPercent - 120) / 120); - $scope.jump_to_animation(v_center.x, v_center.y, scale, false); - }); - - $scope.onRecordButton = function () { - $scope.recording = ! $scope.recording; - if ($scope.recording) { - $scope.trace_id = $scope.trace_id_seq(); - $scope.send_test_message(new messages.MultipleMessage($scope.test_client_id, - [new messages.StartRecording($scope.test_client_id, $scope.trace_id), - new messages.ViewPort($scope.test_client_id, - $scope.current_scale, - $scope.panX, - $scope.panY, - $scope.graph.width, - $scope.graph.height, - $scope.trace_id), - new messages.Snapshot($scope.test_client_id, - $scope.devices, - $scope.links, - $scope.inventory_toolbox.items, - 0, - $scope.trace_id)])); - } else { - $scope.send_test_message(new messages.MultipleMessage($scope.test_client_id, - [new messages.Snapshot($scope.test_client_id, - $scope.devices, - $scope.links, - $scope.inventory_toolbox.items, - 1, - $scope.trace_id), - new messages.StopRecording($scope.test_client_id, $scope.trace_id)])); - } - }; - - $scope.onExportButton = function () { - $scope.cursor.hidden = true; - $scope.debug.hidden = true; - $scope.hide_buttons = true; - $scope.hide_menus = true; - setTimeout(function () { - svg_crowbar.svg_crowbar(); - $scope.cursor.hidden = false; - $scope.hide_buttons = false; - $scope.hide_menus = false; - $scope.$apply(); - }, 1000); - }; - - $scope.onExportYamlButton = function () { - $window.open('/network_ui/topology.yaml?topology_id=' + $scope.topology_id , '_blank'); - }; - - // Context Menu Buttons - const contextMenuButtonHeight = 26; - let contextMenuHeight = 64; - $scope.context_menu_buttons = [ - new models.ContextMenuButton($scope.strings.get('context_menu.DETAILS'), 236, 231, 160, contextMenuButtonHeight, $scope.onDetailsContextButton, $scope, 'details'), - new models.ContextMenuButton($scope.strings.get('context_menu.REMOVE'), 256, 231, 160, contextMenuButtonHeight, $scope.onDeleteContextMenu, $scope, 'remove') - ]; - if(!$scope.canEdit){ - $scope.context_menu_buttons.pop(); - contextMenuHeight = $scope.context_menu_buttons.length * contextMenuButtonHeight + 12; - } - // Context Menus - $scope.context_menus = [ - new models.ContextMenu('HOST', 210, 200, 160, contextMenuHeight, $scope.contextMenuCallback, false, $scope.context_menu_buttons, $scope) - ]; - - $scope.onDownloadTraceButton = function () { - window.open("/network_ui_test/download_trace?topology_id=" + $scope.topology_id + "&trace_id=" + $scope.trace_id + "&client_id=" + $scope.test_client_id); - }; - - $scope.onDownloadRecordingButton = function () { - window.open("/network_ui_test/download_recording?topology_id=" + $scope.topology_id + "&trace_id=" + $scope.trace_id + "&client_id=" + $scope.test_client_id); - }; - - $scope.onUploadTestButton = function () { - window.open("/network_ui_test/upload_test", "_top"); - }; - - $scope.onRunTestsButton = function () { - - $scope.test_results = []; - $scope.current_tests = $scope.tests.slice(); - $scope.test_channel.send("EnableTest", new messages.EnableTest()); - }; - - $scope.all_buttons = $scope.context_menu_buttons; - - $scope.onDeviceCreate = function(data) { - $scope.create_device(data); - }; - - $scope.create_device = function(data) { - $log.debug(data); - var device = new models.Device(data.id, - data.name, - data.x, - data.y, - data.type, - data.host_id); - $scope.device_id_seq = util.natural_numbers(data.id); - $scope.devices.push(device); - $scope.devices_by_name[device.name] = device; - }; - - $scope.onInterfaceCreate = function(data) { - $scope.create_interface(data); - }; - - $scope.create_interface = function(data) { - var i = 0; - var new_interface = new models.Interface(data.id, data.name); - for (i = 0; i < $scope.devices.length; i++){ - if ($scope.devices[i].id === data.device_id) { - $scope.devices[i].interface_seq = util.natural_numbers(data.id); - new_interface.device = $scope.devices[i]; - $scope.devices[i].interfaces.push(new_interface); - } - } - }; - - $scope.onLinkCreate = function(data) { - $log.debug(data); - $scope.create_link(data); - }; - - $scope.create_link = function(data) { - var i = 0; - var j = 0; - var new_link = new models.Link(null, null, null, null); - new_link.id = data.id; - $scope.link_id_seq = util.natural_numbers(data.id); - for (i = 0; i < $scope.devices.length; i++){ - if ($scope.devices[i].id === data.from_device_id) { - new_link.from_device = $scope.devices[i]; - for (j = 0; j < $scope.devices[i].interfaces.length; j++){ - if ($scope.devices[i].interfaces[j].id === data.from_interface_id) { - new_link.from_interface = $scope.devices[i].interfaces[j]; - $scope.devices[i].interfaces[j].link = new_link; - } - } - } - } - for (i = 0; i < $scope.devices.length; i++){ - if ($scope.devices[i].id === data.to_device_id) { - new_link.to_device = $scope.devices[i]; - for (j = 0; j < $scope.devices[i].interfaces.length; j++){ - if ($scope.devices[i].interfaces[j].id === data.to_interface_id) { - new_link.to_interface = $scope.devices[i].interfaces[j]; - $scope.devices[i].interfaces[j].link = new_link; - } - } - } - } - $log.debug(new_link); - if (new_link.from_interface !== null && new_link.to_interface !== null) { - new_link.from_interface.dot(); - new_link.to_interface.dot(); - } - if (new_link.from_device !== null && new_link.to_device !== null) { - $scope.links.push(new_link); - } - }; - - $scope.onLinkDestroy = function(data) { - $scope.destroy_link(data); - }; - - $scope.destroy_link = function(data) { - var i = 0; - var link = null; - var index = -1; - for (i = 0; i < $scope.links.length; i++) { - link = $scope.links[i]; - if (link.id === data.id && - link.from_device.id === data.from_device_id && - link.to_device.id === data.to_device_id && - link.to_interface.id === data.to_interface_id && - link.from_interface.id === data.from_interface_id) { - link.from_interface.link = null; - link.to_interface.link = null; - index = $scope.links.indexOf(link); - $scope.links.splice(index, 1); - } - } - }; - - $scope.onDeviceMove = function(data) { - $scope.move_device(data); - }; - - $scope.move_device = function(data) { - var i = 0; - var j = 0; - for (i = 0; i < $scope.devices.length; i++) { - if ($scope.devices[i].id === data.id) { - $scope.devices[i].x = data.x; - $scope.devices[i].y = data.y; - for (j = 0; j < $scope.devices[i].interfaces.length; j ++) { - $scope.devices[i].interfaces[j].dot(); - if ($scope.devices[i].interfaces[j].link !== null) { - $scope.devices[i].interfaces[j].link.to_interface.dot(); - $scope.devices[i].interfaces[j].link.from_interface.dot(); - } - } - break; - } - } - }; - - $scope.onClientId = function(data) { - $scope.client_id = data; - }; - - $scope.onTopology = function(data) { - $scope.topology_id = data.topology_id; - $scope.panX = data.panX; - $scope.panY = data.panX; - $scope.$emit('awxNet-UpdateZoomWidget', $scope.current_scale, true); - $scope.link_id_seq = util.natural_numbers(data.link_id_seq); - $scope.device_id_seq = util.natural_numbers(data.device_id_seq); - }; - - $scope.onDeviceSelected = function(data) { - var i = 0; - for (i = 0; i < $scope.devices.length; i++) { - if ($scope.devices[i].id === data.id) { - $scope.devices[i].remote_selected = true; - } - } - }; - - $scope.onDeviceUnSelected = function(data) { - var i = 0; - for (i = 0; i < $scope.devices.length; i++) { - if ($scope.devices[i].id === data.id) { - $scope.devices[i].remote_selected = false; - } - } - }; - - $scope.onSnapshot = function (data) { - - //Erase the existing state - $scope.devices = []; - $scope.links = []; - $scope.devices_by_name = {}; - - var device_map = {}; - var device_interface_map = {}; - var i = 0; - var j = 0; - var device = null; - var intf = null; - var new_device = null; - var new_intf = null; - var max_device_id = null; - var max_link_id = null; - var min_x = null; - var min_y = null; - var max_x = null; - var max_y = null; - var new_link = null; - - //Build the devices - for (i = 0; i < data.devices.length; i++) { - device = data.devices[i]; - if (max_device_id === null || device.id > max_device_id) { - max_device_id = device.id; - } - if (min_x === null || device.x < min_x) { - min_x = device.x; - } - if (min_y === null || device.y < min_y) { - min_y = device.y; - } - if (max_x === null || device.x > max_x) { - max_x = device.x; - } - if (max_y === null || device.y > max_y) { - max_y = device.y; - } - if (device.device_type === undefined) { - device.device_type = device.type; - } - new_device = new models.Device(device.id, - device.name, - device.x, - device.y, - device.device_type, - device.host_id); - if (device.variables !== undefined) { - new_device.variables = device.variables; - } - - for (j=0; j < $scope.inventory_toolbox.items.length; j++) { - if($scope.inventory_toolbox.items[j].name === device.name) { - $scope.inventory_toolbox.items.splice(j, 1); - break; - } - } - new_device.interface_seq = util.natural_numbers(device.interface_id_seq); - new_device.process_id_seq = util.natural_numbers(device.process_id_seq); - $scope.devices.push(new_device); - $scope.devices_by_name[new_device.name] = new_device; - device_map[device.id] = new_device; - device_interface_map[device.id] = {}; - for (j = 0; j < device.interfaces.length; j++) { - intf = device.interfaces[j]; - new_intf = (new models.Interface(intf.id, - intf.name)); - new_intf.device = new_device; - device_interface_map[device.id][intf.id] = new_intf; - new_device.interfaces.push(new_intf); - new_device.interfaces_by_name[new_intf.name] = new_intf; - } - } - - //Build the links - var link = null; - for (i = 0; i < data.links.length; i++) { - link = data.links[i]; - if (max_link_id === null || link.id > max_link_id) { - max_link_id = link.id; - } - new_link = new models.Link(link.id, - device_map[link.from_device_id], - device_map[link.to_device_id], - device_interface_map[link.from_device_id][link.from_interface_id], - device_interface_map[link.to_device_id][link.to_interface_id]); - new_link.name = link.name; - $scope.links.push(new_link); - device_interface_map[link.from_device_id][link.from_interface_id].link = new_link; - device_interface_map[link.to_device_id][link.to_interface_id].link = new_link; - } - - var diff_x; - var diff_y; - - // Calculate the new scale to show the entire diagram - if (min_x !== null && min_y !== null && max_x !== null && max_y !== null) { - diff_x = max_x - min_x; - diff_y = max_y - min_y; - - $scope.current_scale = Math.min(2, Math.max(0.10, Math.min((window.innerWidth-200)/diff_x, (window.innerHeight-300)/diff_y))); - $scope.$emit('awxNet-UpdateZoomWidget', $scope.current_scale, true); - $scope.updateScaledXY(); - } - // Calculate the new panX and panY to show the entire diagram - if (min_x !== null && min_y !== null) { - diff_x = max_x - min_x; - diff_y = max_y - min_y; - $scope.panX = $scope.current_scale * (-min_x - diff_x/2) + window.innerWidth/2; - $scope.panY = $scope.current_scale * (-min_y - diff_y/2) + window.innerHeight/2; - $scope.updateScaledXY(); - } - - //Update the device_id_seq to be greater than all device ids to prevent duplicate ids. - if (max_device_id !== null) { - $scope.device_id_seq = util.natural_numbers(max_device_id); - } - // - //Update the link_id_seq to be greater than all link ids to prevent duplicate ids. - if (max_link_id !== null) { - $scope.link_id_seq = util.natural_numbers(max_link_id); - } - - $log.debug(['data.inventory_toolbox', data.inventory_toolbox]); - if (data.inventory_toolbox !== undefined) { - $scope.inventory_toolbox.items = []; - for (i = 0; i < data.inventory_toolbox.length; i++) { - device = data.inventory_toolbox[i]; - $log.debug(device); - if (device.device_type === undefined) { - device.device_type = device.type; - } - new_device = new models.Device(device.id, - device.name, - device.x, - device.y, - device.device_type, - device.host_id); - if (device.variables !== undefined) { - new_device.variables = device.variables; - } - $scope.inventory_toolbox.items.push(new_device); - } - $log.debug($scope.inventory_toolbox.items); - } - - $scope.updateInterfaceDots(); - $scope.updatePanAndScale(); // Update the canvas element scale to the correct initial scale - $scope.$emit('awxNet-instatiateSelect', $scope.devices); - }; - - $scope.updateInterfaceDots = function() { - var i = 0; - var j = 0; - var devices = $scope.devices; - for (i = devices.length - 1; i >= 0; i--) { - for (j = devices[i].interfaces.length - 1; j >= 0; j--) { - devices[i].interfaces[j].dot(); - } - } - }; - - $scope.control_socket.onmessage = function(message) { - $scope.first_channel.send('Message', message); - $scope.$apply(); - }; - - $scope.control_socket.onopen = function() { - //ignore - }; - - $scope.test_socket.onmessage = function(message) { - $scope.test_channel.send('Message', message); - $scope.$apply(); - }; - - $scope.test_socket.onopen = function() { - //ignore - }; - - // Call onopen directly if $scope.control_socket is already open - if ($scope.control_socket.readyState === WebSocket.OPEN) { - $scope.control_socket.onopen(); - } - // Call onopen directly if $scope.test_socket is already open - if ($scope.test_socket.readyState === WebSocket.OPEN) { - $scope.test_socket.onopen(); - } - - $scope.send_test_message = function (message) { - var i = 0; - message.sender = $scope.test_client_id; - message.message_id = $scope.message_id_seq(); - if (message.constructor.name === "MultipleMessage") { - for (i=0; i < message.messages.length; i++) { - message.messages[i].message_id = $scope.message_id_seq(); - } - } - var data = messages.serialize(message); - if (!$scope.disconnected) { - $scope.test_socket.send(data); - } - }; - - $scope.send_control_message = function (message) { - var i = 0; - message.sender = $scope.client_id; - message.message_id = $scope.message_id_seq(); - if (message.constructor.name === "MultipleMessage") { - for (i=0; i < message.messages.length; i++) { - message.messages[i].message_id = $scope.message_id_seq(); - } - } - var data = messages.serialize(message); - if (!$scope.disconnected) { - $scope.control_socket.send(data); - } - }; - - $scope.$on('awxNet-closeNetworkUI', function(){ - $scope.control_socket.close(); - if ($scope.tests_enabled) { - $scope.test_socket.close(); - } - }); - - // End web socket - // - - angular.element($window).bind('resize', function(){ - - $scope.graph.width = $window.innerWidth; - $scope.graph.right_column = 300; - $scope.graph.height = $window.innerHeight; - - $scope.update_size(); - - // manuall $digest required as resize event - // is outside of angular - $scope.$digest(); - }); - - //60fps ~ 17ms delay - setInterval( function () { - $scope.frame = Math.floor(window.performance.now()); - $scope.$apply(); - }, 17); - - $log.debug("Network UI started"); - - $scope.$on('$destroy', function () { - $log.debug("Network UI stopping"); - $scope.first_channel.send('UnbindDocument', {}); - }); - - $scope.update_toolbox_heights = function(){ - var toolboxTopMargin = $('.Networking-top').height(); - var toolboxTitleMargin = toolboxTopMargin + 35; - var toolboxHeight = $scope.graph.height - toolboxTopMargin; - - let toolboxes = ['inventory_toolbox']; - toolboxes.forEach((toolbox) => { - $scope[toolbox].y = toolboxTopMargin; - $scope[toolbox].height = toolboxHeight; - $scope[toolbox].title_coordinates.y = toolboxTitleMargin; - }); - - $('.Networking-detailPanel').height(toolboxHeight); - $('.Networking-detailPanel').css('top', toolboxTopMargin); - }; - - $scope.update_size = function () { - $scope.update_toolbox_heights(); - }; - - setInterval( function () { - var test_event = null; - if ($scope.test_events.length > 0) { - test_event = $scope.test_events.shift(); - test_event.sender = 0; - try { - $scope.first_channel.send(test_event.msg_type, test_event); - } catch (err) { - $log.debug(["Test Error:", $scope.current_test, err]); - $scope.test_errors.push(err); - } - } - $scope.$apply(); - }, 10); - - ConfigService - .getConfig() - .then(function(config){ - $scope.version = config.version; - }); - - $scope.reset_coverage = function() { - var i = null; - var coverage = null; - var f = null; - if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) { - for (f in window.__coverage__) { - coverage = window.__coverage__[f]; - for (i in coverage.b) { - coverage.b[i] = [0, 0]; - } - for (i in coverage.f) { - coverage.f[i] = 0; - } - for (i in coverage.s) { - coverage.s[i] = 0; - } - } - } - }; - - $scope.reset_flags = function () { - $scope.debug = {'hidden': true}; - $scope.hide_buttons = false; - $scope.hide_links = false; - $scope.hide_interfaces = false; - }; - - - $scope.reset_fsm_state = function () { - $scope.hotkeys_controller.state = hotkeys.Start; - $scope.hotkeys_controller.state.start($scope.hotkeys_controller); - $scope.keybindings_controller.state = keybindings.Start; - $scope.keybindings_controller.state.start($scope.keybindings_controller); - $scope.view_controller.state = view.Start; - $scope.view_controller.state.start($scope.view_controller); - $scope.move_controller.state = move.Start; - $scope.move_controller.state.start($scope.move_controller); - $scope.move_readonly_controller.state = move_readonly.Start; - $scope.move_readonly_controller.state.start($scope.move_readonly_controller); - $scope.details_panel_controller.state = details_panel_fsm.Start; - $scope.details_panel_controller.state.start($scope.details_panel_controller); - $scope.time_controller.state = time.Start; - $scope.time_controller.state.start($scope.time_controller); - $scope.inventory_toolbox_controller.state = toolbox_fsm.Start; - $scope.inventory_toolbox_controller.state.start($scope.inventory_toolbox_controller); - $scope.mode_controller.state = mode_fsm.Start; - $scope.mode_controller.state.start($scope.mode_controller); - }; - - $scope.reset_toolboxes = function () { - $scope.inventory_toolbox.items = []; - $scope.inventory_toolbox.scroll_offset = 0; - }; - - $scope.cancel_animations = function () { - - var i = 0; - for (i = 0; i < $scope.animations.length; i++) { - this.animations[i].fsm.handle_message('AnimationCancelled'); - } - $scope.animations = []; - }; - $log.debug("Network UI loaded"); -}; - -exports.NetworkUIController = NetworkUIController; diff --git a/awx/ui/client/src/network-ui/network.ui.directive.js b/awx/ui/client/src/network-ui/network.ui.directive.js deleted file mode 100644 index af53c59677..0000000000 --- a/awx/ui/client/src/network-ui/network.ui.directive.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/network.ui.route.js b/awx/ui/client/src/network-ui/network.ui.route.js deleted file mode 100644 index 3c158b04f0..0000000000 --- a/awx/ui/client/src/network-ui/network.ui.route.js +++ /dev/null @@ -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; - } - ] - } -}; \ No newline at end of file diff --git a/awx/ui/client/src/network-ui/network.ui.strings.js b/awx/ui/client/src/network-ui/network.ui.strings.js deleted file mode 100644 index c82fcdc623..0000000000 --- a/awx/ui/client/src/network-ui/network.ui.strings.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/network_ui.partial.svg b/awx/ui/client/src/network-ui/network_ui.partial.svg deleted file mode 100644 index afb740b3d5..0000000000 --- a/awx/ui/client/src/network-ui/network_ui.partial.svg +++ /dev/null @@ -1,81 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/awx/ui/client/src/network-ui/quadrants.directive.js b/awx/ui/client/src/network-ui/quadrants.directive.js deleted file mode 100644 index 85874c9f21..0000000000 --- a/awx/ui/client/src/network-ui/quadrants.directive.js +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ - -const templateUrl = require('~network-ui/quadrants.partial.svg'); - -function quadrants () { - return { restrict: 'A', templateUrl}; -} -exports.quadrants = quadrants; diff --git a/awx/ui/client/src/network-ui/quadrants.partial.svg b/awx/ui/client/src/network-ui/quadrants.partial.svg deleted file mode 100644 index 142b733d42..0000000000 --- a/awx/ui/client/src/network-ui/quadrants.partial.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - diff --git a/awx/ui/client/src/network-ui/router.directive.js b/awx/ui/client/src/network-ui/router.directive.js deleted file mode 100644 index 22059d930d..0000000000 --- a/awx/ui/client/src/network-ui/router.directive.js +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ - -const templateUrl = require('~network-ui/router.partial.svg'); - -function router () { - return { restrict: 'A', templateUrl}; -} -exports.router = router; diff --git a/awx/ui/client/src/network-ui/router.partial.svg b/awx/ui/client/src/network-ui/router.partial.svg deleted file mode 100644 index 6e53d2d3b8..0000000000 --- a/awx/ui/client/src/network-ui/router.partial.svg +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{chunk}} - - - {{chunk}} - - - diff --git a/awx/ui/client/src/network-ui/style.less b/awx/ui/client/src/network-ui/style.less deleted file mode 100644 index 8ea255e279..0000000000 --- a/awx/ui/client/src/network-ui/style.less +++ /dev/null @@ -1,692 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ -@import 'network-nav/network.nav.block.less'; -@import 'network-details/details.block.less'; -@import 'zoom-widget/zoom.block.less'; - -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: url(/static/assets/OpenSans-Regular.ttf); -} - -@font-face { - font-family: 'Open Sans'; - font-style: bold; - font-weight: 600; - src: url(/static/assets/OpenSans-Bold.ttf); -} - -@selected-red: #c9232c; -@selected-mango: #ff5850; -@selected-blue: #5bbddf; -@light-background: #ffffff; -@light-widget-detail: #ffffff; -@dark-widget-detail: #707070; -@widget-body: #D7D7D7; -@link: #D7D7D7; -@group: #707070; -@debug-copynot: rgb(77,200,242); -@button-body: #ffffff; -@button-text: #707070; -@button-outline: #b7b7b7; -@button-body-hover: #f2f2f2; -@button-body-pressed: #848992; -@button-text-pressed: #ffffff; -@green: #5CB85C; -@red: #D9534F; -@blue: #337AB7; -@light-toolbox-background: #f6f6f6; -@icon-background-hover:@blue; -@context-menu-text: #333; - -.NetworkUI { - background-color: @light-toolbox-background; - z-index: 1100; -} - -.NetworkUI__text { - fill: @button-text; - font-family: 'Open Sans'; -} - -.NetworkUI__debug-text { - fill: @debug-copynot; - font-family: 'Open Sans'; -} - -.NetworkUI--debug { - fill-opacity: 0; - stroke: @debug-copynot; - stroke-width: 1; -} - -.NetworkUI--construction { - fill-opacity: 0; - stroke: @debug-copynot; - stroke-width: 1; -} - - -.NetworkUI__link--selected { - stroke: @selected-blue; - stroke-width: 6; -} - -.NetworkUI__link--remote-selected { - stroke: @selected-mango; - stroke-width: 6; -} - -.NetworkUI__link--selected-conflict { - stroke: @selected-red; - stroke-width: 6; -} - - -.NetworkUI__link { - stroke: @link; - stroke-width: 2; -} - -.NetworkUI__link--link-pass { - stroke: @green; - stroke-width: 2; -} - -.NetworkUI__link--link-fail { - stroke: @red; - stroke-width: 2; -} - -.NetworkUI__link--debug { - stroke: @debug-copynot; - stroke-width: 1; -} - -.NetworkUI__cursor { - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__debug-cursor { - stroke: @debug-copynot; - stroke-width: 4; -} - -.NetworkUI--hidden { - display: none; -} - -.NetworkUI__router { - fill: @blue; -} - -.NetworkUI__router--background{ - fill: @light-background; -} - -.NetworkUI__router--selected { - stroke: @selected-blue; - stroke-width: 10; - fill:@light-background; -} - -.NetworkUI__router--remote-selected { - stroke: @selected-mango; - stroke-width: 10; - fill: @light-background -} - -.NetworkUI__router--selected-conflict { - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__router-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__router-text--selected { - font-family: 'Open Sans'; -} - - -.NetworkUI__switch { - fill: @blue; -} - -.NetworkUI__switch--background{ - fill: @light-background; -} - -.NetworkUI__switch--selected { - stroke: @selected-blue; - stroke-width: 10; - fill:@light-background; -} - -.NetworkUI__switch--remote-selected { - stroke: @selected-mango; - stroke-width: 10; - fill: @light-background -} - -.NetworkUI__switch--selected-conflict { - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__switch line { - stroke: @light-widget-detail; - stroke-width: 20; -} - -.NetworkUI__switch polygon { - fill: @light-widget-detail; - stroke: none; -} - -.NetworkUI__switch-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__switch-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__rack { - fill: @blue; -} - -.NetworkUI__rack--background { - fill: @light-background; -} - -.NetworkUI__rack--selected { - fill: @light-background; - stroke: @selected-blue; - stroke-width: 10; -} - -.NetworkUI__rack--remote-selected { - fill: @light-background; - stroke: @selected-mango; - stroke-width: 10; -} - -.NetworkUI__rack--selected-conflict { - fill: @selected-red; - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__rack line { - stroke: @light-widget-detail; - stroke-width: 20; -} - -.NetworkUI__rack circle { - fill: @light-widget-detail; - stroke: none; -} - - -.NetworkUI__rack-text { - fill: @button-text; - font-family: 'Open Sans'; -} - -.NetworkUI__rack-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__site { - fill: @blue; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__site--fill0{ - fill:@blue; -} - -.NetworkUI__site--fill1{ - fill:none; - stroke:@light-background; - stroke-width:2; - stroke-miterlimit:10; -} - -.NetworkUI__site--fill2{ - fill:@light-background; -} - -.NetworkUI__site--network { - fill: @dark-widget-detail; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__site--background { - fill: @light-background; -} - -.NetworkUI__site--selected { - fill: @light-background; - stroke: @selected-blue; - stroke-width: 10; -} - -.NetworkUI__site--remote-selected { - fill: @light-background; - stroke: @selected-mango; - stroke-width: 10; -} - -.NetworkUI__site--selected-conflict { - fill: @selected-red; - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__site line { - stroke: @dark-widget-detail; - stroke-width: 10; -} - -.NetworkUI__site circle { - fill: @light-widget-detail; - stroke: none; -} - - -.NetworkUI__site-text { - fill: @button-text; - font-family: 'Open Sans'; -} - -.NetworkUI__site-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__button { - fill: @button-body; - stroke: @button-outline; - stroke-width: 1; -} - -.NetworkUI__button-text { - fill: @button-text; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__button--button-pressed { - fill: @button-body-pressed; - stroke: @button-outline; - stroke-width: 1; -} - -.NetworkUI__button-text--button-pressed { - fill: @button-text-pressed; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__button--button-hover { - fill: @button-body-hover; - stroke: @button-outline; - stroke-width: 1; -} - -.NetworkUI__button-text--button-hover { - fill: @button-text; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__host { - fill: @blue; -} - -.NetworkUI__host--background { - fill: @light-background; -} - -.NetworkUI__host--selected { - fill: @light-background; - stroke: @selected-blue; - stroke-width: 10; -} - -.NetworkUI__host--remote-selected { - fill: @light-background; - stroke: @selected-mango; - stroke-width: 10; -} - -.NetworkUI__host--selected-conflict { - fill: @selected-red; - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__host line { - stroke: @light-widget-detail; - stroke-width: 20; -} - -.NetworkUI__host circle { - fill: @light-widget-detail; - stroke: none; -} - - -.NetworkUI__host-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__host-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__device { - fill: @widget-body; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__device-background { - fill: @light-background; - stroke: @light-background; - stroke-width: 2; -} - -.NetworkUI__device--selected { - fill: @selected-blue; - stroke: @selected-blue; - stroke-width: 10; -} - -.NetworkUI__device--remote-selected { - fill: @light-background; - stroke: @selected-mango; - stroke-width: 10; -} - -.NetworkUI__device--selected-conflict { - fill: @selected-red; - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__device line { - stroke: @light-widget-detail; - stroke-width: 20; -} - - -.NetworkUI__device-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__device-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__status { - fill: @widget-body; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__status--pass { - fill: @green; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__status--fail { - fill: @red; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__status-path { - fill: none; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__circle-debug { - fill: @debug-copynot; -} - - -.NetworkUI__interface { - fill: @button-outline; -} - -.NetworkUI__interface--selected { - fill: @selected-blue; -} - -.NetworkUI__interface-text { - fill: @button-text; - font-size: 8px; - font-family: 'Open Sans'; -} - - -.NetworkUI__interface-text--selected { - font-size: 8px; - font-family: 'Open Sans'; -} - -.NetworkUI__link-text { - fill: @button-text; - font-size: 8px; - font-family: 'Open Sans'; -} - -.NetworkUI__group--selected { - stroke: @selected-blue; - stroke-width: 6; - fill: none; -} - -.NetworkUI__group--remote-selected { - stroke: @selected-mango; - stroke-width: 6; - fill: none; -} - -.NetworkUI__group--selected-conflict { - stroke: @selected-red; - stroke-width: 6; - fill: none; -} - -.NetworkUI__group { - stroke: @group; - stroke-width: 2; - fill: none; -} - -.NetworkUI__group--debug { - stroke: @debug-copynot; - stroke-width: 1; - fill: none; -} - -.NetworkUI__group-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__group-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__location-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__toolbox { - stroke: none; - fill: @light-background; -} - -.NetworkUI__toolbox-collapsed{ - fill: @light-background; - stroke: @button-outline; - stroke-width: 1; - rx: 0; - stroke-dasharray: calc(~"100vh - 80px"); - stroke-dashoffset: -45; -} - -.NetworkUI__toolbox-bezel { - stroke: @button-outline; - stroke-width: 1; - fill: none; - rx: 0; - stroke-dasharray: calc(~"100vh - 80px"); - stroke-dashoffset: -200; -} - -.NetworkUI__process { - fill: @widget-body; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__process-background { - fill: @light-background; - stroke: @light-background; - stroke-width: 2; -} - -.NetworkUI__process--selected { - fill: @selected-blue; - stroke: @selected-blue; - stroke-width: 10; -} - -.NetworkUI__process--remote-selected { - fill: @selected-mango; - stroke: @selected-mango; - stroke-width: 10; -} - -.NetworkUI__process--selected-conflict { - fill: @selected-red; - stroke: @selected-red; - stroke-width: 10; -} - -.NetworkUI__process path { - fill: @widget-body; - stroke: @dark-widget-detail; - stroke-width: 2; -} - -.NetworkUI__process-text { - fill: @button-text; - font-family: 'Open Sans'; -} - - -.NetworkUI__process-text--selected { - font-family: 'Open Sans'; -} - -.NetworkUI__stream { - fill: none; - stroke: @dark-widget-detail; -} - -.NetworkUI__stream-arrow { - fill: @dark-widget-detail; - stroke: @dark-widget-detail; -} - -.NetworkUI__stream--selected { - fill: none; - stroke: @selected-blue; - stroke-width: 6; -} -.NetworkUI__stream-arrow--selected { - fill: @selected-blue; - stroke: @selected-blue; -} - -.NetworkUI__stream-text { - fill: @button-text; - font-size: 8px; - font-family: 'Open Sans'; -} - -.NetworkUI__toolbox--title{ - fill: @dark-widget-detail; - text-transform: uppercase; - font-size: 14px; - font-weight: bold; -} - -.NetworkUI__contextMenu{ - fill: @light-background; - stroke: @button-outline; - stroke-width: 1; - -} - -.NetworkUI__contextMenuButton{ - fill: @light-background; -} - -.NetworkUI__contextMenuButtonText{ - fill: @context-menu-text; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__contextMenuButtonText-hover{ - fill: @context-menu-text; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__contextMenuButton-hover, -.NetworkUI__contextMenuButton-pressed{ - fill:@button-body-hover; -} - -.NetworkUI__contextMenuRemoveButtonText{ - fill: @red; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__contextMenuRemoveButtonText-hover{ - fill: @red; - font-family: 'Open Sans'; - font-size: 14px; -} - -.NetworkUI__test_results { - fill: @light-background; - stroke: @dark-widget-detail; -} diff --git a/awx/ui/client/src/network-ui/switch.directive.js b/awx/ui/client/src/network-ui/switch.directive.js deleted file mode 100644 index a9fbb48a8d..0000000000 --- a/awx/ui/client/src/network-ui/switch.directive.js +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ - -const templateUrl = require('~network-ui/switch.partial.svg'); - -function switchd () { - return { restrict: 'A', templateUrl}; -} -exports.switchd = switchd; diff --git a/awx/ui/client/src/network-ui/switch.partial.svg b/awx/ui/client/src/network-ui/switch.partial.svg deleted file mode 100644 index 44100b677a..0000000000 --- a/awx/ui/client/src/network-ui/switch.partial.svg +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{chunk}} - - - {{chunk}} - - - diff --git a/awx/ui/client/src/network-ui/templates/fsm.jst b/awx/ui/client/src/network-ui/templates/fsm.jst deleted file mode 100644 index afe75f5cd8..0000000000 --- a/awx/ui/client/src/network-ui/templates/fsm.jst +++ /dev/null @@ -1,26 +0,0 @@ -var inherits = require('inherits'); -var fsm = require('./fsm.js'); - -function _State () { -} -inherits(_State, fsm._State); - -{%for state in states%} -function _{{state.label}} () { - this.name = '{{state.label}}'; -} -inherits(_{{state.label}}, _State); -var {{state.label}} = new _{{state.label}}(); -exports.{{state.label}} = {{state.label}}; -{%endfor%} - -{%for state in states%} -{%for fn, transitions in state.functions%} -_{{state.label}}.prototype.{{fn}} = function (controller) { -{%for tn in transitions %} - controller.changeState({{tn.to_state}}); -{%endfor%} -}; -_{{state.label}}.prototype.{{fn}}.transitions = [{%for t in transitions%}'{{t.to_state}}'{% if not loop.last%}, {%endif%}{%endfor%}]; -{%endfor%} -{%endfor%} diff --git a/awx/ui/client/src/network-ui/test.fsm.js b/awx/ui/client/src/network-ui/test.fsm.js deleted file mode 100644 index 8e0b19a6aa..0000000000 --- a/awx/ui/client/src/network-ui/test.fsm.js +++ /dev/null @@ -1,186 +0,0 @@ -var inherits = require('inherits'); -var fsm = require('./fsm.js'); -var messages = require('./messages.js'); -var models = require('./models.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 _Running () { - this.name = 'Running'; -} -inherits(_Running, _State); -var Running = new _Running(); -exports.Running = Running; - -function _Loading () { - this.name = 'Loading'; -} -inherits(_Loading, _State); -var Loading = new _Loading(); -exports.Loading = Loading; - -function _Ready () { - this.name = 'Ready'; -} -inherits(_Ready, _State); -var Ready = new _Ready(); -exports.Ready = Ready; - -function _Reporting () { - this.name = 'Reporting'; -} -inherits(_Reporting, _State); -var Reporting = new _Reporting(); -exports.Reporting = Reporting; - - -_State.prototype.onMessage = function(controller, msg_type, message) { - - var type_data = JSON.parse(message.data); - var type = type_data[0]; - var data = type_data[1]; - - controller.handle_message(type, data); -}; - -_State.prototype.onid = function(controller, msg_type, message) { - controller.scope.test_client_id = message; -}; - -_State.prototype.onTestCase = function(controller, msg_type, message) { - if ('runnable' in message[1]) { - if (!message[1].runnable) { - return; - } - } - controller.scope.tests.push(new models.Test(message[0], - message[1].event_trace, - [], - message[1].snapshots[0], - message[1].snapshots[1])); -}; - -_Disabled.prototype.onEnableTest = function (controller) { - - controller.changeState(Ready); -}; -_Disabled.prototype.onEnableTest.transitions = ['Ready']; - - - -_Start.prototype.start = function (controller) { - - controller.changeState(Disabled); - -}; -_Start.prototype.start.transitions = ['Disabled']; - - - -_Running.prototype.onTestCompleted = function (controller) { - - controller.changeState(Reporting); -}; -_Running.prototype.onTestCompleted.transitions = ['Reporting']; - -_Reporting.prototype.start = function (controller) { - - var test_result = null; - controller.scope.replay = false; - controller.scope.disconnected = false; - controller.scope.recording = false; - controller.scope.cursor.hidden = true; - var result = "passed"; - if (controller.scope.test_errors.length > 0) { - result = "errored"; - } - test_result = new models.TestResult(controller.scope.test_result_id_seq(), - controller.scope.current_test.name, - result, - new Date().toISOString(), - controller.scope.version); - controller.scope.test_results.push(test_result); - controller.log.debug(["Reporting test", test_result.name, test_result.id]); - controller.scope.send_test_message(new messages.TestResult(controller.scope.client_id, - test_result.id, - test_result.name, - test_result.result, - test_result.date, - test_result.code_under_test)); - if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) { - controller.log.debug(["Reporting coverage", test_result.name, test_result.id]); - controller.scope.send_test_message(new messages.Coverage(controller.scope.client_id, window.__coverage__, test_result.id)); - } - controller.changeState(Loading); -}; -_Reporting.prototype.start.transitions = ['Loading']; - - -_Loading.prototype.start = function (controller) { - - if (controller.scope.current_tests.length === 0) { - controller.changeState(Disabled); - } else { - controller.log.debug("Starting test"); - controller.scope.reset_coverage(); - controller.scope.current_test = controller.scope.current_tests.shift(); - controller.scope.reset_toolboxes(); - controller.scope.onSnapshot(controller.scope.current_test.pre_test_snapshot); - controller.scope.replay = true; - controller.scope.disconnected = true; - controller.scope.test_errors = []; - controller.scope.test_events = controller.scope.current_test.event_trace.slice(); - controller.scope.test_events.push(new messages.TestCompleted()); - controller.scope.reset_flags(); - controller.scope.reset_fsm_state(); - controller.scope.cancel_animations(); - controller.scope.cursor.hidden = false; - controller.changeState(Running); - } -}; -_Loading.prototype.start.transitions = ['Running']; - - - -_Ready.prototype.onDisableTest = function (controller) { - - controller.changeState(Disabled); -}; -_Ready.prototype.onDisableTest.transitions = ['Disabled']; - -_Ready.prototype.start = function (controller) { - - var load_id = controller.scope.test_result_id_seq(); - - controller.log.debug(["Reporting Load", load_id]); - controller.scope.send_test_message(new messages.TestResult(controller.scope.client_id, - load_id, - "Load", - "passed", - new Date().toISOString(), - controller.scope.version)); - if (typeof(window.__coverage__) !== "undefined" && window.__coverage__ !== null) { - controller.log.debug(["Reporting Load Coverage", load_id]); - controller.scope.send_test_message(new messages.Coverage(controller.scope.client_id, window.__coverage__, load_id)); - } - - controller.changeState(Loading); -}; -_Ready.prototype.start.transitions = ['Loading']; diff --git a/awx/ui/client/src/network-ui/test_results.directive.js b/awx/ui/client/src/network-ui/test_results.directive.js deleted file mode 100644 index 9430ad4056..0000000000 --- a/awx/ui/client/src/network-ui/test_results.directive.js +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2018 Red Hat, Inc. */ - -const templateUrl = require('~network-ui/test_results.partial.svg'); - -function test_results () { - return { restrict: 'A', templateUrl}; -} -exports.test_results = test_results; diff --git a/awx/ui/client/src/network-ui/test_results.partial.svg b/awx/ui/client/src/network-ui/test_results.partial.svg deleted file mode 100644 index bc0c422a46..0000000000 --- a/awx/ui/client/src/network-ui/test_results.partial.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - -Test Results {{version}} - - -{{result.name}} - {{result.result}} - - - - - diff --git a/awx/ui/client/src/network-ui/time.fsm.js b/awx/ui/client/src/network-ui/time.fsm.js deleted file mode 100644 index cd425df2ae..0000000000 --- a/awx/ui/client/src/network-ui/time.fsm.js +++ /dev/null @@ -1,195 +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 _Start () { - this.name = 'Start'; -} -inherits(_Start, _State); -var Start = new _Start(); -exports.Start = Start; - -function _Present () { - this.name = 'Present'; -} -inherits(_Present, _State); -var Present = new _Present(); -exports.Present = Present; - -_Start.prototype.start = function (controller) { - - controller.changeState(Present); - -}; -_Start.prototype.start.transitions = ['Present']; - -_Present.prototype.onMessage = function(controller, msg_type, message) { - - var type_data = JSON.parse(message.data); - var type = type_data[0]; - var data = type_data[1]; - - controller.handle_message(type, data); -}; - -_Present.prototype.onMultipleMessage = function(controller, msg_type, message) { - - var i = 0; - if (message.sender !== controller.scope.client_id) { - for (i = 0; i< message.messages.length; i++) { - controller.handle_message(message.messages[i].msg_type, message.messages[i]); - } - } -}; - -_Present.prototype.onDeviceCreate = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onDeviceCreate(message); - } -}; -_Present.prototype.onInterfaceCreate = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onInterfaceCreate(message); - } -}; -_Present.prototype.onLinkCreate = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onLinkCreate(message); - } -}; -_Present.prototype.onDeviceMove = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onDeviceMove(message); - } -}; -_Present.prototype.onDeviceDestroy = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onDeviceDestroy(message); - } -}; -_Present.prototype.onLinkDestroy = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onLinkDestroy(message); - } -}; -_Present.prototype.onDeviceSelected = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onDeviceSelected(message); - } -}; -_Present.prototype.onDeviceUnSelected = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onDeviceUnSelected(message); - } -}; -_Present.prototype.onSnapshot = function(controller, msg_type, message) { - if (message.sender !== controller.scope.client_id) { - controller.scope.onSnapshot(message); - } -}; -_Present.prototype.onid = function(controller, msg_type, message) { - controller.scope.onClientId(message); -}; -_Present.prototype.onTopology = function(controller, msg_type, message) { - controller.scope.onTopology(message); -}; -_Present.prototype.onViewPort = function(controller, msg_type, message) { - if (message.sender === controller.scope.client_id) { - return; - } - controller.scope.current_scale = message.scale; - controller.scope.panX = message.panX; - controller.scope.panY = message.panY; - if (message.graph_width !== undefined) { - controller.scope.graph.width = message.graph_width; - } - if (message.graph_height !== undefined) { - controller.scope.graph.height = message.graph_height; - } - controller.scope.update_toolbox_heights(); - controller.scope.updateScaledXY(); - controller.scope.updatePanAndScale(); -}; -_Present.prototype.onMouseEvent = function(controller, msg_type, message) { - if (!controller.scope.replay) { - return; - } - if (message.sender === controller.scope.client_id) { - return; - } - message.preventDefault = util.noop; - if (message.type === "mousemove") { - controller.scope.onMouseMove(message); - } - if (message.type === "mouseup") { - controller.scope.onMouseUp(message); - } - if (message.type === "mousedown") { - controller.scope.onMouseDown(message); - } - if (message.type === "mouseover") { - controller.scope.onMouseOver(message); - } -}; -_Present.prototype.onMouseWheelEvent = function(controller, msg_type, message) { - if (!controller.scope.replay) { - return; - } - if (message.sender === controller.scope.client_id) { - return; - } - message.preventDefault = util.noop; - message.stopPropagation = util.noop; - controller.scope.onMouseWheel(message, message.delta, message.deltaX, message.deltaY); -}; - _Present.prototype.onKeyEvent = function(controller, msg_type, message) { - if (!controller.scope.replay) { - return; - } - if (message.sender === controller.scope.client_id) { - return; - } - message.preventDefault = util.noop; - if (message.type === "keydown") { - controller.scope.onKeyDown(message); - } -}; - -_Present.prototype.onRecordButton = function(controller) { - controller.scope.onRecordButton(); -}; - -_Present.prototype.onExportButton = function(controller) { - controller.scope.onExportButton(); -}; - -_Present.prototype.onExportYamlButton = function(controller) { - controller.scope.onExportYamlButton(); -}; - -_Present.prototype.onDownloadTraceButton = function(controller) { - controller.scope.onDownloadTraceButton(); -}; - -_Present.prototype.onDownloadRecordingButton = function(controller) { - controller.scope.onDownloadRecordingButton(); -}; - -_Present.prototype.onNoop = function() { - -}; - -_Present.prototype.onTestCompleted = function(controller, msg_type, message) { - - controller.scope.test_channel.send(msg_type, message); -}; - - -_Present.prototype.onError = function(controller, msg_type, message) { - throw new Error("ServerError: " + message); -}; diff --git a/awx/ui/client/src/network-ui/toolbox.fsm.js b/awx/ui/client/src/network-ui/toolbox.fsm.js deleted file mode 100644 index 562c38b167..0000000000 --- a/awx/ui/client/src/network-ui/toolbox.fsm.js +++ /dev/null @@ -1,343 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ -var inherits = require('inherits'); -var fsm = require('./fsm.js'); - -function _State () { -} -inherits(_State, fsm._State); - - -function _Dropping () { - this.name = 'Dropping'; -} -inherits(_Dropping, _State); -var Dropping = new _Dropping(); -exports.Dropping = Dropping; - -function _Selecting () { - this.name = 'Selecting'; -} -inherits(_Selecting, _State); -var Selecting = new _Selecting(); -exports.Selecting = Selecting; - -function _Selected () { - this.name = 'Selected'; -} -inherits(_Selected, _State); -var Selected = new _Selected(); -exports.Selected = Selected; - -function _Ready () { - this.name = 'Ready'; -} -inherits(_Ready, _State); -var Ready = new _Ready(); -exports.Ready = Ready; - -function _Scrolling () { - this.name = 'Scrolling'; -} -inherits(_Scrolling, _State); -var Scrolling = new _Scrolling(); -exports.Scrolling = Scrolling; - -function _Start () { - this.name = 'Start'; -} -inherits(_Start, _State); -var Start = new _Start(); -exports.Start = Start; - -function _Move () { - this.name = 'Move'; -} -inherits(_Move, _State); -var Move = new _Move(); -exports.Move = Move; - -function _OffScreen () { - this.name = 'OffScreen'; -} -inherits(_OffScreen, _State); -var OffScreen = new _OffScreen(); -exports.OffScreen = OffScreen; - -function _OffScreen2 () { - this.name = 'OffScreen2'; -} -inherits(_OffScreen2, _State); -var OffScreen2 = new _OffScreen2(); -exports.OffScreen2 = OffScreen2; - -function _Disabled () { - this.name = 'Disabled'; -} -inherits(_Disabled, _State); -var Disabled = new _Disabled(); -exports.Disabled = Disabled; - - -_Dropping.prototype.start = function (controller) { - - - var i = 0; - var toolbox = controller.toolbox; - for(i = 0; i < toolbox.items.length; i++) { - toolbox.items[i].selected = false; - } - - controller.dropped_action(toolbox.selected_item); - - if (controller.remove_on_drop && !toolbox.selected_item.template) { - var dindex = toolbox.items.indexOf(toolbox.selected_item); - if (dindex !== -1) { - toolbox.items.splice(dindex, 1); - } - } - - toolbox.selected_item = null; - controller.changeState(Ready); -}; -_Dropping.prototype.start.transitions = ['Ready']; - - - -_Selected.prototype.onMouseMove = function (controller) { - - controller.changeState(Move); - -}; -_Selected.prototype.onMouseMove.transitions = ['Move']; - -_Selected.prototype.onMouseUp = function (controller) { - - var i = 0; - var toolbox = controller.toolbox; - for(i = 0; i < toolbox.items.length; i++) { - toolbox.items[i].selected = false; - } - toolbox.selected_item = null; - controller.changeState(Ready); -}; -_Selected.prototype.onMouseUp.transitions = ['Ready']; - - -_Selecting.prototype.onMouseDown = function (controller) { - - var i = 0; - - var toolbox = controller.toolbox; - var scope = controller.scope; - var selected_item = Math.floor((controller.scope.mouseY - toolbox.y - toolbox.scroll_offset) / toolbox.spacing); - - for(i = 0; i < toolbox.items.length; i++) { - toolbox.items[i].selected = false; - } - if (selected_item >= 0 && selected_item < toolbox.items.length) { - toolbox.items[selected_item].selected = true; - toolbox.selected_item = toolbox.items[selected_item]; - scope.pressedX = scope.mouseX; - scope.pressedY = scope.mouseY; - scope.pressedScaledX = scope.scaledX; - scope.pressedScaledY = scope.scaledY; - toolbox.selected_item.x = toolbox.x + toolbox.width/2; - toolbox.selected_item.y = selected_item * toolbox.spacing + toolbox.y + toolbox.scroll_offset + toolbox.spacing/2; - controller.scope.clear_selections(); - controller.scope.first_channel.send("UnselectAll", {}); - controller.changeState(Selected); - } else { - toolbox.selected_item = null; - controller.changeState(Ready); - } - -}; -_Selecting.prototype.onMouseDown.transitions = ['Selected', 'Ready']; - -_Ready.prototype.onEnable = function () { - -}; - -_Ready.prototype.onMouseDown = function (controller, msg_type, $event) { - - if(controller.toolbox.enabled && - controller.scope.mouseX > controller.toolbox.x && - controller.scope.mouseY > controller.toolbox.y && - controller.scope.mouseX < controller.toolbox.x + controller.toolbox.width && - controller.scope.mouseY < controller.toolbox.y + controller.toolbox.height) { - - controller.changeState(Selecting); - controller.handle_message(msg_type, $event); - - } else { - controller.delegate_channel.send(msg_type, $event); - } -}; -_Ready.prototype.onMouseDown.transitions = ['Selecting']; - -_Ready.prototype.onMouseWheel = function (controller, msg_type, $event) { - - if(controller.toolbox.enabled && - controller.scope.mouseX > controller.toolbox.x && - controller.scope.mouseY > controller.toolbox.y && - controller.scope.mouseX < controller.toolbox.x + controller.toolbox.width && - controller.scope.mouseY < controller.toolbox.y + controller.toolbox.height) { - - controller.changeState(Scrolling); - controller.handle_message(msg_type, $event); - - } else { - controller.delegate_channel.send(msg_type, $event); - } -}; -_Ready.prototype.onMouseWheel.transitions = ['Scrolling']; - -_Ready.prototype.onToggleToolbox = function (controller, msg_type, message) { - - controller.changeState(OffScreen); - controller.delegate_channel.send(msg_type, message); - -}; -_Ready.prototype.onToggleToolbox.transitions = ['OffScreen']; - -_Ready.prototype.onDisable = function (controller) { - - controller.changeState(Disabled); - -}; -_Ready.prototype.onDisable.transitions = ['Disabled']; - -_Scrolling.prototype.onMouseWheel = function (controller, msg_type, $event) { - - var delta = $event[1]; - controller.toolbox.scroll_offset += -1 * delta; - controller.toolbox.scroll_offset = Math.min(controller.toolbox.scroll_offset, 0); - controller.toolbox.scroll_offset = Math.max(controller.toolbox.scroll_offset, - -1 * controller.toolbox.spacing * (controller.toolbox.items.length + 1) + controller.toolbox.height); - - - controller.changeState(Ready); - -}; -_Scrolling.prototype.onMouseWheel.transitions = ['Ready']; - - - -_Start.prototype.start = function (controller) { - - controller.changeState(Ready); - -}; -_Start.prototype.start.transitions = ['Ready']; - - - -_Move.prototype.onMouseUp = function (controller) { - - var i = 0; - var toolbox = controller.toolbox; - - if (controller.scope.mouseX < controller.toolbox.width) { - for(i = 0; i < toolbox.items.length; i++) { - toolbox.items[i].selected = false; - } - toolbox.selected_item = null; - controller.changeState(Ready); - - } else { - controller.changeState(Dropping); - } -}; -_Move.prototype.onMouseUp.transitions = ['Dropping']; - - -_Move.prototype.onMouseMove = function (controller) { - - var diffX = controller.scope.mouseX - controller.scope.pressedX; - var diffY = controller.scope.mouseY - controller.scope.pressedY; - - controller.toolbox.selected_item.x += diffX; - controller.toolbox.selected_item.y += diffY; - - controller.scope.pressedX = controller.scope.mouseX; - controller.scope.pressedY = controller.scope.mouseY; -}; - - -_OffScreen.prototype.onToggleToolbox = function (controller, msg_type, message) { - - controller.changeState(Ready); - controller.delegate_channel.send(msg_type, message); - -}; -_OffScreen.prototype.onToggleToolbox.transitions = ['Ready']; - - -_OffScreen.prototype.start = function (controller) { - - controller.toolbox.enabled = false; - -}; - -_OffScreen.prototype.end = function (controller) { - - controller.toolbox.enabled = true; - -}; - -_OffScreen.prototype.onDisable = function (controller) { - - controller.changeState(OffScreen2); -}; -_OffScreen.prototype.onDisable.transitions = ['OffScreen2']; - -_OffScreen2.prototype.onEnable = function (controller) { - - controller.changeState(OffScreen); -}; -_OffScreen2.prototype.onEnable.transitions = ['OffScreen']; - -_OffScreen2.prototype.onDisable = function () { - -}; - -_OffScreen2.prototype.start = function (controller) { - - controller.toolbox.enabled = false; -}; - -_OffScreen2.prototype.onToggleToolbox = function (controller, msg_type, message) { - - controller.changeState(Disabled); - controller.delegate_channel.send(msg_type, message); -}; -_OffScreen2.prototype.onToggleToolbox.transitions = ['Disabled']; - -_Disabled.prototype.onDisable = function () { - -}; - -_Disabled.prototype.onEnable = function (controller) { - - controller.changeState(Ready); -}; -_Disabled.prototype.onEnable.transitions = ['Ready']; - -_Disabled.prototype.start = function (controller) { - if(controller.toolbox !== undefined){ - controller.toolbox.enabled = false; - } -}; - -_Disabled.prototype.end = function (controller) { - - controller.toolbox.enabled = true; - -}; - -_Disabled.prototype.onToggleToolbox = function (controller, msg_type, message) { - - controller.changeState(OffScreen2); - controller.delegate_channel.send(msg_type, message); -}; -_Disabled.prototype.onToggleToolbox.transitions = ['OffScreen2']; diff --git a/awx/ui/client/src/network-ui/tools/copy-layout.py b/awx/ui/client/src/network-ui/tools/copy-layout.py deleted file mode 100755 index dd7cfbf947..0000000000 --- a/awx/ui/client/src/network-ui/tools/copy-layout.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2018 Benjamin Thomasson - -""" -Usage: - copy-layout [options] - -Options: - -h, --help Show this page - --debug Show debug logging - --verbose Show verbose logging -""" -from docopt import docopt -import logging -import sys -import yaml - -logger = logging.getLogger('copy-layout') - - -def main(args=None): - if args is None: - args = sys.argv[1:] - parsed_args = docopt(__doc__, args) - if parsed_args['--debug']: - logging.basicConfig(level=logging.DEBUG) - elif parsed_args['--verbose']: - logging.basicConfig(level=logging.INFO) - else: - logging.basicConfig(level=logging.WARNING) - - with open(parsed_args['']) as f: - from_fsm = yaml.load(f.read()) - with open(parsed_args['']) as f: - to_fsm = yaml.load(f.read()) - - to_states = {x['label']: x for x in to_fsm.get('states', [])} - - to_fsm['name'] = from_fsm.get('name', '') - to_fsm['finite_state_machine_id'] = from_fsm.get('finite_state_machine_id', '') - to_fsm['diagram_id'] = from_fsm.get('diagram_id', '') - - for state in from_fsm.get('states', []): - to_states.get(state['label'], {})['x'] = state.get('x', 0) - to_states.get(state['label'], {})['y'] = state.get('y', 0) - - with open(parsed_args[''], 'w') as f: - f.write(yaml.safe_dump(to_fsm, default_flow_style=False)) - - return 0 - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) diff --git a/awx/ui/client/src/network-ui/tools/fsm-diff b/awx/ui/client/src/network-ui/tools/fsm-diff deleted file mode 100755 index 5a400e96fe..0000000000 --- a/awx/ui/client/src/network-ui/tools/fsm-diff +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from fsm_diff.cli import main - -if __name__ == '__main__': - import sys - sys.exit(main(sys.argv[1:])) - diff --git a/awx/ui/client/src/network-ui/tools/fsm_diff/__init__.py b/awx/ui/client/src/network-ui/tools/fsm_diff/__init__.py deleted file mode 100755 index 268c10ff40..0000000000 --- a/awx/ui/client/src/network-ui/tools/fsm_diff/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -__author__ = 'Ben Thomasson' -__email__ = 'benthomasson@gmail.com' -__version__ = '0.1.0' diff --git a/awx/ui/client/src/network-ui/tools/fsm_diff/cli.py b/awx/ui/client/src/network-ui/tools/fsm_diff/cli.py deleted file mode 100644 index d180676016..0000000000 --- a/awx/ui/client/src/network-ui/tools/fsm_diff/cli.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Usage: - fsm_diff [options] [] - -Options: - -h, --help Show this page - --debug Show debug logging - --verbose Show verbose logging -""" -from docopt import docopt -import logging -import sys -import yaml - -logger = logging.getLogger('cli') - - -def fsm_diff(a_name, b_name, a, b, silent=True): - - a_states = {x['label'] for x in a['states']} - b_states = {x['label'] for x in b['states']} - - missing_in_a = b_states - a_states - missing_in_b = a_states - b_states - - - if (missing_in_b) and not silent: - print "Extra states in " + a_name + ":\n ", "\n ".join(list(missing_in_b)) - - if (missing_in_a) and not silent: - print "Extra states in " + b_name + ":\n ", "\n ".join(list(missing_in_a)) - - new_states = missing_in_b.union(missing_in_a) - - a_transitions = {tuple(sorted(x.items())) for x in a['transitions']} - b_transitions = {tuple(sorted(x.items())) for x in b['transitions']} - - missing_in_a = b_transitions - a_transitions - missing_in_b = a_transitions - b_transitions - - - if (missing_in_b) and not silent: - print "Extra transitions in " + a_name + ":\n ", "\n ".join(map(str, missing_in_b)) - - if (missing_in_a) and not silent: - print "Extra transitions in " + b_name + ":\n ", "\n ".join(map(str, missing_in_a)) - - new_transitions = missing_in_b.union(missing_in_a) - - data = dict(states=[dict(label=x) for x in list(new_states)], - transitions=[dict(x) for x in list(new_transitions)]) - - return data - - -def main(args=None): - if args is None: - args = sys.argv[1:] - parsed_args = docopt(__doc__, args) - if parsed_args['--debug']: - logging.basicConfig(level=logging.DEBUG) - elif parsed_args['--verbose']: - logging.basicConfig(level=logging.INFO) - else: - logging.basicConfig(level=logging.WARNING) - - with open(parsed_args['']) as f: - a = yaml.load(f.read()) - - with open(parsed_args['']) as f: - b = yaml.load(f.read()) - - data = fsm_diff(parsed_args[''], parsed_args[''], a, b, silent=False) - - if parsed_args['']: - with open(parsed_args[''], 'w') as f: - f.write(yaml.dump(data, default_flow_style=False)) - - return 0 diff --git a/awx/ui/client/src/network-ui/tools/fsm_generate_diffs.py b/awx/ui/client/src/network-ui/tools/fsm_generate_diffs.py deleted file mode 100755 index b5df78c419..0000000000 --- a/awx/ui/client/src/network-ui/tools/fsm_generate_diffs.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2017 Red Hat, Inc - -""" -Usage: - fsm_generate_diffs [options] - -Options: - -h, --help Show this page - --debug Show debug logging - --verbose Show verbose logging - --append Append the newly generated code to the implementation. -""" -from docopt import docopt -import logging -import sys -import fsm_diff.cli -import transform_fsm -import yaml - -from jinja2 import FileSystemLoader, Environment - -from subprocess import Popen, PIPE - -logger = logging.getLogger('fsm_generate_diffs') - - -def main(args=None): - if args is None: - args = sys.argv[1:] - parsed_args = docopt(__doc__, args) - if parsed_args['--debug']: - logging.basicConfig(level=logging.DEBUG) - elif parsed_args['--verbose']: - logging.basicConfig(level=logging.INFO) - else: - logging.basicConfig(level=logging.WARNING) - - implementation = parsed_args[''] - - p = Popen(['./extract.js', implementation], stdout=PIPE) - output = p.communicate()[0] - if p.returncode == 0: - b = yaml.load(output) - else: - return 1 - - with open(parsed_args['']) as f: - a = yaml.load(f.read()) - - data = fsm_diff.cli.fsm_diff(parsed_args[''], parsed_args[''], a, b) - data = transform_fsm.transform_fsm(data) - - env = Environment(loader=FileSystemLoader("templates")) - template = env.get_template('fsm.jst') - - if parsed_args['--append']: - with open(implementation, "a") as f: - f.write(template.render(**data)) - else: - print (template.render(**data)) - - - - return 0 - -if __name__ == '__main__': - import sys - sys.exit(main(sys.argv[1:])) diff --git a/awx/ui/client/src/network-ui/tools/requirements.txt b/awx/ui/client/src/network-ui/tools/requirements.txt deleted file mode 100644 index ec4c402207..0000000000 --- a/awx/ui/client/src/network-ui/tools/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -jinja2 -docopt -pyyaml - diff --git a/awx/ui/client/src/network-ui/tools/transform_fsm.py b/awx/ui/client/src/network-ui/tools/transform_fsm.py deleted file mode 100755 index 9b5fd0a66a..0000000000 --- a/awx/ui/client/src/network-ui/tools/transform_fsm.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2017 Red Hat, Inc - -""" -Usage: - transform_fsm [options] - -Options: - -h, --help Show this page - --debug Show debug logging - --verbose Show verbose logging -""" -from docopt import docopt -import logging -import sys -import yaml - -logger = logging.getLogger('transform_fsm') - - -def transform_fsm(data): - - state_map = dict() - - for state in data['states']: - state_map[state['label']] = state - state['functions'] = dict() - - for transition in data['transitions']: - state = state_map.get(transition['from_state'], dict(label=transition['from_state'], functions=dict())) - state_map[transition['from_state']] = state - if state not in data['states']: - data['states'].append(state) - function_transitions = state['functions'].get(transition['label'], list()) - function_transitions.append(dict(to_state=transition['to_state'])) - state['functions'][transition['label']] = function_transitions - - for state in data['states']: - state['functions'] = sorted(state['functions'].items()) - - return data - -def main(args=None): - if args is None: - args = sys.argv[1:] - parsed_args = docopt(__doc__, args) - if parsed_args['--debug']: - logging.basicConfig(level=logging.DEBUG) - elif parsed_args['--verbose']: - logging.basicConfig(level=logging.INFO) - else: - logging.basicConfig(level=logging.WARNING) - - with open(parsed_args['']) as f: - data = yaml.load(f.read()) - - data = transform_fsm(data) - - with open(parsed_args[''], 'w') as f: - f.write(yaml.safe_dump(data, default_flow_style=False)) - - return 0 - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) - diff --git a/awx/ui/client/src/network-ui/util.js b/awx/ui/client/src/network-ui/util.js deleted file mode 100644 index b46a95ed5b..0000000000 --- a/awx/ui/client/src/network-ui/util.js +++ /dev/null @@ -1,194 +0,0 @@ -/* Copyright (c) 2017 Red Hat, Inc. */ -var math = require('mathjs'); - -function noop () { -} -exports.noop = noop; - -function natural_numbers (start) { - var counter = start; - return function () {return counter += 1;}; -} -exports.natural_numbers = natural_numbers; - - -function distance (x1, y1, x2, y2) { - - return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); -} -exports.distance = distance; - -function pDistanceLine(x, y, x1, y1, x2, y2) { - //Code from http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment - //Joshua - // Find the dot product of two vectors , - // Divide by the length squared of - // Use scalar project to find param - // - - var A = x - x1; - var B = y - y1; - var C = x2 - x1; - var D = y2 - y1; - - var dot = A * C + B * D; - var len_sq = C * C + D * D; - var param = -1; - if (len_sq !== 0) { - //in case of 0 length line - param = dot / len_sq; - } - - var xx, yy; - - //Find a point xx, yy where the projection and the vector intersect. - //If less than 0 use x1, y1 as the closest point. - //If less than 1 use x2, y2 as the closest point. - //If between 0 and 1 use the projection intersection xx, yy - if (param < 0) { - xx = x1; - yy = y1; - } - else if (param > 1) { - xx = x2; - yy = y2; - } - else { - xx = x1 + param * C; - yy = y1 + param * D; - } - - return {x1:x, y1:y, x2: xx, y2: yy}; -} -exports.pDistanceLine = pDistanceLine; - -function pDistance(x, y, x1, y1, x2, y2) { - //Code from http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment - //Joshua - // Find the dot product of two vectors , - // Divide by the length squared of - // Use scalar project to find param - // - - var A = x - x1; - var B = y - y1; - var C = x2 - x1; - var D = y2 - y1; - - var dot = A * C + B * D; - var len_sq = C * C + D * D; - var param = -1; - if (len_sq !== 0) { - //in case of 0 length line - param = dot / len_sq; - } - - var xx, yy; - - //Find a point xx, yy where the projection and the vector intersect. - //If less than 0 use x1, y1 as the closest point. - //If less than 1 use x2, y2 as the closest point. - //If between 0 and 1 use the projection intersection xx, yy - if (param < 0) { - xx = x1; - yy = y1; - } - else if (param > 1) { - xx = x2; - yy = y2; - } - else { - xx = x1 + param * C; - yy = y1 + param * D; - } - - var dx = x - xx; - var dy = y - yy; - return Math.sqrt(dx * dx + dy * dy); -} -exports.pDistance = pDistance; - - -function cross_z_pos(x, y, x1, y1, x2, y2) { - var A = x - x1; - var B = y - y1; - var C = x2 - x1; - var D = y2 - y1; - - return math.cross([A, B, 0], [C, D, 0])[2] > 0; -} -exports.cross_z_pos = cross_z_pos; - -function intersection (x1, y1, x2, y2, x3, y3, x4, y4) { - //Find the point where lines through x1, y1, x2, y2 and x3, y3, x4, y4 intersect. - // - - var Aslope; - var Aintercept; - var Bslope; - var Bintercept; - - if ((x2 - x1) !== 0 && (x4 - x3) !== 0) { - Aslope = (y2 - y1)/(x2 - x1); - Aintercept = y1 - Aslope * x1; - - Bslope = (y4 - y3)/(x4 - x3); - Bintercept = y3 - Bslope * x3; - - var xi = (Bintercept - Aintercept) / (Aslope - Bslope); - var yi = Bslope * xi + Bintercept; - return {x: xi, y: yi}; - } - if ((x2 - x1) === 0 && (x4 - x3) === 0) { - return {x: null, y: null}; - } - if ((x2 - x1) === 0) { - Bslope = (y4 - y3)/(x4 - x3); - Bintercept = y3 - Bslope * x3; - return {x: x1, y: Bslope * x1 + Bintercept}; - } - if ((x4 - x3) === 0) { - Aslope = (y2 - y1)/(x2 - x1); - Aintercept = y1 - Aslope * x1; - return {x: x3, y: Aslope * x3 + Aintercept}; - } -} -exports.intersection = intersection; - - -function pCase(x, y, x1, y1, x2, y2) { - //Code from http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment - //Joshua - // Find the dot product of two vectors , - // Divide by the length squared of - // Use scalar project to find param - // - - var A = x - x1; - var B = y - y1; - var C = x2 - x1; - var D = y2 - y1; - - var dot = A * C + B * D; - var len_sq = C * C + D * D; - var param = -1; - if (len_sq !== 0) { - //in case of 0 length line - param = dot / len_sq; - } - - return param; -} -exports.pCase = pCase; - -function chunkSubstr(str, size) { - const numChunks = Math.ceil(str.length / size); - const chunks = new Array(numChunks); - - for (let i = 0, o = 0; i < numChunks; ++i, o += size) { - chunks[i] = str.substr(o, size); - } - - return chunks; -} -exports.chunkSubstr = chunkSubstr; diff --git a/awx/ui/client/src/network-ui/vendor/svg-crowbar.js b/awx/ui/client/src/network-ui/vendor/svg-crowbar.js deleted file mode 100644 index bba3093801..0000000000 --- a/awx/ui/client/src/network-ui/vendor/svg-crowbar.js +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @license svg-crowbar - * (c) 2013 The New York Times - * License: MIT - */ -function svg_crowbar () { - var doctype = ''; - - window.URL = (window.URL || window.webkitURL); - - var body = document.body; - - var prefix = { - xmlns: "http://www.w3.org/2000/xmlns/", - xlink: "http://www.w3.org/1999/xlink", - svg: "http://www.w3.org/2000/svg" - }; - - initialize(); - - function initialize() { - var documents = [window.document], - SVGSources = [], - iframes = document.querySelectorAll("iframe"), - objects = document.querySelectorAll("object"); - - [].forEach.call(iframes, function(el) { - try { - if (el.contentDocument) { - documents.push(el.contentDocument); - } - } catch(err) { - console.log(err); - } - }); - - [].forEach.call(objects, function(el) { - try { - if (el.contentDocument) { - documents.push(el.contentDocument); - } - } catch(err) { - console.log(err); - } - }); - - documents.forEach(function(doc) { - var styles = getStyles(doc); - var newSources = getSources(doc, styles); - // because of prototype on NYT pages - for (var i = 0; i < newSources.length; i++) { - SVGSources.push(newSources[i]); - } - }); - if (SVGSources.length > 1) { - createPopover(SVGSources); - } else if (SVGSources.length > 0) { - download(SVGSources[0]); - } else { - alert("The Crowbar couldn’t find any SVG nodes."); - } - } - - function createPopover(sources) { - cleanup(); - - sources.forEach(function(s1) { - sources.forEach(function(s2) { - if (s1 !== s2) { - if ((Math.abs(s1.top - s2.top) < 38) && (Math.abs(s1.left - s2.left) < 38)) { - s2.top += 38; - s2.left += 38; - } - } - }); - }); - - var buttonsContainer = document.createElement("div"); - body.appendChild(buttonsContainer); - - buttonsContainer.setAttribute("class", "svg-crowbar"); - buttonsContainer.style["z-index"] = 1e7; - buttonsContainer.style.position = "absolute"; - buttonsContainer.style.top = 0; - buttonsContainer.style.left = 0; - - - - var background = document.createElement("div"); - body.appendChild(background); - - background.setAttribute("class", "svg-crowbar"); - background.style.background = "rgba(255, 255, 255, 0.7)"; - background.style.position = "fixed"; - background.style.left = 0; - background.style.top = 0; - background.style.width = "100%"; - background.style.height = "100%"; - - sources.forEach(function(d, i) { - var buttonWrapper = document.createElement("div"); - buttonsContainer.appendChild(buttonWrapper); - buttonWrapper.setAttribute("class", "svg-crowbar"); - buttonWrapper.style.position = "absolute"; - buttonWrapper.style.top = (d.top + document.body.scrollTop) + "px"; - buttonWrapper.style.left = (document.body.scrollLeft + d.left) + "px"; - buttonWrapper.style.padding = "4px"; - buttonWrapper.style["border-radius"] = "3px"; - buttonWrapper.style.color = "white"; - buttonWrapper.style["text-align"] = "center"; - buttonWrapper.style["font-family"] = "'Helvetica Neue'"; - buttonWrapper.style.background = "rgba(0, 0, 0, 0.8)"; - buttonWrapper.style["box-shadow"] = "0px 4px 18px rgba(0, 0, 0, 0.4)"; - buttonWrapper.style.cursor = "move"; - buttonWrapper.textContent = "SVG #" + i + ": " + (d.id ? "#" + d.id : "") + (d.class ? "." + d.class : ""); - - var button = document.createElement("button"); - buttonWrapper.appendChild(button); - button.setAttribute("data-source-id", i); - button.style.width = "150px"; - button.style["font-size"] = "12px"; - button.style["line-height"] = "1.4em"; - button.style.margin = "5px 0 0 0"; - button.textContent = "Download"; - - button.onclick = function() { - // console.log(el, d, i, sources) - download(d); - }; - - }); - - } - - function cleanup() { - var crowbarElements = document.querySelectorAll(".svg-crowbar"); - - [].forEach.call(crowbarElements, function(el) { - el.parentNode.removeChild(el); - }); - } - - - function getSources(doc, styles) { - var svgInfo = [], - svgs = doc.querySelectorAll("svg"); - - styles = (styles === undefined) ? "" : styles; - - [].forEach.call(svgs, function (svg) { - - svg.setAttribute("version", "1.1"); - - var defsEl = document.createElement("defs"); - svg.insertBefore(defsEl, svg.firstChild); //TODO .insert("defs", ":first-child") - // defsEl.setAttribute("class", "svg-crowbar"); - - var styleEl = document.createElement("style"); - defsEl.appendChild(styleEl); - styleEl.setAttribute("type", "text/css"); - - - // removing attributes so they aren't doubled up - svg.removeAttribute("xmlns"); - svg.removeAttribute("xlink"); - - // These are needed for the svg - if (!svg.hasAttributeNS(prefix.xmlns, "xmlns")) { - svg.setAttributeNS(prefix.xmlns, "xmlns", prefix.svg); - } - - if (!svg.hasAttributeNS(prefix.xmlns, "xmlns:xlink")) { - svg.setAttributeNS(prefix.xmlns, "xmlns:xlink", prefix.xlink); - } - - var source = (new XMLSerializer()).serializeToString(svg).replace('', ''); - var rect = svg.getBoundingClientRect(); - svgInfo.push({ - top: rect.top, - left: rect.left, - width: rect.width, - height: rect.height, - class: svg.getAttribute("class"), - id: svg.getAttribute("id"), - childElementCount: svg.childElementCount, - source: [doctype + source] - }); - }); - return svgInfo; - } - - function download(source) { - var filename = "untitled"; - - if (source.id) { - filename = source.id; - } else if (source.class) { - filename = source.class; - } else if (window.document.title) { - filename = window.document.title.replace(/[^a-z0-9]/gi, '-').toLowerCase(); - } - - var url = window.URL.createObjectURL(new Blob(source.source, { "type" : "text\/xml" })); - - var a = document.createElement("a"); - body.appendChild(a); - a.setAttribute("class", "svg-crowbar"); - a.setAttribute("download", filename + ".svg"); - a.setAttribute("href", url); - a.style.display = "none"; - a.click(); - - setTimeout(function() { - window.URL.revokeObjectURL(url); - }, 10); - } - - function getStyles(doc) { - var styles = "", - styleSheets = doc.styleSheets; - - if (styleSheets) { - for (var i = 0; i < styleSheets.length; i++) { - processStyleSheet(styleSheets[i]); - } - } - - function processStyleSheet(ss) { - if (ss.cssRules) { - for (var i = 0; i < ss.cssRules.length; i++) { - var rule = ss.cssRules[i]; - if (rule.type === 3) { - // Import Rule - processStyleSheet(rule.styleSheet); - } else { - // hack for illustrator crashing on descendent selectors - if (rule.selectorText) { - if (rule.selectorText.indexOf(">") === -1) { - styles += "\n" + rule.cssText; - } - } - } - } - } - } - return styles; - } - -} -exports.svg_crowbar = svg_crowbar; diff --git a/awx/ui/client/src/network-ui/view.fsm.js b/awx/ui/client/src/network-ui/view.fsm.js deleted file mode 100644 index b1e047c1da..0000000000 --- a/awx/ui/client/src/network-ui/view.fsm.js +++ /dev/null @@ -1,124 +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 _Scale () { - this.name = 'Scale'; -} -inherits(_Scale, _State); -var Scale = new _Scale(); -exports.Scale = Scale; - -function _Pressed () { - this.name = 'Pressed'; -} -inherits(_Pressed, _State); -var Pressed = new _Pressed(); -exports.Pressed = Pressed; - -function _Pan () { - this.name = 'Pan'; -} -inherits(_Pan, _State); -var Pan = new _Pan(); -exports.Pan = Pan; - - - - -_Ready.prototype.onMouseDown = function (controller) { - - controller.scope.pressedX = controller.scope.mouseX; - controller.scope.pressedY = controller.scope.mouseY; - controller.scope.lastPanX = controller.scope.panX; - controller.scope.lastPanY = controller.scope.panY; - controller.scope.closeDetailsPanel(); - controller.changeState(Pressed); - -}; -_Ready.prototype.onMouseDown.transitions = ['Pressed']; - -_Ready.prototype.onMouseWheel = function (controller, msg_type, $event) { - - controller.changeState(Scale); - controller.handle_message(msg_type, $event); -}; -_Ready.prototype.onMouseWheel.transitions = ['Scale']; - - -_Start.prototype.start = function (controller) { - - controller.changeState(Ready); - -}; -_Start.prototype.start.transitions = ['Ready']; - -_Scale.prototype.onMouseWheel = function (controller, msg_type, message) { - var delta = message[1]; - if (Math.abs(delta) > 100) { - delta = delta / 10; - } - var new_scale = Math.max(controller.scope.MIN_ZOOM, - Math.min(controller.scope.MAX_ZOOM, - (controller.scope.current_scale + delta / (100 / controller.scope.current_scale)))); - var new_panX = controller.scope.mouseX - new_scale * ((controller.scope.mouseX - controller.scope.panX) / controller.scope.current_scale); - var new_panY = controller.scope.mouseY - new_scale * ((controller.scope.mouseY - controller.scope.panY) / controller.scope.current_scale); - controller.scope.updateScaledXY(); - controller.scope.current_scale = new_scale; - controller.scope.panX = new_panX; - controller.scope.panY = new_panY; - var item = controller.scope.context_menus[0]; - item.enabled = false; - controller.scope.$emit('awxNet-UpdateZoomWidget', controller.scope.current_scale, true); - controller.scope.updatePanAndScale(); - controller.changeState(Ready); -}; -_Scale.prototype.onMouseWheel.transitions = ['Ready']; - - -_Pressed.prototype.onMouseUp = function (controller) { - - controller.changeState(Ready); - -}; -_Pressed.prototype.onMouseUp.transitions = ['Ready']; - -_Pressed.prototype.onMouseMove = function (controller, msg_type, $event) { - - controller.changeState(Pan); - controller.handle_message(msg_type, $event); -}; -_Pressed.prototype.onMouseMove.transitions = ['Pan']; - -_Pan.prototype.onMouseMove = function (controller) { - - controller.scope.panX = (controller.scope.mouseX - controller.scope.pressedX) + controller.scope.lastPanX; - controller.scope.panY = (controller.scope.mouseY - controller.scope.pressedY) + controller.scope.lastPanY; - controller.scope.updateScaledXY(); - controller.scope.updatePanAndScale(); -}; - -_Pan.prototype.onMouseUp = function (controller) { - - controller.changeState(Ready); - -}; -_Pan.prototype.onMouseUp.transitions = ['Ready']; diff --git a/awx/ui/client/src/network-ui/zoom-widget/main.js b/awx/ui/client/src/network-ui/zoom-widget/main.js deleted file mode 100644 index 518ec0976b..0000000000 --- a/awx/ui/client/src/network-ui/zoom-widget/main.js +++ /dev/null @@ -1,11 +0,0 @@ -/************************************************* - * Copyright (c) 2018 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -import awxNetZoomWidget from './zoom.directive'; - -export default - angular.module('networkZoomWidget', []) - .directive('awxNetZoomWidget', awxNetZoomWidget); diff --git a/awx/ui/client/src/network-ui/zoom-widget/zoom.block.less b/awx/ui/client/src/network-ui/zoom-widget/zoom.block.less deleted file mode 100644 index d827dcbe1e..0000000000 --- a/awx/ui/client/src/network-ui/zoom-widget/zoom.block.less +++ /dev/null @@ -1,59 +0,0 @@ -.Networking-zoomPanel{ - position: absolute; - bottom:0px; - right:0px; - border-top: 1px solid @btn-bord; - border-left: 1px solid @btn-bord; - width: 200px; - height:60px; -} - -.Networking-zoomPanel--expanded{ - right:400px; -} - -.NetworkingControls-manualControls{ - position: absolute; - background-color: @default-bg; - padding-left:15px; - width: 100%; -} - -.NetworkingControls-Zoom{ - display: flex; - flex: 1 0 auto; -} - -.NetworkingControls-Zoom--button { - line-height: 60px; - color: @default-icon; -} - -.NetworkingControls-Zoom--button:hover { - color: @default-link-hov; -} - -.NetworkingControls-zoomSlider { - width: 150px; - padding-left: 8px; - padding-right: 8px; -} - -.NetworkingControls-zoomPercentage { - text-align: center; - font-size: 0.7em; - height: 24px; - line-height: 24px; -} - -.ui-slider-handle.ui-state-default.ui-corner-all { - border-radius: 50%; - border-color: @default-link; - background: @default-link; -} - -.ui-slider-handle.ui-state-default.ui-corner-all:hover, -.ui-slider-handle.ui-state-default.ui-corner-all:active { - border-color: @default-link-hov; - background: @default-link-hov; -} diff --git a/awx/ui/client/src/network-ui/zoom-widget/zoom.directive.js b/awx/ui/client/src/network-ui/zoom-widget/zoom.directive.js deleted file mode 100644 index b4ba023988..0000000000 --- a/awx/ui/client/src/network-ui/zoom-widget/zoom.directive.js +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************* - * Copyright (c) 2018 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -// import detailsController from './details.controller'; - -const templateUrl = require('~network-ui/zoom-widget/zoom.partial.html'); - -export default [ - function() { - return { - templateUrl, - restrict: 'E', - link(scope){ - - function init() { - scope.zoom = 100; - $( "#networking-slider" ).slider({ - value:100, - min: 0, - max: 200, - step: 10, - slide: function( event, ui ) { - scope.zoom = ui.value; - scope.zoomTo(); - } - }); - } - - init(); - - scope.$parent.$on('awxNet-UpdateZoomWidget', (e, scale, updateBoolean) => { - if(scale && updateBoolean){ - // scale is included, meaning this was triggered by - // the view FSM's onMouseWheel transition - let sliderPercent = 120 * (Math.log10(scale) + 1); - scope.zoom = Math.round(sliderPercent / 10) * 10; - } - $("#networking-slider").slider('value', scope.zoom); - }); - - scope.zoomTo = function() { - scope.zoom = Math.ceil(scope.zoom / 10) * 10; - this.$parent.$broadcast('awxNet-zoom', scope.zoom); - }; - - scope.zoomOut = function(){ - scope.zoom = scope.zoom - 10 > 0 ? scope.zoom - 10 : 0; - this.$parent.$broadcast('awxNet-zoom', scope.zoom); - }; - - scope.zoomIn = function(){ - scope.zoom = scope.zoom + 10 < 200 ? scope.zoom + 10 : 200; - this.$parent.$broadcast('awxNet-zoom', scope.zoom); - }; - } - }; -}]; diff --git a/awx/ui/client/src/network-ui/zoom-widget/zoom.partial.html b/awx/ui/client/src/network-ui/zoom-widget/zoom.partial.html deleted file mode 100644 index 09fa5acb70..0000000000 --- a/awx/ui/client/src/network-ui/zoom-widget/zoom.partial.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
-
- -
-
-
{{zoom}}%
-
-
-
- -
-
-
diff --git a/awx/ui/client/src/vendor.js b/awx/ui/client/src/vendor.js index c4263249f1..de496ac02d 100644 --- a/awx/ui/client/src/vendor.js +++ b/awx/ui/client/src/vendor.js @@ -63,11 +63,3 @@ require('ng-toast'); require('lr-infinite-scroll'); require('codemirror/mode/yaml/yaml'); require('codemirror/mode/javascript/javascript'); - -// Network Visualization -require('angular-mousewheel'); -require('angular-xeditable'); -require('hamsterjs'); -require('titlecase'); -require('inherits'); -require('mathjs'); diff --git a/awx/ui/package.json b/awx/ui/package.json index e3c9d52c8a..b4b3307619 100644 --- a/awx/ui/package.json +++ b/awx/ui/package.json @@ -128,12 +128,6 @@ "reconnectingwebsocket": "^1.0.0", "rrule": "git+https://git@github.com/jkbrzt/rrule#4ff63b2f8524fd6d5ba6e80db770953b5cd08a0c", "select2": "^4.0.2", - "sprintf-js": "^1.0.3", - "mathjs": "^3.15.0", - "hamsterjs": "^1.1.2", - "titlecase": "^1.1.2", - "inherits": "^1.0.2", - "angular-mousewheel": "^1.0.5", - "angular-xeditable": "~0.8.0" + "sprintf-js": "^1.0.3" } } diff --git a/awx/urls.py b/awx/urls.py index 57a97fdae5..554eb2c813 100644 --- a/awx/urls.py +++ b/awx/urls.py @@ -15,7 +15,6 @@ urlpatterns = [ url(r'^api/', include('awx.api.urls', namespace='api')), url(r'^sso/', include('awx.sso.urls', namespace='sso')), url(r'^sso/', include('social_django.urls', namespace='social')), - url(r'^network_ui/', include('awx.network_ui.urls', namespace='network_uiui', app_name='network_ui')), url(r'^(?:api/)?400.html$', handle_400), url(r'^(?:api/)?403.html$', handle_403), url(r'^(?:api/)?404.html$', handle_404), diff --git a/docs/networking.md b/docs/networking.md deleted file mode 100644 index 1334b45395..0000000000 --- a/docs/networking.md +++ /dev/null @@ -1,686 +0,0 @@ -# Tower Networking Overview -The networking tool is built with the main goal of allowing users to organize hosts and their relationships in a visual tool. Upon organizing hosts, the user can export these relationships as a YAML file and use that as input to a playbook. - -## Usage Manual - -### Inventory Creation -The first step in is to create an inventory to be loaded into the network UI. There are no specific credentials or variables necessary to indicate that an inventory can be used in the network UI. The canvas can be used to represent any kind of inventory. - -### Network Node Creation -Once the user has created an inventory, the next step is to add hosts to the inventory. This can be done manually or via an inventory source. Regardless of the import method, the host should be configured with a certain set of host varialbes that the network UI will reference when creating visual representations of the nodes. When creating a node that will be used in the network UI, the host variables follow this format: -#### YAML: -``` -ansible_topology: - type: host -``` -#### JSON: -``` -{ - "ansible_topology": { - "type": "host", - } -} -``` - -This structure denotes that the `type` that the network UI will use when drawing the visual representation of this node in the UI. The options for `ansible_topology` are as follows: - -| Key Name | Value Type | Description | -|------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `type` | `str` | This will dictate what type of device the network UI will draw. Options are `host`, `switch`, and `router`. If left blank, the UI will denote the node type as `unknown`. | -| `links` | `array` | This array contains objects that will denote what other nodes this particular node is connected to. Each connecting node object requires a `remote_device_name`, a `name`, and a `remote_interface_name`. - -Ex: suppose an inventory had three nodes, titled `host-00`, `switch-00`, and `router-00`. To connect `host-00` to the other two hosts, these would be the host variables saved to the host: -``` -{ - "ansible_topology": { - "type": "host", - "links": [ - { - "remote_device_name": "router-00", - "name": "eth0", - "remote_interface_name": "eth0" - }, - { - "remote_device_name": "switch-00", - "name": "eth1", - "remote_interface_name": "eth1" - } - ] - } -} - -``` -Connecting the other two devices to each other, and you would get the following representation in the network UI: -![Example 1](./img/network-example-1.png?raw=true) - - -### Graphical UI and Restrictions -Once the user has setup their inventory and nodes, they are ready to begin organizing their nodes using the graphical interface. The interface consists of an SVG canvas overlayed with panels that allow the user to drag nodes onto the canvas, as well as the ability to drill-down into the details of the items on the canvas. Below is a breakdown of the panels and their purpose on the interface: -![Example 2](./img/network-example-2.png?raw=true) -1. Toolbox: This panel on the left hand side of the screen will contain all the hosts that are included in the inventory. These are returned from `'/api/v2/inventories/:inventory_id/hosts/'` and therefore are returned in a paginated list. Because of this, the UI will make recursive calls to retrieve the list of hosts. This panel is collapsible using the wrench icon in the toolbar. This panel will scroll vertically with the list of devices. -2. Canvas: The canvas takes up the full screen width and height. The canvas is where the user can drag and drop devices from the toolbox. Once a device is placed on the canvas, it is removed from the toolbox and it can interact with other devices on the canvas. If a device is removed from the canvas, it is not removed from the inventory, it is simply removed from the canvas, and will return to the toolbox -3. Context Menu: When a user clicks on a device for the first time, it selects the device. A second click will activate a context menu with actions for the user. If the user has edit permission on the inventory, they will have the options to view the details of the device, or to remove the device. If the user does not have edit permission, they will only have the option to view the details of the device. -4. Details: The right hand panel displays a read-only form for the device that is currently being inspected by the user. This panel is not shown by default, and is only shown after the user clicks the "Details" button on the context menu for a device. If mutiple devices are displayed on the canvas, the user can select different devices. As the user selects devices, the device detail panel on the right hand side will update with the host data. -5. Search: The search dropdown is a type-ahead dropdown that has a list of the devices currently on the canvas. It is organized by device type. It should always be in sync with the list of devices on the canvas. Devices on the toolbox will not show up in the search dropdown. Selecting a device from this dropdown will focus the canvas on the device. -6. Toolbar actions: These are actions that are specific to the usability of the network UI. Currently they include the toggle for the toolbox, as well as a cheat sheet of hotkeys that can be used for shortcuts on the network UI. -7. Actions dropdown: These are actions for the content of the network UI. These include "Export YAML" and "Export SVG" which is how a user could export the relationships on the canvas to download for their own use. -8. Zoom Widget: The zoom widget ranges from 0-200%, and controls the zoom of the canvas. The user can also control the zoom using the scroll on their mouse or tracking pad. In future versions of this UI, the zoom will control what level detail they are able to see. But currently the only mode available is for devices in an inventory. - - -## Verification - -See [networking.feature](networking.feature) for behavior scenarios. - - -## Implementation Details - -**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: - -**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: - -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](../awx/ui/client/src/network-ui/network.ui.app.js) -``` - .directive('awxNetLink', link.link) -``` - -* See: [link.directive.js](../awx/ui/client/src/network-ui/link.directive.js) -``` -const templateUrl = require('~network-ui/link.partial.svg'); - -function link () { - return { restrict: 'A', templateUrl}; -} -exports.link = link; -``` - -**AngularJS Templates** - -* See: - -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](../awx/ui/client/src/network-ui/link.directive.js) -* See: [link.partial.svg](../awx/ui/client/src/network-ui/link.partial.svg) - -* See: [network_ui.partial.svg](../awx/ui/client/src/network-ui/network_ui.partial.svg) -``` - - - -``` - -* See: [models.js](../awx/ui/client/src/network-ui/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](../awx/ui/client/src/network-ui/inventory_toolbox.partial.svg) -``` - -``` - - -**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: - -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: - -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: - - -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: - -**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](../awx/ui/client/src/network-ui/style.less) -* See: -* See: - -**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](../awx/ui/client/src/network-ui/network_ui.partial.svg#L3) - -``` - -``` - - -Key events are captured by the following code: - -* See: [network.ui.controller.js](../awx/ui/client/src/network-ui/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. - -![Event Pipeline](networking/pipeline.png) - - -**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: - -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. - -**Move FSM** - -![Move FSM](networking/move.png) - -For example the move FSM describes how devices are moved about the virtual -canvas. The FSM diagram above maps out the states and the events that will -select a device to move. 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`. When the user presses the mouse button -if the cursor is over a device the FSM changes state to `Selected1`. If the -user then moves the mouse while the button is still pressed the device will be -moved along with the mouse cursor. When the mouse button is lifted the FSM -changes to the `Selected1` and then also to the `Selected2` state. This -implements clicking and dragging devices around the virtual canvas. Clicking on -the canvas background will return the FSM to the `Ready` state. - -* See: [networking/move.yml](networking/move.yml) -* See: [move.fsm.js](../awx/ui/client/src/network-ui/move.fsm.js) - -The move FSM diagram has an equivalent machine readable representation in -`networking/move.yml`. This representation is useful for comparing the current -implementation in `move.fsm.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. This -machine readable representation of the FSM can be used to generate test inputs -to the FSM to achieve high test coverage of all states and transitions in the -FSM. - - -**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: [networking/README.md](networking/README.md) -* See: -* See: - -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](../awx/ui/client/src/network-ui/fsm.js) will provide empty `start` and `end` functions that -can be overridden as necessary. - -* See: [fsm.js](../awx/ui/client/src/network-ui/fsm.js) - -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](../awx/ui/client/src/network-ui/models.js) - -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: [move.fsm.js](../awx/ui/client/src/network-ui/move.fsm.js) - -This code block defines the `_Selected1` 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 `Selected1`. - -``` - function _Selected1 () { - this.name = 'Selected1'; - } - inherits(_Selected1, _State); - var Selected1 = new _Selected1(); - exports.Selected1 = Selected1; -``` - -**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: [move.fsm.js](../awx/ui/client/src/network-ui/move.fsm.js) - -In this code we define an event handler for the `MouseUp` event on the `Selected1` 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 `Selected2` state. - -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. - -``` - _Selected1.prototype.onMouseUp = function (controller, msg_type, message) { - - ... - - }; - _Selected1.prototype.onMouseUp.transitions = ['Selected2']; - -``` - -**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 `networking` directory. - -* See: [networking/README.md](networking/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 from or serialized into messages that -are sent to other FSMControllers in the client or sent over a websocket to the -server. - -* See: [models.js](../awx/ui/client/src/network-ui/models.js) - -The models defined in [models.js](../awx/ui/client/src/network-ui/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 -* ToolBox - a UI element for holding things that can be placed on the virtual canvas - - -**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](../awx/ui/client/src/network-ui/messages.js) - -The messages defined are [messages.js](../awx/ui/client/src/network-ui/messages.js): - -* DeviceMove - Device has changed x,y position -* DeviceCreate - A device was created -* DeviceDestroy - A device was destroyed -* DeviceSelected - A device was selected -* DeviceUnSelected - A device was unselected -* InterfaceCreate - An interface was created -* InterfaceLabelEdit - The label of an interface was changed -* LinkCreate - A link was created -* LinkDestroy - A link was destroyed -* LinkSelected - A link was selected -* LinkUnSelected - A link was unselected -* 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 -* 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 - - -Server-Side Details ------------------------ - -The Network UI is a UX driven feature to provide a graphical user -experience that fits well into the network engineer's normal workflow. Their -normal workflow includes a diagram drawn in a graphical drawing program, a -spreadsheet, and the command line interface of their network gear. Network -architects design the network on the graphical diagram and then hand off the -architecture to network operators who implement the architecture on the network -using spreadsheets to manage their data and manually converting the data into -CLI commands using their networking expertise and expertise with their physical -gear. - -The server-side code supports the persistence needed to provide this graphical -user experience of architecting a network and using that information along with -additional information (stored in vars files) to configure the network devices -using the CLI or NETCONF using Ansible playbooks and roles. - -Network UI Data Schema ----------------------- - -For the 3.3 release the persistence needed includes the position information of -the devices on the virtual canvas and the type of the devices as well as -information about the interfaces on the devices and the links connecting those -interfaces. - -These requirements determine the database schema needed for the network UI which -requires these models: Topology, Device, Interface, Link, Client, and TopologyInventory. - -![Models](networking/models.png) - -This diagram shows the relationships between the models in the Network UI schema. - -The models are: - -* Device - a host, switch, router, or other networking device -* Interface - a connection point on a device for a link -* Link - a physical connection between two devices to their respective interfaces -* Topology - a collection of devices and links -* TopologyInventory - a mapping between topologies and Tower inventories -* Client - a UI client session - - -Network UI Websocket Protocol ------------------------------ - -Persistence for the network UI canvas state is implemented using an -asynchronous websocket protocol to send information from the client to the -server and vice-versa. This two-way communication was chosen to support future -features for streaming data to the canvas, broadcast messaging between clients, -and for interaction performance on the UI. - - -Messages --------- - -JSON messages are passed over the `/network_ui/topology/` websocket between the -test client and the test server. The protocol that is used for all messages is -in ABNF (RFC5234): - - - message_type = 'DeviceMove' / 'DeviceCreate' / 'DeviceDestroy' / 'DeviceLabelEdit' / 'DeviceSelected' / 'DeviceUnSelected' / 'InterfaceCreate' / 'InterfaceLabelEdit' / 'LinkLabelEdit' / 'LinkCreate' / 'LinkDestroy' / 'LinkSelected' / 'LinkUnSelected' / 'MultipleMessage' / 'Snapshot' - message_data = '{' 'msg_type' ': ' message_type ', ' key-value *( ', ' key-value ) '}' - message = '[ id , ' posint ']' / '[ topology_id , ' posint ']' / '[' message_type ', ' message_data ']' - -See https://github.com/AndyA/abnfgen/blob/master/andy/json.abnf for the rest of -the JSON ABNF. - -See [networking/messages.yml](networking/messages.yml) for the allowable keys and -values for each message type. - - -Initially when the websocket is first opened the server will send four messages -to the client. These are: - -* the client id using the `id` message type. -* the topology id using the `topology` message type. -* a Topology record containing data for the canvas itself. -* a Snapshot message containing all the data of the data on the canvas. - -As the user interacts with the canvas messages will be generated by the client -and the `network_ui.consumers.NetworkEvents` class will update the models that -represent the canvas. - - - -Persistence ------------ - -The class `awx.network_uiconsumers.NetworkEvents` provides persistence for the Network UI canvas. -It does so by providing message handlers that handle storage of the canvas change events -into the database. Each event has a message handle with name `onX` where `X` is the name of the message -type. The handlers use the `filter/values_list`, `filter/values`, `filter/update`, and `filter/delete` -patterns to update the data in the database quickly with a constant O(1) number of queries per event -often with only one query needed. With `filter/update` and `filter/delete` all the work is done -in the database and Python never needs to instaniate and garbage collect the model objects. - -Bulk operations (`filter/values`) in `send_snapshot` are used to produce a constant number of -queries produce a snapshot when the canvas is first loaded. This method avoids creating -the model objects since it only produces dicts that are JSON serializable which are bundled -together for the `Snapshot` message type. - -This method of persistence uses Django as a database query-compiler for transforms from -the event types to the database types. Using Django in this way is very performant since -Python does very little work processing the data and when possible the data never leaves -the database. - - -Client Tracking ---------------- - -Each user session to the network UI canvas is tracked with the `Client` model. Multiple -clients can view and interact with the network UI canvas at a time. They will see each other's -edits to the canvas in real time. This works by broadcasting the canvas change events to -all clients viewing the same topology. - -``` - # Send to all clients editing the topology - Group("topology-%s" % message.channel_session['topology_id']).send({"text": message['text']}) -``` - -API ---- - -There is no user accessible API for this feature in the 3.3 release. diff --git a/docs/networking/README.md b/docs/networking/README.md deleted file mode 100644 index a8e5de591c..0000000000 --- a/docs/networking/README.md +++ /dev/null @@ -1,100 +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. - ---- - - -**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. - -![Button FSM](button.png) - ---- - -**Buttons FSM** -* See: buttons.yml - -The buttons FSM distributes events to the buttons which each have their own FSM. - -![Buttons FSM](buttons.png) - ---- - -**Hot Keys FSM** -* See: hotkeys.yml - -The hot keys FSM handles key events and generates new events like `NewLink` to implement -hot keys. - -![Hot Keys FSM](hotkeys.png) - ---- - -**Mode FSM** -* See: mode.yml - -The mode FSM controls the overall mode of the network UI application. - -![Mode](mode.png) - ---- - -**Move FSM** -* See: move.yml - -The move FSM controls placement of devices as well as editing the device labels. - -![Move](move.png) - ---- - -**Time FSM** -* See: time.yml - -The time FSM controls undo/redo functionality of the network UI. - -![Time](time.png) - ---- - -**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. - -![Toolbox](toolbox.png) - ---- - -**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. - -![View](view.png) diff --git a/docs/networking/animation.yml b/docs/networking/animation.yml deleted file mode 100644 index c99b99dd1c..0000000000 --- a/docs/networking/animation.yml +++ /dev/null @@ -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 diff --git a/docs/networking/button.png b/docs/networking/button.png deleted file mode 100644 index 5a1bc7aaa1..0000000000 Binary files a/docs/networking/button.png and /dev/null differ diff --git a/docs/networking/button.yml b/docs/networking/button.yml deleted file mode 100644 index f037edb8f8..0000000000 --- a/docs/networking/button.yml +++ /dev/null @@ -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 diff --git a/docs/networking/buttons.png b/docs/networking/buttons.png deleted file mode 100644 index 8538b06614..0000000000 Binary files a/docs/networking/buttons.png and /dev/null differ diff --git a/docs/networking/buttons.yml b/docs/networking/buttons.yml deleted file mode 100644 index b1cc56a246..0000000000 --- a/docs/networking/buttons.yml +++ /dev/null @@ -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 diff --git a/docs/networking/details.panel.png b/docs/networking/details.panel.png deleted file mode 100644 index d060f3bd2f..0000000000 Binary files a/docs/networking/details.panel.png and /dev/null differ diff --git a/docs/networking/details.panel.yml b/docs/networking/details.panel.yml deleted file mode 100644 index 555d21c8be..0000000000 --- a/docs/networking/details.panel.yml +++ /dev/null @@ -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 diff --git a/docs/networking/device.detail.png b/docs/networking/device.detail.png deleted file mode 100644 index 0f11ac8ffe..0000000000 Binary files a/docs/networking/device.detail.png and /dev/null differ diff --git a/docs/networking/device.detail.yml b/docs/networking/device.detail.yml deleted file mode 100644 index fcb2f52eb6..0000000000 --- a/docs/networking/device.detail.yml +++ /dev/null @@ -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 diff --git a/docs/networking/group.png b/docs/networking/group.png deleted file mode 100644 index 5ca5ead538..0000000000 Binary files a/docs/networking/group.png and /dev/null differ diff --git a/docs/networking/group.yml b/docs/networking/group.yml deleted file mode 100644 index f618170553..0000000000 --- a/docs/networking/group.yml +++ /dev/null @@ -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 diff --git a/docs/networking/hotkeys.png b/docs/networking/hotkeys.png deleted file mode 100644 index d21ff09cc6..0000000000 Binary files a/docs/networking/hotkeys.png and /dev/null differ diff --git a/docs/networking/hotkeys.yml b/docs/networking/hotkeys.yml deleted file mode 100644 index 6d237bda46..0000000000 --- a/docs/networking/hotkeys.yml +++ /dev/null @@ -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 diff --git a/docs/networking/keybindings.png b/docs/networking/keybindings.png deleted file mode 100644 index b6a0b89a19..0000000000 Binary files a/docs/networking/keybindings.png and /dev/null differ diff --git a/docs/networking/keybindings.yml b/docs/networking/keybindings.yml deleted file mode 100644 index b98167e288..0000000000 --- a/docs/networking/keybindings.yml +++ /dev/null @@ -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 diff --git a/docs/networking/link.png b/docs/networking/link.png deleted file mode 100644 index 4058fd5519..0000000000 Binary files a/docs/networking/link.png and /dev/null differ diff --git a/docs/networking/link.yml b/docs/networking/link.yml deleted file mode 100644 index 7b3a7ea16c..0000000000 --- a/docs/networking/link.yml +++ /dev/null @@ -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 diff --git a/docs/networking/messages.yml b/docs/networking/messages.yml deleted file mode 100644 index 06ee3b9b75..0000000000 --- a/docs/networking/messages.yml +++ /dev/null @@ -1,19 +0,0 @@ -messages: - - {msg_type: DeviceMove, fields: [msg_type, sender, id, x, y, previous_x, previous_y]} - - {msg_type: DeviceCreate, fields: [msg_type, sender, id, x, y, name, type, host_id]} - - {msg_type: DeviceDestroy, fields: [msg_type, sender, id, previous_x, previous_y, previous_name, previous_type, previous_host_id]} - - {msg_type: DeviceLabelEdit, fields: [msg_type, sender, id, name, previous_name]} - - {msg_type: DeviceSelected, fields: [msg_type, sender, id]} - - {msg_type: DeviceUnSelected, fields: [msg_type, sender, id]} - - {msg_type: InterfaceCreate, fields: [msg_type, sender, device_id, id, name]} - - {msg_type: InterfaceLabelEdit, fields: [msg_type, sender, id, device_id, name, previous_name]} - - {msg_type: LinkLabelEdit, fields: [msg_type, sender, id, name, previous_name]} - - {msg_type: LinkCreate, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]} - - {msg_type: LinkDestroy, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]} - - {msg_type: LinkSelected, fields: [msg_type, sender, id]} - - {msg_type: LinkUnSelected, fields: [msg_type, sender, id]} - - {msg_type: MultipleMessage, fields: [msg_type, sender, messages]} - - {msg_type: Snapshot, fields: [msg_type, sender, devices, links, order, trace_id]} - - {msg_type: id, type: int} - - {msg_type: topology_id, type: int} - - {msg_type: Topology, fields: [topology_id, name, panX, panY, scale, link_id_seq, device_id_seq]} diff --git a/docs/networking/mode.png b/docs/networking/mode.png deleted file mode 100644 index b8dff5610d..0000000000 Binary files a/docs/networking/mode.png and /dev/null differ diff --git a/docs/networking/mode.yml b/docs/networking/mode.yml deleted file mode 100644 index b124a3d32e..0000000000 --- a/docs/networking/mode.yml +++ /dev/null @@ -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 diff --git a/docs/networking/models.png b/docs/networking/models.png deleted file mode 100644 index c6b22910d8..0000000000 Binary files a/docs/networking/models.png and /dev/null differ diff --git a/docs/networking/models.yml b/docs/networking/models.yml deleted file mode 100644 index 683dde4bfd..0000000000 --- a/docs/networking/models.yml +++ /dev/null @@ -1,130 +0,0 @@ -app: awx.network_ui -external_models: [] -models: -- display: name - fields: - - name: device_id - pk: true - type: AutoField - - name: topology - ref: Topology - ref_field: topology_id - type: ForeignKey - - len: 200 - name: name - type: CharField - - name: x - type: IntegerField - - name: y - type: IntegerField - - name: id - type: IntegerField - - len: 200 - name: device_type - type: CharField - - default: 0 - name: interface_id_seq - type: IntegerField - - default: 0 - name: host_id - type: IntegerField - name: Device - x: 348 - y: 124 -- fields: - - name: link_id - pk: true - type: AutoField - - name: from_device - ref: Device - ref_field: device_id - related_name: from_link - type: ForeignKey - - name: to_device - ref: Device - ref_field: device_id - related_name: to_link - type: ForeignKey - - name: from_interface - ref: Interface - ref_field: interface_id - related_name: from_link - type: ForeignKey - - name: to_interface - ref: Interface - ref_field: interface_id - related_name: to_link - type: ForeignKey - - name: id - type: IntegerField - - len: 200 - name: name - type: CharField - name: Link - x: 731 - y: -33 -- display: name - fields: - - name: topology_id - pk: true - type: AutoField - - len: 200 - name: name - type: CharField - - name: scale - type: FloatField - - name: panX - type: FloatField - - name: panY - type: FloatField - - default: 0 - name: device_id_seq - type: IntegerField - - default: 0 - name: link_id_seq - type: IntegerField - name: Topology - x: 111 - y: 127 -- fields: - - name: client_id - pk: true - type: AutoField - name: Client - x: -162 - y: 282 -- display: name - fields: - - name: interface_id - pk: true - type: AutoField - - name: device - ref: Device - ref_field: device_id - type: ForeignKey - - len: 200 - name: name - type: CharField - - name: id - type: IntegerField - name: Interface - x: 977 - y: 312 -- fields: - - name: topology_inventory_id - pk: true - type: AutoField - - name: topology - ref: Topology - ref_field: topology_id - type: ForeignKey - - name: inventory_id - type: IntegerField - name: TopologyInventory - x: -204 - y: 12 -modules: [] -view: - panX: 213.729555519212 - panY: 189.446959094643 - scaleXY: 0.69 diff --git a/docs/networking/move.png b/docs/networking/move.png deleted file mode 100644 index e199991c76..0000000000 Binary files a/docs/networking/move.png and /dev/null differ diff --git a/docs/networking/move.readonly.png b/docs/networking/move.readonly.png deleted file mode 100644 index 95db906bcd..0000000000 Binary files a/docs/networking/move.readonly.png and /dev/null differ diff --git a/docs/networking/move.readonly.yml b/docs/networking/move.readonly.yml deleted file mode 100644 index 6d1245d772..0000000000 --- a/docs/networking/move.readonly.yml +++ /dev/null @@ -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 diff --git a/docs/networking/move.yml b/docs/networking/move.yml deleted file mode 100644 index 42e42b6dfd..0000000000 --- a/docs/networking/move.yml +++ /dev/null @@ -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 diff --git a/docs/networking/null.png b/docs/networking/null.png deleted file mode 100644 index f095a1cad4..0000000000 Binary files a/docs/networking/null.png and /dev/null differ diff --git a/docs/networking/null.yml b/docs/networking/null.yml deleted file mode 100644 index 5218cfe1f7..0000000000 --- a/docs/networking/null.yml +++ /dev/null @@ -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 diff --git a/docs/networking/pipeline.png b/docs/networking/pipeline.png deleted file mode 100644 index c5fb2b12f7..0000000000 Binary files a/docs/networking/pipeline.png and /dev/null differ diff --git a/docs/networking/pipeline.yml b/docs/networking/pipeline.yml deleted file mode 100644 index 43052f2b2d..0000000000 --- a/docs/networking/pipeline.yml +++ /dev/null @@ -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: [] diff --git a/docs/networking/rack.png b/docs/networking/rack.png deleted file mode 100644 index 505cfdda6b..0000000000 Binary files a/docs/networking/rack.png and /dev/null differ diff --git a/docs/networking/rack.yml b/docs/networking/rack.yml deleted file mode 100644 index 3a5f7cae8c..0000000000 --- a/docs/networking/rack.yml +++ /dev/null @@ -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 diff --git a/docs/networking/site.png b/docs/networking/site.png deleted file mode 100644 index 72d256f552..0000000000 Binary files a/docs/networking/site.png and /dev/null differ diff --git a/docs/networking/site.yml b/docs/networking/site.yml deleted file mode 100644 index ab807f28d1..0000000000 --- a/docs/networking/site.yml +++ /dev/null @@ -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 diff --git a/docs/networking/stream.png b/docs/networking/stream.png deleted file mode 100644 index 3a00d21e97..0000000000 Binary files a/docs/networking/stream.png and /dev/null differ diff --git a/docs/networking/stream.yml b/docs/networking/stream.yml deleted file mode 100644 index cf12e95312..0000000000 --- a/docs/networking/stream.yml +++ /dev/null @@ -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 diff --git a/docs/networking/test.yml b/docs/networking/test.yml deleted file mode 100644 index 37092ab245..0000000000 --- a/docs/networking/test.yml +++ /dev/null @@ -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 diff --git a/docs/networking/time.png b/docs/networking/time.png deleted file mode 100644 index cec5fe69ee..0000000000 Binary files a/docs/networking/time.png and /dev/null differ diff --git a/docs/networking/time.yml b/docs/networking/time.yml deleted file mode 100644 index 6efaa5f38c..0000000000 --- a/docs/networking/time.yml +++ /dev/null @@ -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 diff --git a/docs/networking/toolbox.png b/docs/networking/toolbox.png deleted file mode 100644 index 14f676bddc..0000000000 Binary files a/docs/networking/toolbox.png and /dev/null differ diff --git a/docs/networking/toolbox.yml b/docs/networking/toolbox.yml deleted file mode 100644 index 99fd550b54..0000000000 --- a/docs/networking/toolbox.yml +++ /dev/null @@ -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 diff --git a/docs/networking/view.png b/docs/networking/view.png deleted file mode 100644 index e0d7f261b2..0000000000 Binary files a/docs/networking/view.png and /dev/null differ diff --git a/docs/networking/view.yml b/docs/networking/view.yml deleted file mode 100644 index 75f3c5cb47..0000000000 --- a/docs/networking/view.yml +++ /dev/null @@ -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 diff --git a/installer/roles/image_build/files/nginx.conf b/installer/roles/image_build/files/nginx.conf index 1076370021..370c1678fb 100644 --- a/installer/roles/image_build/files/nginx.conf +++ b/installer/roles/image_build/files/nginx.conf @@ -49,7 +49,7 @@ http { location /favicon.ico { alias /var/lib/awx/public/static/favicon.ico; } - location ~ ^/(websocket|network_ui/topology/) { + location ~ ^/websocket) { # Pass request to the upstream alias proxy_pass http://daphne; # Require http version 1.1 to allow for upgrade requests diff --git a/tools/docker-compose/nginx.vh.default.conf b/tools/docker-compose/nginx.vh.default.conf index 5e31bce2ee..73a4d1cd8d 100644 --- a/tools/docker-compose/nginx.vh.default.conf +++ b/tools/docker-compose/nginx.vh.default.conf @@ -30,7 +30,7 @@ server { sendfile off; } - location ~ ^/(websocket|network_ui/topology/) { + location ~ ^/websocket { # Pass request to the upstream alias proxy_pass http://daphne; # Require http version 1.1 to allow for upgrade requests @@ -90,7 +90,7 @@ server { sendfile off; } - location ~ ^/(websocket|network_ui/topology/) { + location ~ ^/websocket { # Pass request to the upstream alias proxy_pass http://daphne; # Require http version 1.1 to allow for upgrade requests diff --git a/tools/docker-compose/unit-tests/docker-compose-shippable.yml b/tools/docker-compose/unit-tests/docker-compose-shippable.yml index 5485b2e415..b314d6acdd 100644 --- a/tools/docker-compose/unit-tests/docker-compose-shippable.yml +++ b/tools/docker-compose/unit-tests/docker-compose-shippable.yml @@ -8,7 +8,7 @@ services: image: gcr.io/ansible-tower-engineering/unit-test-runner:${GIT_BRANCH:-latest} environment: SWIG_FEATURES: "-cpperraswarn -includeall -I/usr/include/openssl" - TEST_DIRS: awx/main/tests/functional awx/main/tests/unit awx/conf/tests awx/sso/tests awx/network_ui/tests + TEST_DIRS: awx/main/tests/functional awx/main/tests/unit awx/conf/tests awx/sso/tests command: ["make test"] volumes: - /awx_devel:/awx_devel diff --git a/tools/docker-compose/unit-tests/docker-compose.yml b/tools/docker-compose/unit-tests/docker-compose.yml index 0f652e40d5..9c94cc3564 100644 --- a/tools/docker-compose/unit-tests/docker-compose.yml +++ b/tools/docker-compose/unit-tests/docker-compose.yml @@ -8,7 +8,7 @@ services: image: gcr.io/ansible-tower-engineering/unit-test-runner:${GIT_BRANCH:-latest} environment: SWIG_FEATURES: "-cpperraswarn -includeall -I/usr/include/openssl" - TEST_DIRS: awx/main/tests/functional awx/main/tests/unit awx/conf/tests awx/sso/tests awx/network_ui/tests + TEST_DIRS: awx/main/tests/functional awx/main/tests/unit awx/conf/tests awx/sso/tests command: ["make test_combined"] volumes: - ../../../:/awx_devel