Implement firmware upload function

Change-Id: Ie89793ec9add1fc9e5241b422cfff64784f7b078
Signed-off-by: Iftekharul Islam <iislam@us.ibm.com>
diff --git a/app/assets/images/crit-x.svg b/app/assets/images/crit-x.svg
index 9ae6c7d..1d71c09 100644
--- a/app/assets/images/crit-x.svg
+++ b/app/assets/images/crit-x.svg
@@ -1,11 +1,11 @@
 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 31.6 29.5" style="enable-background:new 0 0 31.6 29.5;" xml:space="preserve">
+	 viewBox="0 0 27.7 28" style="enable-background:new 0 0 27.7 28;" xml:space="preserve">
 <style type="text/css">
-	.st0{fill:none;stroke:#E62325;stroke-width:4;stroke-miterlimit:10;}
+	.st0{fill:none;stroke:#B72129;stroke-width:3;stroke-miterlimit:10;}
 </style>
-<g id="Layer_1_1_">
-	<path class="st0" d="M28.9,27.7C25.5,24.4,3.6,2.4,3.6,2.4"/>
-	<path class="st0" d="M28.9,2.4C25.5,5.7,3.6,27.7,3.6,27.7"/>
+<g id="Layer_1">
+	<path class="st0" d="M26.5,26.5C23.1,23.2,1.2,1.2,1.2,1.2"/>
+	<path class="st0" d="M26.5,1.2C23.1,4.5,1.2,26.5,1.2,26.5"/>
 </g>
 <g id="Layer_2">
 </g>
diff --git a/app/common/directives/file.js b/app/common/directives/file.js
new file mode 100644
index 0000000..11adf8a
--- /dev/null
+++ b/app/common/directives/file.js
@@ -0,0 +1,21 @@
+window.angular && (function (angular) {
+    'use strict';
+
+    angular
+        .module('app.common.directives')
+        .directive('file', function () {
+            return {
+                scope: {
+                    file: '='
+                },
+                link: function (scope, el, attrs) {
+                    el.bind('change', function (event) {
+                        var file = event.target.files[0];
+                        scope.file = file ? file : undefined;
+                        scope.$apply();
+                    });
+                }
+            };
+        });
+
+})(window.angular);
\ No newline at end of file
diff --git a/app/common/directives/firmware-list.html b/app/common/directives/firmware-list.html
new file mode 100644
index 0000000..91f08a6
--- /dev/null
+++ b/app/common/directives/firmware-list.html
@@ -0,0 +1,67 @@
+<div class="row column firmware__table">
+	<div class="table-header column small-12">
+		<p class="inline">{{title}}</p>
+		<p class="inline firmware__active-version">In-memory firmware version: {{version}}</p>
+	</div>
+	<div class="table row column">
+		<div class="table__head">
+			<div class="table__row">
+				<div class="table__cell">
+					Boot Priority
+				</div>
+				<div class="table__cell">
+					Image state
+				</div>
+				<div class="table__cell">
+					Image ID
+				</div>
+				<div class="table__cell">
+					Version
+				</div>
+				<div class="table__cell">
+					Action
+				</div>
+			</div>
+		</div>
+		<div class="table__body">
+			<div class="table__row" ng-repeat="firmware in firmwares|filter:filterBy">
+				<div class="table__cell firmware__primary">
+					<span class="table__cell-label">Boot Priority:</span>
+					<div class="icon icon__up-arrow icon-as-spacer" aria-hidden="true">
+						<span class="accessible-text">firmware down in priority</span></div>
+					<div class="icon icon__down-arrow" aria-hidden="true">
+						<span class="accessible-text">firmware down in priority</span></div>
+				</div>
+				<div class="table__cell firmware__active">
+					<span class="table__cell-label">Image state:</span><span ng-if="firmware.active">Active</span>
+				</div>
+				<div class="table__cell">
+					<span class="table__cell-label">Image ID:</span>{{firmware.imageId}}
+				</div>
+				<div class="table__cell firmware__version" ng-class="{'active':firmware.isExtended}">
+					<span class="table__cell-label">Version:</span>{{firmware.Version}}
+					<div class="icon icon__more" ng-click="firmware.extended.show = ! firmware.extended.show"
+							ng-class="{'active':firmware.isExtended}" ng-show="firmware.isExtended">
+						<svg version="1.1" x="0px" y="0px" viewBox="0 0 24.3 24.6">
+							<path d="M12.1,23C6.1,23,1.3,18.2,1.3,12.3S6.1,1.6,12.1,1.6s10.7,4.8,10.7,10.7S18,23,12.1,23z M12.1,2.6c-5.4,0-9.7,4.4-9.7,9.7 S6.7,22,12.1,22s9.7-4.4,9.7-9.7S17.4,2.6,12.1,2.6z"/>
+							<g>
+								<circle cx="6.7" cy="12.5" r="1.5"/>
+								<circle cx="12.1" cy="12.5" r="1.5"/>
+								<circle cx="17.4" cy="12.5" r="1.5"/>
+							</g>
+						</svg>
+					</div>
+					<div class="icon__more-dropdown" ng-show="firmware.extended.show">
+						<h5 class="bold">Extended version information</h5>
+						<p class="no-margin" ng-repeat="version in firmware.extended.versions">{{version.title}}: {{version.version}}</p>
+					</div>
+				</div>
+				<div class="table__cell">
+				    <span class="table__cell-label">Action:</span>
+				    <button class="firmware__action-link" ng-show="!firmware.active" ng-click="activate(firmware.imageId)">Activate</button>
+				    <button class="firmware__action-link" ng-show="!firmware.active" ng-click="delete(firmware.imageId)">Delete</button>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/app/common/directives/firmware-list.js b/app/common/directives/firmware-list.js
new file mode 100644
index 0000000..f4cc94f
--- /dev/null
+++ b/app/common/directives/firmware-list.js
@@ -0,0 +1,28 @@
+window.angular && (function (angular) {
+    'use strict';
+
+    angular
+        .module('app.common.directives')
+        .directive('firmwareList', ['APIUtils', function (APIUtils) {
+            return {
+                'restrict': 'E',
+                'templateUrl': 'common/directives/firmware-list.html',
+                'scope': {
+                   'title': '@',
+                   'firmwares': '=',
+                   'filterBy': '=',
+                   'version': '='
+                },
+                'controller': ['$rootScope', '$scope','dataService', '$location', '$timeout', function($rootScope, $scope, dataService, $location, $timeout){
+                    $scope.dataService = dataService;
+                    $scope.activate = function(imageId){
+                        $scope.$parent.activateImage(imageId);
+                    }
+
+                    $scope.delete = function(imageId){
+                        $scope.$parent.deleteImage(imageId);
+                    }
+                }]
+            };
+        }]);
+})(window.angular);
\ No newline at end of file
diff --git a/app/common/directives/log-event.html b/app/common/directives/log-event.html
index 2f02315..70d7dee 100644
--- a/app/common/directives/log-event.html
+++ b/app/common/directives/log-event.html
@@ -11,23 +11,22 @@
                  <button class="btn-primary" ng-click="event.confirm=false;">No</button>
              </div>
          </div>
-         <div class="column small-1 large-1 event-log__col-check">
+         <div class="column small-1 large-2 event-log__col-check">
              <label class="control-check">
                  <input type="checkbox" name="events__check" ng-click="event.selected= ! event.selected"
                         ng-checked="event.selected"/>
                  <div class="control__indicator"></div>
              </label>
          </div>
-         <div class="column small-9 large-10 event-log__event-info"
+         <div class="column small-9 large-9 event-log__event-info"
               ng-click="event.meta = ! event.meta">
-             <p class="inline event__id">#{{event.Id}}</p>
              <p class="inline event__priority event-resolved" ng-hide="event.Resolved == 0">Resolved</p>
              <p class="inline event__priority med-priority" ng-class="{'low-priority': event.priority == 'Low', 'medium-priority': event.priority == 'Medium', 'high-priority': event.priority == 'High'}" ng-hide="event.Resolved == 1">{{event.priority}}</p>
              <p class="inline event__severity">{{event.severity_code}}</p>
-             <p class="inline event__timestamp">{{event.Timestamp| date:'MM/dd/yyyy  HH:mm:ss '+tmz: tmz}}</p>
+             <p class="inline event__description">{{event.Severity}}</p>
              <div>
-                 <p class="inline event__description">{{event.Severity}}</p>
-             </div>
+                 <p class="inline event__id">#{{event.Id}}</p>
+                 <p class="inline event__timestamp">{{event.Timestamp| date:'MM/dd/yyyy  HH:mm:ss '+tmz: tmz}}</p></div>
          </div>
          <div class="column small-1 large-1">
              <button class="accord-trigger" ng-class="{'active': event.meta}"
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index 120bcb8..2df7b5f 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -476,7 +476,115 @@
                 }).error(function(error){
                   console.log(error);
                 });
