Skip to content

Commit 1b2d319

Browse files
authored
0.21.0. (#143)
1 parent 879dfe3 commit 1b2d319

38 files changed

+462
-261
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.21.0
2+
3+
This version introduces several changes related with the collapsible regions in the pro version.
4+
15
## 0.20.0
26

37
This version introduces the localization feature. Now you can localize the designer to any language you want.

README.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Pro:
4444
* [🍬 Custom Theme Flat](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/custom-theme-flat.html)
4545
* [🌹 Custom Step Types](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/custom-step-types.html)
4646
* [📺 Popup Editor](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/popup-editor.html)
47+
* [🔽 Collapsible Region](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/collapsible-region.html)
4748
* [💼 Copy Paste](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/copy-paste.html)
4849
* [👈 Goto](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/goto.html)
4950
* [📁 Folders](https://nocode-js.com/examples/sequential-workflow-designer-pro/webpack-pro-app/public/folders.html)
@@ -101,10 +102,10 @@ Add the below code to your head section in HTML document.
101102
```html
102103
<head>
103104
...
104-
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/css/designer.css" rel="stylesheet">
105-
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/css/designer-light.css" rel="stylesheet">
106-
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/css/designer-dark.css" rel="stylesheet">
107-
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/dist/index.umd.js"></script>
105+
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/css/designer.css" rel="stylesheet">
106+
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/css/designer-light.css" rel="stylesheet">
107+
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/css/designer-dark.css" rel="stylesheet">
108+
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/dist/index.umd.js"></script>
108109
```
109110

110111
Call the designer by:

angular/designer/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sequential-workflow-designer-angular",
33
"description": "Angular wrapper for Sequential Workflow Designer component.",
4-
"version": "0.20.0",
4+
"version": "0.21.0",
55
"author": {
66
"name": "NoCode JS",
77
"url": "https://nocode-js.com/"
@@ -15,7 +15,7 @@
1515
"peerDependencies": {
1616
"@angular/common": "12 - 16",
1717
"@angular/core": "12 - 16",
18-
"sequential-workflow-designer": "^0.20.0"
18+
"sequential-workflow-designer": "^0.21.0"
1919
},
2020
"dependencies": {
2121
"tslib": "^2.3.0"

angular/designer/src/designer.component.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import {
2929
ToolboxConfiguration,
3030
UidGenerator,
3131
ValidatorConfiguration,
32-
I18n
32+
I18n,
33+
PreferenceStorage
3334
} from 'sequential-workflow-designer';
3435

3536
export interface RootEditorWrapper {
@@ -76,6 +77,8 @@ export class DesignerComponent implements AfterViewInit, OnChanges, OnDestroy {
7677
public contextMenu?: boolean;
7778
@Input('keyboard')
7879
public keyboard?: boolean | KeyboardConfiguration;
80+
@Input('preferenceStorage')
81+
public preferenceStorage?: PreferenceStorage;
7982
@Input('extensions')
8083
public extensions?: DesignerExtension[];
8184
@Input('i18n')
@@ -220,6 +223,7 @@ export class DesignerComponent implements AfterViewInit, OnChanges, OnDestroy {
220223
controlBar: this.controlBar,
221224
contextMenu: this.contextMenu,
222225
keyboard: this.keyboard,
226+
preferenceStorage: this.preferenceStorage,
223227
extensions: this.extensions,
224228
isReadonly: this.isReadonly,
225229
i18n: this.i18n,

demos/angular-app/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
"@angular/platform-browser-dynamic": "^15.2.9",
2727
"@angular/router": "^15.2.9",
2828
"rxjs": "~7.8.0",
29-
"sequential-workflow-designer": "^0.20.0",
30-
"sequential-workflow-designer-angular": "^0.20.0",
29+
"sequential-workflow-designer": "^0.21.0",
30+
"sequential-workflow-designer-angular": "^0.21.0",
3131
"tslib": "^2.3.0",
3232
"zone.js": "~0.13.0"
3333
},
@@ -45,4 +45,4 @@
4545
"prettier": "^3.2.5",
4646
"typescript": "~4.9.5"
4747
}
48-
}
48+
}

demos/angular-app/yarn.lock

+8-8
Original file line numberDiff line numberDiff line change
@@ -5956,17 +5956,17 @@ send@0.18.0:
59565956
range-parser "~1.2.1"
59575957
statuses "2.0.1"
59585958

5959-
sequential-workflow-designer-angular@^0.20.0:
5960-
version "0.20.0"
5961-
resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.20.0.tgz#abe658c0fe0911acc04506c32030fe5e1a0c6db2"
5962-
integrity sha512-dAV0U+Iw+xJUJfH5lva4Y0hNd3jcs8FfUDVQgohr8TTSYpnQRQlCDUN8oiI1zmZd59GInX3ckWR7Vfl0hE764Q==
5959+
sequential-workflow-designer-angular@^0.21.0:
5960+
version "0.21.0"
5961+
resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.21.0.tgz#c18481347b4011dc2ce9c8f422027702382a33dc"
5962+
integrity sha512-MajrGNFskcG2V1OpiiL/OigP1MD1CJtdD8Nl+X8KClqeZ+kw+aqNRJqIBjC7zPdcoGsHyKGGORUyPzlwTWoLwg==
59635963
dependencies:
59645964
tslib "^2.3.0"
59655965

5966-
sequential-workflow-designer@^0.20.0:
5967-
version "0.20.0"
5968-
resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.20.0.tgz#fb6a1fc15969e62e060251e57c9977c0b22cecd3"
5969-
integrity sha512-nndGqJuOR7KAmY5OasPBYt842KWeDC05DgJ3J/M+tQNxddqCHWlafy6rwHfO1cPB3Ui1m0b0sOrNNJmv1r6dWA==
5966+
sequential-workflow-designer@^0.21.0:
5967+
version "0.21.0"
5968+
resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.21.0.tgz#34a461163634b140b12a46943cf9c1eb9443c7c7"
5969+
integrity sha512-P+LTR0umWwiZEWtwvaZ4ZhWAAwrF4vYJhY6ge32yrltJzsViiM951+wo9l3945i5Vv7GoLvgovSX4nhZDHDlSQ==
59705970
dependencies:
59715971
sequential-workflow-model "^0.2.0"
59725972

demos/react-app/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"dependencies": {
77
"react": "^18.2.0",
88
"react-dom": "^18.2.0",
9-
"sequential-workflow-designer": "^0.20.0",
10-
"sequential-workflow-designer-react": "^0.20.0"
9+
"sequential-workflow-designer": "^0.21.0",
10+
"sequential-workflow-designer-react": "^0.21.0"
1111
},
1212
"devDependencies": {
1313
"@types/jest": "^29.2.5",
@@ -48,4 +48,4 @@
4848
"last 1 safari version"
4949
]
5050
}
51-
}
51+
}

