mcgilman commented on code in PR #8762:
URL: https://github.com/apache/nifi/pull/8762#discussion_r1592636749
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts:
##########
@@ -1606,6 +1606,8 @@ export class FlowEffects {
ofType(FlowActions.updateComponentSuccess),
map((action) => action.response),
tap((response) => {
+ this.birdseyeView.refresh();
+
Review Comment:
Can this be moved into a `tap` within the `updatePositionComplete` effect?
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts:
##########
@@ -321,24 +326,209 @@ export class CanvasContextMenu implements
ContextMenuDefinitionProvider {
menuItems: [
{
condition: (selection: any) => {
- // TODO - canAlign
- return false;
+ return this.canvasUtils.canAlign(selection);
},
clazz: 'fa fa-align-center fa-rotate-90',
text: 'Horizontally',
- action: () => {
- // TODO - alignHorizontal
+ action: (selection: any) => {
+ const updates = new Map();
+
+ // determine the extent
+ let minY: number = 0,
+ maxY: number = 0;
+ selection.each((d: any) => {
+ if (d.type !== 'Connection') {
+ if (minY === 0 || d.position.y < minY) {
+ minY = d.position.y;
+ }
+ const componentMaxY = d.position.y +
d.dimensions.height;
+ if (maxY === 0 || componentMaxY > maxY) {
+ maxY = componentMaxY;
+ }
+ }
+ });
+
+ const center = (minY + maxY) / 2;
+
+ // align all components with top most component
+ selection.each((d: any) => {
+ if (d.type !== 'Connection') {
+ const 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
+ const connections =
this.canvasUtils.getComponentConnections(d.id);
+
+ connections.forEach((connection: any) => {
+ const connectionSelection =
d3.select('#id-' + connection.id);
+
+ if (
+ !updates.has(connection.id) &&
+
this.canvasUtils.getConnectionSourceComponentId(connection) ===
+
this.canvasUtils.getConnectionDestinationComponentId(connection)
+ ) {
+ // this connection is self looping and
hasn't been updated by the delta yet
+ const connectionUpdate =
this.draggableBehavior.updateConnectionPosition(
+ connectionSelection.datum(),
+ delta
+ );
+ if (connectionUpdate !== null) {
+ updates.set(connection.id,
connectionUpdate);
+ }
+ } else if (
+ !updates.has(connection.id) &&
+
connectionSelection.classed('selected') &&
+
this.canvasUtils.canModify(connectionSelection)
+ ) {
+ // this is a selected connection that
hasn't been updated by the delta yet
+ if (
+
this.canvasUtils.getConnectionSourceComponentId(connection) === d.id ||
+
!this.canvasUtils.isSourceSelected(connection, selection)
+ ) {
+ // the connection is either
outgoing or incoming when the source of the connection is not part of the
selection
+ const connectionUpdate =
this.draggableBehavior.updateConnectionPosition(
+ connectionSelection.datum(),
+ delta
+ );
+ if (connectionUpdate !== null) {
+ updates.set(connection.id,
connectionUpdate);
+ }
+ }
+ }
+ });
+
+ updates.set(d.id,
this.draggableBehavior.updateComponentPosition(d, delta));
+ }
+ }
+ });
+
+ if (updates.size > 0) {
+ // dispatch the position updates
+ this.store.dispatch(
+ updatePositions({
+ request: {
+ requestId:
this.updateConnectionRequestId++,
+ componentUpdates:
Array.from(updates.values()),
+ connectionUpdates:
Array.from(updates.values())
+ }
+ })
+ );
+
+ for (const id of updates.keys()) {
+ FlowActions.renderConnectionsForComponent({
+ id,
+ updatePath: true,
+ updateLabel: true
+ });
+ }
Review Comment:
This is not needed because `updatePositions` will do it when the action is
complete.
##########
nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts:
##########
@@ -321,24 +326,209 @@ export class CanvasContextMenu implements
ContextMenuDefinitionProvider {
menuItems: [
{
condition: (selection: any) => {
- // TODO - canAlign
- return false;
+ return this.canvasUtils.canAlign(selection);
},
clazz: 'fa fa-align-center fa-rotate-90',
text: 'Horizontally',
- action: () => {
- // TODO - alignHorizontal
+ action: (selection: any) => {
+ const updates = new Map();
+
+ // determine the extent
+ let minY: number = 0,
+ maxY: number = 0;
+ selection.each((d: any) => {
+ if (d.type !== 'Connection') {
+ if (minY === 0 || d.position.y < minY) {
+ minY = d.position.y;
+ }
+ const componentMaxY = d.position.y +
d.dimensions.height;
+ if (maxY === 0 || componentMaxY > maxY) {
+ maxY = componentMaxY;
+ }
+ }
+ });
+
+ const center = (minY + maxY) / 2;
+
+ // align all components with top most component
+ selection.each((d: any) => {
+ if (d.type !== 'Connection') {
+ const 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
+ const connections =
this.canvasUtils.getComponentConnections(d.id);
+
+ connections.forEach((connection: any) => {
+ const connectionSelection =
d3.select('#id-' + connection.id);
+
+ if (
+ !updates.has(connection.id) &&
+
this.canvasUtils.getConnectionSourceComponentId(connection) ===
+
this.canvasUtils.getConnectionDestinationComponentId(connection)
+ ) {
+ // this connection is self looping and
hasn't been updated by the delta yet
+ const connectionUpdate =
this.draggableBehavior.updateConnectionPosition(
+ connectionSelection.datum(),
+ delta
+ );
+ if (connectionUpdate !== null) {
+ updates.set(connection.id,
connectionUpdate);
+ }
+ } else if (
+ !updates.has(connection.id) &&
+
connectionSelection.classed('selected') &&
+
this.canvasUtils.canModify(connectionSelection)
+ ) {
+ // this is a selected connection that
hasn't been updated by the delta yet
+ if (
+
this.canvasUtils.getConnectionSourceComponentId(connection) === d.id ||
+
!this.canvasUtils.isSourceSelected(connection, selection)
+ ) {
+ // the connection is either
outgoing or incoming when the source of the connection is not part of the
selection
+ const connectionUpdate =
this.draggableBehavior.updateConnectionPosition(
+ connectionSelection.datum(),
+ delta
+ );
+ if (connectionUpdate !== null) {
+ updates.set(connection.id,
connectionUpdate);
+ }
+ }
+ }
+ });
+
+ updates.set(d.id,
this.draggableBehavior.updateComponentPosition(d, delta));
+ }
+ }
+ });
+
+ if (updates.size > 0) {
+ // dispatch the position updates
+ this.store.dispatch(
+ updatePositions({
+ request: {
+ requestId:
this.updateConnectionRequestId++,
+ componentUpdates:
Array.from(updates.values()),
+ connectionUpdates:
Array.from(updates.values())
+ }
+ })
+ );
+
+ for (const id of updates.keys()) {
+ FlowActions.renderConnectionsForComponent({
+ id,
+ updatePath: true,
+ updateLabel: true
+ });
+ }
+ }
}
},
{
condition: (selection: any) => {
- // TODO - canAlign
- return false;
+ return this.canvasUtils.canAlign(selection);
},
clazz: 'fa fa-align-center',
text: 'Vertically',
- action: () => {
- // TODO - alignVertical
+ action: (selection: any) => {
+ const updates = new Map();
+
+ // determine the extent
+ let minX = 0;
+ let maxX = 0;
+ selection.each((d: any) => {
+ if (d.type !== 'Connection') {
+ if (minX === 0 || d.position.x < minX) {
+ minX = d.position.x;
+ }
+ const componentMaxX = d.position.x +
d.dimensions.width;
+ if (maxX === 0 || componentMaxX > maxX) {
+ maxX = componentMaxX;
+ }
+ }
+ });
+
+ const center = (minX + maxX) / 2;
+
+ // align all components with top most component
+ selection.each((d: any) => {
+ if (d.type !== 'Connection') {
+ const 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
+ const connections =
this.canvasUtils.getComponentConnections(d.id);
+ connections.forEach((connection: any) => {
+ const connectionSelection =
d3.select('#id-' + connection.id);
+
+ if (
+ !updates.has(connection.id) &&
+
this.canvasUtils.getConnectionSourceComponentId(connection) ===
+
this.canvasUtils.getConnectionDestinationComponentId(connection)
+ ) {
+ // this connection is self looping and
hasn't been updated by the delta yet
+ const connectionUpdate =
this.draggableBehavior.updateConnectionPosition(
+ connectionSelection.datum(),
+ delta
+ );
+ if (connectionUpdate !== null) {
+ updates.set(connection.id,
connectionUpdate);
+ }
+ } else if (
+ !updates.has(connection.id) &&
+
connectionSelection.classed('selected') &&
+
this.canvasUtils.canModify(connectionSelection)
+ ) {
+ // this is a selected connection that
hasn't been updated by the delta yet
+ if (
+
this.canvasUtils.getConnectionSourceComponentId(connection) === d.id ||
+
!this.canvasUtils.isSourceSelected(connection, selection)
+ ) {
+ // the connection is either
outgoing or incoming when the source of the connection is not part of the
selection
+ const connectionUpdate =
this.draggableBehavior.updateConnectionPosition(
+ connectionSelection.datum(),
+ delta
+ );
+ if (connectionUpdate !== null) {
+ updates.set(connection.id,
connectionUpdate);
+ }
+ }
+ }
+ });
+
+ updates.set(d.id,
this.draggableBehavior.updateComponentPosition(d, delta));
+ }
+ }
+ });
+
+ if (updates.size > 0) {
+ // dispatch the position updates
+ this.store.dispatch(
+ updatePositions({
+ request: {
+ requestId:
this.updateConnectionRequestId++,
+ componentUpdates:
Array.from(updates.values()),
+ connectionUpdates:
Array.from(updates.values())
+ }
+ })
+ );
+
+ for (const id of updates.keys()) {
+ FlowActions.renderConnectionsForComponent({
+ id,
+ updatePath: true,
+ updateLabel: true
+ });
+ }
Review Comment:
This is not needed because `updatePositions` will do it when the action is
complete.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]