-              }
+              },
+              getFirmwares: function(callback){
+                $http({
+                  method: 'GET',
+                  //url: SERVICE.API_CREDENTIALS.mock_host + "/software",
+                  url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/software/enumerate",
+                  headers: {
+                      'Accept': 'application/json',
+                      'Content-Type': 'application/json'
+                  },
+                  withCredentials: true
+                }).success(function(response){
+                      var json = JSON.stringify(response);
+                      var content = JSON.parse(json);
+                      var data = [];
+                      var active = false;
+                      var isExtended = false;
+                      var bmcActiveVersion = "";
+                      var hostActiveVersion = "";
+                      var imageType = "";
+                      var extendedVersions = [];
+
+                      function getFormatedExtendedVersions(extendedVersion){
+                        var versions = [];
+                        extendedVersion = extendedVersion.split(",");
+
+                        extendedVersion.forEach(function(item){
+                          var parts = item.split("-");
+                          var numberIndex = 0;
+                          for(var i = 0; i < parts.length; i++){
+                            if(/[0-9]/.test(parts[i])){
+                              numberIndex = i;
+                              break;
+                            }
+                          }
+                          var titlePart = parts.splice(0, numberIndex);
+                          titlePart = titlePart.join("");
+                          titlePart = titlePart[0].toUpperCase() + titlePart.substr(1, titlePart.length);
+                          var versionPart = parts.join("-");
+                          versions.push({
+                            title: titlePart,
+                            version: versionPart
+                          });
+                        });
+
+                        return versions;
+                      }
+
+                      for(var key in content.data){
+                        if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Version')){
+                          active = (/\.Active$/).test(content.data[key].Activation);
+                          imageType = content.data[key].Purpose.split(".").pop();
+                          isExtended = content.data[key].hasOwnProperty('ExtendedVersion') && content.data[key].ExtendedVersion != "";
+                          if(isExtended){
+                            extendedVersions = getFormatedExtendedVersions(content.data[key].ExtendedVersion);
+                          }
+                          data.push(Object.assign({
+                            path: key,
+                            active: active,
+                            imageId: key.split("/").pop(),
+                            imageType: imageType,
+                            isExtended: isExtended,
+                            extended: {
+                              show: false,
+                              versions: extendedVersions
+                            },
+                            data: {key: key, value: content.data[key]}
+                          }, content.data[key]));
+
+                          if(active && imageType == 'BMC'){
+                            bmcActiveVersion = content.data[key].Version;
+                          }
+
+                          if(active && imageType == 'Host'){
+                            hostActiveVersion = content.data[key].Version;
+                          }
+                        }
+                      }
+                      callback(data, bmcActiveVersion, hostActiveVersion);
+                }).error(function(error){
+                  console.log(error);
+                });
+              },
+              uploadImage: function(file, callback){
+                $http({
+                  method: 'PUT',
+                  timeout: 5 * 60 * 1000,
+                  //url: 'http://localhost:3002/upload',
+                  url: SERVICE.API_CREDENTIALS.host + "/upload/image/",
+                  headers: {
+                      'Accept': 'application/octet-stream',
+                      'Content-Type': 'application/octet-stream'
+                  },
+                  withCredentials: true,
+                  data: file
+                }).success(function(response){
+                      var json = JSON.stringify(response);
+                      var content = JSON.parse(json);
+                      if(callback){
+                          return callback(content);
+                      }
+                }).error(function(error){
+                  if(callback){
+                      callback(error);
+                  }else{
+                      console.log(error);
+                  }
+                });
+              },
           };
           return SERVICE;
         }]);
diff --git a/app/common/services/constants.js b/app/common/services/constants.js
index dba4afa..7616b3e 100644
--- a/app/common/services/constants.js
+++ b/app/common/services/constants.js
@@ -20,7 +20,8 @@
                     password: "testpass",
                 },
                 API_CREDENTIALS: {
-                    host: 'https://9.41.165.233/'
+                    host: 'https://9.3.185.173',
+                    mock_host: 'http://localhost:3000'
                 },
                 API_RESPONSE: {
                     ERROR_STATUS: 'error',
diff --git a/app/common/styles/base/colors.scss b/app/common/styles/base/colors.scss
index 46e7b0a..7308cec 100644
--- a/app/common/styles/base/colors.scss
+++ b/app/common/styles/base/colors.scss
@@ -52,7 +52,6 @@
 
 // Severity
 $critical-lightbg: #e62325;
-$critical-bg: #fad3d3;
 $critical-darkbg: #ff5c49;
 $medium-lightbg: #dc267f;
 $medium-darkbg: #FF509E;
diff --git a/app/common/styles/base/foundation.scss b/app/common/styles/base/foundation.scss
index d621b13..9c31f8f 100644
--- a/app/common/styles/base/foundation.scss
+++ b/app/common/styles/base/foundation.scss
@@ -814,7 +814,7 @@
     display: block !important; } }
 
 .row {
-  max-width: 67.500rem; //960px
+  max-width: 60.38rem; //960px
   margin-right: auto;
   margin-left: auto; }
 .row::before, .row::after {
diff --git a/app/common/styles/base/icons.scss b/app/common/styles/base/icons.scss
index 9772ba4..e499095 100644
--- a/app/common/styles/base/icons.scss
+++ b/app/common/styles/base/icons.scss
@@ -44,7 +44,7 @@
   }
 }
 
