NIFI-4436:
- Adding the version number to the start version control, commit, and change 
version dialog.
- Showing a loading item in the combo's while querying for the registries, 
buckets, and flows.
- Adding tooltips to display version control information on the canvas.
- Adding progress bar dialogs for changing version and reverting local changes.
- Updating canvas and breadcrumb according to the version control state.
- Updating to use registry name, bucket name, and flow name where appropriate.


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/d6e54f19
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/d6e54f19
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/d6e54f19

Branch: refs/heads/master
Commit: d6e54f19ee249da45fe8d625cf68ce3d3e61380a
Parents: 6b00dff
Author: Matt Gilman <[email protected]>
Authored: Fri Nov 10 15:58:59 2017 -0500
Committer: Bryan Bende <[email protected]>
Committed: Mon Jan 8 12:44:53 2018 -0500

----------------------------------------------------------------------
 .../api/dto/VersionedFlowUpdateRequestDTO.java  |  10 +-
 .../apache/nifi/web/api/VersionsResource.java   |  82 ++--
 .../org/apache/nifi/web/api/dto/DtoFactory.java |   4 +-
 .../canvas/import-flow-version-dialog.jsp       |  18 +
 .../WEB-INF/partials/canvas/navigation.jsp      |   6 +-
 .../canvas/save-flow-version-dialog.jsp         |   3 +-
 .../nifi-web-ui/src/main/webapp/css/dialog.css  |  31 +-
 .../nifi-web-ui/src/main/webapp/css/graph.css   |   3 +-
 .../src/main/webapp/css/navigation.css          |  13 +-
 .../controllers/nf-ng-breadcrumbs-controller.js |  51 +++
 .../directives/nf-ng-breadcrumbs-directive.js   |   6 +-
 .../main/webapp/js/nf/canvas/nf-flow-version.js | 443 ++++++++++++++-----
 .../webapp/js/nf/canvas/nf-process-group.js     | 131 +++++-
 .../src/main/webapp/js/nf/nf-common.js          |  19 +
 .../views/nf-ng-breadcrumbs-directive-view.html |   9 +-
 15 files changed, 653 insertions(+), 176 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowUpdateRequestDTO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowUpdateRequestDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowUpdateRequestDTO.java
