diff --git a/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html new file mode 100644 index 0000000..f56e139 --- /dev/null +++ b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html @@ -0,0 +1,10 @@ + + + + + + +
I'm a node
+
I'm a node
+
+
diff --git a/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss new file mode 100644 index 0000000..e31db81 --- /dev/null +++ b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss @@ -0,0 +1,10 @@ +@use "../../flow-common"; + +::ng-deep grid-system-example { + @include flow-common.connection; +} + +.f-node { + @include flow-common.node; +} + diff --git a/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts new file mode 100644 index 0000000..7f55022 --- /dev/null +++ b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core'; +import { FCanvasComponent, FFlowModule } from '@foblex/flow'; + +@Component({ + selector: 'grid-system-example', + styleUrls: [ './grid-system-example.component.scss' ], + templateUrl: './grid-system-example.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [ + FFlowModule, + ] +}) +export class GridSystemExampleComponent { + + @ViewChild(FCanvasComponent, { static: true }) + public fCanvas!: FCanvasComponent; + + public onLoaded(): void { + this.fCanvas.resetScaleAndCenter(false); + } +} diff --git a/projects/f-flow/package.json b/projects/f-flow/package.json index db354ec..a581f79 100644 --- a/projects/f-flow/package.json +++ b/projects/f-flow/package.json @@ -1,6 +1,6 @@ { "name": "@foblex/flow", - "version": "17.0.5", + "version": "17.0.6", "description": "An Angular library designed to simplify the creation and manipulation of dynamic flow. Provides components for flows, nodes, and connections, automating node manipulation and inter-node connections.", "main": "index.js", "types": "index.d.ts", diff --git a/projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.execution.ts b/projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.execution.ts similarity index 100% rename from projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.execution.ts rename to projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.execution.ts diff --git a/projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.request.ts b/projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.request.ts similarity index 100% rename from projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.request.ts rename to projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.request.ts diff --git a/projects/f-flow/src/f-draggable/domain/get-node-padding/index.ts b/projects/f-flow/src/domain/f-node/get-node-padding/index.ts similarity index 100% rename from projects/f-flow/src/f-draggable/domain/get-node-padding/index.ts rename to projects/f-flow/src/domain/f-node/get-node-padding/index.ts diff --git a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.execution.ts b/projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.execution.ts similarity index 62% rename from projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.execution.ts rename to projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.execution.ts index 54f8c82..3b6a93c 100644 --- a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.execution.ts +++ b/projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.execution.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { GetParentNodesRequest } from './get-parent-nodes.request'; import { FExecutionRegister, IExecution } from '@foblex/mediator'; import { FNodeBase } from '../../../f-node'; @@ -9,27 +9,24 @@ import { FComponentsStore } from '../../../f-storage'; export class GetParentNodesExecution implements IExecution { - constructor( - private fComponentsStore: FComponentsStore - ) { - } + private _fComponentsStore = inject(FComponentsStore); public handle(request: GetParentNodesRequest): FNodeBase[] { - return this.getParentNodes(request.fNode, new Set(), []); + return this._getParentNodes(request.fNode, new Set(), []); } - private getParentNodes(fNode: FNodeBase, visited: Set, result: FNodeBase[]): FNodeBase[] { + private _getParentNodes(fNode: FNodeBase, visited: Set, result: FNodeBase[]): FNodeBase[] { if (visited.has(fNode.fId)) { throw new Error('Circular reference detected in the node hierarchy. Node id: ' + fNode.fId); } visited.add(fNode.fId); - const parent = this.fComponentsStore.fNodes.find((x) => x.fId === fNode.fParentId); + const parent = this._fComponentsStore.fNodes.find((x) => x.fId === fNode.fParentId); if (!parent) { return result; } result.push(parent); - return this.getParentNodes(parent, visited, result); + return this._getParentNodes(parent, visited, result); } } diff --git a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.request.ts b/projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.request.ts similarity index 100% rename from projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.request.ts rename to projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.request.ts diff --git a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/index.ts b/projects/f-flow/src/domain/f-node/get-parent-nodes/index.ts similarity index 100% rename from projects/f-flow/src/f-draggable/domain/get-parent-nodes/index.ts rename to projects/f-flow/src/domain/f-node/get-parent-nodes/index.ts diff --git a/projects/f-flow/src/domain/f-node/index.ts b/projects/f-flow/src/domain/f-node/index.ts index e8ff167..3acd809 100644 --- a/projects/f-flow/src/domain/f-node/index.ts +++ b/projects/f-flow/src/domain/f-node/index.ts @@ -4,8 +4,12 @@ export * from './calculate-nodes-bounding-box'; export * from './calculate-nodes-bounding-box-normalized-position'; +export * from './get-node-padding'; + export * from './get-nodes'; +export * from './get-parent-nodes'; + export * from './update-node-when-state-or-size-changed'; export * from './remove-node-from-store'; diff --git a/projects/f-flow/src/domain/f-node/providers.ts b/projects/f-flow/src/domain/f-node/providers.ts index 590f495..8efc03c 100644 --- a/projects/f-flow/src/domain/f-node/providers.ts +++ b/projects/f-flow/src/domain/f-node/providers.ts @@ -6,6 +6,8 @@ import { CalculateNodesBoundingBoxExecution } from './calculate-nodes-bounding-b import { CalculateNodesBoundingBoxNormalizedPositionExecution } from './calculate-nodes-bounding-box-normalized-position'; +import { GetNodePaddingExecution } from './get-node-padding'; +import { GetParentNodesExecution } from './get-parent-nodes'; export const F_NODE_FEATURES = [ @@ -15,8 +17,12 @@ export const F_NODE_FEATURES = [ CalculateNodesBoundingBoxNormalizedPositionExecution, + GetNodePaddingExecution, + GetNodesExecution, + GetParentNodesExecution, + UpdateNodeWhenStateOrSizeChangedExecution, RemoveNodeFromStoreExecution diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.execution.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.execution.ts deleted file mode 100644 index 0d55dd7..0000000 --- a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.execution.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core'; -import { GetNormalizedNodeRectRequest } from './get-normalized-node-rect.request'; -import { IPoint, IRect, RectExtensions } from '@foblex/2d'; -import { FExecutionRegister, IExecution } from '@foblex/mediator'; -import { FComponentsStore } from '../../../f-storage'; - -@Injectable() -@FExecutionRegister(GetNormalizedNodeRectRequest) -export class GetNormalizedNodeRectExecution - implements IExecution { - - constructor( - private fComponentsStore: FComponentsStore - ) { - } - - public handle(request: GetNormalizedNodeRectRequest): IRect { - return this.normalizeRect(RectExtensions.fromElement(request.fNode.hostElement), request.fNode.position); - } - - private normalizeRect(scaledRect: IRect, position: IPoint): IRect { - const rect = RectExtensions.div(scaledRect, this.fComponentsStore.fCanvas!.transform.scale); - - return RectExtensions.initialize(position.x, position.y, rect.width, rect.height); - } -} diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.request.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.request.ts deleted file mode 100644 index e85dd3b..0000000 --- a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.request.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FNodeBase } from '../../../f-node'; - -export class GetNormalizedNodeRectRequest { - - constructor( - public fNode: FNodeBase - ) { - } -} diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/index.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/index.ts deleted file mode 100644 index c444ed8..0000000 --- a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './get-normalized-node-rect.execution'; - -export * from './get-normalized-node-rect.request'; diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts index e86ce5e..54cba89 100644 --- a/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts +++ b/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts @@ -1,11 +1,11 @@ import { Injectable } from '@angular/core'; import { GetNormalizedParentNodeRectRequest } from './get-normalized-parent-node-rect.request'; import { IRect, RectExtensions } from '@foblex/2d'; -import { GetNormalizedNodeRectRequest } from '../get-normalized-node-rect'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; import { FNodeBase } from '../../../f-node'; import { FComponentsStore } from '../../../f-storage'; -import { GetNodePaddingRequest } from '../get-node-padding'; +import { GetNodePaddingRequest } from '../../../domain'; +import { GetNormalizedElementRectRequest } from '../../../domain'; @Injectable() @FExecutionRegister(GetNormalizedParentNodeRectRequest) @@ -32,18 +32,18 @@ export class GetNormalizedParentNodeRectExecution } private getParentRect(node: FNodeBase): IRect { - const rect = this.getNormalizedNodeRect(node); + const rect = this._getNodeRect(node); const padding = this.getNodePadding(node, rect); return RectExtensions.initialize( - rect.x + padding[0], - rect.y + padding[1], - rect.width - padding[0] - padding[2], - rect.height - padding[1] - padding[3] + rect.x + padding[ 0 ], + rect.y + padding[ 1 ], + rect.width - padding[ 0 ] - padding[ 2 ], + rect.height - padding[ 1 ] - padding[ 3 ] ); } - private getNormalizedNodeRect(node: FNodeBase): IRect { - return this.fMediator.send(new GetNormalizedNodeRectRequest(node)); + private _getNodeRect(fNode: FNodeBase): IRect { + return this.fMediator.send(new GetNormalizedElementRectRequest(fNode.hostElement)); } private getNodePadding(node: FNodeBase, rect: IRect): [ number, number, number, number ] { diff --git a/projects/f-flow/src/f-draggable/domain/index.ts b/projects/f-flow/src/f-draggable/domain/index.ts index a5d4d32..5c2178c 100644 --- a/projects/f-flow/src/f-draggable/domain/index.ts +++ b/projects/f-flow/src/f-draggable/domain/index.ts @@ -1,11 +1,5 @@ -export * from './get-node-padding'; - -export * from './get-normalized-node-rect'; - export * from './get-normalized-parent-node-rect'; -export * from './get-parent-nodes'; - export * from './is-array-has-parent-node'; export * from './is-connection-under-node'; diff --git a/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts b/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts index 250e2b8..b36e8f4 100644 --- a/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts +++ b/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { IsArrayHasParentNodeRequest } from './is-array-has-parent-node.request'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; import { FNodeBase } from '../../../f-node'; -import { GetParentNodesRequest } from '../get-parent-nodes'; +import { GetParentNodesRequest } from '../../../domain/f-node/get-parent-nodes'; @Injectable() @FExecutionRegister(IsArrayHasParentNodeRequest) diff --git a/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts b/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts index e1919f7..87088c5 100644 --- a/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts +++ b/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts @@ -1,3 +1,2 @@ export class IsConnectionUnderNodeRequest { - } diff --git a/projects/f-flow/src/f-draggable/domain/providers.ts b/projects/f-flow/src/f-draggable/domain/providers.ts index 5c4b244..e052299 100644 --- a/projects/f-flow/src/f-draggable/domain/providers.ts +++ b/projects/f-flow/src/f-draggable/domain/providers.ts @@ -1,20 +1,11 @@ -import { GetNormalizedNodeRectExecution } from './get-normalized-node-rect'; -import { GetParentNodesExecution } from './get-parent-nodes'; import { IsArrayHasParentNodeExecution } from './is-array-has-parent-node'; import { GetNormalizedParentNodeRectExecution } from './get-normalized-parent-node-rect'; -import { GetNodePaddingExecution } from './get-node-padding'; import { IsConnectionUnderNodeExecution, IsConnectionUnderNodeValidator } from './is-connection-under-node'; export const DRAG_AND_DROP_COMMON_PROVIDERS = [ - GetNodePaddingExecution, - - GetNormalizedNodeRectExecution, - GetNormalizedParentNodeRectExecution, - GetParentNodesExecution, - IsArrayHasParentNodeExecution, IsConnectionUnderNodeExecution, diff --git a/projects/f-flow/src/f-draggable/f-draggable-base.ts b/projects/f-flow/src/f-draggable/f-draggable-base.ts index 123f4cd..0b4a168 100644 --- a/projects/f-flow/src/f-draggable/f-draggable-base.ts +++ b/projects/f-flow/src/f-draggable/f-draggable-base.ts @@ -21,6 +21,10 @@ export abstract class FDraggableBase extends DragAndDropBase { public abstract fDropToGroup: EventEmitter; + public abstract vCellSize: number; + + public abstract hCellSize: number; + protected constructor( ngZone: ICanRunOutsideAngular | undefined ) { diff --git a/projects/f-flow/src/f-draggable/f-draggable.directive.ts b/projects/f-flow/src/f-draggable/f-draggable.directive.ts index 4a03e49..e7ceb9e 100644 --- a/projects/f-flow/src/f-draggable/f-draggable.directive.ts +++ b/projects/f-flow/src/f-draggable/f-draggable.directive.ts @@ -66,22 +66,29 @@ export class FDraggableDirective extends FDraggableBase implements OnInit, After } @Output() - public override fSelectionChange: EventEmitter = new EventEmitter(); + public override fSelectionChange = new EventEmitter(); @Output() - public override fNodeIntersectedWithConnections: EventEmitter = new EventEmitter(); + public override fNodeIntersectedWithConnections = new EventEmitter(); @Output() - public override fCreateNode: EventEmitter = new EventEmitter(); + public override fCreateNode = new EventEmitter(); @Output() - public override fReassignConnection: EventEmitter = new EventEmitter(); + public override fReassignConnection = new EventEmitter(); @Output() - public override fCreateConnection: EventEmitter = new EventEmitter(); + public override fCreateConnection = new EventEmitter(); @Output() - public override fDropToGroup: EventEmitter = new EventEmitter(); + public override fDropToGroup = new EventEmitter(); + + @Input() + public override vCellSize = 1; + + + @Input() + public override hCellSize = 1; @ContentChildren(F_DRAG_AND_DROP_PLUGIN, { descendants: true }) private plugins!: QueryList; diff --git a/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts b/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts index 09f01cb..61acd2f 100644 --- a/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts +++ b/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts @@ -3,9 +3,10 @@ import { GetNodeResizeRestrictionsRequest } from './get-node-resize-restrictions import { IRect, SizeExtensions } from '@foblex/2d'; import { INodeResizeRestrictions } from './i-node-resize-restrictions'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; -import { GetNodePaddingRequest, GetNormalizedParentNodeRectRequest } from '../../domain'; +import { GetNormalizedParentNodeRectRequest } from '../../domain'; import { GetNormalizedChildrenNodesRectRequest } from '../get-normalized-children-nodes-rect'; import { FNodeBase } from '../../../f-node'; +import { GetNodePaddingRequest } from '../../../domain'; @Injectable() diff --git a/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts b/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts index 15af09b..87d6058 100644 --- a/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts +++ b/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts @@ -3,8 +3,7 @@ import { GetNormalizedChildrenNodesRectRequest } from './get-normalized-children import { IRect, RectExtensions } from '@foblex/2d'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; import { FNodeBase } from '../../../f-node'; -import { GetNormalizedNodeRectRequest } from '../../domain'; -import { GetDeepChildrenNodesAndGroupsRequest } from '../../../domain'; +import { GetDeepChildrenNodesAndGroupsRequest, GetNormalizedElementRectRequest } from '../../../domain'; @Injectable() @FExecutionRegister(GetNormalizedChildrenNodesRectRequest) @@ -28,8 +27,8 @@ export class GetNormalizedChildrenNodesRectExecution return this.fMediator.send(new GetDeepChildrenNodesAndGroupsRequest(fId)); } - private normalizeRect(node: FNodeBase): IRect { - return this.fMediator.send(new GetNormalizedNodeRectRequest(node)); + private normalizeRect(fNode: FNodeBase): IRect { + return this.fMediator.send(new GetNormalizedElementRectRequest(fNode.hostElement)); } private concatRectWithParentPadding(rect: IRect, padding: [ number, number, number, number ]): IRect { diff --git a/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts b/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts index d02ce24..e1c6464 100644 --- a/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts +++ b/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts @@ -2,12 +2,12 @@ import { IPoint, IRect, ISize, RectExtensions } from '@foblex/2d'; import { IDraggableItem } from '../i-draggable-item'; import { EFResizeHandleType, FNodeBase } from '../../f-node'; import { FMediator } from '@foblex/mediator'; -import { GetNormalizedNodeRectRequest } from '../domain'; import { GetNodeResizeRestrictionsRequest, INodeResizeRestrictions } from './get-node-resize-restrictions'; import { ApplyChildResizeRestrictionsRequest } from './apply-child-resize-restrictions'; import { CalculateChangedSizeRequest } from './calculate-changed-size'; import { CalculateChangedPositionRequest } from './calculate-changed-position'; import { ApplyParentResizeRestrictionsRequest } from './apply-parent-resize-restrictions'; +import { GetNormalizedElementRectRequest } from '../../domain'; export class NodeResizeDragHandler implements IDraggableItem { @@ -26,7 +26,7 @@ export class NodeResizeDragHandler implements IDraggableItem { } public prepareDragSequence(): void { - this.originalRect = this.fMediator.send(new GetNormalizedNodeRectRequest(this.fNode)); + this.originalRect = this.fMediator.send(new GetNormalizedElementRectRequest(this.fNode.hostElement)); this.restrictions = this.fMediator.send(new GetNodeResizeRestrictionsRequest(this.fNode, this.originalRect)); if (this.restrictions.childRect) { diff --git a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts index a28c3ee..af696b4 100644 --- a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts +++ b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { CreateMoveNodesDragModelFromSelectionRequest } from './create-move-nodes-drag-model-from-selection.request'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; import { FComponentsStore } from '../../../f-storage'; @@ -14,8 +14,8 @@ import { PutInputConnectionHandlersToArrayRequest } from './domain/put-input-connection-handlers-to-array'; import { NodeResizeByChildDragHandler } from '../node-resize-by-child.drag-handler'; -import { GetParentNodesRequest, IsArrayHasParentNodeRequest } from '../../domain'; -import { GetDeepChildrenNodesAndGroupsRequest } from '../../../domain'; +import { IsArrayHasParentNodeRequest } from '../../domain'; +import { GetDeepChildrenNodesAndGroupsRequest, GetParentNodesRequest } from '../../../domain'; import { flatMap } from '@foblex/utils'; @Injectable() @@ -23,15 +23,14 @@ import { flatMap } from '@foblex/utils'; export class CreateMoveNodesDragModelFromSelectionExecution implements IExecution { - constructor( - private fComponentsStore: FComponentsStore, - private fDraggableDataContext: FDraggableDataContext, - private fMediator: FMediator - ) { - } + private _fMediator = inject(FMediator); + private _fComponentsStore = inject(FComponentsStore); + private _fDraggableDataContext = inject(FDraggableDataContext); public handle(request: CreateMoveNodesDragModelFromSelectionRequest): IDraggableItem[] { - const itemsToDrag = this.getNodesWithRestrictions(this.getSelectedNodes(request.nodeWithDisabledSelection)); + const itemsToDrag = this._getNodesWithRestrictions( + this._getSelectedNodes(request.nodeWithDisabledSelection) + ); return this.getDragHandlersWithConnections( this.getDragHandlersFromNodes(itemsToDrag), this.getAllOutputIds(itemsToDrag), @@ -39,27 +38,31 @@ export class CreateMoveNodesDragModelFromSelectionExecution ); } - private getSelectedNodes(nodeWithDisabledSelection?: FNodeBase): FNodeBase[] { - const result = this.fDraggableDataContext.selectedItems - .map((x) => this._findNode(x.hostElement)) - .filter((x): x is FNodeBase => !!x); + private _getSelectedNodes(nodeWithDisabledSelection?: FNodeBase): FNodeBase[] { + const result = this._getNodesFromSelection(); if(nodeWithDisabledSelection) { result.push(nodeWithDisabledSelection); } return result; } + private _getNodesFromSelection(): FNodeBase[] { + return this._fDraggableDataContext.selectedItems + .map((x) => this._findNode(x.hostElement)) + .filter((x): x is FNodeBase => !!x); + } + private _findNode(hostElement: HTMLElement | SVGElement): FNodeBase | undefined { - return this.fComponentsStore.fNodes.find(n => n.isContains(hostElement)); + return this._fComponentsStore.fNodes.find(n => n.isContains(hostElement)); } - private getNodesWithRestrictions(selectedNodes: FNodeBase[]): INodeWithDistanceRestrictions[] { + private _getNodesWithRestrictions(nodesToDrag: FNodeBase[]): INodeWithDistanceRestrictions[] { const result: INodeWithDistanceRestrictions[] = []; - selectedNodes.forEach((x) => { - const hasParentNodeInSelected = this.fMediator.send(new IsArrayHasParentNodeRequest(x, selectedNodes)); - const restrictions = this.fMediator.send(new GetNodeMoveRestrictionsRequest(x, hasParentNodeInSelected)); - const parentNodes = this.fMediator.send(new GetParentNodesRequest(x)); + nodesToDrag.forEach((x) => { + const hasParentNodeInSelected = this._fMediator.send(new IsArrayHasParentNodeRequest(x, nodesToDrag)); + const restrictions = this._fMediator.send(new GetNodeMoveRestrictionsRequest(x, hasParentNodeInSelected)); + const parentNodes = this._fMediator.send(new GetParentNodesRequest(x)); result.push({ node: x, parentNodes, ...restrictions }, ...this.getChildrenItemsToDrag(x, restrictions)); }); @@ -71,7 +74,7 @@ export class CreateMoveNodesDragModelFromSelectionExecution } private getChildrenNodes(fId: string): FNodeBase[] { - return this.fMediator.send(new GetDeepChildrenNodesAndGroupsRequest(fId)); + return this._fMediator.send(new GetDeepChildrenNodesAndGroupsRequest(fId)); } private getAllOutputIds(items: INodeWithDistanceRestrictions[]): string[] { @@ -79,7 +82,7 @@ export class CreateMoveNodesDragModelFromSelectionExecution } private getOutputsForNode(node: FNodeBase): FConnectorBase[] { - return this.fComponentsStore.fOutputs.filter((x) => node.isContains(x.hostElement)); + return this._fComponentsStore.fOutputs.filter((x) => node.isContains(x.hostElement)); } private getAllInputIds(items: INodeWithDistanceRestrictions[]): string[] { @@ -87,7 +90,7 @@ export class CreateMoveNodesDragModelFromSelectionExecution } private getInputsForNode(node: FNodeBase): FConnectorBase[] { - return this.fComponentsStore.fInputs.filter((x) => node.isContains(x.hostElement)); + return this._fComponentsStore.fInputs.filter((x) => node.isContains(x.hostElement)); } private getDragHandlersFromNodes(items: INodeWithDistanceRestrictions[]): IDraggableItem[] { @@ -95,8 +98,8 @@ export class CreateMoveNodesDragModelFromSelectionExecution items.forEach((node) => { result.push( - new NodeDragHandler(this.fDraggableDataContext, node.node, node.min, node.max), - ...(node.parentNodes || []).map(() => new NodeResizeByChildDragHandler(this.fDraggableDataContext)) + new NodeDragHandler(this._fDraggableDataContext, this._fComponentsStore, node.node, node.min, node.max), + ...(node.parentNodes || []).map(() => new NodeResizeByChildDragHandler(this._fDraggableDataContext)) ); }); return result; @@ -107,8 +110,8 @@ export class CreateMoveNodesDragModelFromSelectionExecution ): IDraggableItem[] { let result: IDraggableItem[] = handlers; handlers.filter((x) => x instanceof NodeDragHandler).forEach((dragHandler) => { - this.fMediator.send(new PutOutputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, inputIds, result)); - this.fMediator.send(new PutInputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, outputIds, result)); + this._fMediator.send(new PutOutputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, inputIds, result)); + this._fMediator.send(new PutInputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, outputIds, result)); }); return result; } diff --git a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts index 1849476..6950494 100644 --- a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts +++ b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts @@ -1,25 +1,23 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { GetNodeMoveRestrictionsRequest } from './get-node-move-restrictions.request'; import { IRect, PointExtensions } from '@foblex/2d'; import { INodeMoveRestrictions } from './i-node-move-restrictions'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; -import { GetNormalizedNodeRectRequest, GetNormalizedParentNodeRectRequest } from '../../../../domain'; +import { GetNormalizedParentNodeRectRequest } from '../../../../domain'; import { FNodeBase } from '../../../../../f-node'; +import { GetNormalizedElementRectRequest } from '../../../../../domain'; @Injectable() @FExecutionRegister(GetNodeMoveRestrictionsRequest) export class GetNodeMoveRestrictionsExecution implements IExecution { - constructor( - private fMediator: FMediator - ) { - } + private _fMediator = inject(FMediator); public handle(request: GetNodeMoveRestrictionsRequest): INodeMoveRestrictions { if (request.fNode.fParentId && !request.hasParentNodeInSelected) { const fParentNodeRect = this.getParentNodeRect(request.fNode); - const fCurrentNodeRect = this.getCurrentNodeRect(request.fNode); + const fCurrentNodeRect = this._getNodeRect(request.fNode); return { min: PointExtensions.initialize(fParentNodeRect.x - fCurrentNodeRect.x, fParentNodeRect.y - fCurrentNodeRect.y), max: PointExtensions.initialize( @@ -31,12 +29,12 @@ export class GetNodeMoveRestrictionsExecution return { ...DEFAULT_RESTRICTIONS }; } - private getCurrentNodeRect(fNode: FNodeBase): IRect { - return this.fMediator.send(new GetNormalizedNodeRectRequest(fNode)); + private _getNodeRect(fNode: FNodeBase): IRect { + return this._fMediator.send(new GetNormalizedElementRectRequest(fNode.hostElement)); } private getParentNodeRect(fNode: FNodeBase): IRect { - return this.fMediator.send(new GetNormalizedParentNodeRectRequest(fNode)); + return this._fMediator.send(new GetNormalizedParentNodeRectRequest(fNode)); } } diff --git a/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts b/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts index f1e1376..4a9d34d 100644 --- a/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts +++ b/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { NodeMoveFinalizeRequest } from './node-move-finalize.request'; import { IPoint, Point } from '@foblex/2d'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; @@ -6,50 +6,70 @@ import { FComponentsStore } from '../../../f-storage'; import { FDraggableDataContext } from '../../f-draggable-data-context'; import { IsConnectionUnderNodeRequest -} from '../../domain/is-connection-under-node/is-connection-under-node.request'; +} from '../../domain'; import { IDraggableItem } from '../../i-draggable-item'; import { NodeDragToParentDragHandler } from '../node-drag-to-parent.drag-handler'; +import { ILineAlignmentResult } from '../../../f-line-alignment'; +import { NodeDragHandler } from '../node.drag-handler'; @Injectable() @FExecutionRegister(NodeMoveFinalizeRequest) export class NodeMoveFinalizeExecution implements IExecution { - private get flowHost(): HTMLElement { - return this.fComponentsStore.fFlow!.hostElement; - } + private _fMediator = inject(FMediator); + private _fComponentsStore = inject(FComponentsStore); + private _fDraggableDataContext = inject(FDraggableDataContext); - constructor( - private fComponentsStore: FComponentsStore, - private fDraggableDataContext: FDraggableDataContext, - private fMediator: FMediator - ) { + private get _fHost(): HTMLElement { + return this._fComponentsStore.fFlow!.hostElement; } public handle(request: NodeMoveFinalizeRequest): void { - const difference = this.getDifferenceWithLineAlignment( - this.getDifferenceBetweenPreparationAndFinalize(request.event.getPosition()) + const difference = this._getDifferenceWithLineAlignment( + this._getDifferenceBetweenPreparationAndFinalize(request.event.getPosition()) ); - this.getItems().forEach((x) => { + + const firstNodeOrGroup = this._fDraggableDataContext.draggableItems + .find((x) => x instanceof NodeDragHandler)!; + + const differenceWithCellSize = firstNodeOrGroup.getDifferenceWithCellSize(difference); + + this._finalizeMove(differenceWithCellSize); + + this._fMediator.send(new IsConnectionUnderNodeRequest()); + this._fDraggableDataContext.fLineAlignment?.complete(); + } + + private _finalizeMove(difference: IPoint): void { + this._getItems().forEach((x) => { x.onPointerMove({ ...difference }); x.onPointerUp?.(); }); - this.fMediator.send(new IsConnectionUnderNodeRequest()); - this.fDraggableDataContext.fLineAlignment?.complete(); } - private getItems(): IDraggableItem[] { - return this.fDraggableDataContext.draggableItems + private _getItems(): IDraggableItem[] { + return this._fDraggableDataContext.draggableItems .filter((x) => !(x instanceof NodeDragToParentDragHandler)); } - private getDifferenceBetweenPreparationAndFinalize(position: IPoint): Point { - return Point.fromPoint(position).elementTransform(this.flowHost) - .div(this.fDraggableDataContext.onPointerDownScale) - .sub(this.fDraggableDataContext.onPointerDownPosition); + private _getDifferenceBetweenPreparationAndFinalize(position: IPoint): Point { + return Point.fromPoint(position).elementTransform(this._fHost) + .div(this._fDraggableDataContext.onPointerDownScale) + .sub(this._fDraggableDataContext.onPointerDownPosition); + } + + private _getDifferenceWithLineAlignment(difference: IPoint): IPoint { + return this._applyLineAlignmentDifference( + difference, + this._getLineAlignmentDifference(difference) + ); + } + + private _getLineAlignmentDifference(difference: IPoint): ILineAlignmentResult | undefined { + return this._fDraggableDataContext.fLineAlignment?.findNearestCoordinate(difference); } - private getDifferenceWithLineAlignment(difference: IPoint): IPoint { - const intersection = this.fDraggableDataContext.fLineAlignment?.findNearestCoordinate(difference); + private _applyLineAlignmentDifference(difference: IPoint, intersection: ILineAlignmentResult | undefined): IPoint { if (intersection) { difference.x = intersection.xResult.value ? (difference.x - intersection.xResult.distance!) : difference.x; difference.y = intersection.yResult.value ? (difference.y - intersection.yResult.distance!) : difference.y; diff --git a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts index 0f4e59c..a8f6fd1 100644 --- a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts +++ b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { NodeMovePreparationRequest } from './node-move-preparation.request'; import { ITransformModel, Point } from '@foblex/2d'; import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator'; @@ -14,66 +14,68 @@ import { SelectAndUpdateNodeLayerRequest } from '../../../domain'; @FExecutionRegister(NodeMovePreparationRequest) export class NodeMovePreparationExecution implements IExecution { - private get transform(): ITransformModel { - return this.fComponentsStore.fCanvas!.transform; - } + private _fMediator = inject(FMediator); + private _fComponentsStore = inject(FComponentsStore); + private _fDraggableDataContext = inject(FDraggableDataContext); - private get flowHost(): HTMLElement { - return this.fComponentsStore.fFlow!.hostElement; + private get _transform(): ITransformModel { + return this._fComponentsStore.fCanvas!.transform; } - constructor( - private fComponentsStore: FComponentsStore, - private fDraggableDataContext: FDraggableDataContext, - private fMediator: FMediator - ) { + private get _fHost(): HTMLElement { + return this._fComponentsStore.fFlow!.hostElement; } public handle(request: NodeMovePreparationRequest): void { - const node = this.getNode(request.event.targetElement); - if (!node) { - throw new Error('Node not found'); - } - let itemsToDrag: IDraggableItem[] = []; - if (!node.fSelectionDisabled) { - this.selectAndUpdateNodeLayer(node); - itemsToDrag = this.createDragModelFromSelection(); - } else { - itemsToDrag = this.createDragModelFromSelection(node); - } - this.initializeLineAlignment(this.filterNodesFromDraggableItems(itemsToDrag)); + const itemsToDrag = this._calculateDraggableItems( + this._getNode(request.event.targetElement) + ); + + this._initializeLineAlignment(itemsToDrag); - this.fDraggableDataContext.onPointerDownScale = this.transform.scale; - this.fDraggableDataContext.onPointerDownPosition = Point.fromPoint(request.event.getPosition()) - .elementTransform(this.flowHost).div(this.transform.scale); - this.fDraggableDataContext.draggableItems = itemsToDrag; + this._fDraggableDataContext.onPointerDownScale = this._transform.scale; + this._fDraggableDataContext.onPointerDownPosition = Point.fromPoint(request.event.getPosition()) + .elementTransform(this._fHost).div(this._transform.scale); + this._fDraggableDataContext.draggableItems = itemsToDrag; } - private selectAndUpdateNodeLayer(node: FNodeBase) { - this.fMediator.send( - new SelectAndUpdateNodeLayerRequest(node) - ); + private _getNode(targetElement: HTMLElement): FNodeBase { + const result = this._fComponentsStore.fNodes.find(n => n.isContains(targetElement))!; + if (!result) { + throw new Error('Node not found'); + } + return result; } - private getNode(targetElement: HTMLElement): FNodeBase { - return this.fComponentsStore.fNodes.find(n => n.isContains(targetElement))!; + //We drag nodes from selection model + private _calculateDraggableItems(fNode: FNodeBase): IDraggableItem[] { + let result: IDraggableItem[] = []; + if (!fNode.fSelectionDisabled) { + // Need to select node before drag + this._fMediator.send(new SelectAndUpdateNodeLayerRequest(fNode)); + + result = this._dragModelFromSelection(); + } else { + // User can drag node that can't be selected + result = this._dragModelFromSelection(fNode); + } + return result; } - private createDragModelFromSelection(nodeWithDisabledSelection?: FNodeBase): IDraggableItem[] { - return this.fMediator.send( + private _dragModelFromSelection(nodeWithDisabledSelection?: FNodeBase): IDraggableItem[] { + return this._fMediator.send( new CreateMoveNodesDragModelFromSelectionRequest(nodeWithDisabledSelection) ); } - private initializeLineAlignment(nodesToDrag: FNodeBase[]): void { - this.fDraggableDataContext.fLineAlignment?.initialize( - this.fComponentsStore.fNodes, - nodesToDrag + private _initializeLineAlignment(itemsToDrag: IDraggableItem[]): void { + this._fDraggableDataContext.fLineAlignment?.initialize( + this._fComponentsStore.fNodes, this._filterNodesFromDraggableItems(itemsToDrag) ); } - private filterNodesFromDraggableItems(items: IDraggableItem[]): FNodeBase[] { + private _filterNodesFromDraggableItems(items: IDraggableItem[]): FNodeBase[] { return items.filter((x) => x instanceof NodeDragHandler) .map(x => (x as NodeDragHandler).fNode); } diff --git a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts index f92941f..31a4a33 100644 --- a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts +++ b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { NodeMovePreparationRequest } from './node-move-preparation.request'; import { FValidatorRegister, IValidator } from '@foblex/mediator'; import { FComponentsStore } from '../../../f-storage'; @@ -10,31 +10,28 @@ import { isClosestElementHasClass } from '@foblex/utils'; @FValidatorRegister(NodeMovePreparationRequest) export class NodeMovePreparationValidator implements IValidator { - constructor( - private fComponentsStore: FComponentsStore, - private fDraggableDataContext: FDraggableDataContext - ) { - } + private _fComponentsStore = inject(FComponentsStore); + private _fDraggableDataContext = inject(FDraggableDataContext); public handle(request: NodeMovePreparationRequest): boolean { - return this.isDragHandlesEmpty() - && this.isDragHandleElement(request.event.targetElement) - && this.isNodeCanBeDragged(this.getNode(request.event.targetElement)); + return this._isDragHandlesEmpty() + && this._isDragHandleElement(request.event.targetElement) + && this._isNodeCanBeDragged(this._getNode(request.event.targetElement)); } - private isDragHandlesEmpty(): boolean { - return !this.fDraggableDataContext.draggableItems.length; + private _isDragHandlesEmpty(): boolean { + return !this._fDraggableDataContext.draggableItems.length; } - private getNode(targetElement: HTMLElement): FNodeBase | undefined { - return this.fComponentsStore.fNodes.find(n => n.isContains(targetElement)); + private _isDragHandleElement(element: HTMLElement): boolean { + return isClosestElementHasClass(element, '.f-drag-handle'); } - private isNodeCanBeDragged(node: FNodeBase | undefined): boolean { - return !!node && !node.fDraggingDisabled; + private _isNodeCanBeDragged(fNode: FNodeBase | undefined): boolean { + return !!fNode && !fNode.fDraggingDisabled; } - private isDragHandleElement(targetElement: HTMLElement): boolean { - return isClosestElementHasClass(targetElement, '.f-drag-handle'); + private _getNode(element: HTMLElement): FNodeBase | undefined { + return this._fComponentsStore.fNodes.find(x => x.isContains(element)); } } diff --git a/projects/f-flow/src/f-draggable/node/node.drag-handler.ts b/projects/f-flow/src/f-draggable/node/node.drag-handler.ts index a1dd66e..b18de13 100644 --- a/projects/f-flow/src/f-draggable/node/node.drag-handler.ts +++ b/projects/f-flow/src/f-draggable/node/node.drag-handler.ts @@ -5,39 +5,41 @@ import { FNodeBase } from '../../f-node'; import { INodeMoveRestrictions } from './create-move-nodes-drag-model-from-selection'; +import { FComponentsStore } from '../../f-storage'; export class NodeDragHandler implements IDraggableItem { - private onPointerDownPosition: IPoint = PointExtensions.initialize(); + private readonly _onPointerDownPosition = PointExtensions.initialize(); constructor( private fDraggableDataContext: FDraggableDataContext, + private fComponentsStore: FComponentsStore, public fNode: FNodeBase, public minDistance: IPoint, public maxDistance: IPoint, ) { - this.onPointerDownPosition = { ...fNode.position }; + this._onPointerDownPosition = { ...fNode.position }; } public onPointerMove(difference: IPoint): void { - const restrictedDifference = this.getDifference(difference, { min: this.minDistance, max: this.maxDistance }); + const restrictedDifference = this._getDifference(difference, { min: this.minDistance, max: this.maxDistance }); - this.redrawNode(this.getNewPosition(restrictedDifference)); + this._redraw(this._getPosition(restrictedDifference)); this.fDraggableDataContext.fLineAlignment?.handle(restrictedDifference); } - private getNewPosition(difference: IPoint): IPoint { - return Point.fromPoint(this.onPointerDownPosition).add(difference); + private _getPosition(difference: IPoint): IPoint { + return Point.fromPoint(this._onPointerDownPosition).add(difference); } - private getDifference(difference: IPoint, restrictions: INodeMoveRestrictions): IPoint { + private _getDifference(difference: IPoint, restrictions: INodeMoveRestrictions): IPoint { return { x: Math.min(Math.max(difference.x, restrictions.min.x), restrictions.max.x), y: Math.min(Math.max(difference.y, restrictions.min.y), restrictions.max.y) } } - private redrawNode(position: IPoint): void { + private _redraw(position: IPoint): void { this.fNode.updatePosition(position); this.fNode.redraw(); } @@ -45,4 +47,20 @@ export class NodeDragHandler implements IDraggableItem { public onPointerUp(): void { this.fNode.positionChange.emit(this.fNode.position); } + + public getDifferenceWithCellSize(difference: IPoint): IPoint { + const restrictedDifference = this._getDifference(difference, { min: this.minDistance, max: this.maxDistance }); + const position = this._getPosition(restrictedDifference); + + return Point.fromPoint(this._applyCellSize(position)).sub(this._onPointerDownPosition); + } + + private _applyCellSize(position: IPoint): IPoint { + const hCellSize = this.fComponentsStore.fDraggable!.hCellSize; + const vCellSize = this.fComponentsStore.fDraggable!.vCellSize; + return { + x: Math.round(position.x / hCellSize) * hCellSize, + y: Math.round(position.y / vCellSize) * vCellSize + }; + } } diff --git a/projects/f-flow/src/f-node/domain/index.ts b/projects/f-flow/src/f-node/domain/index.ts deleted file mode 100644 index 1760961..0000000 --- a/projects/f-flow/src/f-node/domain/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './is-node'; diff --git a/projects/f-flow/src/f-node/f-drag-handle/f-drag-handle.directive.ts b/projects/f-flow/src/f-node/f-drag-handle.directive.ts similarity index 90% rename from projects/f-flow/src/f-node/f-drag-handle/f-drag-handle.directive.ts rename to projects/f-flow/src/f-node/f-drag-handle.directive.ts index 59f1afe..5ee63bc 100644 --- a/projects/f-flow/src/f-node/f-drag-handle/f-drag-handle.directive.ts +++ b/projects/f-flow/src/f-node/f-drag-handle.directive.ts @@ -1,7 +1,7 @@ import { Directive, ElementRef, inject, InjectionToken } from "@angular/core"; -import { IHasHostElement } from '../../i-has-host-element'; +import { IHasHostElement } from '../i-has-host-element'; export const F_DRAG_HANDLE = new InjectionToken('F_DRAG_HANDLE'); diff --git a/projects/f-flow/src/f-node/f-drag-handle/index.ts b/projects/f-flow/src/f-node/f-drag-handle/index.ts deleted file mode 100644 index fc5f5d6..0000000 --- a/projects/f-flow/src/f-node/f-drag-handle/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './f-drag-handle.directive'; diff --git a/projects/f-flow/src/f-node/index.ts b/projects/f-flow/src/f-node/index.ts index 2ebbf99..be9c61f 100644 --- a/projects/f-flow/src/f-node/index.ts +++ b/projects/f-flow/src/f-node/index.ts @@ -1,17 +1,17 @@ -export * from './domain'; - -export * from './f-drag-handle'; - export * from './f-resize-handle'; export * from './f-rotate-handle'; +export * from './f-drag-handle.directive'; + export * from './f-group.directive'; export * from './f-node.directive'; export * from './f-node-base'; +export * from './is-node'; + export * from './providers'; diff --git a/projects/f-flow/src/f-node/domain/is-node.ts b/projects/f-flow/src/f-node/is-node.ts similarity index 100% rename from projects/f-flow/src/f-node/domain/is-node.ts rename to projects/f-flow/src/f-node/is-node.ts diff --git a/projects/f-flow/src/f-node/providers.ts b/projects/f-flow/src/f-node/providers.ts index c571063..899ded7 100644 --- a/projects/f-flow/src/f-node/providers.ts +++ b/projects/f-flow/src/f-node/providers.ts @@ -1,7 +1,7 @@ import { FNodeDirective } from './f-node.directive'; -import { FDragHandleDirective } from './f-drag-handle'; import { FResizeHandleDirective } from './f-resize-handle'; import { FGroupDirective } from './f-group.directive'; +import { FDragHandleDirective } from './f-drag-handle.directive'; export const F_NODE_PROVIDERS = [ diff --git a/public/markdown/examples/environment.ts b/public/markdown/examples/environment.ts index 9f394c4..44b0208 100644 --- a/public/markdown/examples/environment.ts +++ b/public/markdown/examples/environment.ts @@ -176,6 +176,10 @@ function createEnvironment(): IDocsEnvironment { tag: 'tournament-bracket', component: import('../../../projects/f-pro-examples/tournament-bracket/tournament-bracket.component') }, + { + tag: 'grid-system-example', + component: import('../../../projects/f-examples/extensions/grid-system-example/grid-system-example.component') + } ], socialLinks: [ { icon: 'github', link: 'https://github.com/Foblex/f-flow' }, @@ -545,6 +549,20 @@ function extensionGroup(): INavigationGroup { image_height: 600, image_type: 'image/png', }, + { + link: 'grid-system', + text: 'Grid System', + description: 'Add a grid system to Foblex Flow diagrams for Angular.', + image: './previews/examples/grid-system-example.light.png', + image_dark: './previews/examples/grid-system-example.dark.png', + image_width: 821, + image_height: 600, + image_type: 'image/png', + badge: { + text: 'New', + type: 'info' + } + }, { link: 'minimap', text: 'Minimap', diff --git a/public/markdown/examples/grid-system.md b/public/markdown/examples/grid-system.md new file mode 100644 index 0000000..a72ddcd --- /dev/null +++ b/public/markdown/examples/grid-system.md @@ -0,0 +1,21 @@ +# Grid System + +## Description + +This guide demonstrates how to position nodes in a grid system using Foblex Flow for Angular. To enable the grid system, you need to parameterize the [fDraggable](./docs/f-draggable-directive) directive with the grid properties `[vCellSize]` and `[hCellSize]`. + +- `[vCellSize]`: Defines the vertical size of each grid cell. +- `[hCellSize]`: Defines the horizontal size of each grid cell. + +## Example + +::: ng-component [height]="600" +[component.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html +[component.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts +[component.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss +[common.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/_flow-common.scss +::: + + + + diff --git a/public/markdown/guides/f-draggable-directive.md b/public/markdown/guides/f-draggable-directive.md index 9ef3cd4..5a56a7d 100644 --- a/public/markdown/guides/f-draggable-directive.md +++ b/public/markdown/guides/f-draggable-directive.md @@ -6,7 +6,11 @@ The **FDraggableDirective** enhances a component, typically a flow [f-flow](f-fl ## Inputs - - `fDraggableDisabled: boolean;` Determines whether the draggable functionality is disabled. Default: `false + - `fDraggableDisabled: boolean;` Determines whether the draggable functionality is disabled. Default: `false`. + + - `vCellSize: number;` Defines the vertical size of each grid cell. Default: `1`. + + - `hCellSize: number;` Defines the horizontal size of each grid cell. Default: `1`. ## Outputs diff --git a/public/previews/examples/grid-system-example.dark.png b/public/previews/examples/grid-system-example.dark.png new file mode 100644 index 0000000..550f760 Binary files /dev/null and b/public/previews/examples/grid-system-example.dark.png differ diff --git a/public/previews/examples/grid-system-example.light.png b/public/previews/examples/grid-system-example.light.png new file mode 100644 index 0000000..6923e49 Binary files /dev/null and b/public/previews/examples/grid-system-example.light.png differ