-.icon__warning {
+.icon__warning{
   width: 30px;
   height: 30px;
   background-image: url(/assets/images/icon-warning.svg);
@@ -52,23 +52,7 @@
   vertical-align: middle;
 }
 
-.icon__critical {
-  width: 20px;
-  height: 20px;
-  border-radius: 50%;
-  position: relative;
-  border-width: 2px;
-  border-style: solid;
-  color: $critical-lightbg;
-  background-color: rgba($critical-bg, 1);
-  background-image: url(/assets/images/crit-x.svg);
-  background-size: 120%;
-  background-position: 50% 50%;
-  background-repeat: no-repeat;
-  border-color: $critical-lightbg;
-}
-
-.icon__info {
+.icon__info{
   margin-top: -4px;
   margin-right: .5em;
   width: 25px;
@@ -91,7 +75,6 @@
     text-align: -9999px;
   }
 }
-
 .icon__down-arrow {
   margin-right: 1em;
   &:before {
diff --git a/app/common/styles/base/utility.scss b/app/common/styles/base/utility.scss
index b82efc4..33cf61a 100644
--- a/app/common/styles/base/utility.scss
+++ b/app/common/styles/base/utility.scss
@@ -3,7 +3,7 @@
 }
 
 .disabled {
-  color: darken($lightbg__grey, 10%);
+  color: $lightbg__grey;
 }
 
 .float-right {
diff --git a/app/common/styles/elements/modals.scss b/app/common/styles/elements/modals.scss
index 70c0af1..299dfb1 100644
--- a/app/common/styles/elements/modals.scss
+++ b/app/common/styles/elements/modals.scss
@@ -12,6 +12,10 @@
   padding:0;
 }
 
+.modal-overlay.active{
+  display: block;
+}
+
 .modal {
   width:50%;
   max-width: 850px;
@@ -31,6 +35,10 @@
   }
 }
 
+.modal.active{
+  display: block;
+}
+
 .modal .page-header {
   padding-bottom: .7em;
 }
diff --git a/app/common/styles/elements/quicklinks b/app/common/styles/elements/quicklinks.scss
similarity index 100%
rename from app/common/styles/elements/quicklinks
rename to app/common/styles/elements/quicklinks.scss
diff --git a/app/common/styles/elements/tags.scss b/app/common/styles/elements/tags.scss
index 238a772..8a480c9 100644
--- a/app/common/styles/elements/tags.scss
+++ b/app/common/styles/elements/tags.scss
@@ -103,11 +103,8 @@
   border-color: $normal;
   &.high-priority {
     color: $critical-lightbg;
-    background-color: rgba( $critical-bg, 1 );
+    background-color: rgba( $critical-lightbg, .4 );
     background-image: url(/assets/images/crit-x.svg);
-    background-size: 120%;
-    background-position: 50% 50%;
-    background-repeat: no-repeat;
     border-color: $critical-lightbg;
     &:before {
       content: '';
diff --git a/app/configuration/controllers/firmware-controller.html b/app/configuration/controllers/firmware-controller.html
index 817fd06..8c681df 100644
--- a/app/configuration/controllers/firmware-controller.html
+++ b/app/configuration/controllers/firmware-controller.html
@@ -18,252 +18,8 @@
 		<span class="icon icon__bar-arrow">&nbsp;</span>&nbsp;&nbsp;Scroll to upload image file
 	</button>
 </div>
-<div class="row column firmware__table">
-	<div class="table-header column small-12">
-		<p class="inline">Server images</p>
-		<p class="inline firmware__active-version">In-memory firmware version: v1.99.4-82-g874f12e</p>
-	</div>
-	<div class="table row column">
-		<div class="table__head">
-			<div class="table__row">
-				<div class="table__cell">
-					Boot Priority
-				</div>
-				<div class="table__cell">
-					Image state
-				</div>
-				<div class="table__cell">
-					Image ID
-				</div>
-				<div class="table__cell">
-					Version
-				</div>
-				<div class="table__cell">
-					Action
-				</div>
-			</div>
-		</div>
-		<div class="table__body">
-			<div class="table__row">
-				<div class="table__cell firmware__primary">
-					<span class="table__cell-label">Boot Priority:</span>
-					<div class="icon icon__up-arrow icon-as-spacer" aria-hidden="true">
-						<span class="accessible-text">firmware down in priority</span></div>
-					<div class="icon icon__down-arrow" aria-hidden="true">
-						<span class="accessible-text">firmware down in priority</span></div>
-				</div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Active
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>46c8c3d0
-				</div>
-				<div class="table__cell firmware__version" ng-class="{'active':extendedVersion === true}">
-					<span class="table__cell-label">Version:</span>v1.99.4-82-g874f12e
-					<div class="icon icon__more" ng-click="extendedVersion = ! extendedVersion"
-							ng-class="{'active':extendedVersion === true}">
-						<svg version="1.1" x="0px" y="0px" viewBox="0 0 24.3 24.6">
-							<path d="M12.1,23C6.1,23,1.3,18.2,1.3,12.3S6.1,1.6,12.1,1.6s10.7,4.8,10.7,10.7S18,23,12.1,23z M12.1,2.6c-5.4,0-9.7,4.4-9.7,9.7 S6.7,22,12.1,22s9.7-4.4,9.7-9.7S17.4,2.6,12.1,2.6z"/>
-							<g>
-								<circle cx="6.7" cy="12.5" r="1.5"/>
-								<circle cx="12.1" cy="12.5" r="1.5"/>
-								<circle cx="17.4" cy="12.5" r="1.5"/>
-							</g>
-						</svg>
-					</div>
-					<div class="icon__more-dropdown" ng-show="extendedVersion">
-						<h5 class="bold">Extended version information</h5>
-						<p class="no-margin">Host: 1.2.3</p>
-						<p class="no-margin">Linux: 2.3.4</p>
-						<p class="no-margin">Other OS: 4.5.6</p>
-					</div>
-				</div>
-				<div class="table__cell">
-					&nbsp;
-				</div>
-			</div>
-			<!-- new row -->
-			<div class="table__row">
-				<div class="table__cell">
-					<span class="table__cell-label">Boot Priority:</span>
-					<div class="icon icon__up-arrow" aria-hidden="true">
-						<span class="accessible-text">firmware up in priority</span></div>
-					<div class="icon icon__down-arrow" aria-hidden="true">
-						<span class="accessible-text">firmware down in priority</span></div>
-				</div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Active
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>46c9c3e4
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v1.99.4-82-g874g45r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<button class="firmware__action-link">Delete</button>
-				</div>
-			</div>
-			<!-- new row -->
-			<div class="table__row">
-				<div class="table__cell">
-					<span class="table__cell-label">Boot Priority:</span>
-					<div class="icon icon__up-arrow" aria-hidden="true">
-						<span class="accessible-text">firmware up in priority</span></div>
-					<div class="icon icon__down-arrow icon-as-spacer" aria-hidden="true">
-						<span class="accessible-text">firmware down in priority</span></div>
-				</div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Active
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>46c9c3e4
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v1.99.4-82-g974g48r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<button class="firmware__action-link">Delete</button>
-				</div>
-			</div>
-			<!-- new row -->
-			<div class="table__row disabled">
-				<div class="table__cell"></div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Invalid
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>46c9c3e4
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v1.99.4-82-g774g15r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<button class="firmware__action-link">Delete</button>
-				</div>
-			</div>
-			<div class="table__row">
-				<div class="table__row-save" role="alert"><p>Saved</p></div> <!-- inject div when row is saved -->
-				<div class="table__cell"></div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Invalid
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>46c9c3e4
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v1.99.4-82-g774g15r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<button class="firmware__action-link">Delete</button>
-				</div>
-			</div>
-		</div>
-	</div>
-</div>
-<div class="row column firmware__table">
-	<div class="table-header column small-12">
-		<p class="inline">BMC images</p>
-		<p class="inline firmware__active-version">In-memory firmware version: v4.0.4-83r</p>
-	</div>
-	<div class="table row column">
-		<div class="table__head">
-			<div class="table__row">
-				<div class="table__cell">
-					Boot Priority
-				</div>
-				<div class="table__cell">
-					Image state
-				</div>
-				<div class="table__cell">
-					Image ID
-				</div>
-				<div class="table__cell">
-					Version
-				</div>
-				<div class="table__cell">
-					Action
-				</div>
-			</div>
-		</div>
-		<div class="table__body">
-			<!-- new row -->
-			<div class="table__row">
-				<div class="table__cell">
-					<span class="table__cell-label">Boot Priority:</span>
-				</div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Active
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>nnnnnn0
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v4.0.4-83r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-				</div>
-			</div>
-			<!-- new row -->
-			<div class="table__row disabled">
-				<div class="table__cell"></div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Activation failed
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>50c9c3e4
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v3.4-82-g874g45r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<button class="firmware__action-link">Delete</button>
-				</div>
-			</div>
-			<!-- new row -->
-			<div class="table__row">
-				<div class="table__cell"></div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Ready
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>nnnnnn1
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v4.0.3-83r
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<button class="firmware__action-link">Activate</button>
-					<button class="firmware__action-link">Delete</button>
-				</div>
-			</div>
-			<!-- new row -->
-			<div class="table__row table__row-uploading">
-				<div class="table__cell"></div>
-				<div class="table__cell firmware__active">
-					<span class="table__cell-label">Image state:</span>Not ready
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Image ID:</span>nnnnnn2
-				</div>
-				<div class="table__cell firmware__version">
-					<span class="table__cell-label">Version:</span>v4.0.2-82p
-				</div>
-				<div class="table__cell">
-					<span class="table__cell-label">Action:</span>
-					<span>Validating...</span>
-				</div>
-			</div>
-		</div>
-	</div>
-</div>
+<firmware-list title="BMC images" version="bmcActiveVersion" firmwares="firmwares" filter-by="filters.bmc"></firmware-list>
+<firmware-list title="Server images" version="hostActiveVersion" firmwares="firmwares" filter-by="filters.host"></firmware-list>
 <div class="row column" id="upload">
 	<div class="column small-12 page-header">
 		<h2 class="inline h3 bold">Upload firmware image</h2>
@@ -275,12 +31,12 @@
 			<p>Optional text area. Can be used to explain about updating openBMC firmware from workstation. This could
 				be step-by-step instruction. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et</p>
 			<label for="file-upload" class="inline firmware__upload-chooser">
-				<input id="file-upload" type="file" class="hide"/>
+				<input id="file-upload" type="file" file="file" class="hide" onchange="angular.element(this).scope().fileNameChanged()"/>
 				<span class="button btn-secondary inline">Choose a file</span>
-				<span class="inline firmware__upload-file-name">No file chosen</span>
+				<span class="inline firmware__upload-file-name"><span ng-if="!file">No file chosen</span><span ng-if="file.name !== undefined">{{file.name}}</span></span>
 			</label>
-			<input type="submit" value="Upload firmware" class="inline btn btn-primary float-right"/>
-			<div class="inline uploading">Upload in progress...</div>
+			<input type="button" value="Upload firmware" class="inline button btn-primary float-right" ng-click="upload()"/>
+			<div class="inline uploading" ng-show="uploading">Upload in progress...</div>
 		</div>
 		<div class=" column firmware__upload-tftp">
 			<h3 class="h4 bold">Download from TFTP server</h3>
@@ -297,63 +53,33 @@
 						<input name="tftp-file-name" id="tftp-file-name" type="text"/>
 					</div>
 					<div class="column small-12 large-4">
-						<input type="submit" value="Download firmware" class="inline btn btn-primary float-right"/>
+						<input type="submit" value="Download firmware" class="inline button btn-primary float-right"/>
 					</div>
 				</div>
-				<div class="inline uploading">Upload in progress...</div>
+				<div class="inline uploading" ng-show="downloading">Downloading in progress...</div>
 			</fieldset>
 		</div>
 	</form>
 </div>
 
 <!-- Firmware modals -->
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
+<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': display_error}">
 	<div class="modal__upload-fail" role="document">
-		<div class="screen-reader-offscreen modal-description">Upload failure modal</div><!-- accessibility only; used for screen readers -->
+		<div class="screen-reader-offscreen modal-description">{{error.modal_title}}</div><!-- accessibility only; used for screen readers -->
 		<div class="page-header ">
-			<span class="icon icon__warning inline"><span class="accessible-text" role="alert">Warning</span></span>
-			<h1 class="modal-title h4 inline">Upload failed</h1>
+			<span class="icon icon__warning inline"><span class="accessible-text" role="alert">{{error.type}}</span></span>
+			<h1 class="modal-title h4 inline">{{error.title}}</h1>
 		</div>
 		<div class="modal__content">
-			<p>The upload of the image file has failed.</p>
+			<p>{{error.desc}}</p>
 		</div>
 		<div class="modal__button-wrapper">
-			<button class="inline btn-primary">Close</button>
+			<button class="inline btn-primary" ng-click="display_error = false;">Close</button>
 		</div>
 	</div>
 </section>
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
-	<div class="modal__activation-fail" role="document">
-		<div class="screen-reader-offscreen modal-description">Activation failure modal</div><!-- accessibility only; used for screen readers -->
-		<div class="page-header ">
-			<span class="icon icon__warning inline"><span class="accessible-text" role="alert">Warning</span></span>
-			<h1 class="modal-title h4 inline">Activation failed</h1>
-		</div>
-		<div class="modal__content">
-			<p>Activation of the image file has failed.</p>
-		</div>
-		<div class="modal__button-wrapper">
-			<button class="inline btn-primary">Close</button>
-		</div>
-	</div>
-</section>
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
-	<div class="modal__tftp-unreachable" role="document">
-		<div class="screen-reader-offscreen modal-description">TFTP server unreachable modal</div><!-- accessibility only; used for screen readers -->
-		<div class="page-header ">
-			<span class="icon icon__warning inline"><span class="accessible-text" role="alert">Warning</span></span>
-			<h1 class="modal-title h4 inline">TFTP server unreachable </h1>
-		</div>
-		<div class="modal__content">
-			<p>Could not make a connection with the TFTP server. Check the IP address and connections, and try
-				again.</p>
-		</div>
-		<div class="modal__button-wrapper">
-			<button class="inline btn-primary">Close</button>
-		</div>
-	</div>
-</section>
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
+
+<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': confirm_delete}">
 	<div class="modal__tftp-unreachable" role="document">
 		<div class="screen-reader-offscreen modal-description">Delete firmware image</div><!-- accessibility only; used for screen readers -->
 		<div class="page-header ">
@@ -361,15 +87,16 @@
 			<h1 class="modal-title h4 inline">Delete image</h1>
 		</div>
 		<div class="modal__content">
-			<p>Delete firmware v3.4-82-g874g45r?</p>
+			<p>Delete firmware {{delete_image_version}}?</p>
 		</div>
 		<div class="modal__button-wrapper">
-			<button class="inline btn-secondary">Cancel</button>
-			<button class="inline btn-primary">Continue</button>
+			<button class="inline btn-secondary" ng-click="confirm_delete=false;">Cancel</button>
+			<button class="inline btn-primary" ng-click="confirmDeleteImage()">Continue</button>
 		</div>
 	</div>
 </section>
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
+
+<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': confirm_upload_image}">
 	<div class="modal__upload" role="document">
 		<div class="screen-reader-offscreen modal-description">Upload image file modal</div><!-- accessibility only; used for screen readers -->
 		<div class="page-header ">
@@ -385,12 +112,12 @@
 				to the previous image.</p>
 		</div>
 		<div class="modal__button-wrapper">
-			<button class="inline btn-secondary">Cancel</button>
-			<button class="inline btn-primary">Continue</button>
+			<button class="inline btn-secondary" ng-click="confirm_upload_image = false;">Cancel</button>
+			<button class="inline btn-primary" ng-click="confirmUpload()">Continue</button>
 		</div>
 	</div>
 </section>
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
+<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': reboot_confirm}">
 	<div class="modal__reboot" role="document">
 		<div class="screen-reader-offscreen modal-description">Server reboot required modal</div><!-- accessibility only; used for screen readers -->
 		<div class="page-header ">
@@ -407,12 +134,12 @@
 		</div>
 		<a href="#/server-control/power-operations" class="bold modal__link">Go to power operations page</a>
 		<div class="modal__button-wrapper">
-			<button class="inline btn-secondary">Cancel</button>
-			<button class="inline btn-primary">Warm reboot</button>
+			<button class="inline btn-secondary" ng-click="reboot_confirm=false;">Cancel</button>
+			<button class="inline btn-primary" ng-click="confirmWarmReboot()">Warm reboot</button>
 		</div>
 	</div>
 </section>
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog">
+<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': preserve_settings_confirm}">
 	<div class="modal__preserve-settings" role="document">
 		<div class="screen-reader-offscreen modal-description">Preserve setting modal</div><!-- accessibility only; used for screen readers -->
 		<div class="page-header ">
@@ -443,9 +170,9 @@
 			</form>
 		</div>
 		<div class="modal__button-wrapper">
-			<button class="inline btn-secondary">Cancel</button>
-			<button class="inline btn-primary">Continue</button>
+			<button class="inline btn-secondary" ng-click="preserve_settings_confirm=false;">Cancel</button>
+			<button class="inline btn-primary" ng-click="preserveSettingsConfirmed()">Continue</button>
 		</div>
 	</div>
 </section>
-<div class="modal-overlay" tabindex="-1"></div>
\ No newline at end of file
+<div class="modal-overlay" tabindex="-1" ng-class="{'active': (display_error || confirm_upload_image || reboot_confirm || preserve_settings_confirm)}"></div>
\ No newline at end of file
diff --git a/app/configuration/controllers/firmware-controller.js b/app/configuration/controllers/firmware-controller.js
index 0eef4ea..2bdfced 100644
--- a/app/configuration/controllers/firmware-controller.js
+++ b/app/configuration/controllers/firmware-controller.js
@@ -27,6 +27,99 @@
                         $location.hash('upload');
                         $anchorScroll();
                     };
+
+                    $scope.firmwares = [];
+                    $scope.bmcActiveVersion = "";
+                    $scope.hostActiveVersion = "";
+                    $scope.display_error = false;
+                    $scope.confirm_upload_image = false;
+                    $scope.reboot_confirm = false;
+                    $scope.preserve_settings_confirm = false;
+                    $scope.delete_image_id = "";
+                    $scope.activate_image_id = "";
+                    $scope.file_empty = true;
+                    $scope.uploading = false;
+
+                    $scope.error = {
+                        modal_title: "",
+                        title: "",
+                        desc: "",
+                        type: "warning"
+                    };
+
+                    $scope.activateImage = function(imageId){
+                        $scope.activate_image_id = imageId;
+                        $scope.preserve_settings_confirm = true;
+                    }
+
+                    $scope.displayError = function(data){
+                        $scope.error = data;
+                        $scope.display_error = true;
+                    }
+
+                    $scope.preserveSettingsConfirmed = function(){
+                        //show progress..callapi..hide..iferror..show error
+                        $scope.preserve_settings_confirm = false;
+                    }
+
+                    $scope.confirmWarmReboot = function(){
+                        $scope.reboot_confirm = false;
+                    }
+
+                    $scope.upload = function(){
+                        if(!$scope.file_empty){
+                            $scope.confirm_upload_image = true;
+                        }
+                    }
+                    $scope.confirmUpload = function(){
+                        $scope.uploading = true;
+                        APIUtils.uploadImage($scope.file, function(response){
+                            $scope.uploading = false; 
+                            if(response.status == 'error'){
+                                $scope.displayError({
+                                    modal_title: response.data.description,
+                                    title: response.data.description,
+                                    desc: response.data.exception,
+                                    type: 'Error'
+                                });
+                            }else{
+                                $scope.loadFirmwares();
+                            }
+                        });
+                        $scope.confirm_upload_image = false;
+                    }
+
+                    $scope.deleteImage = function(imageId){
+                        $scope.delete_image_id = imageId;
+                        $scope.confirm_delete = true;
+                    }
+                    $scope.confirmDeleteImage = function(imageId){
+                        $scope.confirm_delete = false;
+                    }
+
+                    $scope.fileNameChanged = function(){
+                        $scope.file_empty = false;
+                    }
+
+                    $scope.uploading = false;
+                    $scope.filters = {
+                        bmc: {
+                            imageType: 'BMC'
+                        },
+                        host: {
+                            imageType: 'Host'
+                        }
+                    };
+
+                    $scope.loadFirmwares = function(){
+                        APIUtils.getFirmwares(function(data, bmcActiveVersion, hostActiveVersion){
+                           $scope.firmwares = data;
+                           $scope.bmcActiveVersion = bmcActiveVersion;
+                           $scope.hostActiveVersion = hostActiveVersion;
+                        });
+                    }
+
+                    $scope.loadFirmwares();
                 }
             ]
         );