index 013b40d..cc82af4 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowUpdateRequestDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowUpdateRequestDTO.java
@@ -32,7 +32,7 @@ public class VersionedFlowUpdateRequestDTO {
     private Date lastUpdated;
     private boolean complete = false;
     private String failureReason;
-    private int percentComplete;
+    private int percentCompleted;
     private String state;
     private VersionControlInformationDTO versionControlInformation;
 
@@ -110,11 +110,11 @@ public class VersionedFlowUpdateRequestDTO {
     }
 
     @ApiModelProperty(value = "The percentage complete for the request, 
between 0 and 100", readOnly = true)
-    public int getPercentComplete() {
-        return percentComplete;
+    public int getPercentCompleted() {
+        return percentCompleted;
     }
 
-    public void setPercentComplete(int percentComplete) {
-        this.percentComplete = percentComplete;
+    public void setPercentCompleted(int percentCompleted) {
+        this.percentCompleted = percentCompleted;
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java
index b808ae6..f61b399 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/VersionsResource.java
@@ -17,37 +17,12 @@
 
 package org.apache.nifi.web.api;
 
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Authorization;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.authorization.Authorizer;
 import org.apache.nifi.authorization.ProcessGroupAuthorizable;
@@ -94,12 +69,35 @@ import org.apache.nifi.web.util.Pause;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-import io.swagger.annotations.Authorization;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 @Path("/versions")
 @Api(value = "/versions", description = "Endpoint for managing version control 
for a flow")
@@ -776,7 +774,7 @@ public class VersionsResource extends ApplicationResource {
         updateRequestDto.setRequestId(requestId);
         updateRequestDto.setUri(generateResourceUri("versions", requestType, 
requestId));
         updateRequestDto.setState(asyncRequest.getState());
-        updateRequestDto.setPercentComplete(asyncRequest.getPercentComplete());
+        
updateRequestDto.setPercentCompleted(asyncRequest.getPercentComplete());
 
         if (updateRequestDto.isComplete()) {
             final VersionControlInformationEntity vciEntity = 
serviceFacade.getVersionControlInformation(asyncRequest.getProcessGroupId());
@@ -858,7 +856,7 @@ public class VersionsResource extends ApplicationResource {
         updateRequestDto.setProcessGroupId(asyncRequest.getProcessGroupId());
         updateRequestDto.setRequestId(requestId);
         updateRequestDto.setUri(generateResourceUri("versions", requestType, 
requestId));
-        updateRequestDto.setPercentComplete(asyncRequest.getPercentComplete());
+        
updateRequestDto.setPercentCompleted(asyncRequest.getPercentComplete());
         updateRequestDto.setState(asyncRequest.getState());
 
         if (updateRequestDto.isComplete()) {
@@ -1040,7 +1038,7 @@ public class VersionsResource extends ApplicationResource 
{
                 updateRequestDto.setProcessGroupId(groupId);
                 updateRequestDto.setRequestId(requestId);
                 updateRequestDto.setUri(generateResourceUri("versions", 
"update-requests", requestId));
-                
updateRequestDto.setPercentComplete(request.getPercentComplete());
+                
updateRequestDto.setPercentCompleted(request.getPercentComplete());
                 updateRequestDto.setState(request.getState());
 
                 final VersionedFlowUpdateRequestEntity updateRequestEntity = 
new VersionedFlowUpdateRequestEntity();
@@ -1192,7 +1190,7 @@ public class VersionsResource extends ApplicationResource 
{
                     updateRequestDto.setRequestId(requestId);
                     
updateRequestDto.setVersionControlInformation(currentVersion);
                     updateRequestDto.setUri(generateResourceUri("versions", 
"revert-requests", requestId));
-                    updateRequestDto.setPercentComplete(100);
+                    updateRequestDto.setPercentCompleted(100);
                     updateRequestDto.setState(request.getState());
 
                     final VersionedFlowUpdateRequestEntity updateRequestEntity 
= new VersionedFlowUpdateRequestEntity();
@@ -1231,6 +1229,8 @@ public class VersionsResource extends ApplicationResource 
{
                 updateRequestDto.setLastUpdated(request.getLastUpdated());
                 updateRequestDto.setProcessGroupId(groupId);
                 updateRequestDto.setRequestId(requestId);
+                updateRequestDto.setState(request.getState());
+                
updateRequestDto.setPercentCompleted(request.getPercentComplete());
                 updateRequestDto.setUri(generateResourceUri("versions", 
"revert-requests", requestId));
 
                 final VersionedFlowUpdateRequestEntity updateRequestEntity = 
new VersionedFlowUpdateRequestEntity();

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 1c1e729..bd603be 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -2230,8 +2230,8 @@ public final class DtoFactory {
         dto.setFlowName(versionControlInfo.getFlowName());
         dto.setFlowDescription(versionControlInfo.getFlowDescription());
         dto.setVersion(versionControlInfo.getVersion());
-        dto.setCurrent(versionControlInfo.getCurrent().orElse(null));
-        dto.setModified(versionControlInfo.getModified().orElse(null));
+        dto.setCurrent(versionControlInfo.getCurrent().orElse(true));
+        dto.setModified(versionControlInfo.getModified().orElse(false));
         return dto;
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/import-flow-version-dialog.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/import-flow-version-dialog.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/import-flow-version-dialog.jsp
index 5169c7c..5ea622a 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/import-flow-version-dialog.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/import-flow-version-dialog.jsp
@@ -39,6 +39,24 @@
                 <div id="import-flow-version-name" class="hidden"></div>
             </div>
         </div>
+        <div id="import-flow-version-container" class="setting hidden">
+            <div class="setting-name">Current Version</div>
+            <div class="setting-field">
+                <div id="import-flow-version-label"></div>
+            </div>
+        </div>
         <div id="import-flow-version-table"></div>
     </div>
+</div>
+<div id="change-version-status-dialog" layout="column" class="hidden 
small-dialog">
+    <div class="dialog-content">
+        <div class="setting">
+            <div class="setting-field">
+                <div id="change-version-status-message"></div>
+            </div>
+            <div class="setting-field">
+                <div id="change-version-percent-complete"></div>
+            </div>
+        </div>
+    </div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
index 86f4ba3..4700b8b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp
@@ -19,7 +19,11 @@
         breadcrumbs="appCtrl.serviceProvider.breadcrumbsCtrl.getBreadcrumbs();"
         
click-func="appCtrl.nf.CanvasUtils.getComponentByType('ProcessGroup').enterGroup"
         highlight-crumb-id="appCtrl.nf.CanvasUtils.getGroupId();"
-        separator-func="appCtrl.nf.Common.isDefinedAndNotNull">
+        separator-func="appCtrl.nf.Common.isDefinedAndNotNull"
+        is-tracking="appCtrl.serviceProvider.breadcrumbsCtrl.isTracking"
+        is-current="appCtrl.serviceProvider.breadcrumbsCtrl.isCurrent"
+        is-modified="appCtrl.serviceProvider.breadcrumbsCtrl.isModified"
+        
get-version-control-tooltip="appCtrl.serviceProvider.breadcrumbsCtrl.getVersionControlTooltip">
 </nf-breadcrumbs>
 <div id="graph-controls">
     <div id="navigation-control" class="graph-control">

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/save-flow-version-dialog.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/save-flow-version-dialog.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/save-flow-version-dialog.jsp
index 5e653d2..a7f54b6 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/save-flow-version-dialog.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/save-flow-version-dialog.jsp
@@ -19,9 +19,10 @@
     <div class="dialog-content">
         <div class="setting">
             <div class="setting-name">Registry</div>
-            <div class="setting-field">
+            <div id="save-flow-version-registry-container" 
class="setting-field">
                 <div id="save-flow-version-registry-combo" 
class="hidden"></div>
                 <div id="save-flow-version-registry" class="hidden"></div>
+                <div id="save-flow-version-label"></div>
             </div>
         </div>
         <div class="setting">

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css
index f8f5177..29a8c0e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css
@@ -216,10 +216,30 @@ div.progress-label {
     Save Flow Version
  */
 
+#save-flow-version-registry-container {
+    display: flex;
+}
+
 #save-flow-version-description-field, #save-flow-version-change-comments {
     height: 85px;
 }
 
+#save-flow-version-registry-combo, #save-flow-version-registry {
+    width: 100%;
+    margin-right: 10px;
+}
+
+#save-flow-version-label {
+    flex: 0 0 30px;
+    background-color: #728E9B;
+    color: #fff;
+    height: 30px;
+    line-height: 30px;
+    text-align: center;
+    border-radius: 50%;
+    padding: 0 1px;
+}
+
 /*
     Import Flow Version
  */
@@ -227,13 +247,22 @@ div.progress-label {
 #import-flow-version-table {
     overflow: hidden;
     position: absolute;
-    top: 202px;
+    top: 190px;
     left: 0px;
     right: 0px;
     bottom: 0px;
     height: 225px;
 }
 
+#change-version-percent-complete {
+    margin-top: 10px;
+    border-radius: 0;
+}
+
+#change-version-percent-complete .ui-progressbar-value {
+    border-radius: 0;
+}
+
 /*
     Variable Registry
  */

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
index caad5bd..204b1d1 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
@@ -425,8 +425,7 @@ text.process-group-name {
 text.version-control {
     font-family: FontAwesome;
     font-size: 18px;
-    fill: rgba(0, 255, 0, 0.65);
-    stroke: rgba(0, 0, 0, 0.65);
+    text-shadow: 0 0 4px rgba(255,255,255,1);
     visibility: hidden;
 }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
index fc930eb..85b499e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/navigation.css
@@ -278,9 +278,16 @@ rect.birdseye-brush {
     top: 8px;
 }
 
-span.breadcrumb-version-control {
-    color: #0f0;
-    text-shadow: 0px 0px 1px #000;
+span.breadcrumb-version-control-green {
+    color: #1a9964;
+}
+
+span.breadcrumb-version-control-red {
+    color: #ba554a;
+}
+
+span.breadcrumb-version-control-gray {
+    color: #666666;
 }
 
 #breadcrumbs-left-border {

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
index 5bf70b1..0b71e3c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-breadcrumbs-controller.js
@@ -97,6 +97,57 @@
             },
 
             /**
+             * Whether this crumb is tracking.
+             *
+             * @param breadcrumbEntity
+             * @returns {*}
+             */
+            isTracking: function (breadcrumbEntity) {
+                return 
nfCommon.isDefinedAndNotNull(breadcrumbEntity.breadcrumb.versionControlInformation);
+            },
+
+            /**
+             * Returns whether the specified version control information is 
current.
+             *
+             * @param breadcrumbEntity
+             * @returns {boolean}
+             */
+            isCurrent: function (breadcrumbEntity) {
+                if 
(nfCommon.isDefinedAndNotNull(breadcrumbEntity.breadcrumb.versionControlInformation))
 {
+                    return 
breadcrumbEntity.breadcrumb.versionControlInformation.current === true;
+                }
+
+                return false;
+            },
+
+            /**
+             * Returns whether the specified version control information is 
current.
+             *
+             * @param versionControlInformation
+             * @returns {boolean}
+             */
+            isModified: function (breadcrumbEntity) {
+                if 
(nfCommon.isDefinedAndNotNull(breadcrumbEntity.breadcrumb.versionControlInformation))
 {
+                    return 
breadcrumbEntity.breadcrumb.versionControlInformation.modified === true;
+                }
+
+                return false;
+            },
+
+            /**
+             * Gets the content for the version control tooltip for the 
specified breadcrumb.
+             *
+             * @param breadcrumbEntity
+             */
+            getVersionControlTooltip: function (breadcrumbEntity) {
+                if 
(nfCommon.isDefinedAndNotNull(breadcrumbEntity.breadcrumb.versionControlInformation))
 {
+                    return 
nfCommon.getVersionControlTooltip(breadcrumbEntity.breadcrumb.versionControlInformation);
+                } else {
+                    return 'This Process Group is not under version control.'
+                }
+            },
+
+            /**
              * Get the breadcrumbs.
              */
             getBreadcrumbs: function () {

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/directives/nf-ng-breadcrumbs-directive.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/directives/nf-ng-breadcrumbs-directive.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/directives/nf-ng-breadcrumbs-directive.js
index cb8a8b2..1a549d7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/directives/nf-ng-breadcrumbs-directive.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/directives/nf-ng-breadcrumbs-directive.js
@@ -40,7 +40,11 @@
                 'breadcrumbs': '=',
                 'clickFunc': '=',
                 'highlightCrumbId': '=',
-                'separatorFunc': '='
+                'separatorFunc': '=',
+                'isTracking': '=',
+                'isCurrent': '=',
+                'isModified': '=',
+                'getVersionControlTooltip': '='
             },
             link: function (scope, element, attrs) {
                 breadcrumbsCtrl.registerMouseWheelEvent(element);

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
index 1652624..4eb5286 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
@@ -81,6 +81,8 @@
         $('#save-flow-version-registry-combo').combo('destroy').hide();
         $('#save-flow-version-bucket-combo').combo('destroy').hide();
 
+        $('#save-flow-version-label').text('');
+
         $('#save-flow-version-registry').text('').hide();
         $('#save-flow-version-bucket').text('').hide();
 
@@ -98,6 +100,8 @@
      * Reset the import flow version dialog.
      */
     var resetImportFlowVersionDialog = function () {
+        $('#import-flow-version-dialog').removeData('pt');
+
         $('#import-flow-version-registry-combo').combo('destroy').hide();
         $('#import-flow-version-bucket-combo').combo('destroy').hide();
         $('#import-flow-version-name-combo').combo('destroy').hide();
@@ -108,11 +112,17 @@
 
         var importFlowVersionGrid = 
$('#import-flow-version-table').data('gridInstance');
         if (nfCommon.isDefinedAndNotNull(importFlowVersionGrid)) {
+            importFlowVersionGrid.setSelectedRows([]);
+            importFlowVersionGrid.resetActiveCell();
+
             var importFlowVersionData = importFlowVersionGrid.getData();
             importFlowVersionData.setItems([]);
         }
 
         
$('#import-flow-version-process-group-id').removeData('versionControlInformation').removeData('revision').text('');
+
+        $('#import-flow-version-container').hide();
+        $('#import-flow-version-label').text('');
     };
 
     /**
@@ -392,9 +402,13 @@
             $('#import-flow-version-dialog').modal('refreshButtons');
         });
         importFlowVersionGrid.onDblClick.subscribe(function (e, args) {
-            changeFlowVersion().done(function () {
-                $('#import-flow-version-dialog').modal('hide');
-            });
+            if ($('#import-flow-version-label').is(':visible')) {
+                changeFlowVersion();
+            } else {
+                importFlowVersion().always(function () {
+                    $('#import-flow-version-dialog').modal('hide');
+                });
+            }
         });
 
         // wire up the dataview to the grid
@@ -417,19 +431,35 @@
      */
     var showImportFlowVersionDialog = function () {
         var pt = $('#new-process-group-dialog').data('pt');
+        $('#import-flow-version-dialog').data('pt', pt);
 
         // update the registry and bucket visibility
-        var registryCombo = $('#import-flow-version-registry-combo').show();
-        var bucketCombo = $('#import-flow-version-bucket-combo').show();
-        $('#import-flow-version-name-combo').show();
+        var registryCombo = 
$('#import-flow-version-registry-combo').combo('destroy').combo({
+            options: [{
+                text: 'Loading registries...',
+                value: null,
+                optionClass: 'unset',
+                disabled: true
+            }]
+        }).show();
+        var bucketCombo = 
$('#import-flow-version-bucket-combo').combo('destroy').combo({
+            options: [{
+                text: 'Loading buckets...',
+                value: null,
+                optionClass: 'unset',
+                disabled: true
+            }]
+        }).show();
+        $('#import-flow-version-name-combo').combo('destroy').combo({
+            options: [{
+                text: 'Loading flows...',
+                value: null,
+                optionClass: 'unset',
+                disabled: true
+            }]
+        }).show();
 
         loadRegistries($('#import-flow-version-dialog'), registryCombo, 
bucketCombo, selectBucketImportVersion).done(function () {
-            // reposition the version table
-            $('#import-flow-version-table').css({
-                'top': '202px',
-                'height': '225px'
-            });
-
             // show the import dialog
             $('#import-flow-version-dialog').modal('setHeaderText', 'Import 
Version').modal('setButtonModel', [{
                 buttonText: 'Import',
@@ -441,8 +471,7 @@
                 disabled: disableImportOrChangeButton,
                 handler: {
                     click: function () {
-                        importFlowVersion(pt).always(function (response) {
-                            // close the dialog
+                        importFlowVersion().always(function () {
                             $('#import-flow-version-dialog').modal('hide');
                         });
                     }
@@ -599,7 +628,9 @@
     /**
      * Imports the selected flow version.
      */
-    var importFlowVersion = function (pt) {
+    var importFlowVersion = function () {
+        var pt = $('#import-flow-version-dialog').data('pt');
+
         var selectedRegistry =  
$('#import-flow-version-registry-combo').combo('getSelectedOption');
         var selectedBucket =  
$('#import-flow-version-bucket-combo').combo('getSelectedOption');
         var selectedFlow =  
$('#import-flow-version-name-combo').combo('getSelectedOption');
@@ -673,6 +704,8 @@
      */
     var changeFlowVersion = function () {
         var changeTimer = null;
+        var changeRequest = null;
+        var cancelled = false;
 
         var processGroupId = $('#import-flow-version-process-group-id').text();
         var processGroupRevision = 
$('#import-flow-version-process-group-id').data('revision');
@@ -682,7 +715,34 @@
         var selectedVersionIndex = importFlowVersionGrid.getSelectedRows();
         var selectedVersion = 
importFlowVersionGrid.getDataItem(selectedVersionIndex[0]);
 
-        // TODO - introduce dialog to show current state with option to cancel 
once available
+        // update the button model of the change version status dialog
+        $('#change-version-status-dialog').modal('setButtonModel', [{
+            buttonText: 'Stop',
+            color: {
+                base: '#728E9B',
+                hover: '#004849',
+                text: '#ffffff'
+            },
+            handler: {
+                click: function () {
+                    cancelled = true;
+
+                    $('#change-version-status-dialog').modal('setButtonModel', 
[]);
+
+                    // we are waiting for the next poll attempt
+                    if (changeTimer !== null) {
+                        // cancel it
+                        clearTimeout(changeTimer);
+
+                        // cancel the change request
+                        completeChangeRequest();
+                    }
+                }
+            }
+        }]);
+
+        // hide the import dialog immediately
+        $('#import-flow-version-dialog').modal('hide');
 
         var submitChangeRequest = function () {
             var changeVersionRequest = {
@@ -706,69 +766,116 @@
                 url: '../nifi-api/versions/update-requests/process-groups/' + 
encodeURIComponent(processGroupId),
                 dataType: 'json',
                 contentType: 'application/json'
-            }).done(function (response) {
-                console.log(response);
+            }).done(function () {
+                // initialize the progress bar value
+                updateProgress(0);
+
+                // show the progress dialog
+                $('#change-version-status-dialog').modal('show');
             }).fail(nfErrorHandler.handleAjaxError);
         };
 
-        var pollChangeRequest = function (changeRequest) {
-            getChangeRequest(changeRequest).done(function (response) {
-                processChangeResponse(response);
-            })
+        var pollChangeRequest = function () {
+            getChangeRequest().done(processChangeResponse);
         };
 
-        var getChangeRequest = function (changeRequest) {
+        var getChangeRequest = function () {
             return $.ajax({
                 type: 'GET',
                 url: changeRequest.uri,
                 dataType: 'json'
-            }).fail(nfErrorHandler.handleAjaxError);
+            
}).fail(completeChangeRequest).fail(nfErrorHandler.handleAjaxError);
         };
 
-        var deleteChangeRequest = function (changeRequest) {
-            var deleteXhr = $.ajax({
-                type: 'DELETE',
-                url: changeRequest.uri,
-                dataType: 'json'
-            }).fail(nfErrorHandler.handleAjaxError);
+        var completeChangeRequest = function () {
+            if (cancelled === true) {
+                // update the message to indicate successful completion
+                $('#change-version-status-message').text('The change version 
request has been cancelled.');
 
-            updateProcessGroup(processGroupId);
+                // update the button model
+                $('#change-version-status-dialog').modal('setButtonModel', [{
+                    buttonText: 'Close',
+                    color: {
+                        base: '#728E9B',
+                        hover: '#004849',
+                        text: '#ffffff'
+                    },
+                    handler: {
+                        click: function () {
+                            $(this).modal('hide');
+                        }
+                    }
+                }]);
+            }
 
-            nfDialog.showOkDialog({
-                headerText: 'Change Version',
-                dialogContent: 'This Process Group version has changed.'
-            });
+            if (nfCommon.isDefinedAndNotNull(changeRequest)) {
+                $.ajax({
+                    type: 'DELETE',
+                    url: changeRequest.uri,
+                    dataType: 'json'
+                }).done(function (response) {
+                    changeRequest = response.request;
 
-            return deleteXhr;
-        };
+                    // update the component that was changing
+                    updateProcessGroup(processGroupId);
 
-        var processChangeResponse = function (response) {
-            var changeRequest = response.request;
+                    if 
(nfCommon.isDefinedAndNotNull(changeRequest.failureReason)) {
+                        // hide the progress dialog
+                        $('#change-version-status-dialog').modal('hide');
 
-            if (nfCommon.isDefinedAndNotNull(changeRequest.failureReason)) {
-                nfDialog.showOkDialog({
-                    headerText: 'Change Version',
-                    dialogContent: 
nfCommon.escapeHtml(changeRequest.failureReason)
+                        nfDialog.showOkDialog({
+                            headerText: 'Change Version',
+                            dialogContent: 
nfCommon.escapeHtml(changeRequest.failureReason)
+                        });
+                    } else {
+                        // update the percent complete
+                        updateProgress(changeRequest.percentCompleted);
+
+                        // update the message to indicate successful completion
+                        $('#change-version-status-message').text('This Process 
Group version has changed.');
+
+                        // update the button model
+                        
$('#change-version-status-dialog').modal('setButtonModel', [{
+                            buttonText: 'Close',
+                            color: {
+                                base: '#728E9B',
+                                hover: '#004849',
+                                text: '#ffffff'
+                            },
+                            handler: {
+                                click: function () {
+                                    $(this).modal('hide');
+                                }
+                            }
+                        }]);
+                    }
                 });
             }
+        };
 
-            if (changeRequest.complete === true) {
-                deleteChangeRequest(changeRequest);
+        var processChangeResponse = function (response) {
+            changeRequest = response.request;
+
+            if (changeRequest.complete === true || cancelled === true) {
+                completeChangeRequest();
             } else {
+                // update the percent complete
+                updateProgress(changeRequest.percentCompleted);
+
+                // update the status of the listing request
+                $('#change-version-status-message').text(changeRequest.state);
+
                 changeTimer = setTimeout(function () {
                     // clear the timer since we've been invoked
                     changeTimer = null;
 
                     // poll revert request
-                    pollChangeRequest(changeRequest);
+                    pollChangeRequest();
                 }, 2000);
             }
         };
 
-        submitChangeRequest().done(function (response) {
-            processChangeResponse(response);
-        });
-
+        submitChangeRequest().done(processChangeResponse);
     };
 
     /**
@@ -826,7 +933,7 @@
      */
     var updateProcessGroup = function (processGroupId) {
         if (nfCanvasUtils.getGroupId() === processGroupId) {
-            // if reverting current PG... reload/refresh this group/canvas
+            // if reverting/changing current PG... reload/refresh this 
group/canvas
 
             // TODO consider implementing this differently
             $.ajax({
@@ -842,6 +949,23 @@
         }
     };
 
+    /**
+     * Updates the progress bar to the specified percent complete.
+     *
+     * @param percentComplete
+     */
+    var updateProgress = function (percentComplete) {
+        // remove existing labels
+        var progressBar = $('#change-version-percent-complete');
+        progressBar.find('div.progress-label').remove();
+        progressBar.find('md-progress-linear').remove();
+
+        // update the progress
+        var label = $('<div 
class="progress-label"></div>').text(percentComplete + '%');
+        (nfNgBridge.injector.get('$compile')($('<md-progress-linear ng-cloak 
ng-value="' + percentComplete + '" class="md-hue-2" md-mode="determinate" 
aria-label="Searching 
Queue"></md-progress-linear>'))(nfNgBridge.rootScope)).appendTo(progressBar);
+        progressBar.append(label);
+    };
+
     return {
         init: function (timeOffset) {
             serverTimeOffset = timeOffset;
@@ -913,6 +1037,18 @@
                 }
             });
 
+            // configure the drop request status dialog
+            $('#change-version-status-dialog').modal({
+                scrollableContentStyle: 'scrollable',
+                headerText: 'Change Flow Version',
+                handler: {
+                    close: function () {
+                        // clear the current button model
+                        
$('#change-version-status-dialog').modal('setButtonModel', []);
+                    }
+                }
+            });
+
             // handle the click for the process group import
             $('#import-process-group-link').on('click', function() {
                 showImportFlowVersionDialog();
@@ -939,26 +1075,50 @@
                         var versionControlInformation = 
groupVersionControlInformation.versionControlInformation;
 
                         // update the registry and bucket visibility
-                        
$('#save-flow-version-registry').text(versionControlInformation.registryId).show();
-                        
$('#save-flow-version-bucket').text(versionControlInformation.bucketId).show();
+                        
$('#save-flow-version-registry').text(versionControlInformation.registryName).show();
+                        
$('#save-flow-version-bucket').text(versionControlInformation.bucketName).show();
+                        
$('#save-flow-version-label').text(versionControlInformation.version + 1);
 
                         
$('#save-flow-version-name').text(versionControlInformation.flowName).show();
-                        $('#save-flow-version-description').text('Flow 
description goes here').show();
+                        
$('#save-flow-version-description').text(versionControlInformation.flowDescription).show();
 
                         // record the versionControlInformation
                         
$('#save-flow-version-process-group-id').data('versionControlInformation', 
versionControlInformation);
 
+                        // reposition the version label
+                        $('#save-flow-version-label').css('margin-top', 
'-15px');
+
                         focusName = false;
                         deferred.resolve();
                     } else {
                         // update the registry and bucket visibility
-                        $('#save-flow-version-registry-combo').show();
-                        $('#save-flow-version-bucket-combo').show();
+                        var registryCombo = 
$('#save-flow-version-registry-combo').combo('destroy').combo({
+                            options: [{
+                                text: 'Loading registries...',
+                                value: null,
+                                optionClass: 'unset',
+                                disabled: true
+                            }]
+                        }).show();
+                        var bucketCombo = 
$('#save-flow-version-bucket-combo').combo('destroy').combo({
+                            options: [{
+                                text: 'Loading buckets...',
+                                value: null,
+                                optionClass: 'unset',
+                                disabled: true
+                            }]
+                        }).show();
+
+                        // set the initial version
+                        $('#save-flow-version-label').text(1);
 
                         $('#save-flow-version-name-field').show();
                         $('#save-flow-version-description-field').show();
 
-                        loadRegistries($('#save-flow-version-dialog'), 
$('#save-flow-version-registry-combo'), $('#save-flow-version-bucket-combo'), 
selectBucketSaveFlowVersion).done(function () {
+                        // reposition the version label
+                        $('#save-flow-version-label').css('margin-top', '0');
+
+                        loadRegistries($('#save-flow-version-dialog'), 
registryCombo, bucketCombo, selectBucketSaveFlowVersion).done(function () {
                             deferred.resolve();
                         }).fail(function () {
                             deferred.reject();
@@ -996,8 +1156,37 @@
                     getVersionControlInformation(processGroupId).done(function 
(response) {
                         if 
(nfCommon.isDefinedAndNotNull(response.versionControlInformation)) {
                             var revertTimer = null;
+                            var revertRequest = null;
+                            var cancelled = false;
+
+                            // update the button model of the revert status 
dialog
+                            
$('#change-version-status-dialog').modal('setButtonModel', [{
+                                buttonText: 'Stop',
+                                color: {
+                                    base: '#728E9B',
+                                    hover: '#004849',
+                                    text: '#ffffff'
+                                },
+                                handler: {
+                                    click: function () {
+                                        cancelled = true;
+
+                                        
$('#change-version-status-dialog').modal('setButtonModel', []);
+
+                                        // we are waiting for the next poll 
attempt
+                                        if (revertTimer !== null) {
+                                            // cancel it
+                                            clearTimeout(revertTimer);
+
+                                            // cancel the revert request
+                                            completeRevertRequest();
+                                        }
+                                    }
+                                }
+                            }]);
 
-                            // TODO - introduce dialog to show current state 
once available
+                            // hide the import dialog immediately
+                            $('#import-flow-version-dialog').modal('hide');
 
                             var submitRevertRequest = function () {
                                 var revertFlowVersionRequest = {
@@ -1015,66 +1204,116 @@
                                     url: 
'../nifi-api/versions/revert-requests/process-groups/' + 
encodeURIComponent(processGroupId),
                                     dataType: 'json',
                                     contentType: 'application/json'
+                                }).done(function () {
+                                    // initialize the progress bar value
+                                    updateProgress(0);
+
+                                    // show the progress dialog
+                                    
$('#change-version-status-dialog').modal('show');
                                 }).fail(nfErrorHandler.handleAjaxError);
                             };
 
-                            var pollRevertRequest = function (revertRequest) {
-                                getRevertRequest(revertRequest).done(function 
(response) {
-                                    processRevertResponse(response);
-                                })
+                            var pollRevertRequest = function () {
+                                getRevertRequest().done(processRevertResponse);
                             };
 
-                            var getRevertRequest = function (revertRequest) {
+                            var getRevertRequest = function () {
                                 return $.ajax({
                                     type: 'GET',
                                     url: revertRequest.uri,
                                     dataType: 'json'
-                                }).fail(nfErrorHandler.handleAjaxError);
+                                
}).fail(completeRevertRequest).fail(nfErrorHandler.handleAjaxError);
                             };
 
-                            var deleteRevertRequest = function (revertRequest) 
{
-                                var deleteXhr = $.ajax({
-                                    type: 'DELETE',
-                                    url: revertRequest.uri,
-                                    dataType: 'json'
-                                }).fail(nfErrorHandler.handleAjaxError);
-
-                                updateProcessGroup(processGroupId);
-
-                                nfDialog.showOkDialog({
-                                    headerText: 'Revert Changes',
-                                    dialogContent: 'This Process Group has 
been reverted.'
-                                });
+                            var completeRevertRequest = function () {
+                                if (cancelled === true) {
+                                    // update the message to indicate 
successful completion
+                                    
$('#change-version-status-message').text('The revert request has been 
cancelled.');
+
+                                    // update the button model
+                                    
$('#change-version-status-dialog').modal('setButtonModel', [{
+                                        buttonText: 'Close',
+                                        color: {
+                                            base: '#728E9B',
+                                            hover: '#004849',
+                                            text: '#ffffff'
+                                        },
+                                        handler: {
+                                            click: function () {
+                                                $(this).modal('hide');
+                                            }
+                                        }
+                                    }]);
+                                }
 
-                                return deleteXhr;
+                                if 
(nfCommon.isDefinedAndNotNull(revertRequest)) {
+                                    $.ajax({
+                                        type: 'DELETE',
+                                        url: revertRequest.uri,
+                                        dataType: 'json'
+                                    }).done(function (response) {
+                                        revertRequest = response.request;
+
+                                        // update the component that was 
changing
+                                        updateProcessGroup(processGroupId);
+
+                                        if 
(nfCommon.isDefinedAndNotNull(revertRequest.failureReason)) {
+                                            // hide the progress dialog
+                                            
$('#change-version-status-dialog').modal('hide');
+
+                                            nfDialog.showOkDialog({
+                                                headerText: 'Revert Local 
Changes',
+                                                dialogContent: 
nfCommon.escapeHtml(changeRequest.failureReason)
+                                            });
+                                        } else {
+                                            // update the percent complete
+                                            
updateProgress(revertRequest.percentCompleted);
+
+                                            // update the message to indicate 
successful completion
+                                            
$('#change-version-status-message').text('This Process Group version has 
changed.');
+
+                                            // update the button model
+                                            
$('#change-version-status-dialog').modal('setButtonModel', [{
+                                                buttonText: 'Close',
+                                                color: {
+                                                    base: '#728E9B',
+                                                    hover: '#004849',
+                                                    text: '#ffffff'
+                                                },
+                                                handler: {
+                                                    click: function () {
+                                                        $(this).modal('hide');
+                                                    }
+                                                }
+                                            }]);
+                                        }
+                                    });
+                                }
                             };
 
                             var processRevertResponse = function (response) {
-                                var revertRequest = response.request;
-
-                                if 
(nfCommon.isDefinedAndNotNull(revertRequest.failureReason)) {
-                                    nfDialog.showOkDialog({
-                                        headerText: 'Revert Changes',
-                                        dialogContent: 
nfCommon.escapeHtml(revertRequest.failureReason)
-                                    });
-                                }
+                                revertRequest = response.request;
 
-                                if (revertRequest.complete === true) {
-                                    deleteRevertRequest(revertRequest);
+                                if (revertRequest.complete === true || 
cancelled === true) {
+                                    completeRevertRequest();
                                 } else {
+                                    // update the percent complete
+                                    
updateProgress(revertRequest.percentCompleted);
+
+                                    // update the status of the revert request
+                                    
$('#change-version-status-message').text(revertRequest.state);
+
                                     revertTimer = setTimeout(function () {
                                         // clear the timer since we've been 
invoked
                                         revertTimer = null;
 
                                         // poll revert request
-                                        pollRevertRequest(revertRequest);
+                                        pollRevertRequest();
                                     }, 2000);
                                 }
                             };
 
-                            submitRevertRequest().done(function (response) {
-                                processRevertResponse(response);
-                            });
+                            submitRevertRequest().done(processRevertResponse);
                         } else {
                             nfDialog.showOkDialog({
                                 headerText: 'Revert Changes',
@@ -1098,9 +1337,13 @@
                         var versionControlInformation = 
groupVersionControlInformation.versionControlInformation;
 
                         // update the registry and bucket visibility
-                        
$('#import-flow-version-registry').text(versionControlInformation.registryId).show();
-                        
$('#import-flow-version-bucket').text(versionControlInformation.bucketId).show();
-                        
$('#import-flow-version-name').text(versionControlInformation.flowId).show();
+                        
$('#import-flow-version-registry').text(versionControlInformation.registryName).show();
+                        
$('#import-flow-version-bucket').text(versionControlInformation.bucketName).show();
+                        
$('#import-flow-version-name').text(versionControlInformation.flowName).show();
+
+                        // show the current version information
+                        $('#import-flow-version-container').show();
+                        
$('#import-flow-version-label').text(versionControlInformation.version);
 
                         // record the versionControlInformation
                         
$('#import-flow-version-process-group-id').data('versionControlInformation', 
versionControlInformation).data('revision', 
groupVersionControlInformation.processGroupRevision).text(processGroupId);
@@ -1126,12 +1369,6 @@
                     }
                 }).fail(nfErrorHandler.handleAjaxError);
             }).done(function () {
-                // reposition the version table
-                $('#import-flow-version-table').css({
-                    'top': '150px',
-                    'height': '277px'
-                });
-
                 // show the dialog
                 $('#import-flow-version-dialog').modal('setHeaderText', 
'Change Version').modal('setButtonModel', [{
                     buttonText: 'Change',
@@ -1143,9 +1380,7 @@
                     disabled: disableImportOrChangeButton,
                     handler: {
                         click: function () {
-                            changeFlowVersion().done(function () {
-                                $('#import-flow-version-dialog').modal('hide');
-                            });
+                            changeFlowVersion();
                         }
                     }
                 }, {

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
index 17bb069..7a61363 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
@@ -99,6 +99,15 @@
     };
 
     /**
+     * Determines whether the specified process group is under version control.
+     *
+     * @param d
+     */
+    var isUnderVersionControl = function (d) {
+        return 
nfCommon.isDefinedAndNotNull(d.component.versionControlInformation);
+    };
+
+    /**
      * Selects the process group elements against the current process group 
map.
      */
     var select = function () {
@@ -183,11 +192,10 @@
         // process group name
         processGroup.append('text')
             .attr({
-                'x': 3,
-                'y': 17,
+                'x': 10,
+                'y': 21,
                 'class': 'version-control'
-            })
-            .text('\uf00c');
+            });
 
         // always support selecting and navigation
         processGroup.on('dblclick', function (d) {
@@ -848,6 +856,77 @@
                     });
 
                 if (processGroupData.permissions.canRead) {
+                    // update version control information
+                    var versionControl = 
processGroup.select('text.version-control')
+                        .style({
+                            'visibility': 
isUnderVersionControl(processGroupData) ? 'visible' : 'hidden',
+                            'fill': function () {
+                                if (isUnderVersionControl(processGroupData)) {
+                                    var modified = 
processGroupData.component.versionControlInformation.modified;
+                                    var current = 
processGroupData.component.versionControlInformation.current;
+                                    if (modified === true && current === 
false) {
+                                        return '#BA554A';
+                                    } else if (current === false) {
+                                        return '#BA554A';
+                                    } else if (modified === true) {
+                                        return '#666666';
+                                    } else {
+                                        return '#1A9964';
+                                    }
+                                } else {
+                                    return '#000';
+                                }
+                            }
+                        })
+                        .text(function () {
+                            if (isUnderVersionControl(processGroupData)) {
+                                var modified = 
processGroupData.component.versionControlInformation.modified;
+                                var current = 
processGroupData.component.versionControlInformation.current;
+                                if (modified === true && current === false) {
+                                    return '\uf06a';
+                                } else if (current === false) {
+                                    return '\uf0aa';
+                                } else if (modified === true) {
+                                    return '\uf069';
+                                } else {
+                                    return '\uf00c';
+                                }
+                            } else {
+                                return '';
+                            }
+                        }).each(function () {
+                            // get the tip
+                            var tip = d3.select('#version-control-tip-' + 
processGroupData.id);
+
+                            // if there are validation errors generate a 
tooltip
+                            if (isUnderVersionControl(processGroupData)) {
+                                // create the tip if necessary
+                                if (tip.empty()) {
+                                    tip = 
d3.select('#process-group-tooltips').append('div')
+                                        .attr('id', function () {
+                                            return 'version-control-tip-' + 
processGroupData.id;
+                                        })
+                                        .attr('class', 'tooltip nifi-tooltip');
+                                }
+
+                                // update the tip
+                                tip.html(function () {
+                                    var vci = 
processGroupData.component.versionControlInformation;
+                                    var versionControlTip = 
$('<div></div>').text('Tracking to "' + vci.flowName + '" version ' + 
vci.version + ' in "' + vci.registryName + ' - ' + vci.bucketName + '"');
+                                    var versionControlStateTip = 
$('<div></div>').text(nfCommon.getVersionControlTooltip(vci));
+                                    return 
$('<div></div>').append(versionControlTip).append('<br/>').append(versionControlStateTip).html();
+                                });
+
+                                // add the tooltip
+                                nfCanvasUtils.canvasTooltip(tip, 
d3.select(this));
+                            } else {
+                                // remove the tip if necessary
+                                if (!tip.empty()) {
+                                    tip.remove();
+                                }
+                            }
+                        });
+
                     // update the process group comments
                     details.select('text.process-group-comments')
                         .each(function (d) {
@@ -866,6 +945,25 @@
 
                     // update the process group name
                     processGroup.select('text.process-group-name')
+                        .attr({
+                            'x': function () {
+                                if (isUnderVersionControl(processGroupData)) {
+                                    var versionControlX = 
parseInt(versionControl.attr('x'), 10);
+                                    return versionControlX + 
Math.round(versionControl.node().getComputedTextLength()) + 
CONTENTS_VALUE_SPACER;
+                                } else {
+                                    return 10;
+                                }
+                            },
+                            'width': function () {
+                                if (isUnderVersionControl(processGroupData)) {
+                                    var versionControlX = 
parseInt(versionControl.attr('x'), 10);
+                                    var processGroupNameX = 
parseInt(d3.select(this).attr('x'), 10);
+                                    return 316 - (processGroupNameX - 
versionControlX);
+                                } else {
+                                    return 316;
+                                }
+                            }
+                        })
                         .each(function (d) {
                             var processGroupName = d3.select(this);
 
@@ -874,21 +972,25 @@
 
                             // apply ellipsis to the process group name as 
necessary
                             nfCanvasUtils.ellipsis(processGroupName, 
d.component.name);
-                        }).append('title').text(function (d) {
-                        return d.component.name;
-                    });
-
-                    // update version control information
-                    
processGroup.select('text.version-control').style('visibility', 
nfCommon.isDefinedAndNotNull(processGroupData.component.versionControlInformation)
 ? 'visible' : 'hidden');
+                        })
+                        .append('title')
+                        .text(function (d) {
+                            return d.component.name;
+                        });
                 } else {
+                    // update version control information
+                    
processGroup.select('text.version-control').style('visibility', false).text('');
+
                     // clear the process group comments
                     details.select('text.process-group-comments').text(null);
 
                     // clear the process group name
-                    processGroup.select('text.process-group-name').text(null);
-
-                    // update version control information
-                    
processGroup.select('text.version-control').style('visibility', false);
+                    processGroup.select('text.process-group-name')
+                        .attr({
+                            'x': 10,
+                            'width': 316
+                        })
+                        .text(null);
                 }
 
                 // populate the stats
@@ -1033,6 +1135,7 @@
         removed.each(function (d) {
             // remove any associated tooltips
             $('#bulletin-tip-' + d.id).remove();
+            $('#version-control-tip-' + d.id).remove();
         });
     };
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 5619bc3..b3671a7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -420,6 +420,25 @@
         },
 
         /**
+         * Gets the version control tooltip.
+         *
+         * @param versionControlInformation
+         */
+        getVersionControlTooltip: function (versionControlInformation) {
+            var modified = versionControlInformation.modified;
+            var current = versionControlInformation.current;
+            if (modified === true && current === false) {
+                return 'Local changes have been made and a newer version of 
this flow is available';
+            } else if (current === false) {
+                return 'A newer version of this flow is available';
+            } else if (modified === true) {
+                return 'Local changes have been made';
+            } else {
+                return 'Flow version is current';
+            }
+        },
+
+        /**
          * Formats the class name of this component.
          *
          * @param dataContext component datum

http://git-wip-us.apache.org/repos/asf/nifi/blob/d6e54f19/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
index a8b8579..3e5d87b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
@@ -22,7 +22,14 @@ limitations under the License.
                 <span ng-if="separatorFunc(crumb.parentBreadcrumb)" 
style="margin: 0 12px;">
                     &raquo;
                 </span>
-                <span 
ng-if="separatorFunc(crumb.breadcrumb.versionControlInformation)" 
class="breadcrumb-version-control fa fa-check" style="margin: 0 6px;"></span>
+                <span ng-if="isTracking(crumb) && isCurrent(crumb) && 
!isModified(crumb)" title="{{getVersionControlTooltip(crumb)}}"
+                      class="breadcrumb-version-control-green fa fa-check" 
style="margin: 0 6px;"></span>
+                <span ng-if="isTracking(crumb) && isCurrent(crumb) && 
isModified(crumb)" title="{{getVersionControlTooltip(crumb)}}"
+                      class="breadcrumb-version-control-gray fa fa-asterisk" 
style="margin: 0 6px;"></span>
+                <span ng-if="isTracking(crumb) && !isCurrent(crumb) && 
!isModified(crumb)" title="{{getVersionControlTooltip(crumb)}}"
+                      class="breadcrumb-version-control-red fa 
fa-arrow-circle-up" style="margin: 0 6px;"></span>
+                <span ng-if="isTracking(crumb) && !isCurrent(crumb) && 
isModified(crumb)" title="{{getVersionControlTooltip(crumb)}}"
+                      class="breadcrumb-version-control-red fa 
fa-exclamation-circle" style="margin: 0 6px;"></span>
                 <span class="link"
                       ng-class="(highlightCrumbId === crumb.id) ? 'link-bold' 
: ''"
                       ng-click="clickFunc(crumb.id)">

Reply via email to