demos/svelte-app/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
"eslint": "eslint ./src --ext .ts"
1717
},
1818
"dependencies": {
19-
"sequential-workflow-designer": "^0.20.0",
20-
"sequential-workflow-designer-svelte": "^0.20.0"
19+
"sequential-workflow-designer": "^0.21.0",
20+
"sequential-workflow-designer-svelte": "^0.21.0"
2121
},
2222
"devDependencies": {
2323
"@sveltejs/adapter-static": "^2.0.3",
@@ -33,4 +33,4 @@
3333
"@typescript-eslint/parser": "^5.47.0",
3434
"eslint": "^8.30.0"
3535
}
36-
}
36+
}

designer/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sequential-workflow-designer",
33
"description": "Customizable no-code component for building flow-based programming applications.",
4-
"version": "0.20.0",
4+
"version": "0.21.0",
55
"type": "module",
66
"main": "./lib/esm/index.js",
77
"types": "./lib/index.d.ts",
@@ -104,4 +104,4 @@
104104
"lowcode",
105105
"flow"
106106
]
107-
}
107+
}

designer/src/component-context.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { DefinitionWalker } from 'sequential-workflow-model';
12
import { DefinitionValidator } from './core/definition-validator';
23
import { IconProvider } from './core/icon-provider';
3-
import { I18n, StepsConfiguration, ValidatorConfiguration } from './designer-configuration';
4+
import { DesignerConfiguration, I18n, PreferenceStorage } from './designer-configuration';
45
import { PlaceholderController } from './designer-extension';
56
import { DesignerState } from './designer-state';
67
import { Services } from './services';
@@ -9,26 +10,38 @@ import { StepExtensionResolver } from './workspace/step-extension-resolver';
910

