diff --git a/CHANGELOG.md b/CHANGELOG.md index ef2a353a..a16c53b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.28.0 + +This update modifies the custom context menu in the pro version. The context menu items provider now retrieves the parent sequence of the selected workspace root sequence. If the root sequence is a folder sequence, the parent sequence is the folder sequence. + # 0.27.4 Support for React 19 has been added. diff --git a/README.md b/README.md index 512ce8de..b105ebf0 100644 --- a/README.md +++ b/README.md @@ -104,10 +104,10 @@ Add the below code to your head section in HTML document. ```html
... - - - - + + + + ``` Call the designer by: diff --git a/angular/designer/package.json b/angular/designer/package.json index cd12b692..3c0601ea 100644 --- a/angular/designer/package.json +++ b/angular/designer/package.json @@ -1,7 +1,7 @@ { "name": "sequential-workflow-designer-angular", "description": "Angular wrapper for Sequential Workflow Designer component.", - "version": "0.27.4", + "version": "0.28.0", "author": { "name": "NoCode JS", "url": "https://nocode-js.com/" @@ -15,7 +15,7 @@ "peerDependencies": { "@angular/common": "12 - 19", "@angular/core": "12 - 19", - "sequential-workflow-designer": "^0.27.4" + "sequential-workflow-designer": "^0.28.0" }, "dependencies": { "tslib": "^2.3.0" diff --git a/demos/angular-app/package.json b/demos/angular-app/package.json index 9e341343..f0915209 100644 --- a/demos/angular-app/package.json +++ b/demos/angular-app/package.json @@ -26,8 +26,8 @@ "@angular/platform-browser-dynamic": "^17.3.9", "@angular/router": "^17.3.9", "rxjs": "~7.8.0", - "sequential-workflow-designer": "^0.27.4", - "sequential-workflow-designer-angular": "^0.27.4", + "sequential-workflow-designer": "^0.28.0", + "sequential-workflow-designer-angular": "^0.28.0", "tslib": "^2.3.0", "zone.js": "~0.14.6" }, diff --git a/demos/angular-app/yarn.lock b/demos/angular-app/yarn.lock index 7f936c1e..27ba9272 100644 --- a/demos/angular-app/yarn.lock +++ b/demos/angular-app/yarn.lock @@ -6744,17 +6744,17 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -sequential-workflow-designer-angular@^0.27.4: - version "0.27.4" - resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.27.4.tgz#ef03a499b4db91429bf602d405bc137ee9f6d335" - integrity sha512-HUTb8dLTxcFyXcFAqAt++TjI2iwS0xPsVSF0t1Wi5z77e+yP2tlzpcq/NqPTvs1/C2udoMcq/pk9Tezln2GCfA== +sequential-workflow-designer-angular@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/sequential-workflow-designer-angular/-/sequential-workflow-designer-angular-0.28.0.tgz#6748b69c5b626424e9d2f1a47686daa825ce7981" + integrity sha512-bSTGD3kh+7BCIPAMvDWipuUaoUv3G0RmdZiaQM7cE1f9P27HNQQueOr1nVRJmUbClE/2gW9+96n8VEpTtZ59xQ== dependencies: tslib "^2.3.0" -sequential-workflow-designer@^0.27.4: - version "0.27.4" - resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.27.4.tgz#84e3d075229d1a3fe93f1913ab44212e66a8f0fb" - integrity sha512-OZr0IjbfTDfXidfe5hTPAGtisc4Q0idDoanAoBf+lKU2Dc7mzclp1EUrE5KP2IBbi8BofwGJIJdVwWQVOVwgkA== +sequential-workflow-designer@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/sequential-workflow-designer/-/sequential-workflow-designer-0.28.0.tgz#b6fd72abf9ec00eab2b8633fe34f7f456b32dbf4" + integrity sha512-GEUERe8giyx/D9hsA+YG+LjescdLPBLs+yydHQ5UnGtXzl8784eUmPqqdGg/AnzsoEB5G+LIcgShoFMLVBYq+A== dependencies: sequential-workflow-model "^0.2.0" diff --git a/demos/react-app/package.json b/demos/react-app/package.json index f0e76d86..1dae2b43 100644 --- a/demos/react-app/package.json +++ b/demos/react-app/package.json @@ -6,8 +6,8 @@ "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", - "sequential-workflow-designer": "^0.27.4", - "sequential-workflow-designer-react": "^0.27.4" + "sequential-workflow-designer": "^0.28.0", + "sequential-workflow-designer-react": "^0.28.0" }, "devDependencies": { "@types/jest": "^29.2.5", diff --git a/demos/svelte-app/package.json b/demos/svelte-app/package.json index 0527235e..160d7226 100644 --- a/demos/svelte-app/package.json +++ b/demos/svelte-app/package.json @@ -16,8 +16,8 @@ "eslint": "eslint ./src --ext .ts" }, "dependencies": { - "sequential-workflow-designer": "^0.27.4", - "sequential-workflow-designer-svelte": "^0.27.4" + "sequential-workflow-designer": "^0.28.0", + "sequential-workflow-designer-svelte": "^0.28.0" }, "devDependencies": { "@sveltejs/adapter-static": "^2.0.3", diff --git a/designer/package.json b/designer/package.json index 0814092a..b2f994d3 100644 --- a/designer/package.json +++ b/designer/package.json @@ -1,7 +1,7 @@ { "name": "sequential-workflow-designer", "description": "Customizable no-code component for building flow-based programming applications.", - "version": "0.27.4", + "version": "0.28.0", "type": "module", "main": "./lib/esm/index.js", "types": "./lib/index.d.ts", diff --git a/designer/src/api/designer-api.ts b/designer/src/api/designer-api.ts index 30d20de6..85327ee7 100644 --- a/designer/src/api/designer-api.ts +++ b/designer/src/api/designer-api.ts @@ -11,7 +11,7 @@ import { I18n } from '../designer-configuration'; export class DesignerApi { public static create(context: DesignerContext): DesignerApi { - const workspace = new WorkspaceApi(context.state, context.workspaceController); + const workspace = new WorkspaceApi(context.state, context.definitionWalker, context.workspaceController); const viewportController = context.services.viewportController.create(workspace); const toolboxDataProvider = new ToolboxDataProvider( context.componentContext.iconProvider, diff --git a/designer/src/api/workspace-api.ts b/designer/src/api/workspace-api.ts index 7786e634..35706cc8 100644 --- a/designer/src/api/workspace-api.ts +++ b/designer/src/api/workspace-api.ts @@ -1,3 +1,4 @@ +import { DefinitionWalker, Sequence, StepChildrenType, StepWithParentSequence } from 'sequential-workflow-model'; import { Vector } from '../core'; import { Viewport } from '../designer-extension'; import { DesignerState } from '../designer-state'; @@ -6,6 +7,7 @@ import { WorkspaceControllerWrapper } from '../workspace/workspace-controller'; export class WorkspaceApi { public constructor( private readonly state: DesignerState, + private readonly definitionWalker: DefinitionWalker, private readonly workspaceController: WorkspaceControllerWrapper ) {} @@ -40,4 +42,28 @@ export class WorkspaceApi { public updateCanvasSize() { this.workspaceController.updateCanvasSize(); } + + public getRootSequence(): WorkspaceRootSequence { + const stepId = this.state.tryGetLastStepIdFromFolderPath(); + if (stepId) { + const parentStep = this.definitionWalker.getParentSequence(this.state.definition, stepId); + const children = this.definitionWalker.getChildren(parentStep.step); + if (!children || children.type !== StepChildrenType.sequence) { + throw new Error('Cannot find single sequence in folder step'); + } + return { + sequence: children.items as Sequence, + parentStep + }; + } + return { + sequence: this.state.definition.sequence, + parentStep: null + }; + } +} + +export interface WorkspaceRootSequence { + sequence: Sequence; + parentStep: StepWithParentSequence | null; } diff --git a/designer/src/behaviors/click-behavior-resolver.ts b/designer/src/behaviors/click-behavior-resolver.ts index 7159fcbb..1282c9c8 100644 --- a/designer/src/behaviors/click-behavior-resolver.ts +++ b/designer/src/behaviors/click-behavior-resolver.ts @@ -21,7 +21,7 @@ export class ClickBehaviorResolver { return SelectStepBehavior.create(commandOrNull.component, forceMove, this.context); case ClickCommandType.rerenderStep: - return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.context)); + return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(commandOrNull, this.context)); case ClickCommandType.openFolder: return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.context)); diff --git a/designer/src/behaviors/pressing-behaviors/rerender-step-pressing-behavior-handler.ts b/designer/src/behaviors/pressing-behaviors/rerender-step-pressing-behavior-handler.ts index 208bba35..2f082b27 100644 --- a/designer/src/behaviors/pressing-behaviors/rerender-step-pressing-behavior-handler.ts +++ b/designer/src/behaviors/pressing-behaviors/rerender-step-pressing-behavior-handler.ts @@ -1,10 +1,17 @@ import { DesignerContext } from '../../designer-context'; +import { RerenderStepClickCommand } from '../../workspace'; import { PressingBehaviorHandler } from './pressing-behavior'; export class RerenderStepPressingBehaviorHandler implements PressingBehaviorHandler { - public constructor(private readonly designerContext: DesignerContext) {} + public constructor( + private readonly command: RerenderStepClickCommand, + private readonly designerContext: DesignerContext + ) {} public handle() { + if (this.command.beforeCallback) { + this.command.beforeCallback(); + } this.designerContext.workspaceController.updateRootComponent(); } } diff --git a/designer/src/designer-extension.ts b/designer/src/designer-extension.ts index e14f8a6c..cd58b660 100644 --- a/designer/src/designer-extension.ts +++ b/designer/src/designer-extension.ts @@ -5,7 +5,7 @@ import { Behavior } from './behaviors'; import { ComponentContext } from './component-context'; import { Vector } from './core'; import { CustomActionController } from './custom-action-controller'; -import { ComponentType, Sequence, Step } from './definition'; +import { ComponentType, Definition, Sequence, Step } from './definition'; import { I18n } from './designer-configuration'; import { Badge, @@ -195,7 +195,7 @@ export interface ContextMenuExtension { } export interface ContextMenuItemsProvider { - getItems(step: Step | null, sequence: Sequence): ContextMenuItem[]; + getItems(step: Step | null, parentSequence: Sequence, definition: Definition): ContextMenuItem[]; } export interface ContextMenuItem { diff --git a/designer/src/workspace/component.ts b/designer/src/workspace/component.ts index 40bcf5cd..c311b26b 100644 --- a/designer/src/workspace/component.ts +++ b/designer/src/workspace/component.ts @@ -68,6 +68,7 @@ export interface SelectStepClickCommand extends BaseClickCommand { export interface RerenderStepClickCommand extends BaseClickCommand { type: ClickCommandType.rerenderStep; step: Step; + beforeCallback?: () => void; } export interface OpenFolderClickCommand extends BaseClickCommand { diff --git a/designer/src/workspace/context-menu/context-menu-items-builder.ts b/designer/src/workspace/context-menu/context-menu-items-builder.ts index 2c701ade..acaff7b5 100644 --- a/designer/src/workspace/context-menu/context-menu-items-builder.ts +++ b/designer/src/workspace/context-menu/context-menu-items-builder.ts @@ -1,5 +1,6 @@ import { Sequence, Step } from '../../definition'; import { ViewportApi } from '../../api/viewport-api'; +import { WorkspaceApi } from '../../api/workspace-api'; import { StateModifier } from '../../modifier/state-modifier'; import { ContextMenuItem, ContextMenuItemsProvider } from '../../designer-extension'; import { DesignerState } from '../../designer-state'; @@ -9,6 +10,7 @@ import { I18n } from '../../designer-configuration'; export class ContextMenuItemsBuilder { public constructor( private readonly viewportApi: ViewportApi, + private readonly workspaceApi: WorkspaceApi, private readonly i18n: I18n, private readonly stateModifier: StateModifier, private readonly state: DesignerState, @@ -70,8 +72,9 @@ export class ContextMenuItemsBuilder { }); } } - } else { - this.tryAppendCustomItems(items, null, this.state.definition.sequence); + } else if (!commandOrNull) { + const rootSequence = this.workspaceApi.getRootSequence(); + this.tryAppendCustomItems(items, null, rootSequence.sequence); } items.push({ @@ -88,7 +91,7 @@ export class ContextMenuItemsBuilder { private tryAppendCustomItems(items: ContextMenuItem[], step: Step | null, parentSequence: Sequence) { if (this.customMenuItemsProvider) { - const customItems = this.customMenuItemsProvider.getItems(step, parentSequence); + const customItems = this.customMenuItemsProvider.getItems(step, parentSequence, this.state.definition); for (const customItem of customItems) { items.push(customItem); } diff --git a/designer/src/workspace/workspace-view.ts b/designer/src/workspace/workspace-view.ts index 097d6498..414e0153 100644 --- a/designer/src/workspace/workspace-view.ts +++ b/designer/src/workspace/workspace-view.ts @@ -73,16 +73,11 @@ export class WorkspaceView { private readonly context: ComponentContext ) {} - public render(sequence: Sequence, parentSequencePlaceIndicator: SequencePlaceIndicator | null) { + public render(sequence: Sequence, parentPlaceIndicator: SequencePlaceIndicator | null) { if (this.rootComponent) { this.foreground.removeChild(this.rootComponent.view.g); } - this.rootComponent = this.context.services.rootComponent.create( - this.foreground, - sequence, - parentSequencePlaceIndicator, - this.context - ); + this.rootComponent = this.context.services.rootComponent.create(this.foreground, sequence, parentPlaceIndicator, this.context); this.refreshSize(); } diff --git a/designer/src/workspace/workspace.ts b/designer/src/workspace/workspace.ts index ea79ab76..746f5b77 100644 --- a/designer/src/workspace/workspace.ts +++ b/designer/src/workspace/workspace.ts @@ -1,6 +1,5 @@ import { race } from '../core/simple-event-race'; import { Vector } from '../core/vector'; -import { DefinitionWalker, Sequence, StepChildrenType } from '../definition'; import { DesignerContext } from '../designer-context'; import { ClickCommand, ClickDetails, Component, FoundPlaceholders } from './component'; import { WorkspaceView } from './workspace-view'; @@ -10,13 +9,14 @@ import { ClickBehaviorResolver } from '../behaviors/click-behavior-resolver'; import { BehaviorController } from '../behaviors/behavior-controller'; import { SimpleEvent } from '../core/simple-event'; import { ClickBehaviorWrapper, SequencePlaceIndicator, Viewport, WheelController } from '../designer-extension'; -import { DesignerApi } from '../api/designer-api'; import { StepComponent } from './step-component'; import { BadgesResultFactory } from './badges/badges-result-factory'; import { Services } from '../services'; import { findValidationBadgeIndex } from './badges/find-validation-badge-index'; import { ContextMenuController } from './context-menu/context-menu-controller'; import { ViewportApi } from '../api/viewport-api'; +import { DesignerApi } from '../api/designer-api'; +import { WorkspaceApi } from '../api/workspace-api'; import { DefinitionChangeType } from '../designer-configuration'; import { ContextMenuItemsBuilder } from './context-menu/context-menu-items-builder'; import { PinchToZoomController } from './viewport/pinch-to-zoom-controller'; @@ -33,6 +33,7 @@ export class Workspace implements WorkspaceController { const contextMenuItemsBuilder = new ContextMenuItemsBuilder( api.viewport, + api.workspace, api.i18n, designerContext.stateModifier, designerContext.state, @@ -48,7 +49,6 @@ export class Workspace implements WorkspaceController { const workspace = new Workspace( view, - designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, @@ -57,6 +57,7 @@ export class Workspace implements WorkspaceController { clickBehaviorResolver, clickBehaviorWrapper, api.viewport, + api.workspace, designerContext.services ); setTimeout(() => { @@ -91,7 +92,6 @@ export class Workspace implements WorkspaceController { private constructor( private readonly view: WorkspaceView, - private readonly definitionWalker: DefinitionWalker, private readonly state: DesignerState, private readonly behaviorController: BehaviorController, private readonly wheelController: WheelController, @@ -100,34 +100,22 @@ export class Workspace implements WorkspaceController { private readonly clickBehaviorResolver: ClickBehaviorResolver, private readonly clickBehaviorWrapper: ClickBehaviorWrapper, private readonly viewportApi: ViewportApi, + private readonly workspaceApi: WorkspaceApi, private readonly services: Services ) {} public updateRootComponent() { this.selectedStepComponent = null; - let parentSequencePlaceIndicator: SequencePlaceIndicator | null; - let sequence: Sequence; - - const stepId = this.state.tryGetLastStepIdFromFolderPath(); - if (stepId) { - const parentSequence = this.definitionWalker.getParentSequence(this.state.definition, stepId); - const children = this.definitionWalker.getChildren(parentSequence.step); - if (!children || children.type !== StepChildrenType.sequence) { - throw new Error('Cannot find single sequence in folder step'); - } - sequence = children.items as Sequence; - - parentSequencePlaceIndicator = { - sequence: parentSequence.parentSequence, - index: parentSequence.index - }; - } else { - sequence = this.state.definition.sequence; - parentSequencePlaceIndicator = null; - } + const rootSequence = this.workspaceApi.getRootSequence(); + const parentPlaceIndicator: SequencePlaceIndicator | null = rootSequence.parentStep + ? { + sequence: rootSequence.parentStep.parentSequence, + index: rootSequence.parentStep.index + } + : null; - this.view.render(sequence, parentSequencePlaceIndicator); + this.view.render(rootSequence.sequence, parentPlaceIndicator); this.trySelectStepComponent(this.state.selectedStepId); this.updateBadges(); diff --git a/examples/assets/lib.js b/examples/assets/lib.js index 3baf32ff..42999096 100644 --- a/examples/assets/lib.js +++ b/examples/assets/lib.js @@ -13,7 +13,7 @@ function embedStylesheet(url) { document.write(``); } -const baseUrl = isTestEnv() ? '../designer' : '//cdn.jsdelivr.net/npm/sequential-workflow-designer@0.27.4'; +const baseUrl = isTestEnv() ? '../designer' : '//cdn.jsdelivr.net/npm/sequential-workflow-designer@0.28.0'; embedScript(`${baseUrl}/dist/index.umd.js`); embedStylesheet(`${baseUrl}/css/designer.css`); diff --git a/react/package.json b/react/package.json index f993d796..acc9963f 100644 --- a/react/package.json +++ b/react/package.json @@ -1,7 +1,7 @@ { "name": "sequential-workflow-designer-react", "description": "React wrapper for Sequential Workflow Designer component.", - "version": "0.27.4", + "version": "0.28.0", "type": "module", "main": "./lib/esm/index.js", "types": "./lib/index.d.ts", @@ -47,7 +47,7 @@ "peerDependencies": { "react": ">=18.2.0", "react-dom": ">=18.2.0", - "sequential-workflow-designer": "^0.27.4" + "sequential-workflow-designer": "^0.28.0" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.1", @@ -63,7 +63,7 @@ "prettier": "^3.2.5", "react": "^18.2.0", "react-dom": "^18.2.0", - "sequential-workflow-designer": "^0.27.4", + "sequential-workflow-designer": "^0.28.0", "rollup": "^3.18.0", "rollup-plugin-dts": "^5.2.0", "rollup-plugin-typescript2": "^0.34.1", diff --git a/svelte/package.json b/svelte/package.json index 406b0850..d0e4f32e 100644 --- a/svelte/package.json +++ b/svelte/package.json @@ -1,7 +1,7 @@ { "name": "sequential-workflow-designer-svelte", "description": "Svelte wrapper for Sequential Workflow Designer component.", - "version": "0.27.4", + "version": "0.28.0", "license": "MIT", "scripts": { "prepare": "cp ../LICENSE LICENSE", @@ -28,10 +28,10 @@ ], "peerDependencies": { "svelte": "^4.0.0", - "sequential-workflow-designer": "^0.27.4" + "sequential-workflow-designer": "^0.28.0" }, "devDependencies": { - "sequential-workflow-designer": "^0.27.4", + "sequential-workflow-designer": "^0.28.0", "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.20.4", "@sveltejs/package": "^2.0.0",