Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.10.1

* Fixed the bug with the auto-hide feature in the smart editor.
* Fixed the bug with rendering wide components in the sequence component.
* Fixed the bug with dragging when the designer is attached to a scrolled page.

## 0.10.0

Refactored the step component interface. Extracted the logic of the step validation to a separated layer called badges. This allowed to create a new type of badge: `counter`. The counter badge is available in the pro version.
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Features:
* [🌻 Rendering Test](https://nocode-js.github.io/sequential-workflow-designer/examples/rendering-test.html)
* [🚄 Stress Test](https://nocode-js.github.io/sequential-workflow-designer/examples/stress-test.html)
* [🚪 Editing Restrictions](https://nocode-js.github.io/sequential-workflow-designer/examples/editing-restrictions.html)
* [📜 Scrollable Page](https://nocode-js.github.io/sequential-workflow-designer/examples/scrollable-page.html)

Pro:

Expand Down Expand Up @@ -87,10 +88,10 @@ Add the below code to your head section in HTML document.
```html
<head>
...
<link href="https://cdn.jsdelivr.net/npm/[email protected].0/css/designer.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected].0/css/designer-light.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected].0/css/designer-dark.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected].0/dist/index.umd.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected].1/css/designer.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected].1/css/designer-light.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected].1/css/designer-dark.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected].1/dist/index.umd.js"></script>
```

Call the designer by:
Expand Down
4 changes: 2 additions & 2 deletions angular/designer/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sequential-workflow-designer-angular",
"description": "Angular wrapper for Sequential Workflow Designer component.",
"version": "0.10.0",
"version": "0.10.1",
"author": {
"name": "NoCode JS",
"url": "https://nocode-js.com/"
Expand All @@ -15,7 +15,7 @@
"peerDependencies": {
"@angular/common": "12 - 15",
"@angular/core": "12 - 15",
"sequential-workflow-designer": "^0.10.0"
"sequential-workflow-designer": "^0.10.1"
},
"dependencies": {
"tslib": "^2.3.0"
Expand Down
4 changes: 2 additions & 2 deletions demos/angular-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"@angular/platform-browser-dynamic": "^15.2.2",
"@angular/router": "^15.2.2",
"rxjs": "~7.8.0",
"sequential-workflow-designer": "^0.10.0",
"sequential-workflow-designer-angular": "^0.10.0",
"sequential-workflow-designer": "^0.10.1",
"sequential-workflow-designer-angular": "^0.10.1",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
},
Expand Down
16 changes: 8 additions & 8 deletions demos/angular-app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5180,17 +5180,17 @@ [email protected]:
range-parser "~1.2.1"
statuses "2.0.1"

sequential-workflow-designer-angular@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.10.0.tgz#bccb2212f6bcf3114c13435291195e7346271f50"
integrity sha512-RivPz4H10wWyviJBfHciEGqy/EBf/mD/zPy2/2yzOXc8sI+NGTBTg9GJSTx0iHqa8LrOtWgv3JAhLrRr3X90/A==
sequential-workflow-designer-angular@^0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.10.1.tgz#ab4dd09d7b7e542b18ba5c3521d9687490213467"
integrity sha512-3vfKQd3IpJiaosDP7kmPz66EUH/w8O5tX/uoufPO8ymDg+TtFaM4owafq88VyvNb9Gy06W7+PM4aWP78cHgdqQ==
dependencies:
tslib "^2.3.0"

sequential-workflow-designer@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.10.0.tgz#c443f867c06cab82703dfc5a84a579392f268d9a"
integrity sha512-50A8bJBNNsHbdu48PbDIqwJk9YsWBNsCpVb7zY0IAJeNWM1yhk8w+h2vtPBqMIwkqoXAX2o/4em6QHkIofXR8A==
sequential-workflow-designer@^0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.10.1.tgz#44dfc4e5bb901f9e0fb95b627a0344cde8f25d44"
integrity sha512-OIR0Glck99alIjliweGo9HZhegXSnQmBwbnSzZjqr15QlVFAIuo4YePPy/PV5y/wTvQZoq02SVpSzgukIQDNGQ==
dependencies:
sequential-workflow-model "^0.1.1"

Expand Down
4 changes: 2 additions & 2 deletions demos/react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sequential-workflow-designer": "^0.10.0",
"sequential-workflow-designer-react": "^0.10.0"
"sequential-workflow-designer": "^0.10.1",
"sequential-workflow-designer-react": "^0.10.1"
},
"devDependencies": {
"@types/jest": "^29.2.5",
Expand Down
2 changes: 1 addition & 1 deletion designer/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sequential-workflow-designer",
"description": "Customizable no-code component for building flow-based programming applications.",
"version": "0.10.0",
"version": "0.10.1",
"type": "module",
"main": "./lib/esm/index.js",
"types": "./lib/index.d.ts",
Expand Down
50 changes: 24 additions & 26 deletions designer/src/behaviors/behavior-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import { readMousePosition, readTouchPosition } from '../core/event-readers';

const notInitializedError = 'State is not initialized';

export class BehaviorController {
private readonly onMouseMoveHandler = (e: MouseEvent) => this.onMouseMove(e);
private readonly onMouseUpHandler = (e: MouseEvent) => this.onMouseUp(e);
private readonly onTouchMoveHandler = (e: TouchEvent) => this.onTouchMove(e);
private readonly onTouchEndHandler = (e: TouchEvent) => this.onTouchEnd(e);
private readonly onTouchStartHandler = (e: TouchEvent) => this.onTouchStart(e);
const nonPassiveOptions: AddEventListenerOptions & EventListenerOptions = {
passive: false
};

export class BehaviorController {
private state?: {
startPosition: Vector;
behavior: Behavior;
Expand All @@ -29,29 +27,29 @@ export class BehaviorController {
};
behavior.onStart(this.state.startPosition);

window.addEventListener('mousemove', this.onMouseMoveHandler, false);
window.addEventListener('touchmove', this.onTouchMoveHandler, false);
window.addEventListener('mouseup', this.onMouseUpHandler, false);
window.addEventListener('touchend', this.onTouchEndHandler, false);
window.addEventListener('touchstart', this.onTouchStartHandler, false);
window.addEventListener('mousemove', this.onMouseMove, false);
window.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
window.addEventListener('mouseup', this.onMouseUp, false);
window.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
window.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
}

private onMouseMove(e: MouseEvent) {
private readonly onMouseMove = (e: MouseEvent) => {
e.preventDefault();
this.move(readMousePosition(e));
}
};

private onTouchMove(e: TouchEvent) {
private readonly onTouchMove = (e: TouchEvent) => {
e.preventDefault();
this.move(readTouchPosition(e));
}
};

private onMouseUp(e: MouseEvent) {
private readonly onMouseUp = (e: MouseEvent) => {
e.preventDefault();
this.stop(false, e.target as Element | null);
}
};

private onTouchEnd(e: TouchEvent) {
private readonly onTouchEnd = (e: TouchEvent) => {
e.preventDefault();
if (!this.state) {
throw new Error(notInitializedError);
Expand All @@ -60,14 +58,14 @@ export class BehaviorController {
const position = this.state.lastPosition ?? this.state.startPosition;
const element = document.elementFromPoint(position.x, position.y);
this.stop(false, element);
}
};

private onTouchStart(e: TouchEvent) {
private readonly onTouchStart = (e: TouchEvent) => {
e.preventDefault();
if (e.touches.length !== 1) {
this.stop(true, null);
}
}
};

private move(position: Vector) {
if (!this.state) {
Expand All @@ -92,11 +90,11 @@ export class BehaviorController {
throw new Error(notInitializedError);
}

window.removeEventListener('mousemove', this.onMouseMoveHandler, false);
window.removeEventListener('touchmove', this.onTouchMoveHandler, false);
window.removeEventListener('mouseup', this.onMouseUpHandler, false);
window.removeEventListener('touchend', this.onTouchEndHandler, false);
window.removeEventListener('touchstart', this.onTouchEndHandler, false);
window.removeEventListener('mousemove', this.onMouseMove, false);
window.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
window.removeEventListener('mouseup', this.onMouseUp, false);
window.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
window.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions);

this.state.behavior.onEnd(interrupt, element);
this.state = undefined;
Expand Down
5 changes: 3 additions & 2 deletions designer/src/behaviors/drag-step-behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ export class DragStepBehavior implements Behavior {
this.draggedStepComponent.view.width === this.view.component.width &&
this.draggedStepComponent.view.height === this.view.component.height;
if (hasSameSize) {
const scroll = new Vector(window.scrollX, window.scrollY);
// Mouse cursor will be positioned on the same place as the source component.
const clientPosition = this.draggedStepComponent.view.getClientPosition();
offset = position.subtract(clientPosition);
const pagePosition = this.draggedStepComponent.view.getClientPosition().add(scroll);
offset = position.subtract(pagePosition);
}
}
if (!offset) {
Expand Down
8 changes: 5 additions & 3 deletions designer/src/behaviors/placeholder-finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ export class PlaceholderFinder {

public find(vLt: Vector, vWidth: number, vHeight: number): Placeholder | undefined {
if (!this.cache) {
const scroll = new Vector(window.scrollX, window.scrollY);

this.cache = this.placeholders.map(placeholder => {
const rect = placeholder.getRect();
const rect = placeholder.getClientRect();
return {
placeholder,
lt: new Vector(rect.x, rect.y),
br: new Vector(rect.x + rect.width, rect.y + rect.height)
lt: new Vector(rect.x, rect.y).add(scroll),
br: new Vector(rect.x + rect.width, rect.y + rect.height).add(scroll)
};
});
this.cache.sort((a, b) => a.lt.y - b.lt.y);
Expand Down
12 changes: 10 additions & 2 deletions designer/src/core/event-readers.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { Vector } from './vector';

export function readMousePosition(e: MouseEvent): Vector {
return new Vector(e.clientX, e.clientY);
return new Vector(e.pageX, e.pageY);
}

export function readTouchPosition(e: TouchEvent): Vector {
export function readTouchClientPosition(e: TouchEvent): Vector {
if (e.touches.length > 0) {
const touch = e.touches[0];
return new Vector(touch.clientX, touch.clientY);
}
throw new Error('Unknown touch position');
}

export function readTouchPosition(e: TouchEvent): Vector {
if (e.touches.length > 0) {
const touch = e.touches[0];
return new Vector(touch.pageX, touch.pageY);
}
throw new Error('Unknown touch position');
}
2 changes: 1 addition & 1 deletion designer/src/smart-editor/smart-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { EditorsConfiguration } from '../designer-configuration';
export class SmartEditor implements UiComponent {
public static create(parent: HTMLElement, api: DesignerApi, configuration: EditorsConfiguration): SmartEditor {
const view = SmartEditorView.create(parent, api, configuration);
view.setIsCollapsed(api.editor.isVisibleAtStart());

const editor = new SmartEditor(view, api.workspace);
view.bindToggleIsCollapsedClick(() => editor.toggleIsCollapsedClick());

editor.setIsCollapsed(api.editor.isVisibleAtStart());
return editor;
}

Expand Down
60 changes: 29 additions & 31 deletions designer/src/toolbox/scrollbox-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { Dom } from '../core/dom';
import { readMousePosition, readTouchPosition } from '../core/event-readers';
import { Vector } from '../core/vector';

const listenerOptions: AddEventListenerOptions & EventListenerOptions = {
passive: false
};

export class ScrollBoxView {
public static create(parent: HTMLElement, viewport: HTMLElement): ScrollBoxView {
const root = Dom.element('div', {
Expand All @@ -10,19 +14,13 @@ export class ScrollBoxView {
parent.appendChild(root);

const view = new ScrollBoxView(root, viewport);
window.addEventListener('resize', view.onResizeHandler, false);
window.addEventListener('resize', view.onResize, false);
root.addEventListener('wheel', e => view.onWheel(e), false);
root.addEventListener('touchstart', e => view.onTouchStart(e), false);
root.addEventListener('touchstart', e => view.onTouchStart(e), listenerOptions);
root.addEventListener('mousedown', e => view.onMouseDown(e), false);
return view;
}

private readonly onResizeHandler = () => this.onResize();
private readonly onTouchMoveHandler = (e: TouchEvent) => this.onTouchMove(e);
private readonly onMouseMoveHandler = (e: MouseEvent) => this.onMouseMove(e);
private readonly onTouchEndHandler = (e: TouchEvent) => this.onTouchEnd(e);
private readonly onMouseUpHandler = (e: MouseEvent) => this.onMouseUp(e);

private content?: {
element: HTMLElement;
height: number;
Expand Down Expand Up @@ -50,7 +48,7 @@ export class ScrollBoxView {
}

public destroy() {
window.removeEventListener('resize', this.onResizeHandler, false);
window.removeEventListener('resize', this.onResize, false);
}

private reload(element: HTMLElement) {
Expand All @@ -69,9 +67,9 @@ export class ScrollBoxView {
};
}

private onResize() {
private readonly onResize = () => {
this.refresh();
}
};

private onWheel(e: WheelEvent) {
e.stopPropagation();
Expand All @@ -83,41 +81,41 @@ export class ScrollBoxView {
}
}

private onTouchStart(e: TouchEvent) {
private readonly onTouchStart = (e: TouchEvent) => {
e.preventDefault();
this.startScroll(readTouchPosition(e));
}
};

private onMouseDown(e: MouseEvent) {
private readonly onMouseDown = (e: MouseEvent) => {
this.startScroll(readMousePosition(e));
}
};

private onTouchMove(e: TouchEvent) {
private readonly onTouchMove = (e: TouchEvent) => {
e.preventDefault();
this.moveScroll(readTouchPosition(e));
}
};

private onMouseMove(e: MouseEvent) {
private readonly onMouseMove = (e: MouseEvent) => {
e.preventDefault();
this.moveScroll(readMousePosition(e));
}
};

private onTouchEnd(e: TouchEvent) {
private readonly onTouchEnd = (e: TouchEvent) => {
e.preventDefault();
this.stopScroll();
}
};

private onMouseUp(e: MouseEvent) {
private readonly onMouseUp = (e: MouseEvent) => {
e.preventDefault();
this.stopScroll();
}
};

private startScroll(startPosition: Vector) {
if (!this.scroll) {
window.addEventListener('touchmove', this.onTouchMoveHandler, false);
window.addEventListener('mousemove', this.onMouseMoveHandler, false);
window.addEventListener('touchend', this.onTouchEndHandler, false);
window.addEventListener('mouseup', this.onMouseUpHandler, false);
window.addEventListener('touchmove', this.onTouchMove, listenerOptions);
window.addEventListener('mousemove', this.onMouseMove, false);
window.addEventListener('touchend', this.onTouchEnd, listenerOptions);
window.addEventListener('mouseup', this.onMouseUp, false);
}

this.scroll = {
Expand All @@ -135,10 +133,10 @@ export class ScrollBoxView {

private stopScroll() {
if (this.scroll) {
window.removeEventListener('touchmove', this.onTouchMoveHandler, false);
window.removeEventListener('mousemove', this.onMouseMoveHandler, false);
window.removeEventListener('touchend', this.onTouchEndHandler, false);
window.removeEventListener('mouseup', this.onMouseUpHandler, false);
window.removeEventListener('touchmove', this.onTouchMove, listenerOptions);
window.removeEventListener('mousemove', this.onMouseMove, false);
window.removeEventListener('touchend', this.onTouchEnd, listenerOptions);
window.removeEventListener('mouseup', this.onMouseUp, false);
this.scroll = undefined;
}
}
Expand Down
Loading