mirror of https://github.com/apache/nifi.git
NIFI-4436:
- Clearing bucket/flow/versions when changing the selected registry/bucket. - Using the versioned flow to get the group name when importing. - Adding menu items for viewing local changes. - Showing local changes during revert request.
This commit is contained in:
parent
f6cc5b6cdc
commit
3d8b1e4890
|
@ -17,12 +17,11 @@
|
|||
|
||||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@XmlType(name = "componentDifference")
|
||||
public class ComponentDifferenceDTO {
|
||||
|
@ -30,7 +29,7 @@ public class ComponentDifferenceDTO {
|
|||
private String componentId;
|
||||
private String componentName;
|
||||
private String processGroupId;
|
||||
private List<String> differences;
|
||||
private List<DifferenceDTO> differences;
|
||||
|
||||
@ApiModelProperty("The type of component")
|
||||
public String getComponentType() {
|
||||
|
@ -69,11 +68,11 @@ public class ComponentDifferenceDTO {
|
|||
}
|
||||
|
||||
@ApiModelProperty("The differences in the component between the two flows")
|
||||
public List<String> getDifferences() {
|
||||
public List<DifferenceDTO> getDifferences() {
|
||||
return differences;
|
||||
}
|
||||
|
||||
public void setDifferences(List<String> differences) {
|
||||
public void setDifferences(List<DifferenceDTO> differences) {
|
||||
this.differences = differences;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
@XmlType(name = "difference")
|
||||
public class DifferenceDTO {
|
||||
private String differenceType;
|
||||
private String difference;
|
||||
|
||||
@ApiModelProperty("The type of difference")
|
||||
public String getDifferenceType() {
|
||||
return differenceType;
|
||||
}
|
||||
|
||||
public void setDifferenceType(String differenceType) {
|
||||
this.differenceType = differenceType;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Description of the difference")
|
||||
public String getDifference() {
|
||||
return difference;
|
||||
}
|
||||
|
||||
public void setDifference(String difference) {
|
||||
this.difference = difference;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,57 +16,12 @@
|
|||
*/
|
||||
package org.apache.nifi.web.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
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.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
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.AuthorizableLookup;
|
||||
import org.apache.nifi.authorization.AuthorizeAccess;
|
||||
|
@ -156,12 +111,55 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
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.servlet.http.HttpServletRequest;
|
||||
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.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* RESTful endpoint for managing a Group.
|
||||
|
@ -341,9 +339,7 @@ public class ProcessGroupResource extends ApplicationResource {
|
|||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
final ProcessGroupAuthorizable groupAuthorizable = lookup.getProcessGroup(groupId);
|
||||
final Authorizable processGroup = groupAuthorizable.getAuthorizable();
|
||||
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
|
||||
super.authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.READ, false, false, true, false);
|
||||
authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.READ, false, false, true, false);
|
||||
});
|
||||
|
||||
final FlowComparisonEntity entity = serviceFacade.getLocalModifications(groupId);
|
||||
|
@ -1625,6 +1621,11 @@ public class ProcessGroupResource extends ApplicationResource {
|
|||
}
|
||||
}
|
||||
|
||||
// if the group name isn't specified, ensure the group is being imported from version control
|
||||
if (StringUtils.isBlank(requestProcessGroupEntity.getComponent().getName()) && requestProcessGroupEntity.getComponent().getVersionControlInformation() == null) {
|
||||
throw new IllegalArgumentException("The group name is required when the group is not imported from version control.");
|
||||
}
|
||||
|
||||
if (requestProcessGroupEntity.getComponent().getParentGroupId() != null && !groupId.equals(requestProcessGroupEntity.getComponent().getParentGroupId())) {
|
||||
throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s",
|
||||
requestProcessGroupEntity.getComponent().getParentGroupId(), groupId));
|
||||
|
@ -1688,15 +1689,22 @@ public class ProcessGroupResource extends ApplicationResource {
|
|||
serviceFacade.verifyComponentTypes(versionedFlowSnapshot.getFlowContents());
|
||||
}
|
||||
},
|
||||
processGroupGroupEntity -> {
|
||||
processGroupEntity -> {
|
||||
final ProcessGroupDTO processGroup = processGroupEntity.getComponent();
|
||||
|
||||
// set the processor id as appropriate
|
||||
processGroupGroupEntity.getComponent().setId(generateUuid());
|
||||
processGroup.setId(generateUuid());
|
||||
|
||||
// ensure the group name comes from the versioned flow
|
||||
final VersionedFlowSnapshot flowSnapshot = processGroupEntity.getVersionedFlowSnapshot();
|
||||
if (flowSnapshot != null && StringUtils.isNotBlank(flowSnapshot.getFlowContents().getName()) && StringUtils.isBlank(processGroup.getName())) {
|
||||
processGroup.setName(flowSnapshot.getFlowContents().getName());
|
||||
}
|
||||
|
||||
// create the process group contents
|
||||
final Revision revision = getRevision(processGroupGroupEntity, processGroupGroupEntity.getComponent().getId());
|
||||
ProcessGroupEntity entity = serviceFacade.createProcessGroup(revision, groupId, processGroupGroupEntity.getComponent());
|
||||
final Revision revision = getRevision(processGroupEntity, processGroup.getId());
|
||||
ProcessGroupEntity entity = serviceFacade.createProcessGroup(revision, groupId, processGroup);
|
||||
|
||||
final VersionedFlowSnapshot flowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
|
||||
if (flowSnapshot != null) {
|
||||
final RevisionDTO revisionDto = entity.getRevision();
|
||||
final String newGroupId = entity.getComponent().getId();
|
||||
|
|
|
@ -16,33 +16,6 @@
|
|||
*/
|
||||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.action.Action;
|
||||
|
@ -215,6 +188,32 @@ import org.apache.nifi.web.api.entity.VariableEntity;
|
|||
import org.apache.nifi.web.controller.ControllerFacade;
|
||||
import org.apache.nifi.web.revision.RevisionManager;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class DtoFactory {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
@ -2181,15 +2180,20 @@ public final class DtoFactory {
|
|||
|
||||
|
||||
public Set<ComponentDifferenceDTO> createComponentDifferenceDtos(final FlowComparison comparison) {
|
||||
final Map<ComponentDifferenceDTO, List<String>> differencesByComponent = new HashMap<>();
|
||||
final Map<ComponentDifferenceDTO, List<DifferenceDTO>> differencesByComponent = new HashMap<>();
|
||||
|
||||
for (final FlowDifference difference : comparison.getDifferences()) {
|
||||
final ComponentDifferenceDTO componentDiff = createComponentDifference(difference);
|
||||
final List<String> differences = differencesByComponent.computeIfAbsent(componentDiff, key -> new ArrayList<>());
|
||||
differences.add(difference.getDescription());
|
||||
final List<DifferenceDTO> differences = differencesByComponent.computeIfAbsent(componentDiff, key -> new ArrayList<>());
|
||||
|
||||
final DifferenceDTO dto = new DifferenceDTO();
|
||||
dto.setDifferenceType(difference.getDifferenceType().getDescription());
|
||||
dto.setDifference(difference.getDescription());
|
||||
|
||||
differences.add(dto);
|
||||
}
|
||||
|
||||
for (final Map.Entry<ComponentDifferenceDTO, List<String>> entry : differencesByComponent.entrySet()) {
|
||||
for (final Map.Entry<ComponentDifferenceDTO, List<DifferenceDTO>> entry : differencesByComponent.entrySet()) {
|
||||
entry.getKey().setDifferences(entry.getValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,9 @@ public class StandardProcessGroupDAO extends ComponentDAO implements ProcessGrou
|
|||
|
||||
// create the process group
|
||||
ProcessGroup group = flowController.createProcessGroup(processGroup.getId());
|
||||
group.setName(processGroup.getName());
|
||||
if (processGroup.getName() != null) {
|
||||
group.setName(processGroup.getName());
|
||||
}
|
||||
if (processGroup.getPosition() != null) {
|
||||
group.setPosition(new Position(processGroup.getPosition().getX(), processGroup.getPosition().getY()));
|
||||
}
|
||||
|
|
|
@ -117,6 +117,8 @@
|
|||
<jsp:include page="/WEB-INF/partials/canvas/connections-dialog.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/save-flow-version-dialog.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/import-flow-version-dialog.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/revert-local-changes-dialog.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/show-local-changes-dialog.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/registry-configuration-dialog.jsp"/>
|
||||
<div id="canvas-container" class="unselectable"></div>
|
||||
<div id="canvas-tooltips">
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<%--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
--%>
|
||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||
<div id="revert-local-changes-dialog" layout="column" class="hidden large-dialog">
|
||||
<div class="dialog-content">
|
||||
<div class="setting">
|
||||
<div class="setting-field">
|
||||
Are you sure you want to revert changes? All flow configuration changes detailed below will be reverted to the last version.
|
||||
</div>
|
||||
</div>
|
||||
<span id="revert-local-changes-process-group-id" class="hidden"></span>
|
||||
<div id="revert-local-changes-filter-controls">
|
||||
<div id="revert-local-changes-filter-status" class="filter-status">
|
||||
Displaying <span id="displayed-revert-local-changes-entries"></span> of <span id="total-revert-local-changes-entries"></span>
|
||||
</div>
|
||||
<div id="revert-local-changes-filter-container">
|
||||
<input type="text" id="revert-local-changes-filter" placeholder="Filter"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="revert-local-changes-table"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,35 @@
|
|||
<%--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
--%>
|
||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||
<div id="show-local-changes-dialog" layout="column" class="hidden large-dialog">
|
||||
<div class="dialog-content">
|
||||
<div class="setting">
|
||||
<div class="setting-field">
|
||||
The following changes have been made to the flow since the last version.
|
||||
</div>
|
||||
</div>
|
||||
<div id="show-local-changes-filter-controls">
|
||||
<div id="show-local-changes-filter-status" class="filter-status">
|
||||
Displaying <span id="displayed-show-local-changes-entries"></span> of <span id="total-show-local-changes-entries"></span>
|
||||
</div>
|
||||
<div id="show-local-changes-filter-container">
|
||||
<input type="text" id="show-local-changes-filter" placeholder="Filter"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="show-local-changes-table"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -263,6 +263,23 @@ div.progress-label {
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Local changes
|
||||
*/
|
||||
|
||||
#revert-local-changes-table, #show-local-changes-table {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
height: 225px;
|
||||
}
|
||||
|
||||
#revert-local-changes-filter, #show-local-changes-filter {
|
||||
width: 173px;
|
||||
}
|
||||
|
||||
/*
|
||||
Variable Registry
|
||||
*/
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
'nf.Graph',
|
||||
'nf.CanvasUtils',
|
||||
'nf.ErrorHandler',
|
||||
'nf.Common'],
|
||||
function ($, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon) {
|
||||
return (nf.ng.GroupComponent = factory($, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon));
|
||||
'nf.Common',
|
||||
'nf.Dialog'],
|
||||
function ($, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon, nfDialog) {
|
||||
return (nf.ng.GroupComponent = factory($, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon, nfDialog));
|
||||
});
|
||||
} else if (typeof exports === 'object' && typeof module === 'object') {
|
||||
module.exports = (nf.ng.GroupComponent =
|
||||
|
@ -37,7 +38,8 @@
|
|||
require('nf.Graph'),
|
||||
require('nf.CanvasUtils'),
|
||||
require('nf.ErrorHandler'),
|
||||
require('nf.Common')));
|
||||
require('nf.Common'),
|
||||
require('nf.Dialog')));
|
||||
} else {
|
||||
nf.ng.GroupComponent = factory(root.$,
|
||||
root.nf.Client,
|
||||
|
@ -45,9 +47,10 @@
|
|||
root.nf.Graph,
|
||||
root.nf.CanvasUtils,
|
||||
root.nf.ErrorHandler,
|
||||
root.nf.Common);
|
||||
root.nf.Common,
|
||||
root.nf.Dialog);
|
||||
}
|
||||
}(this, function ($, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon) {
|
||||
}(this, function ($, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfCommon, nfDialog) {
|
||||
'use strict';
|
||||
|
||||
return function (serviceProvider) {
|
||||
|
@ -236,12 +239,22 @@
|
|||
// hide the dialog
|
||||
groupComponent.modal.hide();
|
||||
|
||||
// create the group and resolve the deferred accordingly
|
||||
createGroup(groupName, pt).done(function (response) {
|
||||
deferred.resolve(response.component);
|
||||
}).fail(function () {
|
||||
// ensure the group name is specified
|
||||
if (nfCommon.isBlank(groupName)) {
|
||||
nfDialog.showOkDialog({
|
||||
headerText: 'Create Process Group',
|
||||
dialogContent: 'The group name is required.'
|
||||
});
|
||||
|
||||
deferred.reject();
|
||||
});
|
||||
} else {
|
||||
// create the group and resolve the deferred accordingly
|
||||
createGroup(groupName, pt).done(function (response) {
|
||||
deferred.resolve(response.component);
|
||||
}).fail(function () {
|
||||
deferred.reject();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
groupComponent.modal.update('setButtonModel', [{
|
||||
|
|
|
@ -1265,6 +1265,18 @@
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows local changes.
|
||||
*/
|
||||
showLocalChanges: function (selection) {
|
||||
if (selection.empty()) {
|
||||
nfFlowVersion.showLocalChanges(nfCanvasUtils.getGroupId());
|
||||
} else if (selection.size() === 1) {
|
||||
var selectionData = selection.datum();
|
||||
nfFlowVersion.showLocalChanges(selectionData.id)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the flow version.
|
||||
*/
|
||||
|
|
|
@ -427,6 +427,123 @@
|
|||
return nfCommon.isUndefinedOrNull(processGroupData.component.versionControlInformation);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the process group support supports commit.
|
||||
*
|
||||
* @param selection
|
||||
* @returns {boolean}
|
||||
*/
|
||||
var supportsCommitFlowVersion = function (selection) {
|
||||
// ensure this selection supports flow versioning above
|
||||
if (supportsFlowVersioning(selection) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var versionControlInformation;
|
||||
if (selection.empty()) {
|
||||
// check bread crumbs for version control information in the current group
|
||||
var breadcrumbEntities = nfNgBridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
|
||||
if (breadcrumbEntities.length > 0) {
|
||||
var breadcrumbEntity = breadcrumbEntities[breadcrumbEntities.length - 1];
|
||||
if (breadcrumbEntity.permissions.canRead) {
|
||||
versionControlInformation = breadcrumbEntity.breadcrumb.versionControlInformation;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
var processGroupData = selection.datum();
|
||||
versionControlInformation = processGroupData.component.versionControlInformation;
|
||||
}
|
||||
|
||||
if (nfCommon.isUndefinedOrNull(versionControlInformation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check the selection for version control information
|
||||
return versionControlInformation.current === true && versionControlInformation.modified === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the process group supports revert local changes.
|
||||
*
|
||||
* @param selection
|
||||
* @returns {boolean}
|
||||
*/
|
||||
var hasLocalChanges = function (selection) {
|
||||
// ensure this selection supports flow versioning above
|
||||
if (supportsFlowVersioning(selection) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var versionControlInformation;
|
||||
if (selection.empty()) {
|
||||
// check bread crumbs for version control information in the current group
|
||||
var breadcrumbEntities = nfNgBridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
|
||||
if (breadcrumbEntities.length > 0) {
|
||||
var breadcrumbEntity = breadcrumbEntities[breadcrumbEntities.length - 1];
|
||||
if (breadcrumbEntity.permissions.canRead) {
|
||||
versionControlInformation = breadcrumbEntity.breadcrumb.versionControlInformation;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
var processGroupData = selection.datum();
|
||||
versionControlInformation = processGroupData.component.versionControlInformation;
|
||||
}
|
||||
|
||||
if (nfCommon.isUndefinedOrNull(versionControlInformation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check the selection for version control information
|
||||
return versionControlInformation.modified === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the process group supports changing the flow version.
|
||||
*
|
||||
* @param selection
|
||||
* @returns {boolean}
|
||||
*/
|
||||
var supportsChangeFlowVersion = function (selection) {
|
||||
// ensure this selection supports flow versioning above
|
||||
if (supportsFlowVersioning(selection) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var versionControlInformation;
|
||||
if (selection.empty()) {
|
||||
// check bread crumbs for version control information in the current group
|
||||
var breadcrumbEntities = nfNgBridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
|
||||
if (breadcrumbEntities.length > 0) {
|
||||
var breadcrumbEntity = breadcrumbEntities[breadcrumbEntities.length - 1];
|
||||
if (breadcrumbEntity.permissions.canRead) {
|
||||
versionControlInformation = breadcrumbEntity.breadcrumb.versionControlInformation;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
var processGroupData = selection.datum();
|
||||
versionControlInformation = processGroupData.component.versionControlInformation;
|
||||
}
|
||||
|
||||
if (nfCommon.isUndefinedOrNull(versionControlInformation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check the selection for version control information
|
||||
return versionControlInformation.modified === false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines whether the current selection supports stopping flow versioning.
|
||||
*
|
||||
|
@ -640,9 +757,10 @@
|
|||
{id: 'version-menu-item', groupMenuItem: {clazz: 'fa', text: 'Version'}, menuItems: [
|
||||
{id: 'start-version-control-menu-item', condition: supportsStartFlowVersioning, menuItem: {clazz: 'fa fa-upload', text: 'Start version control', action: 'saveFlowVersion'}},
|
||||
{separator: true},
|
||||
{id: 'commit-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa fa-upload', text: 'Commit local changes', action: 'saveFlowVersion'}},
|
||||
{id: 'revert-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa fa-undo', text: 'Revert local changes', action: 'revertLocalChanges'}},
|
||||
{id: 'change-version-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa', text: 'Change version', action: 'changeFlowVersion'}},
|
||||
{id: 'commit-menu-item', condition: supportsCommitFlowVersion, menuItem: {clazz: 'fa fa-upload', text: 'Commit local changes', action: 'saveFlowVersion'}},
|
||||
{id: 'local-changes-menu-item', condition: hasLocalChanges, menuItem: {clazz: 'fa', text: 'Show local changes', action: 'showLocalChanges'}},
|
||||
{id: 'revert-menu-item', condition: hasLocalChanges, menuItem: {clazz: 'fa fa-undo', text: 'Revert local changes', action: 'revertLocalChanges'}},
|
||||
{id: 'change-version-menu-item', condition: supportsChangeFlowVersion, menuItem: {clazz: 'fa', text: 'Change version', action: 'changeFlowVersion'}},
|
||||
{separator: true},
|
||||
{id: 'stop-version-control-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa', text: 'Stop version control', action: 'stopVersionControl'}}
|
||||
]},
|
||||
|
|
|
@ -30,10 +30,11 @@
|
|||
'nf.Client',
|
||||
'nf.CanvasUtils',
|
||||
'nf.ProcessGroup',
|
||||
'nf.ProcessGroupConfiguration',
|
||||
'nf.Graph',
|
||||
'nf.Birdseye'],
|
||||
function ($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfGraph, nfBirdseye) {
|
||||
return (nf.FlowVersion = factory($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfGraph, nfBirdseye));
|
||||
function ($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfProcessGroupConfiguration, nfGraph, nfBirdseye) {
|
||||
return (nf.FlowVersion = factory($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfProcessGroupConfiguration, nfGraph, nfBirdseye));
|
||||
});
|
||||
} else if (typeof exports === 'object' && typeof module === 'object') {
|
||||
module.exports = (nf.FlowVerison =
|
||||
|
@ -45,6 +46,7 @@
|
|||
require('nf.Client'),
|
||||
require('nf.CanvasUtils'),
|
||||
require('nf.ProcessGroup'),
|
||||
require('nf.ProcessGroupConfiguration'),
|
||||
require('nf.Graph'),
|
||||
require('nf.Birdseye')));
|
||||
} else {
|
||||
|
@ -56,10 +58,11 @@
|
|||
root.nf.Client,
|
||||
root.nf.CanvasUtils,
|
||||
root.nf.ProcessGroup,
|
||||
root.nf.ProcessGroupConfiguration,
|
||||
root.nf.Graph,
|
||||
root.nf.Birdseye);
|
||||
}
|
||||
}(this, function ($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfGraph, nfBirdseye) {
|
||||
}(this, function ($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfProcessGroupConfiguration, nfGraph, nfBirdseye) {
|
||||
'use strict';
|
||||
|
||||
var serverTimeOffset = null;
|
||||
|
@ -96,6 +99,55 @@
|
|||
$('#save-flow-version-process-group-id').removeData('versionControlInformation').removeData('revision').text('');
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the revert local changes dialog.
|
||||
*/
|
||||
var resetRevertLocalChangesDialog = function () {
|
||||
$('#revert-local-changes-process-group-id').text('');
|
||||
|
||||
clearLocalChangesGrid($('#revert-local-changes-table'), $('#revert-local-changes-filter'), $('#displayed-revert-local-changes-entries'), $('#total-revert-local-changes-entries'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the show local changes dialog.
|
||||
*/
|
||||
var resetShowLocalChangesDialog = function () {
|
||||
clearLocalChangesGrid($('#show-local-changes-table'), $('#show-local-changes-filter'), $('#displayed-show-local-changes-entries'), $('#total-show-local-changes-entries'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the local changes grid.
|
||||
*/
|
||||
var clearLocalChangesGrid = function (localChangesTable, filterInput, displayedLabel, totalLabel) {
|
||||
var localChangesGrid = localChangesTable.data('gridInstance');
|
||||
if (nfCommon.isDefinedAndNotNull(localChangesGrid)) {
|
||||
localChangesGrid.setSelectedRows([]);
|
||||
localChangesGrid.resetActiveCell();
|
||||
|
||||
var localChangesData = localChangesGrid.getData();
|
||||
localChangesData.setItems([]);
|
||||
}
|
||||
|
||||
filterInput.val('');
|
||||
|
||||
displayedLabel.text('0');
|
||||
totalLabel.text('0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the version grid
|
||||
*/
|
||||
var clearFlowVersionsGrid = function () {
|
||||
var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance');
|
||||
if (nfCommon.isDefinedAndNotNull(importFlowVersionGrid)) {
|
||||
importFlowVersionGrid.setSelectedRows([]);
|
||||
importFlowVersionGrid.resetActiveCell();
|
||||
|
||||
var importFlowVersionData = importFlowVersionGrid.getData();
|
||||
importFlowVersionData.setItems([]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the import flow version dialog.
|
||||
*/
|
||||
|
@ -110,14 +162,7 @@
|
|||
$('#import-flow-version-bucket').text('').hide();
|
||||
$('#import-flow-version-name').text('').hide();
|
||||
|
||||
var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance');
|
||||
if (nfCommon.isDefinedAndNotNull(importFlowVersionGrid)) {
|
||||
importFlowVersionGrid.setSelectedRows([]);
|
||||
importFlowVersionGrid.resetActiveCell();
|
||||
|
||||
var importFlowVersionData = importFlowVersionGrid.getData();
|
||||
importFlowVersionData.setItems([]);
|
||||
}
|
||||
clearFlowVersionsGrid();
|
||||
|
||||
$('#import-flow-version-process-group-id').removeData('versionControlInformation').removeData('revision').text('');
|
||||
|
||||
|
@ -131,9 +176,10 @@
|
|||
* @param dialog
|
||||
* @param registryCombo
|
||||
* @param bucketCombo
|
||||
* @param flowCombo
|
||||
* @returns {deferred}
|
||||
*/
|
||||
var loadRegistries = function (dialog, registryCombo, bucketCombo, selectBucket) {
|
||||
var loadRegistries = function (dialog, registryCombo, bucketCombo, flowCombo, selectBucket) {
|
||||
return $.ajax({
|
||||
type: 'GET',
|
||||
url: '../nifi-api/flow/registries',
|
||||
|
@ -167,7 +213,7 @@
|
|||
registryCombo.combo({
|
||||
options: registries,
|
||||
select: function (selectedOption) {
|
||||
selectRegistry(dialog, selectedOption, bucketCombo, selectBucket)
|
||||
selectRegistry(dialog, selectedOption, bucketCombo, flowCombo, selectBucket)
|
||||
}
|
||||
});
|
||||
}).fail(nfErrorHandler.handleAjaxError);
|
||||
|
@ -178,6 +224,7 @@
|
|||
*
|
||||
* @param registryIdentifier
|
||||
* @param bucketCombo
|
||||
* @param selectBucket
|
||||
* @returns {*}
|
||||
*/
|
||||
var loadBuckets = function (registryIdentifier, bucketCombo, selectBucket) {
|
||||
|
@ -224,9 +271,10 @@
|
|||
* @param dialog
|
||||
* @param selectedOption
|
||||
* @param bucketCombo
|
||||
* @param flowCombo
|
||||
* @param selectBucket
|
||||
*/
|
||||
var selectRegistry = function (dialog, selectedOption, bucketCombo, selectBucket) {
|
||||
var selectRegistry = function (dialog, selectedOption, bucketCombo, flowCombo, selectBucket) {
|
||||
var showNoBucketsAvailable = function () {
|
||||
bucketCombo.combo('destroy').combo({
|
||||
options: [{
|
||||
|
@ -243,6 +291,28 @@
|
|||
if (selectedOption.disabled === true) {
|
||||
showNoBucketsAvailable();
|
||||
} else {
|
||||
bucketCombo.combo('destroy').combo({
|
||||
options: [{
|
||||
text: 'Loading buckets...',
|
||||
value: null,
|
||||
optionClass: 'unset',
|
||||
disabled: true
|
||||
}]
|
||||
});
|
||||
|
||||
if (nfCommon.isDefinedAndNotNull(flowCombo)) {
|
||||
flowCombo.combo('destroy').combo({
|
||||
options: [{
|
||||
text: 'Loading flows...',
|
||||
value: null,
|
||||
optionClass: 'unset',
|
||||
disabled: true
|
||||
}]
|
||||
});
|
||||
|
||||
clearFlowVersionsGrid();
|
||||
}
|
||||
|
||||
loadBuckets(selectedOption.value, bucketCombo, selectBucket).fail(function () {
|
||||
showNoBucketsAvailable();
|
||||
});
|
||||
|
@ -344,7 +414,7 @@
|
|||
return nfCommon.formatDateTime(date);
|
||||
};
|
||||
|
||||
// define the column model for the controller services table
|
||||
// define the column model for flow versions
|
||||
var importFlowVersionColumns = [
|
||||
{
|
||||
id: 'version',
|
||||
|
@ -426,6 +496,185 @@
|
|||
importFlowVersionTable.data('gridInstance', importFlowVersionGrid);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the specified local changes table.
|
||||
*
|
||||
* @param localChangesTable
|
||||
* @param filterInput
|
||||
* @param displayedLabel
|
||||
* @param totalLabel
|
||||
*/
|
||||
var initLocalChangesTable = function (localChangesTable, filterInput, displayedLabel, totalLabel) {
|
||||
|
||||
var getFilterText = function () {
|
||||
return filterInput.val();
|
||||
};
|
||||
|
||||
var applyFilter = function () {
|
||||
// get the dataview
|
||||
var localChangesGrid = localChangesTable.data('gridInstance');
|
||||
|
||||
// ensure the grid has been initialized
|
||||
if (nfCommon.isDefinedAndNotNull(localChangesGrid)) {
|
||||
var localChangesData = localChangesGrid.getData();
|
||||
|
||||
// update the search criteria
|
||||
localChangesData.setFilterArgs({
|
||||
searchString: getFilterText()
|
||||
});
|
||||
localChangesData.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
var filter = function (item, args) {
|
||||
if (args.searchString === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// perform the row filtering
|
||||
var filterExp = new RegExp(args.searchString, 'i');
|
||||
} catch (e) {
|
||||
// invalid regex
|
||||
return false;
|
||||
}
|
||||
|
||||
// determine if the item matches the filter
|
||||
var matchesId = item['componentId'].search(filterExp) >= 0;
|
||||
var matchesComponent = item['componentName'].search(filterExp) >= 0;
|
||||
var matchesDifferenceType = item['differenceType'].search(filterExp) >= 0;
|
||||
var matchesDifference = item['difference'].search(filterExp) >= 0;
|
||||
|
||||
return matchesId || matchesComponent || matchesDifferenceType || matchesDifference;
|
||||
};
|
||||
|
||||
// initialize the component state filter
|
||||
filterInput.on('keyup', function () {
|
||||
applyFilter();
|
||||
});
|
||||
|
||||
var valueFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
return nfCommon.escapeHtml(value);
|
||||
};
|
||||
|
||||
var actionsFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
var markup = '';
|
||||
|
||||
if (dataContext.differenceType !== 'Component Removed' && nfCommon.isDefinedAndNotNull(dataContext.processGroupId)) {
|
||||
markup += '<div class="pointer go-to-component fa fa-long-arrow-right" title="Go To" style="margin-top: 2px" ></div>';
|
||||
}
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
||||
// define the column model for local changes
|
||||
var localChangesColumns = [
|
||||
{
|
||||
id: 'component',
|
||||
name: 'Component Name',
|
||||
field: 'componentName',
|
||||
formatter: valueFormatter,
|
||||
sortable: true,
|
||||
resizable: true
|
||||
},
|
||||
{
|
||||
id: 'differenceType',
|
||||
name: 'Type',
|
||||
field: 'differenceType',
|
||||
formatter: valueFormatter,
|
||||
sortable: true,
|
||||
resizable: true
|
||||
},
|
||||
{
|
||||
id: 'difference',
|
||||
name: 'Difference',
|
||||
field: 'difference',
|
||||
formatter: valueFormatter,
|
||||
sortable: true,
|
||||
resizable: true,
|
||||
minWidth: 300
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
name: ' ',
|
||||
formatter: actionsFormatter,
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
width: 25
|
||||
}
|
||||
];
|
||||
|
||||
// initialize the dataview
|
||||
var localChangesData = new Slick.Data.DataView({
|
||||
inlineFilters: false
|
||||
});
|
||||
localChangesData.setFilterArgs({
|
||||
searchString: '',
|
||||
property: 'component'
|
||||
});
|
||||
localChangesData.setFilter(filter);
|
||||
|
||||
// initialize the sort
|
||||
sort({
|
||||
columnId: 'version',
|
||||
sortAsc: false
|
||||
}, localChangesData);
|
||||
|
||||
// initialize the grid
|
||||
var localChangesGrid = new Slick.Grid(localChangesTable, localChangesData, localChangesColumns, gridOptions);
|
||||
localChangesGrid.setSelectionModel(new Slick.RowSelectionModel());
|
||||
localChangesGrid.registerPlugin(new Slick.AutoTooltips());
|
||||
localChangesGrid.setSortColumn('version', false);
|
||||
localChangesGrid.onSort.subscribe(function (e, args) {
|
||||
sort({
|
||||
columnId: args.sortCol.id,
|
||||
sortAsc: args.sortAsc
|
||||
}, localChangesData);
|
||||
});
|
||||
|
||||
// configure a click listener
|
||||
localChangesGrid.onClick.subscribe(function (e, args) {
|
||||
var target = $(e.target);
|
||||
|
||||
// get the node at this row
|
||||
var componentDifference = localChangesData.getItem(args.row);
|
||||
|
||||
// determine the desired action
|
||||
if (localChangesGrid.getColumns()[args.cell].id === 'actions') {
|
||||
if (target.hasClass('go-to-component')) {
|
||||
if (componentDifference.componentType === 'Controller Service') {
|
||||
nfProcessGroupConfiguration.showConfiguration(componentDifference.processGroupId).done(function () {
|
||||
nfProcessGroupConfiguration.selectControllerService(componentDifference.componentId);
|
||||
});
|
||||
} else {
|
||||
nfCanvasUtils.showComponent(componentDifference.processGroupId, componentDifference.componentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// wire up the dataview to the grid
|
||||
localChangesData.onRowCountChanged.subscribe(function (e, args) {
|
||||
localChangesGrid.updateRowCount();
|
||||
localChangesGrid.render();
|
||||
|
||||
// update the total number of displayed items
|
||||
displayedLabel.text(nfCommon.formatInteger(args.current));
|
||||
});
|
||||
localChangesData.onRowsChanged.subscribe(function (e, args) {
|
||||
localChangesGrid.invalidateRows(args.rows);
|
||||
localChangesGrid.render();
|
||||
});
|
||||
localChangesData.syncGridSelection(localChangesGrid, true);
|
||||
|
||||
// hold onto an instance of the grid
|
||||
localChangesTable.data('gridInstance', localChangesGrid);
|
||||
|
||||
// initialize the number of display items
|
||||
displayedLabel.text('0');
|
||||
totalLabel.text('0');
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the import flow version dialog.
|
||||
*/
|
||||
|
@ -450,7 +699,7 @@
|
|||
disabled: true
|
||||
}]
|
||||
}).show();
|
||||
$('#import-flow-version-name-combo').combo('destroy').combo({
|
||||
var flowCombo = $('#import-flow-version-name-combo').combo('destroy').combo({
|
||||
options: [{
|
||||
text: 'Loading flows...',
|
||||
value: null,
|
||||
|
@ -459,7 +708,7 @@
|
|||
}]
|
||||
}).show();
|
||||
|
||||
loadRegistries($('#import-flow-version-dialog'), registryCombo, bucketCombo, selectBucketImportVersion).done(function () {
|
||||
loadRegistries($('#import-flow-version-dialog'), registryCombo, bucketCombo, flowCombo, selectBucketImportVersion).done(function () {
|
||||
// show the import dialog
|
||||
$('#import-flow-version-dialog').modal('setHeaderText', 'Import Version').modal('setButtonModel', [{
|
||||
buttonText: 'Import',
|
||||
|
@ -619,6 +868,19 @@
|
|||
* @param selectedBucket
|
||||
*/
|
||||
var selectBucketImportVersion = function (selectedBucket) {
|
||||
// mark the flows as loading
|
||||
$('#import-flow-version-name-combo').combo('destroy').combo({
|
||||
options: [{
|
||||
text: 'Loading flows...',
|
||||
value: null,
|
||||
optionClass: 'unset',
|
||||
disabled: true
|
||||
}]
|
||||
});
|
||||
|
||||
// clear the flow versions grid
|
||||
clearFlowVersionsGrid();
|
||||
|
||||
var selectedRegistry = $('#import-flow-version-registry-combo').combo('getSelectedOption');
|
||||
|
||||
// load the flows for the currently selected registry and bucket
|
||||
|
@ -646,7 +908,6 @@
|
|||
}
|
||||
}),
|
||||
'component': {
|
||||
'name': selectedFlow.text, // TODO - name from versioned PG?
|
||||
'position': {
|
||||
'x': pt.x,
|
||||
'y': pt.y
|
||||
|
@ -966,6 +1227,240 @@
|
|||
progressBar.append(label);
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows local changes for the specified process group.
|
||||
*
|
||||
* @param processGroupId
|
||||
* @param localChangesTable
|
||||
* @param totalLabel
|
||||
*/
|
||||
var loadLocalChanges = function (processGroupId, localChangesTable, totalLabel) {
|
||||
var localChangesGrid = localChangesTable.data('gridInstance');
|
||||
var localChangesData = localChangesGrid.getData();
|
||||
|
||||
// begin the update
|
||||
localChangesData.beginUpdate();
|
||||
|
||||
// remove the current versions
|
||||
localChangesGrid.setSelectedRows([]);
|
||||
localChangesGrid.resetActiveCell();
|
||||
localChangesData.setItems([]);
|
||||
|
||||
return $.ajax({
|
||||
type: 'GET',
|
||||
url: '../nifi-api/process-groups/' + encodeURIComponent(processGroupId) + '/local-modifications',
|
||||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
if (nfCommon.isDefinedAndNotNull(response.componentDifferences) && response.componentDifferences.length > 0) {
|
||||
var totalDifferences = 0;
|
||||
$.each(response.componentDifferences, function (_, componentDifference) {
|
||||
$.each(componentDifference.differences, function (_, difference) {
|
||||
localChangesData.addItem({
|
||||
id: totalDifferences++,
|
||||
componentId: componentDifference.componentId,
|
||||
componentName: componentDifference.componentName,
|
||||
componentType: componentDifference.componentType,
|
||||
processGroupId: componentDifference.processGroupId,
|
||||
differenceType: difference.differenceType,
|
||||
difference: difference.difference
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// end the update
|
||||
localChangesData.endUpdate();
|
||||
|
||||
// resort
|
||||
localChangesData.reSort();
|
||||
localChangesGrid.invalidate();
|
||||
|
||||
// update the total displayed
|
||||
totalLabel.text(nfCommon.formatInteger(totalDifferences));
|
||||
} else {
|
||||
nfDialog.showOkDialog({
|
||||
headerText: 'Local Changes',
|
||||
dialogContent: 'This Process Group does not have any local changes.'
|
||||
});
|
||||
}
|
||||
}).fail(nfErrorHandler.handleAjaxError);
|
||||
};
|
||||
|
||||
/**
|
||||
* Revert local changes for the specified process group.
|
||||
*
|
||||
* @param processGroupId
|
||||
*/
|
||||
var revertLocalChanges = function (processGroupId) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
// hide the import dialog immediately
|
||||
$('#import-flow-version-dialog').modal('hide');
|
||||
|
||||
var submitRevertRequest = function () {
|
||||
var revertFlowVersionRequest = {
|
||||
'processGroupRevision': nfClient.getRevision({
|
||||
'revision': {
|
||||
'version': response.processGroupRevision.version
|
||||
}
|
||||
}),
|
||||
'versionControlInformation': response.versionControlInformation
|
||||
};
|
||||
|
||||
return $.ajax({
|
||||
type: 'POST',
|
||||
data: JSON.stringify(revertFlowVersionRequest),
|
||||
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 () {
|
||||
getRevertRequest().done(processRevertResponse);
|
||||
};
|
||||
|
||||
var getRevertRequest = function () {
|
||||
return $.ajax({
|
||||
type: 'GET',
|
||||
url: revertRequest.uri,
|
||||
dataType: 'json'
|
||||
}).fail(completeRevertRequest).fail(nfErrorHandler.handleAjaxError);
|
||||
};
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
}]);
|
||||
}
|
||||
|
||||
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) {
|
||||
revertRequest = response.request;
|
||||
|
||||
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();
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
submitRevertRequest().done(processRevertResponse);
|
||||
} else {
|
||||
nfDialog.showOkDialog({
|
||||
headerText: 'Revert Changes',
|
||||
dialogContent: 'This Process Group is not currently under version control.'
|
||||
});
|
||||
}
|
||||
}).fail(nfErrorHandler.handleAjaxError);
|
||||
};
|
||||
|
||||
return {
|
||||
init: function (timeOffset) {
|
||||
serverTimeOffset = timeOffset;
|
||||
|
@ -998,13 +1493,11 @@
|
|||
handler: {
|
||||
click: function () {
|
||||
var processGroupId = $('#save-flow-version-process-group-id').text();
|
||||
|
||||
saveFlowVersion().done(function (response) {
|
||||
updateVersionControlInformation(processGroupId, response.versionControlInformation);
|
||||
|
||||
// close the dialog
|
||||
$('#save-flow-version-dialog').modal('hide');
|
||||
});
|
||||
|
||||
$(this).modal('hide');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
|
@ -1049,6 +1542,69 @@
|
|||
}
|
||||
});
|
||||
|
||||
// init the revert local changes dialog
|
||||
$('#revert-local-changes-dialog').modal({
|
||||
scrollableContentStyle: 'scrollable',
|
||||
headerText: 'Revert Local Changes',
|
||||
buttons: [{
|
||||
buttonText: 'Revert',
|
||||
color: {
|
||||
base: '#728E9B',
|
||||
hover: '#004849',
|
||||
text: '#ffffff'
|
||||
},
|
||||
handler: {
|
||||
click: function () {
|
||||
var processGroupId = $('#revert-local-changes-process-group-id').text();
|
||||
revertLocalChanges(processGroupId);
|
||||
|
||||
$(this).modal('hide');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
color: {
|
||||
base: '#E3E8EB',
|
||||
hover: '#C7D2D7',
|
||||
text: '#004849'
|
||||
},
|
||||
handler: {
|
||||
click: function () {
|
||||
$(this).modal('hide');
|
||||
}
|
||||
}
|
||||
}],
|
||||
handler: {
|
||||
close: function () {
|
||||
resetRevertLocalChangesDialog();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// init the show local changes dialog
|
||||
$('#show-local-changes-dialog').modal({
|
||||
scrollableContentStyle: 'scrollable',
|
||||
headerText: 'Local Changes',
|
||||
buttons: [{
|
||||
buttonText: 'Close',
|
||||
color: {
|
||||
base: '#728E9B',
|
||||
hover: '#004849',
|
||||
text: '#ffffff'
|
||||
},
|
||||
handler: {
|
||||
click: function () {
|
||||
$(this).modal('hide');
|
||||
}
|
||||
}
|
||||
}],
|
||||
handler: {
|
||||
close: function () {
|
||||
resetShowLocalChangesDialog();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// handle the click for the process group import
|
||||
$('#import-process-group-link').on('click', function() {
|
||||
showImportFlowVersionDialog();
|
||||
|
@ -1056,6 +1612,8 @@
|
|||
|
||||
// initialize the import flow version table
|
||||
initImportFlowVersionTable();
|
||||
initLocalChangesTable($('#revert-local-changes-table'), $('#revert-local-changes-filter'), $('#displayed-revert-local-changes-entries'), $('#total-revert-local-changes-entries'));
|
||||
initLocalChangesTable($('#show-local-changes-table'), $('#show-local-changes-filter'), $('#displayed-show-local-changes-entries'), $('#total-show-local-changes-entries'));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1118,7 +1676,7 @@
|
|||
// reposition the version label
|
||||
$('#save-flow-version-label').css('margin-top', '0');
|
||||
|
||||
loadRegistries($('#save-flow-version-dialog'), registryCombo, bucketCombo, selectBucketSaveFlowVersion).done(function () {
|
||||
loadRegistries($('#save-flow-version-dialog'), registryCombo, bucketCombo, null, selectBucketSaveFlowVersion).done(function () {
|
||||
deferred.resolve();
|
||||
}).fail(function () {
|
||||
deferred.reject();
|
||||
|
@ -1144,184 +1702,20 @@
|
|||
* @param processGroupId
|
||||
*/
|
||||
revertLocalChanges: function (processGroupId) {
|
||||
// TODO update to show user the ramifications of reverting for confirmation
|
||||
loadLocalChanges(processGroupId, $('#revert-local-changes-table'), $('#total-revert-local-changes-entries')).done(function () {
|
||||
$('#revert-local-changes-process-group-id').text(processGroupId);
|
||||
$('#revert-local-changes-dialog').modal('show');
|
||||
});
|
||||
},
|
||||
|
||||
// prompt the user before reverting
|
||||
nfDialog.showYesNoDialog({
|
||||
headerText: 'Revert Changes',
|
||||
dialogContent: 'Are you sure you want to revert changes? All flow configuration changes will be reverted to the last version.',
|
||||
noText: 'Cancel',
|
||||
yesText: 'Revert',
|
||||
yesHandler: function () {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
// hide the import dialog immediately
|
||||
$('#import-flow-version-dialog').modal('hide');
|
||||
|
||||
var submitRevertRequest = function () {
|
||||
var revertFlowVersionRequest = {
|
||||
'processGroupRevision': nfClient.getRevision({
|
||||
'revision': {
|
||||
'version': response.processGroupRevision.version
|
||||
}
|
||||
}),
|
||||
'versionControlInformation': response.versionControlInformation
|
||||
};
|
||||
|
||||
return $.ajax({
|
||||
type: 'POST',
|
||||
data: JSON.stringify(revertFlowVersionRequest),
|
||||
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 () {
|
||||
getRevertRequest().done(processRevertResponse);
|
||||
};
|
||||
|
||||
var getRevertRequest = function () {
|
||||
return $.ajax({
|
||||
type: 'GET',
|
||||
url: revertRequest.uri,
|
||||
dataType: 'json'
|
||||
}).fail(completeRevertRequest).fail(nfErrorHandler.handleAjaxError);
|
||||
};
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
}]);
|
||||
}
|
||||
|
||||
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) {
|
||||
revertRequest = response.request;
|
||||
|
||||
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();
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
submitRevertRequest().done(processRevertResponse);
|
||||
} else {
|
||||
nfDialog.showOkDialog({
|
||||
headerText: 'Revert Changes',
|
||||
dialogContent: 'This Process Group is not currently under version control.'
|
||||
});
|
||||
}
|
||||
}).fail(nfErrorHandler.handleAjaxError);
|
||||
}
|
||||
/**
|
||||
* Shows local changes for the specified process group.
|
||||
*
|
||||
* @param processGroupId
|
||||
*/
|
||||
showLocalChanges: function (processGroupId) {
|
||||
loadLocalChanges(processGroupId, $('#show-local-changes-table'), $('#total-show-local-changes-entries')).done(function () {
|
||||
$('#show-local-changes-dialog').modal('show');
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1407,8 +1801,8 @@
|
|||
stopVersionControl: function (processGroupId) {
|
||||
// prompt the user before disconnecting
|
||||
nfDialog.showYesNoDialog({
|
||||
headerText: 'Disconnect',
|
||||
dialogContent: 'Are you sure you want to disconnect?',
|
||||
headerText: 'Stop Version Control',
|
||||
dialogContent: 'Are you sure you want to stop version control?',
|
||||
noText: 'Cancel',
|
||||
yesText: 'Disconnect',
|
||||
yesHandler: function () {
|
||||
|
@ -1434,7 +1828,7 @@
|
|||
|
||||
nfDialog.showOkDialog({
|
||||
headerText: 'Disconnect',
|
||||
dialogContent: 'This Process Group has been disconnected.'
|
||||
dialogContent: 'This Process Group is no longer under version control.'
|
||||
});
|
||||
}).fail(nfErrorHandler.handleAjaxError);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue