diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
new file mode 100644
index 0000000..5ed744b
--- /dev/null
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Component, OnInit, ViewChild } from '@angular/core';
+import {
+    FnService,
+    KeysService, KeysToken,
+    LogService, PrefsService,
+    SvgUtilService, WebSocketService
+} from 'gui2-fw-lib';
+import {InstanceComponent} from '../panel/instance/instance.component';
+import {SummaryComponent} from '../panel/summary/summary.component';
+import {DetailsComponent} from '../panel/details/details.component';
+
+/**
+ * ONOS GUI Topology View
+ *
+ * This Topology View component is the top level component in a hierarchy that
+ * comprises the whole Topology View
+ *
+ * There are three main parts (panels, graphical and breadcrumbs)
+ * The panel hierarchy
+ * |-- Instances Panel (shows ONOS instances)
+ * |-- Summary Panel (summary of ONOS)
+ * |-- Toolbar Panel (the toolbar)
+ * |-- Details Panel (when a node is selected in the Force graphical view (see below))
+ *
+ * The graphical hierarchy contains
+ * Topology (this)
+ *  |-- No Devices Connected (only of there are no nodes to show)
+ *  |-- Zoom Layer (everything beneath this can be zoomed and panned)
+ *      |-- Background (container for any backgrounds - can be toggled on and off)
+ *          |-- Map
+ *      |-- Forces (all of the nodes and links laid out by a d3.force simulation)
+ *
+ * The breadcrumbs
+ * |-- Breadcrumb (in region view a way of navigating back up through regions)
+ */
+@Component({
+  selector: 'onos-topology',
+  templateUrl: './topology.component.html',
+  styleUrls: ['./topology.component.css']
+})
+export class TopologyComponent implements OnInit {
+    @ViewChild(InstanceComponent) instance: InstanceComponent;
+    @ViewChild(SummaryComponent) summary: SummaryComponent;
+    @ViewChild(DetailsComponent) details: DetailsComponent;
+
+    flashMsg: string = '';
+    prefsState = {};
+    svg: any;
+    hostLabelIdx: number = 1;
+
+    constructor(
+        protected log: LogService,
+        protected fs: FnService,
+        protected ks: KeysService,
+        protected sus: SvgUtilService,
+        protected ps: PrefsService,
+        protected wss: WebSocketService
+    ) {
+
+        this.log.debug('Topology component constructed');
+    }
+
+    ngOnInit() {
+        this.bindCommands();
+        this.log.debug('Topology component initialized');
+    }
+
+    actionMap() {
+        return {
+            L: [() => {this.cycleDeviceLabels(); }, 'Cycle device labels'],
+            B: [(token) => {this.toggleBackground(token); }, 'Toggle background'],
+            D: [(token) => {this.toggleDetails(token); }, 'Toggle details panel'],
+            I: [(token) => {this.toggleInstancePanel(token); }, 'Toggle ONOS Instance Panel'],
+            O: [() => {this.toggleSummary(); }, 'Toggle the Summary Panel'],
+            R: [() => {this.resetZoom(); }, 'Reset pan / zoom'],
+            P: [(token) => {this.togglePorts(token); }, 'Toggle Port Highlighting'],
+            E: [() => {this.equalizeMasters(); }, 'Equalize mastership roles'],
+            X: [() => {this.resetNodeLocation(); }, 'Reset Node Location'],
+            U: [() => {this.unpinNode(); }, 'Unpin node (mouse over)'],
+            H: [() => {this.toggleHosts(); }, 'Toggle host visibility'],
+            M: [() => {this.toggleOfflineDevices(); }, 'Toggle offline visibility'],
+            dot: [() => {this.toggleToolbar(); }, 'Toggle Toolbar'],
+            'shift-L': [() => {this.cycleHostLabels(); }, 'Cycle host labels'],
+
+            // -- instance color palette debug
+            9: function () {
+                this.sus.cat7().testCard(this.svg);
+            },
+
+            esc: this.handleEscape,
+
+            // TODO update after adding in Background Service
+            // topology overlay selections
+            // F1: function () { t2tbs.fnKey(0); },
+            // F2: function () { t2tbs.fnKey(1); },
+            // F3: function () { t2tbs.fnKey(2); },
+            // F4: function () { t2tbs.fnKey(3); },
+            // F5: function () { t2tbs.fnKey(4); },
+            //
+            // _keyListener: t2tbs.keyListener.bind(t2tbs),
+
+            _helpFormat: [
+                ['I', 'O', 'D', 'H', 'M', 'P', 'dash', 'B'],
+                ['X', 'Z', 'N', 'L', 'shift-L', 'U', 'R', 'E', 'dot'],
+                [], // this column reserved for overlay actions
+            ],
+        };
+    }
+
+
+    bindCommands(additional?: any) {
+
+        const am = this.actionMap();
+        const add = this.fs.isO(additional);
+
+        // TODO: Reimplement when we have a use case
+        // if (add) {
+        //     _.each(add, function (value, key) {
+        //         // filter out meta properties (e.g. _keyOrder)
+        //         if (!(_.startsWith(key, '_'))) {
+        //             // don't allow re-definition of existing key bindings
+        //             if (am[key]) {
+        //                 this.log.warn('keybind: ' + key + ' already exists');
+        //             } else {
+        //                 am[key] = [value.cb, value.tt];
+        //             }
+        //         }
+        //     });
+        // }
+
+        this.ks.keyBindings(am);
+
+        this.ks.gestureNotes([
+            ['click', 'Select the item and show details'],
+            ['shift-click', 'Toggle selection state'],
+            ['drag', 'Reposition (and pin) device / host'],
+            ['cmd-scroll', 'Zoom in / out'],
+            ['cmd-drag', 'Pan'],
+        ]);
+    }
+
+    handleEscape() {
+
+        if (false) {
+            // TODO: Cancel show mastership
+            // TODO: Cancel Active overlay
+            // TODO: Reinstate with components
+        } else {
+            this.log.debug('Handling escape');
+            // } else if (t2rs.deselectAllNodes()) {
+            //     // else if we have node selections, deselect them all
+            //     // (work already done)
+            // } else if (t2rs.deselectLink()) {
+            //     // else if we have a link selection, deselect it
+            //     // (work already done)
+            // } else if (t2is.isVisible()) {
+            //     // If the instance panel is visible, close it
+            //     t2is.toggle();
+            // } else if (t2sp.isVisible()) {
+            //     // If the summary panel is visible, close it
+            //     t2sp.toggle();
+        }
+    }
+
+
+
+    updatePrefsState(what, b) {
+        this.prefsState[what] = b ? 1 : 0;
+        this.ps.setPrefs('topo2_prefs', this.prefsState);
+    }
+
+    deviceLabelFlashMessage(index) {
+        switch (index) {
+            case 0: return 'Hide device labels';
+            case 1: return 'Show friendly device labels';
+            case 2: return 'Show device ID labels';
+        }
+    }
+
+    hostLabelFlashMessage(index) {
+        switch (index) {
+            case 0: return 'Hide host labels';
+            case 1: return 'Show friendly host labels';
+            case 2: return 'Show host IP labels';
+            case 3: return 'Show host MAC Address labels';
+        }
+    }
+
+    protected cycleDeviceLabels() {
+        this.log.debug('Cycling device labels');
+        // TODO: Reinstate with components
+        // let deviceLabelIndex = t2ps.get('dlbls') + 1;
+        // let newDeviceLabelIndex = deviceLabelIndex % 3;
+        //
+        // t2ps.set('dlbls', newDeviceLabelIndex);
+        // t2fs.updateNodes();
+        // flash.flash(deviceLabelFlashMessage(newDeviceLabelIndex));
+    }
+
+    protected cycleHostLabels() {
+        const hostLabelIndex = this.hostLabelIdx + 1;
+        this.hostLabelIdx = hostLabelIndex % 4;
+        this.flashMsg = this.hostLabelFlashMessage(this.hostLabelIdx);
+        this.log.debug('Cycling host labels');
+        // TODO: Reinstate with components
+        // t2ps.set('hlbls', newHostLabelIndex);
+        // t2fs.updateNodes();
+    }
+
+    protected toggleBackground(token: KeysToken) {
+        this.flashMsg = 'Toggling background';
+        this.log.debug('Toggling background', token);
+        // TODO: Reinstate with components
+        // t2bgs.toggle(x);
+    }
+
+    protected toggleDetails(token: KeysToken) {
+        this.flashMsg = 'Toggling details';
+        this.details.togglePanel(() => {});
+        this.log.debug('Toggling details', token);
+    }
+
+    protected toggleInstancePanel(token: KeysToken) {
+        this.flashMsg = 'Toggling instances';
+        this.instance.togglePanel(() => {});
+        this.log.debug('Toggling instances', token);
+        // TODO: Reinstate with components
+        // this.updatePrefsState('insts', t2is.toggle(x));
+    }
+
+    protected toggleSummary() {
+        this.flashMsg = 'Toggling summary';
+        this.summary.togglePanel(() => {});
+    }
+
+    protected resetZoom() {
+        this.log.debug('resetting zoom');
+        // TODO: Reinstate with components
+        // t2bgs.resetZoom();
+        // flash.flash('Pan and zoom reset');
+    }
+
+    protected togglePorts(token: KeysToken) {
+        this.log.debug('Toggling ports');
+        // TODO: Reinstate with components
+        // this.updatePrefsState('porthl', t2vs.togglePortHighlights(x));
+        // t2fs.updateLinks();
+    }
+
+    protected equalizeMasters() {
+        this.wss.sendEvent('equalizeMasters', null);
+
+        this.log.debug('equalizing masters');
+        // TODO: Reinstate with components
+        // flash.flash('Equalizing master roles');
+    }
+
+    protected resetNodeLocation() {
+        this.log.debug('resetting node location');
+        // TODO: Reinstate with components
+        // t2fs.resetNodeLocation();
+        // flash.flash('Reset node locations');
+    }
+
+    protected unpinNode() {
+        this.log.debug('unpinning node');
+        // TODO: Reinstate with components
+        // t2fs.unpin();
+        // flash.flash('Unpin node');
+    }
+
+    protected toggleToolbar() {
+        this.log.debug('toggling toolbar');
+        // TODO: Reinstate with components
+        // t2tbs.toggle();
+    }
+
+    protected actionedFlashed(action, message) {
+        this.log.debug('action flashed');
+        // TODO: Reinstate with components
+        // this.flash.flash(action + ' ' + message);
+    }
+
+    protected toggleHosts() {
+        // this.flashMsg = on ? 'Show': 'Hide', 'Hosts';
+        this.log.debug('toggling hosts');
+        // TODO: Reinstate with components
+        // let on = t2rs.toggleHosts();
+        // this.actionedFlashed(on ? 'Show': 'Hide', 'Hosts');
+    }
+
+    protected toggleOfflineDevices() {
+        this.log.debug('toggling offline devices');
+        // TODO: Reinstate with components
+        // let on = t2rs.toggleOfflineDevices();
+        // this.actionedFlashed(on ? 'Show': 'Hide', 'offline devices');
+    }
+
+    protected notValid(what) {
+        this.log.warn('topo.js getActionEntry(): Not a valid ' + what);
+    }
+
+    getActionEntry(key) {
+        let entry;
+
+        if (!key) {
+            this.notValid('key');
+            return null;
+        }
+
+        entry = this.actionMap()[key];
+
+        if (!entry) {
+            this.notValid('actionMap (' + key + ') entry');
+            return null;
+        }
+        return this.fs.isA(entry) || [entry, ''];
+    }
+
+}