diff --git a/app/configuration/styles/firmware.scss b/app/configuration/styles/firmware.scss
index 08de2bd..ea51b57 100644
--- a/app/configuration/styles/firmware.scss
+++ b/app/configuration/styles/firmware.scss
@@ -75,12 +75,7 @@
   label {
     font-weight: 700;
   }
-  .row p,
-  fieldset {
-    label {
-      font-weight: 300;
-    }
-  }
+
   input {
     height: 2.4em;
   }
diff --git a/app/index.html b/app/index.html
index 840d71d..2026eb6 100644
--- a/app/index.html
+++ b/app/index.html
@@ -52,6 +52,8 @@
 	<script src="common/directives/log-filter.js"></script>
 	<script src="common/directives/log-search-control.js"></script>
     <script src="common/directives/toggle-flag.js"></script>
+    <script src="common/directives/firmware-list.js"></script>
+    <script src="common/directives/file.js"></script>
 
     <script src="login/index.js"></script>
     <script src="login/controllers/login-controller.js"></script>
diff --git a/app/overview/controllers/system-overview-controller.html b/app/overview/controllers/system-overview-controller.html
index 895ec5f..0c314e6 100644
--- a/app/overview/controllers/system-overview-controller.html
+++ b/app/overview/controllers/system-overview-controller.html
@@ -51,7 +51,7 @@
 						</li>
 						<li class="overview__metadata-block">
 							<p class="content-label">Mac address</p>
-							<p class="courier-bold">70:E2:84:14:05:2F</p>
+							<p class="courier-bold"></p>
 						</li>
 						<li class="overview__metadata-block">
 							<p class="content-label">Firmware</p>
diff --git a/app/server-health/controllers/inventory-controller.html b/app/server-health/controllers/inventory-controller.html
index d674efb..2941aaa 100644
--- a/app/server-health/controllers/inventory-controller.html
+++ b/app/server-health/controllers/inventory-controller.html
@@ -58,7 +58,8 @@
 		        ng-class="{'active': inventory__metadatarow, 'selected': inventory__selected}">
             <div class="row column" ng-click="inventory__metadatarow = ! inventory__metadatarow">
                 <div class="column small-12 large-3 inventory__info">
-                    <p class="overview__title">CPU core 5</p>
+                    <p class="priority-tag-circ high-priority" aria-label="High Priority"></p>
+                    <p class="inventory__title">CPU core 5</p>
                 </div>
                 <div class="column small-12 large-3">
                     <p class="content-label">Part Number</p>
diff --git a/app/server-health/controllers/log-controller.html b/app/server-health/controllers/log-controller.html
index f8c08da..6646845 100644
--- a/app/server-health/controllers/log-controller.html
+++ b/app/server-health/controllers/log-controller.html
@@ -28,11 +28,11 @@
         <log-filter></log-filter>
     </section> <!-- end filter -->
     <section id="event-log__events" class="row column">
