mirror of https://github.com/apache/nifi.git
[NIFI-96] add align horizontal and align vertical capability to components on the canvas. This closes #1354
This commit is contained in:
parent
e65aad8fe6
commit
5ea17d30c5
|
@ -97,6 +97,11 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
|
||||||
margin: -2px;
|
margin: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*shift rotated font awesome icons*/
|
||||||
|
.fa-rotate-90 {
|
||||||
|
left: -2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
display: block;
|
display: block;
|
||||||
font-family: Roboto, sans-serif;
|
font-family: Roboto, sans-serif;
|
||||||
|
|
|
@ -75,6 +75,13 @@ nf.Actions = (function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// determine if the source of this connection is part of the selection
|
||||||
|
var isSourceSelected = function (connection, selection) {
|
||||||
|
return selection.filter(function (d) {
|
||||||
|
return nf.CanvasUtils.getConnectionSourceComponentId(connection) === d.id;
|
||||||
|
}).size() > 0;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* Initializes the actions.
|
* Initializes the actions.
|
||||||
|
@ -1094,6 +1101,145 @@ nf.Actions = (function () {
|
||||||
nf.ComponentState.showState(processor, nf.CanvasUtils.isConfigurable(selection));
|
nf.ComponentState.showState(processor, nf.CanvasUtils.isConfigurable(selection));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns the components in the specified selection vertically along the center of the components.
|
||||||
|
*
|
||||||
|
* @param {array} selection The selection
|
||||||
|
*/
|
||||||
|
alignVertical: function (selection) {
|
||||||
|
var updates = d3.map();
|
||||||
|
// ensure every component is writable
|
||||||
|
if (nf.CanvasUtils.canModify(selection) === false) {
|
||||||
|
nf.Dialog.showOkDialog({
|
||||||
|
headerText: 'Component Position',
|
||||||
|
dialogContent: 'Must be authorized to modify every component selected.'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// determine the extent
|
||||||
|
var minX = null, maxX = null;
|
||||||
|
selection.each(function (d) {
|
||||||
|
if (d.type !== "Connection") {
|
||||||
|
if (minX === null || d.position.x < minX) {
|
||||||
|
minX = d.position.x;
|
||||||
|
}
|
||||||
|
var componentMaxX = d.position.x + d.dimensions.width;
|
||||||
|
if (maxX === null || componentMaxX > maxX) {
|
||||||
|
maxX = componentMaxX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var center = (minX + maxX) / 2;
|
||||||
|
|
||||||
|
// align all components left
|
||||||
|
selection.each(function(d) {
|
||||||
|
if (d.type !== "Connection") {
|
||||||
|
var delta = {
|
||||||
|
x: center - (d.position.x + d.dimensions.width / 2),
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
// if this component is already centered, no need to updated it
|
||||||
|
if (delta.x !== 0) {
|
||||||
|
// consider any connections
|
||||||
|
var connections = nf.Connection.getComponentConnections(d.id);
|
||||||
|
$.each(connections, function(_, connection) {
|
||||||
|
var connectionSelection = d3.select('#id-' + connection.id);
|
||||||
|
|
||||||
|
if (!updates.has(connection.id) && nf.CanvasUtils.getConnectionSourceComponentId(connection) === nf.CanvasUtils.getConnectionDestinationComponentId(connection)) {
|
||||||
|
// this connection is self looping and hasn't been updated by the delta yet
|
||||||
|
var connectionUpdate = nf.Draggable.updateConnectionPosition(nf.Connection.get(connection.id), delta);
|
||||||
|
if (connectionUpdate !== null) {
|
||||||
|
updates.set(connection.id, connectionUpdate);
|
||||||
|
}
|
||||||
|
} else if (!updates.has(connection.id) && connectionSelection.classed('selected') && nf.CanvasUtils.canModify(connectionSelection)) {
|
||||||
|
// this is a selected connection that hasn't been updated by the delta yet
|
||||||
|
if (nf.CanvasUtils.getConnectionSourceComponentId(connection) === d.id || !isSourceSelected(connection, selection)) {
|
||||||
|
// the connection is either outgoing or incoming when the source of the connection is not part of the selection
|
||||||
|
var connectionUpdate = nf.Draggable.updateConnectionPosition(nf.Connection.get(connection.id), delta);
|
||||||
|
if (connectionUpdate !== null) {
|
||||||
|
updates.set(connection.id, connectionUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updates.set(d.id, nf.Draggable.updateComponentPosition(d, delta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nf.Draggable.refreshConnections(updates);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns the components in the specified selection horizontally along the center of the components.
|
||||||
|
*
|
||||||
|
* @param {array} selection The selection
|
||||||
|
*/
|
||||||
|
alignHorizontal: function (selection) {
|
||||||
|
var updates = d3.map();
|
||||||
|
// ensure every component is writable
|
||||||
|
if (nf.CanvasUtils.canModify(selection) === false) {
|
||||||
|
nf.Dialog.showOkDialog({
|
||||||
|
headerText: 'Component Position',
|
||||||
|
dialogContent: 'Must be authorized to modify every component selected.'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the extent
|
||||||
|
var minY = null, maxY = null;
|
||||||
|
selection.each(function (d) {
|
||||||
|
if (d.type !== "Connection") {
|
||||||
|
if (minY === null || d.position.y < minY) {
|
||||||
|
minY = d.position.y;
|
||||||
|
}
|
||||||
|
var componentMaxY = d.position.y + d.dimensions.height;
|
||||||
|
if (maxY === null || componentMaxY > maxY) {
|
||||||
|
maxY = componentMaxY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var center = (minY + maxY) / 2;
|
||||||
|
|
||||||
|
// align all components with top most component
|
||||||
|
selection.each(function(d) {
|
||||||
|
if (d.type !== "Connection") {
|
||||||
|
var delta = {
|
||||||
|
x: 0,
|
||||||
|
y: center - (d.position.y + d.dimensions.height / 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
// if this component is already centered, no need to updated it
|
||||||
|
if (delta.y !== 0) {
|
||||||
|
// consider any connections
|
||||||
|
var connections = nf.Connection.getComponentConnections(d.id);
|
||||||
|
$.each(connections, function(_, connection) {
|
||||||
|
var connectionSelection = d3.select('#id-' + connection.id);
|
||||||
|
|
||||||
|
if (!updates.has(connection.id) && nf.CanvasUtils.getConnectionSourceComponentId(connection) === nf.CanvasUtils.getConnectionDestinationComponentId(connection)) {
|
||||||
|
// this connection is self looping and hasn't been updated by the delta yet
|
||||||
|
var connectionUpdate = nf.Draggable.updateConnectionPosition(nf.Connection.get(connection.id), delta);
|
||||||
|
if (connectionUpdate !== null) {
|
||||||
|
updates.set(connection.id, connectionUpdate);
|
||||||
|
}
|
||||||
|
} else if (!updates.has(connection.id) && connectionSelection.classed('selected') && nf.CanvasUtils.canModify(connectionSelection)) {
|
||||||
|
// this is a selected connection that hasn't been updated by the delta yet
|
||||||
|
if (nf.CanvasUtils.getConnectionSourceComponentId(connection) === d.id || !isSourceSelected(connection, selection)) {
|
||||||
|
// the connection is either outgoing or incoming when the source of the connection is not part of the selection
|
||||||
|
var connectionUpdate = nf.Draggable.updateConnectionPosition(nf.Connection.get(connection.id), delta);
|
||||||
|
if (connectionUpdate !== null) {
|
||||||
|
updates.set(connection.id, connectionUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updates.set(d.id, nf.Draggable.updateComponentPosition(d, delta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
nf.Draggable.refreshConnections(updates);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the fill color dialog for the component in the specified selection.
|
* Opens the fill color dialog for the component in the specified selection.
|
||||||
*
|
*
|
||||||
|
|
|
@ -546,6 +546,34 @@ nf.CanvasUtils = (function () {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the specified selection is alignable (in a single action).
|
||||||
|
*
|
||||||
|
* @param {selection} selection The selection
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
canAlign: function(selection) {
|
||||||
|
var canAlign = true;
|
||||||
|
|
||||||
|
// determine if the current selection is entirely connections
|
||||||
|
var selectedConnections = selection.filter(function(d) {
|
||||||
|
var connection = d3.select(this);
|
||||||
|
return nf.CanvasUtils.isConnection(connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
// require multiple selections besides connections
|
||||||
|
if (selection.size() - selectedConnections.size() < 2) {
|
||||||
|
canAlign = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// require write permissions
|
||||||
|
if (nf.CanvasUtils.canModify(selection) === false) {
|
||||||
|
canAlign = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canAlign;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the specified selection is colorable (in a single action).
|
* Determines if the specified selection is colorable (in a single action).
|
||||||
*
|
*
|
||||||
|
|
|
@ -157,6 +157,15 @@ nf.ContextMenu = (function () {
|
||||||
return nf.CanvasUtils.isConnection(selection);
|
return nf.CanvasUtils.isConnection(selection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the components in the specified selection are alignable.
|
||||||
|
*
|
||||||
|
* @param {selection} selection The selection
|
||||||
|
*/
|
||||||
|
var canAlign = function (selection) {
|
||||||
|
return nf.CanvasUtils.canAlign(selection);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the components in the specified selection are colorable.
|
* Determines whether the components in the specified selection are colorable.
|
||||||
*
|
*
|
||||||
|
@ -435,7 +444,9 @@ nf.ContextMenu = (function () {
|
||||||
{condition: canMoveToParent, menuItem: {clazz: 'fa fa-arrows', text: 'Move to parent group', action: 'moveIntoParent'}},
|
{condition: canMoveToParent, menuItem: {clazz: 'fa fa-arrows', text: 'Move to parent group', action: 'moveIntoParent'}},
|
||||||
{condition: canListQueue, menuItem: {clazz: 'fa fa-list', text: 'List queue', action: 'listQueue'}},
|
{condition: canListQueue, menuItem: {clazz: 'fa fa-list', text: 'List queue', action: 'listQueue'}},
|
||||||
{condition: canEmptyQueue, menuItem: {clazz: 'fa fa-minus-circle', text: 'Empty queue', action: 'emptyQueue'}},
|
{condition: canEmptyQueue, menuItem: {clazz: 'fa fa-minus-circle', text: 'Empty queue', action: 'emptyQueue'}},
|
||||||
{condition: isDeletable, menuItem: {clazz: 'fa fa-trash', text: 'Delete', action: 'delete'}}
|
{condition: isDeletable, menuItem: {clazz: 'fa fa-trash', text: 'Delete', action: 'delete'}},
|
||||||
|
{condition: canAlign, menuItem: {clazz: 'fa fa-align-center', text: 'Align vertical', action: 'alignVertical'}},
|
||||||
|
{condition: canAlign, menuItem: {clazz: 'fa fa-align-center fa-rotate-90', text: 'Align horizontal', action: 'alignHorizontal'}}
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -41,107 +41,6 @@ nf.Draggable = (function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateComponentPosition = function(d) {
|
|
||||||
var newPosition = {
|
|
||||||
'x': d.position.x + delta.x,
|
|
||||||
'y': d.position.y + delta.y
|
|
||||||
};
|
|
||||||
|
|
||||||
// build the entity
|
|
||||||
var entity = {
|
|
||||||
'revision': nf.Client.getRevision(d),
|
|
||||||
'component': {
|
|
||||||
'id': d.id,
|
|
||||||
'position': newPosition
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// update the component positioning
|
|
||||||
return $.Deferred(function (deferred) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'PUT',
|
|
||||||
url: d.uri,
|
|
||||||
data: JSON.stringify(entity),
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json'
|
|
||||||
}).done(function (response) {
|
|
||||||
// update the component
|
|
||||||
nf[d.type].set(response);
|
|
||||||
|
|
||||||
// resolve with an object so we can refresh when finished
|
|
||||||
deferred.resolve({
|
|
||||||
type: d.type,
|
|
||||||
id: d.id
|
|
||||||
});
|
|
||||||
}).fail(function (xhr, status, error) {
|
|
||||||
if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
|
|
||||||
nf.Dialog.showOkDialog({
|
|
||||||
headerText: 'Component Position',
|
|
||||||
dialogContent: nf.Common.escapeHtml(xhr.responseText)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
nf.Common.handleAjaxError(xhr, status, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
deferred.reject();
|
|
||||||
});
|
|
||||||
}).promise();
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateConnectionPosition = function(d) {
|
|
||||||
// only update if necessary
|
|
||||||
if (d.bends.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the new bend points
|
|
||||||
var newBends = $.map(d.bends, function (bend) {
|
|
||||||
return {
|
|
||||||
x: bend.x + delta.x,
|
|
||||||
y: bend.y + delta.y
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
var entity = {
|
|
||||||
'revision': nf.Client.getRevision(d),
|
|
||||||
'component': {
|
|
||||||
id: d.id,
|
|
||||||
bends: newBends
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// update the component positioning
|
|
||||||
return $.Deferred(function (deferred) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'PUT',
|
|
||||||
url: d.uri,
|
|
||||||
data: JSON.stringify(entity),
|
|
||||||
dataType: 'json',
|
|
||||||
contentType: 'application/json'
|
|
||||||
}).done(function (response) {
|
|
||||||
// update the component
|
|
||||||
nf.Connection.set(response);
|
|
||||||
|
|
||||||
// resolve with an object so we can refresh when finished
|
|
||||||
deferred.resolve({
|
|
||||||
type: d.type,
|
|
||||||
id: d.id
|
|
||||||
});
|
|
||||||
}).fail(function (xhr, status, error) {
|
|
||||||
if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
|
|
||||||
nf.Dialog.showOkDialog({
|
|
||||||
headerText: 'Component Position',
|
|
||||||
dialogContent: nf.Common.escapeHtml(xhr.responseText)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
nf.Common.handleAjaxError(xhr, status, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
deferred.reject();
|
|
||||||
});
|
|
||||||
}).promise();
|
|
||||||
};
|
|
||||||
|
|
||||||
var selectedConnections = d3.selectAll('g.connection.selected');
|
var selectedConnections = d3.selectAll('g.connection.selected');
|
||||||
var selectedComponents = d3.selectAll('g.component.selected');
|
var selectedComponents = d3.selectAll('g.component.selected');
|
||||||
|
|
||||||
|
@ -156,7 +55,7 @@ nf.Draggable = (function () {
|
||||||
|
|
||||||
// go through each selected connection
|
// go through each selected connection
|
||||||
selectedConnections.each(function (d) {
|
selectedConnections.each(function (d) {
|
||||||
var connectionUpdate = updateConnectionPosition(d);
|
var connectionUpdate = nf.Draggable.updateConnectionPosition(d, delta);
|
||||||
if (connectionUpdate !== null) {
|
if (connectionUpdate !== null) {
|
||||||
updates.set(d.id, connectionUpdate);
|
updates.set(d.id, connectionUpdate);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +67,7 @@ nf.Draggable = (function () {
|
||||||
var connections = nf.Connection.getComponentConnections(d.id);
|
var connections = nf.Connection.getComponentConnections(d.id);
|
||||||
$.each(connections, function(_, connection) {
|
$.each(connections, function(_, connection) {
|
||||||
if (!updates.has(connection.id) && nf.CanvasUtils.getConnectionSourceComponentId(connection) === nf.CanvasUtils.getConnectionDestinationComponentId(connection)) {
|
if (!updates.has(connection.id) && nf.CanvasUtils.getConnectionSourceComponentId(connection) === nf.CanvasUtils.getConnectionDestinationComponentId(connection)) {
|
||||||
var connectionUpdate = updateConnectionPosition(nf.Connection.get(connection.id));
|
var connectionUpdate = nf.Draggable.updateConnectionPosition(nf.Connection.get(connection.id), delta);
|
||||||
if (connectionUpdate !== null) {
|
if (connectionUpdate !== null) {
|
||||||
updates.set(connection.id, connectionUpdate);
|
updates.set(connection.id, connectionUpdate);
|
||||||
}
|
}
|
||||||
|
@ -176,35 +75,10 @@ nf.Draggable = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
// consider the component itself
|
// consider the component itself
|
||||||
updates.set(d.id, updateComponentPosition(d));
|
updates.set(d.id, nf.Draggable.updateComponentPosition(d, delta));
|
||||||
});
|
});
|
||||||
|
|
||||||
// wait for all updates to complete
|
nf.Draggable.refreshConnections(updates);
|
||||||
$.when.apply(window, updates.values()).done(function () {
|
|
||||||
var dragged = $.makeArray(arguments);
|
|
||||||
var connections = d3.set();
|
|
||||||
|
|
||||||
// refresh this component
|
|
||||||
$.each(dragged, function (_, component) {
|
|
||||||
// check if the component in question is a connection
|
|
||||||
if (component.type === 'Connection') {
|
|
||||||
connections.add(component.id);
|
|
||||||
} else {
|
|
||||||
// get connections that need to be refreshed because its attached to this component
|
|
||||||
var componentConnections = nf.Connection.getComponentConnections(component.id);
|
|
||||||
$.each(componentConnections, function (_, connection) {
|
|
||||||
connections.add(connection.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// refresh the connections
|
|
||||||
connections.forEach(function (connectionId) {
|
|
||||||
nf.Connection.refresh(connectionId);
|
|
||||||
});
|
|
||||||
}).always(function(){
|
|
||||||
nf.Birdseye.refresh();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -328,6 +202,155 @@ nf.Draggable = (function () {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the component's position
|
||||||
|
*
|
||||||
|
* @param d The component
|
||||||
|
* @param delta The change in position
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
updateComponentPosition: function(d, delta) {
|
||||||
|
var newPosition = {
|
||||||
|
'x': d.position.x + delta.x,
|
||||||
|
'y': d.position.y + delta.y
|
||||||
|
};
|
||||||
|
|
||||||
|
// build the entity
|
||||||
|
var entity = {
|
||||||
|
'revision': nf.Client.getRevision(d),
|
||||||
|
'component': {
|
||||||
|
'id': d.id,
|
||||||
|
'position': newPosition
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// update the component positioning
|
||||||
|
return $.Deferred(function (deferred) {
|
||||||
|
$.ajax({
|
||||||
|
type: 'PUT',
|
||||||
|
url: d.uri,
|
||||||
|
data: JSON.stringify(entity),
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json'
|
||||||
|
}).done(function (response) {
|
||||||
|
// update the component
|
||||||
|
nf[d.type].set(response);
|
||||||
|
|
||||||
|
// resolve with an object so we can refresh when finished
|
||||||
|
deferred.resolve({
|
||||||
|
type: d.type,
|
||||||
|
id: d.id
|
||||||
|
});
|
||||||
|
}).fail(function (xhr, status, error) {
|
||||||
|
if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
|
||||||
|
nf.Dialog.showOkDialog({
|
||||||
|
headerText: 'Component Position',
|
||||||
|
dialogContent: nf.Common.escapeHtml(xhr.responseText)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
nf.Common.handleAjaxError(xhr, status, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
}).promise();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the connection's position
|
||||||
|
*
|
||||||
|
* @param d The connection
|
||||||
|
* @param delta The change in position
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
updateConnectionPosition: function(d, delta) {
|
||||||
|
// only update if necessary
|
||||||
|
if (d.bends.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the new bend points
|
||||||
|
var newBends = $.map(d.bends, function (bend) {
|
||||||
|
return {
|
||||||
|
x: bend.x + delta.x,
|
||||||
|
y: bend.y + delta.y
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
var entity = {
|
||||||
|
'revision': nf.Client.getRevision(d),
|
||||||
|
'component': {
|
||||||
|
id: d.id,
|
||||||
|
bends: newBends
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// update the component positioning
|
||||||
|
return $.Deferred(function (deferred) {
|
||||||
|
$.ajax({
|
||||||
|
type: 'PUT',
|
||||||
|
url: d.uri,
|
||||||
|
data: JSON.stringify(entity),
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json'
|
||||||
|
}).done(function (response) {
|
||||||
|
// update the component
|
||||||
|
nf.Connection.set(response);
|
||||||
|
|
||||||
|
// resolve with an object so we can refresh when finished
|
||||||
|
deferred.resolve({
|
||||||
|
type: d.type,
|
||||||
|
id: d.id
|
||||||
|
});
|
||||||
|
}).fail(function (xhr, status, error) {
|
||||||
|
if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
|
||||||
|
nf.Dialog.showOkDialog({
|
||||||
|
headerText: 'Component Position',
|
||||||
|
dialogContent: nf.Common.escapeHtml(xhr.responseText)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
nf.Common.handleAjaxError(xhr, status, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
}).promise();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the connections after dragging a component
|
||||||
|
*
|
||||||
|
* @param updates
|
||||||
|
*/
|
||||||
|
refreshConnections: function(updates) {
|
||||||
|
// wait for all updates to complete
|
||||||
|
$.when.apply(window, updates.values()).done(function () {
|
||||||
|
var dragged = $.makeArray(arguments);
|
||||||
|
var connections = d3.set();
|
||||||
|
|
||||||
|
// refresh this component
|
||||||
|
$.each(dragged, function (_, component) {
|
||||||
|
// check if the component in question is a connection
|
||||||
|
if (component.type === 'Connection') {
|
||||||
|
connections.add(component.id);
|
||||||
|
} else {
|
||||||
|
// get connections that need to be refreshed because its attached to this component
|
||||||
|
var componentConnections = nf.Connection.getComponentConnections(component.id);
|
||||||
|
$.each(componentConnections, function (_, connection) {
|
||||||
|
connections.add(connection.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// refresh the connections
|
||||||
|
connections.forEach(function (connectionId) {
|
||||||
|
nf.Connection.refresh(connectionId);
|
||||||
|
});
|
||||||
|
}).always(function(){
|
||||||
|
nf.Birdseye.refresh();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates the drag behavior for the components in the specified selection.
|
* Activates the drag behavior for the components in the specified selection.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue