ONOS-6335: Flows View: columns should be re-ordered.
 - WIP. Still need to understand "duration".

Change-Id: I9db0966584f16e19656f55642cae4e66faab427a
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
index a5c7a60..1321bb6 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
@@ -34,7 +34,6 @@
 import org.onosproject.ui.table.TableModel;
 import org.onosproject.ui.table.TableRequestHandler;
 import org.onosproject.ui.table.cell.EnumFormatter;
-import org.onosproject.ui.table.cell.HexFormatter;
 import org.onosproject.ui.table.cell.HexLongFormatter;
 import org.onosproject.ui.table.cell.NumberFormatter;
 
@@ -63,12 +62,15 @@
     private static final String GROUP_ID = "groupId";
     private static final String TABLE_ID = "tableId";
     private static final String PRIORITY = "priority";
+    private static final String SELECTOR_C = "selector_c"; // for table column
     private static final String SELECTOR = "selector";
+    private static final String TREATMENT_C = "treatment_c"; // for table column
     private static final String TREATMENT = "treatment";
     private static final String TIMEOUT = "timeout";
     private static final String PERMANENT = "permanent";
     private static final String STATE = "state";
     private static final String PACKETS = "packets";
+    private static final String DURATION = "duration";
     private static final String BYTES = "bytes";
 
     private static final String COMMA = ", ";
@@ -76,8 +78,23 @@
     private static final String EMPTY = "";
 
     private static final String[] COL_IDS = {
-            ID, APP_ID, GROUP_ID, TABLE_ID, PRIORITY, SELECTOR,
-            TREATMENT, TIMEOUT, PERMANENT, STATE, PACKETS, BYTES
+            ID,
+            STATE,
+            BYTES,
+            PACKETS,
+            DURATION,
+            PRIORITY,
+            TABLE_ID,
+            APP_ID,
+
+            GROUP_ID,
+            TIMEOUT,
+            PERMANENT,
+
+            SELECTOR_C,
+            SELECTOR,
+            TREATMENT_C,
+            TREATMENT,
     };
 
     @Override
@@ -117,11 +134,14 @@
         protected TableModel createTableModel() {
             TableModel tm = super.createTableModel();
             tm.setFormatter(ID, HexLongFormatter.INSTANCE);
-            tm.setFormatter(GROUP_ID, HexFormatter.INSTANCE);
             tm.setFormatter(STATE, EnumFormatter.INSTANCE);
-            tm.setFormatter(PACKETS, NumberFormatter.INTEGER);
             tm.setFormatter(BYTES, NumberFormatter.INTEGER);
+            tm.setFormatter(PACKETS, NumberFormatter.INTEGER);
+            tm.setFormatter(DURATION, NumberFormatter.INTEGER);
+
+            tm.setFormatter(SELECTOR_C, new SelectorShortFormatter());
             tm.setFormatter(SELECTOR, new SelectorFormatter());
+            tm.setFormatter(TREATMENT_C, new TreatmentShortFormatter());
             tm.setFormatter(TREATMENT, new TreatmentFormatter());
             return tm;
         }
@@ -140,20 +160,32 @@
 
         private void populateRow(TableModel.Row row, FlowEntry flow) {
             row.cell(ID, flow.id().value())
-                    .cell(APP_ID, flow.appId())
-                    .cell(GROUP_ID, flow.groupId().id())
-                    .cell(TABLE_ID, flow.tableId())
+                    .cell(STATE, flow.state())
+                    .cell(BYTES, flow.bytes())
+                    .cell(PACKETS, flow.packets())
+                    .cell(DURATION, flow.life())
                     .cell(PRIORITY, flow.priority())
+                    .cell(TABLE_ID, flow.tableId())
+                    .cell(APP_ID, flow.appId())
+
+                    .cell(GROUP_ID, flow.groupId().id())
                     .cell(TIMEOUT, flow.timeout())
                     .cell(PERMANENT, flow.isPermanent())
-                    .cell(STATE, flow.state())
-                    .cell(PACKETS, flow.packets())
-                    .cell(BYTES, flow.bytes())
+
+                    .cell(SELECTOR_C, flow)
                     .cell(SELECTOR, flow)
+                    .cell(TREATMENT_C, flow)
                     .cell(TREATMENT, flow);
         }
 