-        <div id="event__actions-bar" class="row header__actions-bar no-margin">
+        <div id="event__actions-bar" class="row header__actions-bar ">
             <div class="column small-1 large-1 event-log__col-check">
                 <label class="control-check">
                     <input type="checkbox" name="events__check-all" ng-model="all" ng-checked="(logs|filter:{selected: true}).length == logs.length"/>
-                    <span class="control__indicator"></span>
+                    <div class="control__indicator"></div>
                 </label>
             </div>
             <div class="column small-11 large-11 end col-logged-events">
@@ -60,9 +60,9 @@
                 </div>
             </div>
         </div>
-        <log-event
-        dir-paginate="event in (filteredLogs = (logs|filter:filterBySeverity|filter:filterByStatus|filter:filterByDate|filter:filterBySearchTerms))| itemsPerPage: itemsPerPage"
-        event="event"
+        <log-event 
+        dir-paginate="event in (filteredLogs = (logs|filter:filterBySeverity|filter:filterByStatus|filter:filterByDate|filter:filterBySearchTerms))| itemsPerPage: itemsPerPage" 
+        event="event" 
         tmz="tmz">
         </log-event>
     </section>
diff --git a/app/server-health/controllers/sensors-controller.html b/app/server-health/controllers/sensors-controller.html
index 5b1d872..15cd997 100644
--- a/app/server-health/controllers/sensors-controller.html
+++ b/app/server-health/controllers/sensors-controller.html
@@ -81,5 +81,6 @@
                 </div>
             </div>
         </div>
+
     </section>
 </div> <!-- end event log -->