sequential-workflow-designer 0.18.5 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -196,8 +196,8 @@
196
196
  }
197
197
 
198
198
  class ControlBarApi {
199
- static create(state, historyController, definitionModifier, viewportApi) {
200
- const api = new ControlBarApi(state, historyController, definitionModifier, viewportApi);
199
+ static create(state, historyController, stateModifier, viewportApi) {
200
+ const api = new ControlBarApi(state, historyController, stateModifier, viewportApi);
201
201
  state.onIsReadonlyChanged.subscribe(api.onStateChanged.forward);
202
202
  state.onSelectedStepIdChanged.subscribe(api.onStateChanged.forward);
203
203
  state.onIsDragDisabledChanged.subscribe(api.onStateChanged.forward);
@@ -206,19 +206,13 @@
206
206
  }
207
207
  return api;
208
208
  }
209
- constructor(state, historyController, definitionModifier, viewportApi) {
209
+ constructor(state, historyController, stateModifier, viewportApi) {
210
210
  this.state = state;
211
211
  this.historyController = historyController;
212
- this.definitionModifier = definitionModifier;
212
+ this.stateModifier = stateModifier;
213
213
  this.viewportApi = viewportApi;
214
214
  this.onStateChanged = new SimpleEvent();
215
215
  }
216
- /**
217
- * @deprecated Don't use this method
218
- */
219
- subscribe(handler) {
220
- this.onStateChanged.subscribe(handler);
221
- }
222
216
  resetViewport() {
223
217
  this.viewportApi.resetViewport();
224
218
  }
@@ -259,7 +253,7 @@
259
253
  }
260
254
  tryDelete() {
261
255
  if (this.canDelete() && this.state.selectedStepId) {
262
- this.definitionModifier.tryDelete(this.state.selectedStepId);
256
+ this.stateModifier.tryDelete(this.state.selectedStepId);
263
257
  return true;
264
258
  }
265
259
  return false;
@@ -268,7 +262,7 @@
268
262
  return (!!this.state.selectedStepId &&
269
263
  !this.state.isReadonly &&
270
264
  !this.state.isDragging &&
271
- this.definitionModifier.isDeletable(this.state.selectedStepId));
265
+ this.stateModifier.isDeletable(this.state.selectedStepId));
272
266
  }
273
267
  }
274
268
 
@@ -289,29 +283,30 @@
289
283
  })(exports.DefinitionChangeType || (exports.DefinitionChangeType = {}));
290
284
 