-        private final class SelectorFormatter implements CellFormatter {
+
+        private class InternalSelectorFormatter implements CellFormatter {
+            private final boolean shortFormat;
+
+            InternalSelectorFormatter(boolean shortFormat) {
+                this.shortFormat = shortFormat;
+            }
+
             @Override
             public String format(Object value) {
                 FlowEntry flow = (FlowEntry) value;
@@ -162,7 +194,12 @@
                 if (criteria.isEmpty()) {
                     return "(No traffic selector criteria for this flow)";
                 }
-                StringBuilder sb = new StringBuilder("Criteria: ");
+
+                StringBuilder sb = new StringBuilder();
+                if (!shortFormat) {
+                    sb.append("Criteria: ");
+                }
+
                 for (Criterion c : criteria) {
                     sb.append(c).append(COMMA);
                 }
@@ -172,7 +209,25 @@
             }
         }
 
-        private final class TreatmentFormatter implements CellFormatter {
+        private final class SelectorShortFormatter extends InternalSelectorFormatter {
+            SelectorShortFormatter() {
+                super(true);
+            }
+        }
+
+        private final class SelectorFormatter extends InternalSelectorFormatter {
+            SelectorFormatter() {
+                super(false);
+            }
+        }
+
+        private class InternalTreatmentFormatter implements CellFormatter {
+            private final boolean shortFormat;
+
+            InternalTreatmentFormatter(boolean shortFormat) {
+                this.shortFormat = shortFormat;
+            }
+
             @Override
             public String format(Object value) {
                 FlowEntry flow = (FlowEntry) value;
@@ -186,7 +241,12 @@
                     return "(No traffic treatment instructions for this flow)";
                 }
 
-                StringBuilder sb = new StringBuilder("Treatment Instructions: ");
+                StringBuilder sb = new StringBuilder();
+
+                if (!shortFormat) {
+                    sb.append("Treatment Instructions: ");
+                }
+
                 formatInstructs(sb, imm, "immediate:");
                 formatInstructs(sb, def, "deferred:");
 
@@ -214,6 +274,18 @@
             }
         }
 
+        private final class TreatmentShortFormatter extends InternalTreatmentFormatter {
+            TreatmentShortFormatter() {
+                super(true);
+            }
+        }
+
+        private final class TreatmentFormatter extends InternalTreatmentFormatter {
+            TreatmentFormatter() {
+                super(false);
+            }
+        }
+
         private void formatInstructs(StringBuilder sb,
                                      List<Instruction> instructs,
                                      String type) {
@@ -287,24 +359,30 @@
 
             String flowId = string(payload, FLOW_ID);
             String appId = string(payload, APP_ID);
-            FlowRule flow = findFlowById(appId, flowId);
+
+            FlowEntry flow = findFlowById(appId, flowId);
             if (flow != null) {
                 ObjectNode data = objectNode();
 
-
                 data.put(FLOW_ID, decorateFlowId(flow));
+
+                // TODO: use formatters for these values..
+                data.put(STATE, flow.state().toString());
+                data.put(BYTES, flow.bytes());
+                data.put(PACKETS, flow.packets());
+                data.put(DURATION, flow.life());
+
                 data.put(FLOW_PRIORITY, flow.priority());
-                data.put(GROUP_ID, decorateGroupId(flow));
-                data.put(APP_ID, flow.appId());
                 data.put(TABLE_ID, flow.tableId());
+                data.put(APP_ID, flow.appId());
+
+                data.put(GROUP_ID, decorateGroupId(flow));
                 data.put(TIMEOUT, flow.hardTimeout());
                 data.put(PERMANENT, Boolean.toString(flow.isPermanent()));
+
                 data.put(SELECTOR, getCriteriaString(flow));
                 data.put(TREATMENT, getTreatmentString(flow));
 
-
-                //TODO put more detail info to data
-
                 ObjectNode rootNode = objectNode();
                 rootNode.set(DETAILS, data);
                 sendMessage(FLOW_DETAILS_RESP, rootNode);
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.html b/web/gui/src/main/webapp/app/view/flow/flow.html
index 180a53e..b18e424 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.html
+++ b/web/gui/src/main/webapp/app/view/flow/flow.html
@@ -60,12 +60,12 @@
             <select ng-model="queryBy">
                 <option value="" disabled>Search By</option>
                 <option value="$">All Fields</option>
-                <option value="id">Flow ID</option>
-                <option value="appId">App ID</option>
-                <option value="groupId">Group ID</option>
-                <option value="tableId">Table ID</option>
+                <!--<option value="id">Flow ID</option>-->
                 <option value="priority">Priority</option>
-                <option value="timeout">Timeout</option>
+                <option value="tableId">Table ID</option>
+                <option value="selector">Selector</option>
+                <option value="treatment">Treatment</option>
+                <option value="appId">App ID</option>
             </select>
         </div>
 
@@ -75,16 +75,16 @@
         <div class="table-header" onos-sortable-header>
             <table>
                 <tr>
-                    <td colId="id" col-width="180px" sortable>Flow ID </td>
-                    <td colId="appId" sortable>App ID </td>
-                    <td colId="groupId" sortable>Group ID </td>
-                    <td colId="tableId" sortable>Table ID </td>
-                    <td colId="priority" sortable>Priority </td>
-                    <td colId="timeout" sortable>Timeout </td>
-                    <td colId="permanent" sortable>Permanent </td>
-                    <td colId="state" sortable>State </td>
-                    <td class="right" colId="packets" sortable>Packets </td>
-                    <td class="right" colId="bytes" sortable>Bytes </td>
+                    <!--<td colId="id" col-width="180px" sortable>Flow ID </td>-->
+                    <td colId="state" col-width="100px" sortable>State </td>
+                    <!--<td class="right" colId="bytes" col-width="90px" sortable> Bytes </td>-->
+                    <td class="right" colId="packets" col-width="90px" sortable> Packets </td>
+                    <td class="right" colId="duration" col-width="90px" sortable> Duration </td>
+                    <td colId="priority" col-width="80px" sortable> Priority </td>
+                    <td colId="tableId" col-width="80px" sortable> Table ID </td>
+                    <td colId="selector" sortable> Selector </td>
+                    <td colId="treatment" sortable> Treatment </td>
+                    <td colId="appId" sortable> App ID </td>
                 </tr>
             </table>
         </div>
@@ -101,26 +101,27 @@
                     ng-click="selectCallback($event, flow)"
                     ng-class="{selected: flow.id === selId}"
                     ng-repeat-complete row-id="{{flow.id}}">
-                    <td>{{flow.id}}</td>
-                    <td>{{flow.appId}}</td>
-                    <td>{{flow.groupId}}</td>
-                    <td>{{flow.tableId}}</td>
-                    <td>{{flow.priority}}</td>
-                    <td>{{flow.timeout}}</td>
-                    <td>{{flow.permanent}}</td>
+
+                    <!--<td>{{flow.id}}</td>-->
                     <td>{{flow.state}}</td>
+                    <!--<td class="right">{{flow.bytes}}</td>-->
                     <td class="right">{{flow.packets}}</td>
-                    <td class="right">{{flow.bytes}}</td>
+                    <td class="right">{{flow.duration}}</td>
+                    <td>{{flow.priority}}</td>
+                    <td>{{flow.tableId}}</td>
+                    <td>{{flow.selector_c}}</td>
+                    <td>{{flow.treatment_c}}</td>
+                    <td>{{flow.appId}}</td>
                 </tr>
                 <tr ng-click="selectCallback($event, flow)"
                     ng-class="{selected: flow.id === selId}"
                     row-id="{{flow.id}}" ng-hide="brief">
-                    <td class="selector" colspan="10" >{{flow.selector}} </td>
+                    <td class="selector" colspan="8" >{{flow.selector}} </td>
                 </tr>
                 <tr ng-click="selectCallback($event, flow)"
                     ng-class="{selected: flow.id === selId}"
                     row-id="{{flow.id}}" ng-hide="brief" ng-repeat-end>
-                    <td class="treatment" colspan="10">{{flow.treatment}}</td>
+                    <td class="treatment" colspan="8">{{flow.treatment}}</td>
                 </tr>
             </table>
         </div>
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.js b/web/gui/src/main/webapp/app/view/flow/flow.js
index a48c63e..11c897d 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.js
+++ b/web/gui/src/main/webapp/app/view/flow/flow.js
@@ -53,12 +53,36 @@
         detailsResp = 'flowDetailsResponse',
 
         propOrder = [
-            'flowId', 'priority', 'groupId', 'appId', 'tableId',
-            'timeout', 'permanent'
+            'flowId',
+            'state',
+
+            'bytes',
+            'packets',
+            'duration',
+
+            'priority',
+            'tableId',
+            'appId',
+
+            'groupId',
+            'timeout',
+            'permanent'
         ],
         friendlyProps = [
-            'Flow ID', 'Flow Priority', 'Group ID', 'Application ID',
-            'Table ID', 'Timeout', 'Permanent'
+            'Flow ID',
+            'State',
+
+            'Bytes',
+            'Packets',
+            'Duration',
+
+            'Flow Priority',
+            'Table ID',
+            'App ID',
+
+            'Group ID',
+            'Timeout',
+            'Permanent'
         ];
 
     function closePanel() {
@@ -85,25 +109,26 @@
 
         container = detailsPanel.append('div').classed('container', true);
         top = container.append('div').classed('top', true);
-        trmtDiv = container.append('div').classed('top', true);
         selDiv = container.append('div').classed('top', true);
+        trmtDiv = container.append('div').classed('top', true);
         closeBtn = top.append('div').classed('close-btn', true);
         addCloseBtn(closeBtn);
         iconDiv = top.append('div').classed('dev-icon', true);
         top.append('h2');
         topTable = top.append('div').classed('top-content', true)
             .append('table');
+
         top.append('hr');
-        trmtDiv.append('h2').text('Treatment');
-        topTrmtTable = trmtDiv.append('div').classed('top-content', true)
-            .append('table');
-        trmtDiv.append('hr');
+
         selDiv.append('h2').text('Selector');
         topSelTable = selDiv.append('div').classed('top-content', true)
             .append('table');
 
+        selDiv.append('hr');
 
-        //ToDo add more details
+        trmtDiv.append('h2').text('Treatment');
+        topTrmtTable = trmtDiv.append('div').classed('top-content', true)
+            .append('table');
     }
 
     function addProp(tbody, index, value) {