1011
export class ComponentContext {
1112
public static create(
12-
stepsConfiguration: StepsConfiguration,
13-
validatorConfiguration: ValidatorConfiguration | undefined,
13+
configuration: DesignerConfiguration,
1414
state: DesignerState,
1515
stepExtensionResolver: StepExtensionResolver,
16+
definitionWalker: DefinitionWalker,
17+
preferenceStorage: PreferenceStorage,
1618
i18n: I18n,
1719
services: Services
1820
): ComponentContext {
19-
const validator = new DefinitionValidator(validatorConfiguration, state);
20-
const iconProvider = new IconProvider(stepsConfiguration);
21+
const validator = new DefinitionValidator(configuration.validator, state);
22+
const iconProvider = new IconProvider(configuration.steps);
2123
const placeholderController = services.placeholderController.create();
2224
const stepComponentFactory = new StepComponentFactory(stepExtensionResolver);
23-
return new ComponentContext(validator, iconProvider, placeholderController, stepComponentFactory, i18n, services);
25+
return new ComponentContext(
26+
validator,
27+
iconProvider,
28+
placeholderController,
29+
stepComponentFactory,
30+
definitionWalker,
31+
services,
32+
preferenceStorage,
33+
i18n
34+
);
2435
}
2536

2637
private constructor(
2738
public readonly validator: DefinitionValidator,
2839
public readonly iconProvider: IconProvider,
2940
public readonly placeholderController: PlaceholderController,
3041
public readonly stepComponentFactory: StepComponentFactory,
31-
public readonly i18n: I18n,
32-
public readonly services: Services
42+
public readonly definitionWalker: DefinitionWalker,
43+
public readonly services: Services,
44+
public readonly preferenceStorage: PreferenceStorage,
45+
public readonly i18n: I18n
3346
) {}
3447
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { MemoryPreferenceStorage } from './memory-preference-storage';
2+
3+
describe('MemoryPreferenceStorage', () => {
4+
it('remember a value', () => {
5+
const storage = new MemoryPreferenceStorage();
6+
7+
expect(storage.getItem('key0')).toBeNull();
8+
9+
storage.setItem('key0', 'value');
10+
11+
expect(storage.getItem('key0')).toBe('value');
12+
});
13+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { PreferenceStorage } from '../designer-configuration';
2+
3+
export class MemoryPreferenceStorage implements PreferenceStorage {
4+
private readonly map: Record<string, string> = {};
5+
6+
public setItem(key: string, value: string) {
7+
this.map[key] = value;
8+
}
9+
10+
public getItem(key: string): string | null {
11+
return this.map[key] ?? null;
12+
}
13+
}

designer/src/designer-configuration.ts

+10
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ export interface DesignerConfiguration<TDefinition extends Definition = Definiti
7373
*/
7474
definitionWalker?: DefinitionWalker;
7575

76+
/**
77+
* @description Custom preference storage. By default, all preferences are stored in the memory.
78+
*/
79+
preferenceStorage?: PreferenceStorage;
80+
7681
/**
7782
* @description Custom generator of unique identifiers.
7883
*/
@@ -144,6 +149,11 @@ export interface ToolboxGroupConfiguration {
144149
steps: StepDefinition[];
145150
}
146151

152+
export interface PreferenceStorage {
153+
setItem(key: string, value: string): void;
154+
getItem(key: string): string | null;
155+
}
156+
147157
export interface StepsConfiguration {
148158
isSelectable?: (step: Step, parentSequence: Sequence) => boolean;
149159
canInsertStep?: (step: Step, targetSequence: Sequence, targetIndex: number) => boolean;

designer/src/designer-context.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { LayoutController } from './layout-controller';
1111
import { Services } from './services';
1212
import { StepExtensionResolver } from './workspace/step-extension-resolver';
1313
import { WorkspaceController, WorkspaceControllerWrapper } from './workspace/workspace-controller';
14+
import { MemoryPreferenceStorage } from './core/memory-preference-storage';
1415

1516
export class DesignerContext {
1617
public static create(
@@ -42,11 +43,13 @@ export class DesignerContext {
4243
historyController = HistoryController.create(configuration.undoStack, state, stateModifier, configuration);
4344
}
4445

46+
const preferenceStorage = configuration.preferenceStorage ?? new MemoryPreferenceStorage();
4547
const componentContext = ComponentContext.create(
46-
configuration.steps,
47-
configuration.validator,
48+
configuration,
4849
state,
4950
stepExtensionResolver,
51+
definitionWalker,
52+
preferenceStorage,
5053
i18n,
5154
services
5255
);

designer/src/designer-extension.ts

+45-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@ import { Vector } from './core';
55
import { CustomActionController } from './custom-action-controller';
66
import { ComponentType, Sequence, Step } from './definition';
77
import { I18n } from './designer-configuration';
8-
import { Badge, Component, Placeholder, PlaceholderDirection, SequenceComponent, StepComponentView } from './workspace';
8+
import {
9+
Badge,
10+
ClickCommand,
11+
ClickDetails,
12+
Component,
13+
Placeholder,
14+
PlaceholderDirection,
15+
SequenceComponent,
16+
StepComponentView
17+
} from './workspace';
918

1019
export interface DesignerExtension {
1120
steps?: StepExtension[];
@@ -17,6 +26,7 @@ export interface DesignerExtension {
1726
viewportController?: ViewportControllerExtension;
1827
placeholderController?: PlaceholderControllerExtension;
1928
placeholder?: PlaceholderExtension;
29+
regionComponentView?: RegionComponentViewExtension;
2030
grid?: GridExtension;
2131
rootComponent?: RootComponentExtension;
2232
sequenceComponent?: SequenceComponentExtension;
@@ -34,6 +44,7 @@ export interface StepExtension<S extends Step = Step> {
3444
export type StepComponentViewFactory = StepExtension['createComponentView'];
3545

3646
export interface StepComponentViewContext {
47+
i18n: I18n;
3748
getStepName(): string;
3849
getStepIconUrl(): string | null;
3950
createSequenceComponent(parentElement: SVGElement, sequence: Sequence): SequenceComponent;
@@ -44,7 +55,13 @@ export interface StepComponentViewContext {
4455
sequence: Sequence,
4556
index: number
4657
): Placeholder;
47-
i18n: I18n;
58+
createRegionComponentView(
59+
parentElement: SVGElement,
60+
componentClassName: string,
61+
contentFactory: RegionComponentViewContentFactory
62+
): StepComponentView;
63+
getPreference(key: string): string | null;
64+
setPreference(key: string, value: string): void;
4865
}
4966

5067
export interface StepContext<S extends Step = Step> {
@@ -71,7 +88,7 @@ export interface StepComponentViewWrapperExtension {
7188

7289
export interface BadgeExtension {
7390
id: string;
74-
createForStep(parentElement: SVGElement, stepContext: StepContext, componentContext: ComponentContext): Badge;
91+
createForStep(parentElement: SVGElement, view: StepComponentView, stepContext: StepContext, componentContext: ComponentContext): Badge;
7592
createForRoot?: (parentElement: SVGElement, componentContext: ComponentContext) => Badge;
7693
createStartValue(): unknown;
7794
}
@@ -202,3 +219,28 @@ export interface DaemonExtension {
202219
export interface Daemon {
203220
destroy(): void;
204221
}
222+
223+
// RegionComponentViewExtension
224+
225+
export interface RegionView {
226+
getClientPosition(): Vector;
227+
/**
228+
* @returns `true` if the click is inside the region, `null` if it's outside. The view may return a command to be executed.
229+
*/
230+
resolveClick(click: ClickDetails): true | ClickCommand | null;
231+
setIsSelected(isSelected: boolean): void;
232+
}
233+
234+
export type RegionViewFactory = (parent: SVGElement, widths: number[], height: number) => RegionView;
235+
236+
export type RegionComponentViewContentFactory = (g: SVGGElement, regionViewFactory: RegionViewFactory) => StepComponentView;
237+
238+
export interface RegionComponentViewExtension {
239+
create(
240+
parentElement: SVGElement,
241+
componentClassName: string,
242+
stepContext: StepContext,
243+
viewContext: StepComponentViewContext,
244+
contentFactory: RegionComponentViewContentFactory
245+
): StepComponentView;
246+
}

0 commit comments

Comments
 (0)