291
285
  class EditorRenderer {
292
- static create(state, definitionWalker, handler) {
293
- const raceEvent = race(0, state.onDefinitionChanged, state.onSelectedStepIdChanged, state.onIsReadonlyChanged);
294
- const listener = new EditorRenderer(state, definitionWalker, handler, raceEvent);
286
+ static create(state, selectedStepIdProvider, definitionWalker, handler) {
287
+ const raceEvent = race(0, state.onDefinitionChanged, selectedStepIdProvider.onSelectedStepIdChanged, state.onIsReadonlyChanged);
288
+ const listener = new EditorRenderer(state, selectedStepIdProvider, definitionWalker, handler, raceEvent);
295
289
  raceEvent.subscribe(listener.raceEventHandler);
296
- listener.renderIfStepChanged(state.selectedStepId);
290
+ listener.renderIfStepChanged(selectedStepIdProvider.selectedStepId);
297
291
  return listener;
298
292
  }
299
- constructor(state, definitionWalker, handler, raceEvent) {
293
+ constructor(state, selectedStepIdProvider, definitionWalker, handler, raceEvent) {
300
294
  this.state = state;
295
+ this.selectedStepIdProvider = selectedStepIdProvider;
301
296
  this.definitionWalker = definitionWalker;
302
297
  this.handler = handler;
303
298
  this.raceEvent = raceEvent;
304
299
  this.currentStepId = undefined;
305
300
  this.raceEventHandler = ([definitionChanged, selectedStepId, isReadonlyChanged]) => {
306
301
  if (isReadonlyChanged !== undefined) {
307
- this.render(this.state.selectedStepId);
302
+ this.render(this.selectedStepIdProvider.selectedStepId);
308
303
  }
309
304
  else if (definitionChanged) {
310
305
  if (definitionChanged.changeType === exports.DefinitionChangeType.rootReplaced) {
311
- this.render(this.state.selectedStepId);
306
+ this.render(this.selectedStepIdProvider.selectedStepId);
312
307
  }
313
308
  else {
314
- this.renderIfStepChanged(this.state.selectedStepId);
309
+ this.renderIfStepChanged(this.selectedStepIdProvider.selectedStepId);
315
310
  }
316
311
  }
317
312
  else if (selectedStepId !== undefined) {
@@ -335,10 +330,10 @@
335
330
  }
336
331
 
337
332
  class EditorApi {
338
- constructor(state, definitionWalker, definitionModifier) {
333
+ constructor(state, definitionWalker, stateModifier) {
339
334
  this.state = state;
340
335
  this.definitionWalker = definitionWalker;
341
- this.definitionModifier = definitionModifier;
336
+ this.stateModifier = stateModifier;
342
337
  }
343
338
  isCollapsed() {
344
339
  return this.state.isEditorCollapsed;
@@ -355,8 +350,12 @@
355
350
  getDefinition() {
356
351
  return this.state.definition;
357
352
  }
358
- runRenderer(rendererHandler) {
359
- return EditorRenderer.create(this.state, this.definitionWalker, rendererHandler);
353
+ addDefinitionModifierDependency(dependency) {
354
+ this.stateModifier.addDependency(dependency);
355
+ }
356
+ runRenderer(rendererHandler, customSelectedStepIdProvider) {
357
+ const selectedStepIdProvider = customSelectedStepIdProvider || this.state;
358
+ return EditorRenderer.create(this.state, selectedStepIdProvider, this.definitionWalker, rendererHandler);
360
359
  }
361
360
  createStepEditorContext(stepId) {
362
361
  if (!stepId) {
@@ -371,7 +370,7 @@
371
370
  },
372
371
  notifyChildrenChanged: () => {
373
372
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepChildrenChanged, stepId);
374
- this.definitionModifier.updateDependantFields();
373
+ this.stateModifier.updateDependencies();
375
374
  }
376
375
  };
377
376
  }
@@ -390,12 +389,6 @@
390
389
  this.definitionWalker = definitionWalker;
391
390
  this.onStateChanged = race(0, this.state.onFolderPathChanged, this.state.onDefinitionChanged);
392
391
  }
393
- /**
394
- * @deprecated Don't use this method
395
- */
396
- subscribe(handler) {
397
- this.onStateChanged.subscribe(handler);
398
- }
399
392
  setFolderPath(path) {
400
393
  this.state.setFolderPath(path);
401
394
  }
@@ -476,14 +469,14 @@
476
469
  class DragStepBehavior {
477
470
  static create(designerContext, step, draggedStepComponent) {
478
471
  const view = DragStepView.create(step, designerContext.theme, designerContext.componentContext);
479
- return new DragStepBehavior(view, designerContext.workspaceController, designerContext.state, step, designerContext.definitionModifier, draggedStepComponent);
472
+ return new DragStepBehavior(view, designerContext.workspaceController, designerContext.state, step, designerContext.stateModifier, draggedStepComponent);
480
473
  }
481
- constructor(view, workspaceController, designerState, step, definitionModifier, draggedStepComponent) {
474
+ constructor(view, workspaceController, designerState, step, stateModifier, draggedStepComponent) {
482
475
  this.view = view;
483
476
  this.workspaceController = workspaceController;
484
477
  this.designerState = designerState;
485
478
  this.step = step;
486
- this.definitionModifier = definitionModifier;
479
+ this.stateModifier = stateModifier;
487
480
  this.draggedStepComponent = draggedStepComponent;
488
481
  }
489
482
  onStart(position) {
@@ -538,10 +531,10 @@
538
531
  let modified = false;
539
532
  if (!interrupt && this.currentPlaceholder) {
540
533
  if (this.draggedStepComponent) {
541
- modified = this.definitionModifier.tryMove(this.draggedStepComponent.parentSequence, this.draggedStepComponent.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
534
+ modified = this.stateModifier.tryMove(this.draggedStepComponent.parentSequence, this.draggedStepComponent.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
542
535
  }
543
536
  else {
544
- modified = this.definitionModifier.tryInsert(this.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
537
+ modified = this.stateModifier.tryInsert(this.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
545
538
  }
546
539
  }
547
540
  if (!modified) {
@@ -714,15 +707,16 @@
714
707
  const viewportController = context.services.viewportController.create(workspace);
715
708
  const viewport = new ViewportApi(context.workspaceController, viewportController);
716
709
  const toolboxDataProvider = new ToolboxDataProvider(context.componentContext.iconProvider, context.configuration.toolbox);
717
- return new DesignerApi(ControlBarApi.create(context.state, context.historyController, context.definitionModifier, viewport), new ToolboxApi(context.state, context, context.behaviorController, toolboxDataProvider, context.configuration.uidGenerator), new EditorApi(context.state, context.definitionWalker, context.definitionModifier), workspace, viewport, new PathBarApi(context.state, context.definitionWalker));
710
+ return new DesignerApi(ControlBarApi.create(context.state, context.historyController, context.stateModifier, viewport), new ToolboxApi(context.state, context, context.behaviorController, toolboxDataProvider, context.configuration.uidGenerator), new EditorApi(context.state, context.definitionWalker, context.stateModifier), workspace, viewport, new PathBarApi(context.state, context.definitionWalker), context.definitionWalker);
718
711
  }
719
- constructor(controlBar, toolbox, editor, workspace, viewport, pathBar) {
712
+ constructor(controlBar, toolbox, editor, workspace, viewport, pathBar, definitionWalker) {
720
713
  this.controlBar = controlBar;
721
714
  this.toolbox = toolbox;
722
715
  this.editor = editor;
723
716
  this.workspace = workspace;
724
717
  this.viewport = viewport;
725
718
  this.pathBar = pathBar;
719
+ this.definitionWalker = definitionWalker;
726
720
  }
727
721
  }
728
722
 
@@ -969,6 +963,41 @@
969
963
  }
970
964
  }
971
965
 
966
+ class CustomActionController {
967
+ constructor(configuration, state, stateModifier) {
968
+ this.configuration = configuration;
969
+ this.state = state;
970
+ this.stateModifier = stateModifier;
971
+ }
972
+ trigger(action, step, sequence) {
973
+ const handler = this.configuration.customActionHandler;
974
+ if (!handler) {
975
+ console.warn(`Custom action handler is not defined (action type: ${action.type})`);
976
+ return;
977
+ }
978
+ const context = this.createCustomActionHandlerContext();
979
+ handler(action, step, sequence, context);
980
+ }
981
+ createCustomActionHandlerContext() {
982
+ return {
983
+ notifyStepNameChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepNameChanged, stepId, false),
984
+ notifyStepPropertiesChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepPropertyChanged, stepId, false),
985
+ notifyStepInserted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepInserted, stepId, true),
986
+ notifyStepMoved: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepMoved, stepId, true),
987
+ notifyStepDeleted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepDeleted, stepId, true)
988
+ };
989
+ }
990
+ notifyStepChanged(changeType, stepId, updateDependencies) {
991
+ if (!stepId) {
992
+ throw new Error('Step id is empty');
993
+ }
994
+ this.state.notifyDefinitionChanged(changeType, stepId);
995
+ if (updateDependencies) {
996
+ this.stateModifier.updateDependencies();
997
+ }
998
+ }
999
+ }
1000
+
972
1001
  class EditorView {
973
1002
  static create(parent) {
974
1003
  return new EditorView(parent);
@@ -996,7 +1025,7 @@
996
1025
  }
997
1026
 
998
1027
  class Editor {
999
- static create(parent, api, stepEditorClassName, stepEditorProvider, rootEditorClassName, rootEditorProvider) {
1028
+ static create(parent, api, stepEditorClassName, stepEditorProvider, rootEditorClassName, rootEditorProvider, customSelectedStepIdProvider) {
1000
1029
  const view = EditorView.create(parent);
1001
1030
  function render(step) {
1002
1031
  const definition = api.getDefinition();
@@ -1014,7 +1043,7 @@
1014
1043
  }
1015
1044
  view.setContent(content, className);
1016
1045
  }
1017
- const renderer = api.runRenderer(step => render(step));
1046
+ const renderer = api.runRenderer(step => render(step), customSelectedStepIdProvider);
1018
1047
  return new Editor(view, renderer);
1019
1048
  }
1020
1049
  constructor(view, renderer) {
@@ -2265,11 +2294,73 @@
2265
2294
  }
2266
2295
  }
2267
2296
 
2268
- class DefinitionModifier {
2269
- constructor(definitionWalker, state, configuration) {
2297
+ class FolderPathDefinitionModifierDependency {
2298
+ constructor(state, definitionWalker) {
2299
+ this.state = state;
2300
+ this.definitionWalker = definitionWalker;
2301
+ }
2302
+ update() {
2303
+ for (let index = 0; index < this.state.folderPath.length; index++) {
2304
+ const stepId = this.state.folderPath[index];
2305
+ const found = this.definitionWalker.findById(this.state.definition, stepId);
2306
+ if (!found) {
2307
+ // We need to update path if any folder is deleted.
2308
+ const newPath = this.state.folderPath.slice(0, index);
2309
+ this.state.setFolderPath(newPath);
2310
+ break;
2311
+ }
2312
+ }
2313
+ }
2314
+ }
2315
+
2316
+ class SelectedStepIdDefinitionModifierDependency {
2317
+ constructor(state, definitionWalker) {
2318
+ this.state = state;
2319
+ this.definitionWalker = definitionWalker;
2320
+ }
2321
+ update() {
2322
+ if (this.state.selectedStepId) {
2323
+ const found = this.definitionWalker.findById(this.state.definition, this.state.selectedStepId);
2324
+ if (!found) {
2325
+ // We need to unselect step when it's deleted.
2326
+ this.state.setSelectedStepId(null);
2327
+ }
2328
+ }
2329
+ }
2330
+ }
2331
+
2332
+ class StateModifier {
2333
+ static create(definitionWalker, state, configuration) {
2334
+ const dependencies = [];
2335
+ dependencies.push(new SelectedStepIdDefinitionModifierDependency(state, definitionWalker));
2336
+ dependencies.push(new FolderPathDefinitionModifierDependency(state, definitionWalker));
2337
+ return new StateModifier(definitionWalker, state, configuration, dependencies);
2338
+ }
2339
+ constructor(definitionWalker, state, configuration, dependencies) {
2270
2340
  this.definitionWalker = definitionWalker;
2271
2341
  this.state = state;
2272
2342
  this.configuration = configuration;
2343
+ this.dependencies = dependencies;
2344
+ }
2345
+ addDependency(dependency) {
2346
+ this.dependencies.push(dependency);
2347
+ }
2348
+ isSelectable(step, parentSequence) {
2349
+ return this.configuration.steps.isSelectable ? this.configuration.steps.isSelectable(step, parentSequence) : true;
2350
+ }
2351
+ trySelectStep(step, parentSequence) {
2352
+ if (this.isSelectable(step, parentSequence)) {
2353
+ this.state.setSelectedStepId(step.id);
2354
+ }
2355
+ }
2356
+ trySelectStepById(stepId) {
2357
+ if (this.configuration.steps.isSelectable) {
2358
+ const result = this.definitionWalker.getParentSequence(this.state.definition, stepId);
2359
+ this.trySelectStep(result.step, result.parentSequence);
2360
+ }
2361
+ else {
2362
+ this.state.setSelectedStepId(stepId);
2363
+ }
2273
2364
  }
2274
2365
  isDeletable(stepId) {
2275
2366
  if (this.configuration.steps.isDeletable) {
@@ -2288,7 +2379,7 @@
2288
2379
  }
2289
2380
  SequenceModifier.deleteStep(result.step, result.parentSequence);
2290
2381
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepDeleted, result.step.id);
2291
- this.updateDependantFields();
2382
+ this.updateDependencies();
2292
2383
  return true;
2293
2384
  }
2294
2385
  tryInsert(step, targetSequence, targetIndex) {
@@ -2301,7 +2392,7 @@
2301
2392
  SequenceModifier.insertStep(step, targetSequence, targetIndex);
2302
2393
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepInserted, step.id);
2303
2394
  if (!this.configuration.steps.isAutoSelectDisabled) {
2304
- this.state.setSelectedStepId(step.id);
2395
+ this.trySelectStepById(step.id);
2305
2396
  }
2306
2397
  return true;
2307
2398
  }
@@ -2322,7 +2413,7 @@
2322
2413
  apply();
2323
2414
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepMoved, step.id);
2324
2415
  if (!this.configuration.steps.isAutoSelectDisabled) {
2325
- this.state.setSelectedStepId(step.id);
2416
+ this.trySelectStep(step, targetSequence);
2326
2417
  }
2327
2418
  return true;
2328
2419
  }
@@ -2341,26 +2432,10 @@
2341
2432
  throw new Error('Definition is empty');
2342
2433
  }
2343
2434
  this.state.setDefinition(definition);
2344
- this.updateDependantFields();
2435
+ this.updateDependencies();
2345
2436
  }
2346
- updateDependantFields() {
2347
- if (this.state.selectedStepId) {
2348
- const found = this.definitionWalker.findById(this.state.definition, this.state.selectedStepId);
2349
- if (!found) {
2350
- // We need to unselect step when it's deleted.
2351
- this.state.setSelectedStepId(null);
2352
- }
2353
- }
2354
- for (let index = 0; index < this.state.folderPath.length; index++) {
2355
- const stepId = this.state.folderPath[index];
2356
- const found = this.definitionWalker.findById(this.state.definition, stepId);
2357
- if (!found) {
2358
- // We need to update path if any folder is deleted.
2359
- const newPath = this.state.folderPath.slice(0, index);
2360
- this.state.setFolderPath(newPath);
2361
- break;
2362
- }
2363
- }
2437
+ updateDependencies() {
2438
+ this.dependencies.forEach(dependency => dependency.update());
2364
2439
  }
2365
2440
  }
2366
2441
 
@@ -2447,7 +2522,7 @@
2447
2522
  }
2448
2523
 
2449
2524
  class HistoryController {
2450
- static create(initialStack, state, definitionModifier, configuration) {
2525
+ static create(initialStack, state, stateModifier, configuration) {
2451
2526
  if (!configuration.undoStackSize || configuration.undoStackSize < 1) {
2452
2527
  throw new Error('Invalid undo stack size');
2453
2528
  }
@@ -2455,7 +2530,7 @@
2455
2530
  index: 0,
2456
2531
  items: []
2457
2532
  };
2458
- const controller = new HistoryController(stack, state, definitionModifier, configuration.undoStackSize);
2533
+ const controller = new HistoryController(stack, state, stateModifier, configuration.undoStackSize);
2459
2534
  if (!initialStack) {
2460
2535
  controller.rememberCurrent(exports.DefinitionChangeType.rootReplaced, null);
2461
2536
  }
@@ -2466,10 +2541,10 @@
2466
2541
  });
2467
2542
  return controller;
2468
2543
  }
2469
- constructor(stack, state, definitionModifier, stackSize) {
2544
+ constructor(stack, state, stateModifier, stackSize) {
2470
2545
  this.stack = stack;
2471
2546
  this.state = state;
2472
- this.definitionModifier = definitionModifier;
2547
+ this.stateModifier = stateModifier;
2473
2548
  this.stackSize = stackSize;
2474
2549
  }
2475
2550
  canUndo() {
@@ -2521,7 +2596,7 @@
2521
2596
  }
2522
2597
  commit() {
2523
2598
  const definition = ObjectCloner.deepClone(this.stack.items[this.stack.index - 1].definition);
2524
- this.definitionModifier.replaceDefinition(definition);
2599
+ this.stateModifier.replaceDefinition(definition);
2525
2600
  }
2526
2601
  }
2527
2602
  function areItemsEqual(item, changeType, stepId) {
@@ -2590,25 +2665,27 @@
2590
2665
  const behaviorController = new BehaviorController();
2591
2666
  const stepExtensionResolver = StepExtensionResolver.create(services);
2592
2667
  const definitionWalker = (_c = configuration.definitionWalker) !== null && _c !== void 0 ? _c : new DefinitionWalker();
2593
- const definitionModifier = new DefinitionModifier(definitionWalker, state, configuration);
2668
+ const stateModifier = StateModifier.create(definitionWalker, state, configuration);
2669
+ const customActionController = new CustomActionController(configuration, state, stateModifier);
2594
2670
  let historyController = undefined;
2595
2671
  if (configuration.undoStackSize) {
2596
- historyController = HistoryController.create(configuration.undoStack, state, definitionModifier, configuration);
2672
+ historyController = HistoryController.create(configuration.undoStack, state, stateModifier, configuration);
2597
2673
  }
2598
2674
  const componentContext = ComponentContext.create(configuration.steps, configuration.validator, state, stepExtensionResolver, services);
2599
- return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, definitionModifier, layoutController, workspaceController, behaviorController, historyController);
2675
+ return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController);
2600
2676
  }
