Committed by
Ray Milkey
GUI -- TableService can take a div, config object, and data object in order to p…
…rogrammatically render and load data into a table. Test functions added. Change-Id: I95f82108d7bb4f84a701b49e0e419afbdbac6f14
Showing
4 changed files
with
209 additions
and
5 deletions
| ... | @@ -21,6 +21,54 @@ | ... | @@ -21,6 +21,54 @@ |
| 21 | (function () { | 21 | (function () { |
| 22 | 'use strict'; | 22 | 'use strict'; |
| 23 | 23 | ||
| 24 | + var config = { | ||
| 25 | + colIds: ['_iconid_available', 'id', 'mfr', 'hw', 'sw', 'serial', | ||
| 26 | + 'annotations.protocol'], | ||
| 27 | + colText: ['', 'URI', 'Vendor', 'Hardware Version', 'Software Version', | ||
| 28 | + 'Serial Number', 'Protocol'] | ||
| 29 | + }, | ||
| 30 | + deviceData = { | ||
| 31 | + "devices": [{ | ||
| 32 | + "id": "of:0000000000000001", | ||
| 33 | + "available": true, | ||
| 34 | + "_iconid_available": "deviceOnline", | ||
| 35 | + "role": "MASTER", | ||
| 36 | + "mfr": "Nicira, Inc.", | ||
| 37 | + "hw": "Open vSwitch", | ||
| 38 | + "sw": "2.0.1", | ||
| 39 | + "serial": "None", | ||
| 40 | + "annotations": { | ||
| 41 | + "protocol": "OF_10" | ||
| 42 | + } | ||
| 43 | + }, | ||
| 44 | + { | ||
| 45 | + "id": "of:0000000000000004", | ||
| 46 | + "available": false, | ||
| 47 | + "_iconid_available": "deviceOffline", | ||
| 48 | + "role": "MASTER", | ||
| 49 | + "mfr": "Nicira, Inc.", | ||
| 50 | + "hw": "Open vSwitch", | ||
| 51 | + "sw": "2.0.1", | ||
| 52 | + "serial": "None", | ||
| 53 | + "annotations": { | ||
| 54 | + "protocol": "OF_10" | ||
| 55 | + } | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + "id": "of:0000000000000092", | ||
| 59 | + "available": false, | ||
| 60 | + "_iconid_available": "deviceOffline", | ||
| 61 | + "role": "MASTER", | ||
| 62 | + "mfr": "Nicira, Inc.", | ||
| 63 | + "hw": "Open vSwitch", | ||
| 64 | + "sw": "2.0.1", | ||
| 65 | + "serial": "None", | ||
| 66 | + "annotations": { | ||
| 67 | + "protocol": "OF_10" | ||
| 68 | + } | ||
| 69 | + }] | ||
| 70 | + }; | ||
| 71 | + | ||
| 24 | function setColWidth(t) { | 72 | function setColWidth(t) { |
| 25 | var tHeaders, tdElement, colWidth; | 73 | var tHeaders, tdElement, colWidth; |
| 26 | 74 | ||
| ... | @@ -84,4 +132,4 @@ | ... | @@ -84,4 +132,4 @@ |
| 84 | } | 132 | } |
| 85 | }; | 133 | }; |
| 86 | }]); | 134 | }]); |
| 87 | -}()); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 135 | +}()); | ... | ... |
| ... | @@ -22,12 +22,68 @@ | ... | @@ -22,12 +22,68 @@ |
| 22 | 22 | ||
| 23 | var $log; | 23 | var $log; |
| 24 | 24 | ||
| 25 | + function renderTable(div, config) { | ||
| 26 | + var table = div.append('table').attr('fixed-header', true), | ||
| 27 | + thead, tr, numTableCols, i; | ||
| 28 | + table.append('thead'); | ||
| 29 | + table.append('tbody'); | ||
| 30 | + | ||
| 31 | + thead = table.select('thead'); | ||
| 32 | + tr = thead.append('tr'); | ||
| 33 | + numTableCols = config.colIds.length; | ||
| 34 | + | ||
| 35 | + for(i = 0; i < numTableCols; i += 1) { | ||
| 36 | + tr.append('th').html(config.colText[i]); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + return config.colIds; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + // I can delete these comments later... | ||
| 43 | + // loadTableData needs to know which IDs are used to create the table... | ||
| 44 | + // Potentially, there will be some rows in the JSON that the server is | ||
| 45 | + // sending back that will be unused. We don't want to create unneeded rows. | ||
| 46 | + // For example, in device view, we aren't displaying "role" or | ||
| 47 | + // "available" properties, but they would be displayed if we took it | ||
| 48 | + // directly from the data being sent in. | ||
| 49 | + function loadTableData(data, div, colIds) { | ||
| 50 | + // let me know if you have suggestions for this function | ||
| 51 | + | ||
| 52 | + var numTableCols = colIds.length, | ||
| 53 | + tbody, tr, td, i; | ||
| 54 | + tbody = div.select('tbody'); | ||
| 55 | + | ||
| 56 | + // get the array associated with the first object, such as "devices" | ||
| 57 | + // in fakeData | ||
| 58 | + // (for some reason it doesn't like the data.keys() function, saying | ||
| 59 | + // "undefined is not a function" | ||
| 60 | + // Object.keys(data) works though) | ||
| 61 | + // loop through every object in the array, and every property in the object | ||
| 62 | + // put their property in the td of the table | ||
| 63 | + (data[Object.keys(data)[0]]).forEach(function (item) { | ||
| 64 | + tr = tbody.append('tr'); | ||
| 65 | + for(var key in item) { | ||
| 66 | + for(i = 0; i < numTableCols; i += 1) { | ||
| 67 | + if(key === colIds[i]) { | ||
| 68 | + td = tr.append('td').html(item[key]); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + }); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + function renderAndLoadTable(div, config, data) { | ||
| 76 | + loadTableData(data, div, (renderTable(div, config))); | ||
| 77 | + } | ||
| 78 | + | ||
| 25 | angular.module('onosWidget') | 79 | angular.module('onosWidget') |
| 26 | .factory('TableService', ['$log', function (_$log_) { | 80 | .factory('TableService', ['$log', function (_$log_) { |
| 27 | $log = _$log_; | 81 | $log = _$log_; |
| 28 | 82 | ||
| 29 | return { | 83 | return { |
| 30 | - | 84 | + renderTable: renderTable, |
| 85 | + loadTableData: loadTableData, | ||
| 86 | + renderAndLoadTable: renderAndLoadTable | ||
| 31 | }; | 87 | }; |
| 32 | }]); | 88 | }]); |
| 33 | 89 | ... | ... |
| 1 | <!-- Device partial HTML --> | 1 | <!-- Device partial HTML --> |
| 2 | <div id="ov-device"> | 2 | <div id="ov-device"> |
| 3 | <h2>Device View</h2> | 3 | <h2>Device View</h2> |
| 4 | -<!-- TODO: uncomment and test the thead and tbody tags for CSS styling --> | ||
| 5 | <table class="summary-list"> | 4 | <table class="summary-list"> |
| 6 | <tbody> | 5 | <tbody> |
| 7 | <tr> | 6 | <tr> | ... | ... |
| ... | @@ -18,7 +18,54 @@ | ... | @@ -18,7 +18,54 @@ |
| 18 | ONOS GUI -- Widget -- Table Service - Unit Tests | 18 | ONOS GUI -- Widget -- Table Service - Unit Tests |
| 19 | */ | 19 | */ |
| 20 | describe('factory: fw/widget/table.js', function() { | 20 | describe('factory: fw/widget/table.js', function() { |
| 21 | - var ts, $log; | 21 | + var ts, $log, d3Elem; |
| 22 | + | ||
| 23 | + var config = { | ||
| 24 | + colIds: ['id', 'mfr', 'hw', 'sw', 'serial', 'annotations.protocol'], | ||
| 25 | + colText: ['URI', 'Vendor', 'Hardware Version', 'Software Version', | ||
| 26 | + 'Serial Number', 'Protocol'] | ||
| 27 | + }, | ||
| 28 | + fakeData = { | ||
| 29 | + "devices": [{ | ||
| 30 | + "id": "of:0000000000000001", | ||
| 31 | + "available": true, | ||
| 32 | + "_iconid_available": "deviceOnline", | ||
| 33 | + "role": "MASTER", | ||
| 34 | + "mfr": "Nicira, Inc.", | ||
| 35 | + "hw": "Open vSwitch", | ||
| 36 | + "sw": "2.0.1", | ||
| 37 | + "serial": "None", | ||
| 38 | + "annotations": { | ||
| 39 | + "protocol": "OF_10" | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + { | ||
| 43 | + "id": "of:0000000000000004", | ||
| 44 | + "available": false, | ||
| 45 | + "_iconid_available": "deviceOffline", | ||
| 46 | + "role": "MASTER", | ||
| 47 | + "mfr": "Nicira, Inc.", | ||
| 48 | + "hw": "Open vSwitch", | ||
| 49 | + "sw": "2.0.1", | ||
| 50 | + "serial": "None", | ||
| 51 | + "annotations": { | ||
| 52 | + "protocol": "OF_10" | ||
| 53 | + } | ||
| 54 | + }, | ||
| 55 | + { | ||
| 56 | + "id": "of:0000000000000092", | ||
| 57 | + "available": false, | ||
| 58 | + "_iconid_available": "deviceOffline", | ||
| 59 | + "role": "MASTER", | ||
| 60 | + "mfr": "Nicira, Inc.", | ||
| 61 | + "hw": "Open vSwitch", | ||
| 62 | + "sw": "2.0.1", | ||
| 63 | + "serial": "None", | ||
| 64 | + "annotations": { | ||
| 65 | + "protocol": "OF_10" | ||
| 66 | + } | ||
| 67 | + }] | ||
| 68 | + }; | ||
| 22 | 69 | ||
| 23 | beforeEach(module('onosWidget')); | 70 | beforeEach(module('onosWidget')); |
| 24 | 71 | ||
| ... | @@ -30,4 +77,58 @@ describe('factory: fw/widget/table.js', function() { | ... | @@ -30,4 +77,58 @@ describe('factory: fw/widget/table.js', function() { |
| 30 | it('should define TableService', function () { | 77 | it('should define TableService', function () { |
| 31 | expect(ts).toBeDefined(); | 78 | expect(ts).toBeDefined(); |
| 32 | }); | 79 | }); |
| 33 | -}); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 80 | + | ||
| 81 | + function verifyTableTags(div) { | ||
| 82 | + var table = div.select('table'), | ||
| 83 | + tableHeaders; | ||
| 84 | + expect(table).toBeTruthy(); | ||
| 85 | + expect(table.attr('fixed-header')).toBeTruthy(); | ||
| 86 | + expect(table.select('thead')).toBeTruthy(); | ||
| 87 | + expect(table.select('tbody')).toBeTruthy(); | ||
| 88 | + | ||
| 89 | + tableHeaders = table.select('thead').selectAll('th'); | ||
| 90 | + tableHeaders.each(function(thElement, i) { | ||
| 91 | + thElement = d3.select(this); | ||
| 92 | + expect(thElement).toBeTruthy(); | ||
| 93 | + expect(thElement.html()).toBe(config.colText[i]); | ||
| 94 | + }); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + function verifyData(div) { | ||
| 98 | + var tbody = div.select('tbody'), | ||
| 99 | + tableBoxes = tbody.selectAll('td'); | ||
| 100 | + expect(tbody).toBeTruthy(); | ||
| 101 | + expect(tbody.select('tr')).toBeTruthy(); | ||
| 102 | + | ||
| 103 | + tableBoxes.each(function(tdElement, i){ | ||
| 104 | + tdElement = d3.select(this); | ||
| 105 | + if(i === 0) { | ||
| 106 | + expect(tdElement.html()).toBe('of:0000000000000001'); | ||
| 107 | + } | ||
| 108 | + if(i === 1) { | ||
| 109 | + expect(tdElement.html()).toBe('Nicira, Inc.'); | ||
| 110 | + } | ||
| 111 | + if(i === 2) { | ||
| 112 | + expect(tdElement.html()).toBe('Open vSwitch'); | ||
| 113 | + } | ||
| 114 | + expect(tdElement).toBeTruthy(); | ||
| 115 | + }); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + it('should create table tags', function () { | ||
| 119 | + ts.renderTable(d3Elem, config); | ||
| 120 | + verifyTableTags(d3Elem); | ||
| 121 | + }); | ||
| 122 | + | ||
| 123 | + it('should load data into table', function () { | ||
| 124 | + var colIds = ts.renderTable(d3Elem, config); | ||
| 125 | + ts.loadTableData(fakeData, d3Elem, colIds); | ||
| 126 | + verifyData(d3Elem); | ||
| 127 | + }); | ||
| 128 | + | ||
| 129 | + it('should render table and load data', function () { | ||
| 130 | + ts.renderAndLoadTable(d3Elem, config, fakeData); | ||
| 131 | + verifyData(d3Elem); | ||
| 132 | + }); | ||
| 133 | + | ||
| 134 | +}); | ... | ... |
-
Please register or login to post a comment