Simon Hunt

ONOS-2876 -- GUI - first cut at client-side code for device friendly name setting (still WIP).

Change-Id: I531a2f1fef698cb72a5529f732bb2a0a97e2acc4
...@@ -153,6 +153,10 @@ public class DeviceViewMessageHandler extends UiMessageHandler { ...@@ -153,6 +153,10 @@ public class DeviceViewMessageHandler extends UiMessageHandler {
153 ObjectNode data = MAPPER.createObjectNode(); 153 ObjectNode data = MAPPER.createObjectNode();
154 154
155 data.put(ID, deviceId.toString()); 155 data.put(ID, deviceId.toString());
156 +
157 + // TODO: get friendly name from the device
158 + data.put(NAME, deviceId.toString());
159 +
156 data.put(TYPE, capitalizeFully(device.type().toString())); 160 data.put(TYPE, capitalizeFully(device.type().toString()));
157 data.put(TYPE_IID, getTypeIconId(device)); 161 data.put(TYPE_IID, getTypeIconId(device));
158 data.put(MFR, device.manufacturer()); 162 data.put(MFR, device.manufacturer());
......
...@@ -75,6 +75,30 @@ ...@@ -75,6 +75,30 @@
75 margin: 8px 0; 75 margin: 8px 0;
76 } 76 }
77 77
78 +#device-details-panel .name-div {
79 + height: 20px;
80 + padding: 8px 0 0 8px;
81 +}
82 +
83 +#device-details-panel .name-div span {
84 + display: inline-block;
85 +}
86 +
87 +#device-details-panel .name-div .label {
88 + font-style: italic;
89 + padding-right: 12px;
90 + /* works for both light and dark themes ... */
91 + color: #777;
92 +}
93 +
94 +#device-details-panel .name-div .value {
95 +}
96 +
97 +#device-details-panel .editable {
98 + cursor: pointer;
99 + border-bottom: 1px dashed darkgreen;
100 +}
101 +
78 #device-details-panel .top div.left { 102 #device-details-panel .top div.left {
79 float: left; 103 float: left;
80 padding: 0 18px 0 0; 104 padding: 0 18px 0 0;
......
...@@ -26,9 +26,13 @@ ...@@ -26,9 +26,13 @@
26 26
27 // internal state 27 // internal state
28 var detailsPanel, 28 var detailsPanel,
29 - pStartY, pHeight, 29 + pStartY,
30 - top, bottom, iconDiv, 30 + pHeight,
31 - wSize; 31 + top,
32 + bottom,
33 + iconDiv,
34 + wSize,
35 + editingName = false;
32 36
33 // constants 37 // constants
34 var topPdg = 13, 38 var topPdg = 13,
...@@ -59,7 +63,9 @@ ...@@ -59,7 +63,9 @@
59 if (detailsPanel.isVisible()) { 63 if (detailsPanel.isVisible()) {
60 $scope.selId = null; 64 $scope.selId = null;
61 detailsPanel.hide(); 65 detailsPanel.hide();
66 + return true;
62 } 67 }
68 + return false;
63 } 69 }
64 70
65 function addCloseBtn(div) { 71 function addCloseBtn(div) {
...@@ -68,6 +74,72 @@ ...@@ -68,6 +74,72 @@
68 div.on('click', closePanel); 74 div.on('click', closePanel);
69 } 75 }
70 76
77 + function getNameSpan() {
78 + return top.select('.name-div').select('.value');
79 + }
80 +
81 + function nameValid(name) {
82 + // TODO: guard against empty strings etc.
83 + return true;
84 + }
85 +
86 + function editNameSave() {
87 + var span = getNameSpan(),
88 + newVal;
89 + if (editingName) {
90 + newVal = span.select('input').property('value');
91 +
92 + $log.debug("TODO: Saving name change... to '" + newVal + "'");
93 + if (!nameValid(newVal)) {
94 + return editNameCancel();
95 + }
96 +
97 + // TODO: send event to server to set friendly name for device
98 + $scope.panelData.name = newVal;
99 +
100 + span.html(newVal);
101 + span.classed('editable', true);
102 + editingName = false;
103 + }
104 + }
105 +
106 + function editNameCancel() {
107 + var span = getNameSpan();
108 + if (editingName) {
109 + $log.debug("Canceling name change...");
110 + span.html($scope.panelData.name);
111 + span.classed('editable', true);
112 + editingName = false;
113 + return true;
114 + }
115 + return false;
116 + }
117 +
118 + function editName() {
119 + $log.log('editName() .. editing=' + editingName);
120 + var span = getNameSpan();
121 + if (!editingName) {
122 + editingName = true;
123 + span.classed('editable', false);
124 + span.html('');
125 + span.append('input').classed('name-input', true)
126 + .attr('type', 'text')
127 + .attr('value', $scope.panelData.name);
128 + }
129 + }
130 +
131 + function handleEscape() {
132 + return editNameCancel() || closePanel();
133 + }
134 +
135 + function setUpEditableName(top) {
136 + var div = top.append('div').classed('name-div', true);
137 +
138 + div.append('span').classed('label', true);
139 + div.append('span').classed('value editable', true)
140 + .on('click', editName);
141 + }
142 +
71 function setUpPanel() { 143 function setUpPanel() {
72 var container, closeBtn, tblDiv; 144 var container, closeBtn, tblDiv;
73 detailsPanel.empty(); 145 detailsPanel.empty();
...@@ -80,6 +152,8 @@ ...@@ -80,6 +152,8 @@
80 iconDiv = top.append('div').classed('dev-icon', true); 152 iconDiv = top.append('div').classed('dev-icon', true);
81 top.append('h2'); 153 top.append('h2');
82 154
155 + setUpEditableName(top);
156 +
83 tblDiv = top.append('div').classed('top-tables', true); 157 tblDiv = top.append('div').classed('top-tables', true);
84 tblDiv.append('div').classed('left', true).append('table'); 158 tblDiv.append('div').classed('left', true).append('table');
85 tblDiv.append('div').classed('right', true).append('table'); 159 tblDiv.append('div').classed('right', true).append('table');
...@@ -156,14 +230,23 @@ ...@@ -156,14 +230,23 @@
156 detailsPanel.width(tbWidth + ctnrPdg); 230 detailsPanel.width(tbWidth + ctnrPdg);
157 } 231 }
158 232
233 + function populateName(div, name) {
234 + var lab = div.select('.label'),
235 + val = div.select('.value');
236 + lab.html('Friendly Name:');
237 + val.html(name);
238 + }
239 +
159 function populateDetails(details) { 240 function populateDetails(details) {
160 - var topTbs, btmTbl, ports; 241 + var nameDiv, topTbs, btmTbl, ports;
161 setUpPanel(); 242 setUpPanel();
162 243
244 + nameDiv = top.select('.name-div');
163 topTbs = top.select('.top-tables'); 245 topTbs = top.select('.top-tables');
164 btmTbl = bottom.select('table'); 246 btmTbl = bottom.select('table');
165 ports = details.ports; 247 ports = details.ports;
166 248
249 + populateName(nameDiv, details.name);
167 populateTop(topTbs, details); 250 populateTop(topTbs, details);
168 populateBottom(btmTbl, ports); 251 populateBottom(btmTbl, ports);
169 252
...@@ -278,7 +361,8 @@ ...@@ -278,7 +361,8 @@
278 } 361 }
279 // create key bindings to handle panel 362 // create key bindings to handle panel
280 ks.keyBindings({ 363 ks.keyBindings({
281 - esc: [closePanel, 'Close the details panel'], 364 + enter: editNameSave,
365 + esc: [handleEscape, 'Close the details panel'],
282 _helpFormat: ['esc'] 366 _helpFormat: ['esc']
283 }); 367 });
284 ks.gestureNotes([ 368 ks.gestureNotes([
......