2601
- constructor(theme, state, configuration, services, componentContext, definitionWalker, definitionModifier, layoutController, workspaceController, behaviorController, historyController) {
2677
+ constructor(theme, state, configuration, services, componentContext, definitionWalker, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController) {
2602
2678
  this.theme = theme;
2603
2679
  this.state = state;
2604
2680
  this.configuration = configuration;
2605
2681
  this.services = services;
2606
2682
  this.componentContext = componentContext;
2607
2683
  this.definitionWalker = definitionWalker;
2608
- this.definitionModifier = definitionModifier;
2684
+ this.stateModifier = stateModifier;
2609
2685
  this.layoutController = layoutController;
2610
2686
  this.workspaceController = workspaceController;
2611
2687
  this.behaviorController = behaviorController;
2688
+ this.customActionController = customActionController;
2612
2689
  this.historyController = historyController;
2613
2690
  }
2614
2691
  setWorkspaceController(controller) {
@@ -2754,18 +2831,24 @@
2754
2831
  }
2755
2832
 
2756
2833
  class MoveViewportBehavior {
2757
- static create(state, resetSelectedStep) {
2758
- return new MoveViewportBehavior(state.viewport.position, resetSelectedStep, state);
2834
+ static create(resetSelectedStep, context) {
2835
+ return new MoveViewportBehavior(context.state.viewport.position, resetSelectedStep, context.state, context.stateModifier);
2759
2836
  }
2760
- constructor(startPosition, resetSelectedStep, state) {
2837
+ constructor(startPosition, resetSelectedStep, state, stateModifier) {
2761
2838
  this.startPosition = startPosition;
2762
2839
  this.resetSelectedStep = resetSelectedStep;
2763
2840
  this.state = state;
2841
+ this.stateModifier = stateModifier;
2764
2842
  }
2765
2843
  onStart() {
2766
2844
  if (this.resetSelectedStep) {
2767
- const stepId = this.state.tryGetLastStepIdFromFolderPath();
2768
- this.state.setSelectedStepId(stepId);
2845
+ const stepIdOrNull = this.state.tryGetLastStepIdFromFolderPath();
2846
+ if (stepIdOrNull) {
2847
+ this.stateModifier.trySelectStepById(stepIdOrNull);
2848
+ }
2849
+ else {
2850
+ this.state.setSelectedStepId(null);
2851
+ }
2769
2852
  }
2770
2853
  }
2771
2854
  onMove(delta) {
@@ -2783,14 +2866,15 @@
2783
2866
  static create(pressedStepComponent, isMiddleButton, context) {
2784
2867
  const isDragDisabled = isMiddleButton ||
2785
2868
  context.state.isDragDisabled ||
2786
- !context.definitionModifier.isDraggable(pressedStepComponent.step, pressedStepComponent.parentSequence);
2787
- return new SelectStepBehavior(pressedStepComponent, isDragDisabled, context, context.state);
2869
+ !context.stateModifier.isDraggable(pressedStepComponent.step, pressedStepComponent.parentSequence);
2870
+ return new SelectStepBehavior(pressedStepComponent, isDragDisabled, context.state, context.stateModifier, context);
2788
2871
  }
2789
- constructor(pressedStepComponent, isDragDisabled, context, state) {
2872
+ constructor(pressedStepComponent, isDragDisabled, state, stateModifier, context) {
2790
2873
  this.pressedStepComponent = pressedStepComponent;
2791
2874
  this.isDragDisabled = isDragDisabled;
2792
- this.context = context;
2793
2875
  this.state = state;
2876
+ this.stateModifier = stateModifier;
2877
+ this.context = context;
2794
2878
  }
2795
2879
  onStart() {
2796
2880
  // Nothing to do.
@@ -2803,13 +2887,13 @@
2803
2887
  return DragStepBehavior.create(this.context, this.pressedStepComponent.step, this.pressedStepComponent);
2804
2888
  }
2805
2889
  else {
2806
- return MoveViewportBehavior.create(this.state, false);
2890
+ return MoveViewportBehavior.create(false, this.context);
2807
2891
  }
2808
2892
  }
2809
2893
  }
2810
2894
  onEnd(interrupt) {
2811
2895
  if (!interrupt) {
2812
- this.state.setSelectedStepId(this.pressedStepComponent.step.id);
2896
+ this.stateModifier.trySelectStep(this.pressedStepComponent.step, this.pressedStepComponent.parentSequence);
2813
2897
  }
2814
2898
  }
2815
2899
  }
@@ -2856,54 +2940,32 @@
2856
2940
  }
2857
2941
 
2858
2942
  class TriggerCustomActionPressingBehaviorHandler {
2859
- constructor(command, designerContext) {
2943
+ constructor(command, customActionController) {
2860
2944
  this.command = command;
2861
- this.designerContext = designerContext;
2945
+ this.customActionController = customActionController;
2862
2946
  }
2863
2947
  handle() {
2864
- const customActionHandler = this.designerContext.configuration.customActionHandler;
2865
- if (!customActionHandler) {
2866
- console.warn(`Custom action handler is not defined (action type: ${this.command.action.type})`);
2867
- return;
2868
- }
2869
- const context = this.createContext();
2870
- customActionHandler(this.command.action, this.command.step, this.command.sequence, context);
2871
- }
2872
- createContext() {
2873
- return {
2874
- notifyStepNameChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepNameChanged, stepId),
2875
- notifyStepPropertiesChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepPropertyChanged, stepId),
2876
- notifyStepInserted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepInserted, stepId),
2877
- notifyStepMoved: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepMoved, stepId),
2878
- notifyStepDeleted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepDeleted, stepId)
2879
- };
2880
- }
2881
- notifyStepChanged(changeType, stepId) {
2882
- if (!stepId) {
2883
- throw new Error('Step id is empty');
2884
- }
2885
- this.designerContext.state.notifyDefinitionChanged(changeType, stepId);
2948
+ this.customActionController.trigger(this.command.action, this.command.step, this.command.sequence);
2886
2949
  }
2887
2950
  }
2888
2951
 
2889
2952
  class ClickBehaviorResolver {
2890
- constructor(designerContext, state) {
2891
- this.designerContext = designerContext;
2892
- this.state = state;
2953
+ constructor(context) {
2954
+ this.context = context;
2893
2955
  }
2894
2956
  resolve(commandOrNull, element, isMiddleButton) {
2895
2957
  if (!commandOrNull) {
2896
- return MoveViewportBehavior.create(this.state, !isMiddleButton);
2958
+ return MoveViewportBehavior.create(!isMiddleButton, this.context);
2897
2959
  }
2898
2960
  switch (commandOrNull.type) {
2899
2961
  case exports.ClickCommandType.selectStep:
2900
- return SelectStepBehavior.create(commandOrNull.component, isMiddleButton, this.designerContext);
2962
+ return SelectStepBehavior.create(commandOrNull.component, isMiddleButton, this.context);
2901
2963
  case exports.ClickCommandType.rerenderStep:
2902
- return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.designerContext));
2964
+ return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.context));
2903
2965
  case exports.ClickCommandType.openFolder:
2904
- return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.designerContext));
2966
+ return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.context));
2905
2967
  case exports.ClickCommandType.triggerCustomAction:
2906
- return PressingBehavior.create(element, new TriggerCustomActionPressingBehaviorHandler(commandOrNull, this.designerContext));
2968
+ return PressingBehavior.create(element, new TriggerCustomActionPressingBehaviorHandler(commandOrNull, this.context.customActionController));
2907
2969
  default:
2908
2970
  throw new Error('Not supported behavior type');
2909
2971
  }
@@ -2930,12 +2992,12 @@
2930
2992
  for (let index = 0; index < items.length; index++) {
2931
2993
  const item = items[index];
2932
2994
  const element = document.createElement('div');
2933
- if (typeof item === 'string') {
2934
- element.className = 'sqd-context-menu-group';
2935
- element.innerText = item;
2995
+ if (item.callback) {
2996
+ element.className = 'sqd-context-menu-item';
2997
+ element.innerText = item.label;
2936
2998
  }
2937
2999
  else {
2938
- element.className = 'sqd-context-menu-item';
3000
+ element.className = 'sqd-context-menu-group';
2939
3001
  element.innerText = item.label;
2940
3002
  }
2941
3003
  elements.push(element);
@@ -2976,7 +3038,7 @@
2976
3038
  const index = this.findIndex(e.target);
2977
3039
  if (index !== null) {
2978
3040
  const item = this.items[index];
2979
- if (typeof item !== 'string') {
3041
+ if (item.callback) {
2980
3042
  item.callback();
2981
3043
  }
2982
3044
  }
@@ -3006,91 +3068,122 @@
3006
3068
  }
3007
3069
  }
3008
3070
 
3071
+ class ContextMenuController {
3072
+ constructor(theme, configuration, itemsBuilder) {
3073
+ this.theme = theme;
3074
+ this.configuration = configuration;
3075
+ this.itemsBuilder = itemsBuilder;
3076
+ }
3077
+ tryOpen(position, commandOrNull) {
3078
+ if (this.configuration.contextMenu === false) {
3079
+ // Context menu is disabled.
3080
+ return;
3081
+ }
3082
+ if (this.current) {
3083
+ this.current.tryDestroy();
3084
+ }
3085
+ const items = this.itemsBuilder.build(commandOrNull);
3086
+ this.current = ContextMenu.create(position, this.theme, items);
3087
+ }
3088
+ destroy() {
3089
+ if (this.current) {
3090
+ this.current.tryDestroy();
3091
+ }
3092
+ }
3093
+ }
3094
+
3009
3095
  class ContextMenuItemsBuilder {
3010
- static build(commandOrNull, viewportApi, definitionModifier, state) {
3096
+ constructor(viewportApi, stateModifier, state, customMenuItemsProvider) {
3097
+ this.viewportApi = viewportApi;
3098
+ this.stateModifier = stateModifier;
3099
+ this.state = state;
3100
+ this.customMenuItemsProvider = customMenuItemsProvider;
3101
+ }
3102
+ build(commandOrNull) {
3011
3103
  const items = [];
3012
3104
  if (commandOrNull && commandOrNull.type === exports.ClickCommandType.selectStep) {
3013
3105
  const ssc = commandOrNull;
3014
3106
  const step = ssc.component.step;
3015
3107
  const parentSequence = ssc.component.parentSequence;
3016
- items.push(step.name);
3017
- if (state.selectedStepId === step.id) {
3018
- items.push({
3019
- label: `Unselect`,
3020
- callback: () => {
3021
- state.setSelectedStepId(null);
3022
- }
3023
- });
3024
- }
3025
- else {
3026
- items.push({
3027
- label: 'Select',
3028
- callback: () => {
3029
- state.setSelectedStepId(step.id);
3030
- }
3031
- });
3108
+ items.push({
3109
+ label: step.name,
3110
+ order: 0
3111
+ });
3112
+ this.tryAppendCustomItems(items, step, parentSequence);
3113
+ if (this.stateModifier.isSelectable(step, parentSequence)) {
3114
+ if (this.state.selectedStepId === step.id) {
3115
+ items.push({
3116
+ label: `Unselect`,
3117
+ order: 10,
3118
+ callback: () => {
3119
+ this.state.setSelectedStepId(null);
3120
+ }
3121
+ });
3122
+ }
3123
+ else {
3124
+ items.push({
3125
+ label: 'Select',
3126
+ order: 20,
3127
+ callback: () => {
3128
+ this.stateModifier.trySelectStepById(step.id);
3129
+ }
3130
+ });
3131
+ }
3032
3132
  }
3033
- if (!state.isReadonly) {
3034
- if (definitionModifier.isDeletable(step.id)) {
3133
+ if (!this.state.isReadonly) {
3134
+ if (this.stateModifier.isDeletable(step.id)) {
3035
3135
  items.push({
3036
3136
  label: 'Delete',
3137
+ order: 30,
3037
3138
  callback: () => {
3038
- definitionModifier.tryDelete(step.id);
3139
+ this.stateModifier.tryDelete(step.id);
3039
3140
  }
3040
3141
  });
3041
3142
  }
3042
- if (definitionModifier.isDuplicable(step, parentSequence)) {
3143
+ if (this.stateModifier.isDuplicable(step, parentSequence)) {
3043
3144
  items.push({
3044
3145
  label: 'Duplicate',
3146
+ order: 40,
3045
3147
  callback: () => {
3046
- definitionModifier.tryDuplicate(step, parentSequence);
3148
+ this.stateModifier.tryDuplicate(step, parentSequence);
3047
3149
  }
3048
3150
  });
3049
3151
  }
3050
3152
  }
3051
3153
  }
3154
+ else {
3155
+ this.tryAppendCustomItems(items, null, this.state.definition.sequence);
3156
+ }
3052
3157
  items.push({
3053
3158
  label: 'Reset view',
3159
+ order: 50,
3054
3160
  callback: () => {
3055
- viewportApi.resetViewport();
3161
+ this.viewportApi.resetViewport();
3056
3162
  }
3057
3163
  });
3164
+ items.sort((a, b) => a.order - b.order);
3058
3165
  return items;
3059
3166
  }
3060
- }
3061
-
3062
- class ContextMenuController {
3063
- constructor(theme, viewportApi, definitionModifier, state, configuration) {
3064
- this.theme = theme;
3065
- this.viewportApi = viewportApi;
3066
- this.definitionModifier = definitionModifier;
3067
- this.state = state;
3068
- this.configuration = configuration;
3069
- }
3070
- tryOpen(position, commandOrNull) {
3071
- if (this.configuration.contextMenu === false) {
3072
- // Context menu is disabled.
3073
- return;
3074
- }
3075
- if (this.last) {
3076
- this.last.tryDestroy();
3077
- }
3078
- const items = ContextMenuItemsBuilder.build(commandOrNull, this.viewportApi, this.definitionModifier, this.state);
3079
- this.last = ContextMenu.create(position, this.theme, items);
3080
- }
3081
- destroy() {
3082
- if (this.last) {
3083
- this.last.tryDestroy();
3167
+ tryAppendCustomItems(items, step, parentSequence) {
3168
+ if (this.customMenuItemsProvider) {
3169
+ const customItems = this.customMenuItemsProvider.getItems(step, parentSequence);
3170
+ for (const customItem of customItems) {
3171
+ items.push(customItem);
3172
+ }
3084
3173
  }
3085
3174
  }
3086
3175
  }
3087
3176
 
3088
3177
  class Workspace {
3089
3178
  static create(parent, designerContext, api) {
3179
+ var _a;
3090
3180
  const view = WorkspaceView.create(parent, designerContext.componentContext);
3091
- const clickBehaviorResolver = new ClickBehaviorResolver(designerContext, designerContext.state);
3181
+ const clickBehaviorResolver = new ClickBehaviorResolver(designerContext);
3092
3182
  const wheelController = designerContext.services.wheelController.create(api.workspace);
3093
- const contextMenuController = new ContextMenuController(designerContext.theme, api.viewport, designerContext.definitionModifier, designerContext.state, designerContext.configuration);
3183
+ const contextMenuItemsBuilder = new ContextMenuItemsBuilder(api.viewport, designerContext.stateModifier, designerContext.state, ((_a = designerContext.services.contextMenu) === null || _a === void 0 ? void 0 : _a.createItemsProvider)
3184
+ ? designerContext.services.contextMenu.createItemsProvider(designerContext.customActionController)
3185
+ : undefined);
3186
+ const contextMenuController = new ContextMenuController(designerContext.theme, designerContext.configuration, contextMenuItemsBuilder);
3094
3187
  const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
3095
3188
  setTimeout(() => {
3096
3189
  workspace.updateRootComponent();
@@ -3578,7 +3671,7 @@
3578
3671
  if (configuration.globalEditorProvider) {
3579
3672
  throw new Error('globalEditorProvider is renamed to rootEditorProvider');
3580
3673
  }
3581
- const editor = Editor.create(root, api, 'sqd-editor sqd-step-editor', configuration.stepEditorProvider, 'sqd-editor sqd-root-editor', configuration.rootEditorProvider);
3674
+ const editor = Editor.create(root, api, 'sqd-editor sqd-step-editor', configuration.stepEditorProvider, 'sqd-editor sqd-root-editor', configuration.rootEditorProvider, null);
3582
3675
  return new SmartEditorView(root, toggle, editor);
3583
3676
  }
3584
3677
  constructor(root, toggle, editor) {
@@ -4241,7 +4334,7 @@
4241
4334
  static resolve(extensions, configuration) {
4242
4335
  const services = {};
4243
4336
  merge(services, extensions || []);
4244
- setDefault(services, configuration);
4337
+ setDefaults(services, configuration);
4245
4338
  return services;
4246
4339
  }
4247
4340
  }
@@ -4283,12 +4376,15 @@
4283
4376
  if (ext.sequenceComponent) {
4284
4377
  services.sequenceComponent = ext.sequenceComponent;
4285
4378
  }
4379
+ if (ext.contextMenu) {
4380
+ services.contextMenu = ext.contextMenu;
4381
+ }
4286
4382
  if (ext.daemons) {
4287
4383
  services.daemons = (services.daemons || []).concat(ext.daemons);
4288
4384
  }
4289
4385
  }
4290
4386
  }
4291
- function setDefault(services, configuration) {
4387
+ function setDefaults(services, configuration) {
4292
4388
  if (!services.steps) {
4293
4389
  services.steps = [];
4294
4390
  }
@@ -4396,7 +4492,7 @@
4396
4492
  const designerContext = DesignerContext.create(placeholder, startDefinition, config, services);
4397
4493
  const designerApi = DesignerApi.create(designerContext);
4398
4494
  const view = DesignerView.create(placeholder, designerContext, designerApi);
4399
- const designer = new Designer(view, designerContext.state, designerContext.definitionWalker, designerContext.historyController, designerApi);
4495
+ const designer = new Designer(view, designerContext.state, designerContext.stateModifier, designerContext.definitionWalker, designerContext.historyController, designerApi);
4400
4496
  view.workspace.onRendered.first().then(designer.onReady.forward);
4401
4497
  race(0, designerContext.state.onDefinitionChanged, designerContext.state.onSelectedStepIdChanged).subscribe(([definition, selectedStepId]) => {
4402
4498
  if (definition !== undefined) {
@@ -4411,9 +4507,10 @@
4411
4507
  designerContext.state.onIsEditorCollapsedChanged.subscribe(designer.onIsEditorCollapsedChanged.forward);
4412
4508
  return designer;
4413
4509
  }
4414
- constructor(view, state, walker, historyController, api) {
4510
+ constructor(view, state, stateModifier, walker, historyController, api) {
4415
4511
  this.view = view;
4416
4512
  this.state = state;
4513
+ this.stateModifier = stateModifier;
4417
4514
  this.walker = walker;
4418
4515
  this.historyController = historyController;
4419
4516
  this.api = api;
@@ -4476,7 +4573,7 @@
4476
4573
  * @description Selects a step by the id.
4477
4574
  */
4478
4575
  selectStepById(stepId) {
4479
- this.state.setSelectedStepId(stepId);
4576
+ this.stateModifier.trySelectStepById(stepId);
4480
4577
  }
4481
4578
  /**
4482
4579
  * @returns the current viewport.
@@ -4503,12 +4600,6 @@
4503
4600
  moveViewportToStep(stepId) {
4504
4601
  this.api.viewport.moveViewportToStep(stepId);
4505
4602
  }
4506
- /**
4507
- * @deprecated Use `moveViewportToStep` instead.
4508
- */
4509
- moveViewPortToStep(stepId) {
4510
- this.moveViewportToStep(stepId);
4511
- }
4512
4603
  /**
4513
4604
  * @description Rerender the root component and all its children.
4514
4605
  */
@@ -4618,11 +4709,6 @@
4618
4709
  constructor(steps) {
4619
4710
  this.steps = steps;
4620
4711
  }
4621
- }
4622
- /**
4623
- * @deprecated Use `StepsDesignerExtension` instead.
4624
- */
4625
- class StepsExtension extends StepsDesignerExtension {
4626
4712
  }
4627
4713
 
4628
4714
  exports.Badges = Badges;
@@ -4630,6 +4716,7 @@
4630
4716
  exports.ClassicWheelControllerExtension = ClassicWheelControllerExtension;
4631
4717
  exports.ComponentContext = ComponentContext;
4632
4718
  exports.ControlBarApi = ControlBarApi;
4719
+ exports.CustomActionController = CustomActionController;
4633
4720
  exports.DefaultSequenceComponent = DefaultSequenceComponent;
4634
4721
  exports.DefaultSequenceComponentView = DefaultSequenceComponentView;
4635
4722
  exports.DefaultViewportController = DefaultViewportController;
@@ -4659,7 +4746,6 @@
4659
4746
  exports.StepComponent = StepComponent;
4660
4747
  exports.StepExtensionResolver = StepExtensionResolver;
4661
4748
  exports.StepsDesignerExtension = StepsDesignerExtension;
4662
- exports.StepsExtension = StepsExtension;
4663
4749
  exports.ToolboxApi = ToolboxApi;
4664
4750
  exports.Uid = Uid;
4665
4751
  exports.ValidationErrorBadgeExtension = ValidationErrorBadgeExtension;