NIFI-13141: (#8752) - Adding a dragging flag to not reset positioning for labels and connection bends if the user is currently performing an action.

This closes #8752
This commit is contained in:
Matt Gilman 2024-05-06 16:15:15 -04:00 committed by GitHub
parent 030435d996
commit e7facda912
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 291 additions and 199 deletions

View File

@ -343,8 +343,9 @@ export class ConnectionManager {
* Saves the connection entry specified by d with the new configuration specified
* in connection.
*
* @param {type} d
* @param {type} connection
* @param d
* @param connection
* @param restoreOnFailure
*/
private save(d: any, connection: any, restoreOnFailure?: any): void {
const updateConnection: UpdateComponentRequest = {
@ -616,7 +617,7 @@ export class ConnectionManager {
// if we are currently dragging the endpoint to a new target, use that
// position, otherwise we need to calculate it for the current target
if (d.end?.dragging) {
if (d.end?.endPointDragging) {
// since we're dragging, use the same object thats bound to the endpoint drag event
end = d.end;
@ -1844,11 +1845,20 @@ export class ConnectionManager {
// handle bend point drag events
this.bendPointDrag = d3
.drag()
.on('start', function (event) {
.on('start', function (this: any, event) {
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging start
const connection: any = d3.select(this.parentNode);
const connectionData: any = connection.datum();
connectionData.dragging = true;
})
.on('drag', function (this: any, event, d: any) {
const connection: any = d3.select(this.parentNode);
const connectionData: any = connection.datum();
if (connectionData.dragging) {
self.snapEnabled = !event.sourceEvent.shiftKey;
d.x = self.snapEnabled
? Math.round(event.x / ConnectionManager.SNAP_ALIGNMENT_PIXELS) *
@ -1864,10 +1874,13 @@ export class ConnectionManager {
updatePath: true,
updateLabel: false
});
}
})
.on('end', function (this: any, event) {
const connection: any = d3.select(this.parentNode);
const connectionData: any = connection.datum();
if (connectionData.dragging) {
const bends: Position[] = connection.selectAll('rect.midpoint').data();
// ensure the bend lengths are the same
@ -1897,22 +1910,35 @@ export class ConnectionManager {
);
}
}
}
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging complete
connectionData.dragging = false;
});
// handle endpoint drag events
this.endpointDrag = d3
.drag()
.on('start', function (event, d: any) {
// indicate that dragging has begun
d.dragging = true;
.on('start', function (this: any, event, d: any) {
// indicate that end point dragging has begun
d.endPointDragging = true;
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging start
const connection: any = d3.select(this.parentNode);
const connectionData: any = connection.datum();
connectionData.dragging = true;
})
.on('drag', function (this: any, event, d: any) {
const connection: any = d3.select(this.parentNode);
const connectionData: any = connection.datum();
if (connectionData.dragging) {
d.x = event.x - 8;
d.y = event.y - 8;
@ -1926,15 +1952,17 @@ export class ConnectionManager {
updatePath: true,
updateLabel: false
});
}
})
.on('end', function (this: any, event, d: any) {
// indicate that dragging as stopped
d.dragging = false;
// indicate that end point dragging as stopped
d.endPointDragging = false;
// get the corresponding connection
const connection: any = d3.select(this.parentNode);
const connectionData: any = connection.datum();
if (connectionData.dragging) {
// attempt to select a new destination
const destination: any = d3.select('g.connectable-destination');
@ -1977,7 +2005,8 @@ export class ConnectionManager {
const payload: any = {
revision: self.client.getRevision(connectionData),
disconnectedNodeAcknowledged: self.clusterConnectionService.isDisconnectionAcknowledged(),
disconnectedNodeAcknowledged:
self.clusterConnectionService.isDisconnectionAcknowledged(),
component: {
id: connectionData.id,
destination: {
@ -2020,20 +2049,27 @@ export class ConnectionManager {
);
}
}
}
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging complete
connectionData.dragging = false;
});
// label drag behavior
this.labelDrag = d3
.drag()
.on('start', function (event) {
.on('start', function (event, d: any) {
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging start
d.dragging = true;
})
.on('drag', function (this: any, event, d: any) {
if (d && d.bends.length > 1) {
if (d.dragging && d.bends.length > 1) {
// get the dragged component
let drag: any = d3.select('rect.label-drag');
@ -2113,7 +2149,7 @@ export class ConnectionManager {
}
})
.on('end', function (this: any, event, d: any) {
if (d.bends.length > 1) {
if (d.dragging && d.bends.length > 1) {
// get the drag selection
const drag: any = d3.select('rect.label-drag');
@ -2140,6 +2176,9 @@ export class ConnectionManager {
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging complete
d.dragging = false;
});
this.store
@ -2187,12 +2226,38 @@ export class ConnectionManager {
private set(connections: any): void {
// update the connections
this.connections = connections.map((connection: any) => {
const currentConnection: any = this.connections.find((c: any) => c.id === connection.id);
// only consider newer when the version is greater which indicates the component configuration has changed.
// when this happens we should override the current dragging action so that the new changes can be realized.
const isNewerRevision = connection.revision.version > currentConnection?.revision.version;
let dragging = false;
if (currentConnection?.dragging && !isNewerRevision) {
dragging = true;
}
let bends: Position[];
if (dragging) {
bends = currentConnection.bends;
} else {
bends = connection.bends.map((bend: Position) => {
return { ...bend };
});
}
let end: Position | undefined;
if (dragging) {
end = currentConnection.end;
}
return {
...connection,
type: ComponentType.Connection,
bends: connection.bends.map((bend: Position) => {
return { ...bend };
})
dragging,
labelIndex: dragging ? currentConnection.labelIndex : connection.labelIndex,
bends,
end
};
});

View File

@ -304,37 +304,47 @@ export class LabelManager {
// handle bend point drag events
this.labelPointDrag = d3
.drag()
.on('start', function (event) {
.on('start', function (this: any, event) {
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging start
const label = d3.select(this.parentNode);
const labelData: any = label.datum();
labelData.dragging = true;
})
.on('drag', function (this: any, event) {
const label = d3.select(this.parentNode);
const labelData: any = label.datum();
if (labelData.dragging) {
// update the dimensions and ensure they are still within bounds
// snap between aligned sizes unless the user is holding shift
self.snapEnabled = !event.sourceEvent.shiftKey;
labelData.dimensions.width = Math.max(
LabelManager.MIN_WIDTH,
self.snapEnabled
? Math.round(event.x / LabelManager.SNAP_ALIGNMENT_PIXELS) * LabelManager.SNAP_ALIGNMENT_PIXELS
? Math.round(event.x / LabelManager.SNAP_ALIGNMENT_PIXELS) *
LabelManager.SNAP_ALIGNMENT_PIXELS
: event.x
);
labelData.dimensions.height = Math.max(
LabelManager.MIN_HEIGHT,
self.snapEnabled
? Math.round(event.y / LabelManager.SNAP_ALIGNMENT_PIXELS) * LabelManager.SNAP_ALIGNMENT_PIXELS
? Math.round(event.y / LabelManager.SNAP_ALIGNMENT_PIXELS) *
LabelManager.SNAP_ALIGNMENT_PIXELS
: event.y
);
// redraw this connection
self.updateLabels(label);
}
})
.on('end', function (this: any, event) {
const label = d3.select(this.parentNode);
const labelData: any = label.datum();
if (labelData.dragging) {
// determine if the width has changed
let different = false;
const widthSet = !!labelData.component.width;
@ -356,7 +366,8 @@ export class LabelManager {
uri: labelData.uri,
payload: {
revision: self.client.getRevision(labelData),
disconnectedNodeAcknowledged: self.clusterConnectionService.isDisconnectionAcknowledged(),
disconnectedNodeAcknowledged:
self.clusterConnectionService.isDisconnectionAcknowledged(),
component: {
id: labelData.id,
width: labelData.dimensions.width,
@ -378,20 +389,36 @@ export class LabelManager {
})
);
}
}
// stop further propagation
event.sourceEvent.stopPropagation();
// indicate dragging complete
labelData.dragging = false;
});
}
private set(labels: any): void {
// update the labels
this.labels = labels.map((label: any) => {
const currentLabel: any = this.labels.find((l: any) => l.id === label.id);
// only consider newer when the version is greater which indicates the component configuration has changed.
// when this happens we should override the current dragging action so that the new changes can be realized.
const isNewerRevision = label.revision.version > currentLabel?.revision.version;
let dragging = false;
if (currentLabel?.dragging && !isNewerRevision) {
dragging = true;
}
return {
...label,
type: ComponentType.Label,
dragging,
dimensions: {
...label.dimensions
...(dragging ? currentLabel.dimensions : label.dimensions)
}
};
});

View File

@ -28,7 +28,7 @@
<div>Relationships</div>
<div class="flex flex-col gap-y-3">
@for (item of relationshipItems; track item; let i = $index) {
@if (isDisabled && item.selected || !isDisabled) {
@if ((isDisabled && item.selected) || !isDisabled) {
<div class="flex flex-col gap-y-1.5">
<div class="flex items-center gap-x-2">
<mat-checkbox