sequential-workflow-designer 0.18.4 → 0.19.0

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,34 @@
969
963
  }
970
964
  }
971
965
 
966
+ class CustomActionController {
967
+ constructor(configuration, state) {
968
+ this.configuration = configuration;
969
+ this.state = state;
970
+ }
971
+ trigger(action, step, sequence) {
972
+ const handler = this.configuration.customActionHandler;
973
+ if (!handler) {
974
+ console.warn(`Custom action handler is not defined (action type: ${action.type})`);
975
+ return;
976
+ }
977
+ const context = {
978
+ notifyStepNameChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepNameChanged, stepId),
979
+ notifyStepPropertiesChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepPropertyChanged, stepId),
980
+ notifyStepInserted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepInserted, stepId),
981
+ notifyStepMoved: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepMoved, stepId),
982
+ notifyStepDeleted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepDeleted, stepId)
983
+ };
984
+ handler(action, step, sequence, context);
985
+ }
986
+ notifyStepChanged(changeType, stepId) {
987
+ if (!stepId) {
988
+ throw new Error('Step id is empty');
989
+ }
990
+ this.state.notifyDefinitionChanged(changeType, stepId);
991
+ }
992
+ }
993
+
972
994
  class EditorView {
973
995
  static create(parent) {
974
996
  return new EditorView(parent);
@@ -996,7 +1018,7 @@
996
1018
  }
997
1019
 
998
1020
  class Editor {
999
- static create(parent, api, stepEditorClassName, stepEditorProvider, rootEditorClassName, rootEditorProvider) {
1021
+ static create(parent, api, stepEditorClassName, stepEditorProvider, rootEditorClassName, rootEditorProvider, customSelectedStepIdProvider) {
1000
1022
  const view = EditorView.create(parent);
1001
1023
  function render(step) {
1002
1024
  const definition = api.getDefinition();
@@ -1014,7 +1036,7 @@
1014
1036
  }
1015
1037
  view.setContent(content, className);
1016
1038
  }
1017
- const renderer = api.runRenderer(step => render(step));
1039
+ const renderer = api.runRenderer(step => render(step), customSelectedStepIdProvider);
1018
1040
  return new Editor(view, renderer);
1019
1041
  }
1020
1042
  constructor(view, renderer) {
@@ -2265,11 +2287,73 @@
2265
2287
  }
2266
2288
  }
2267
2289
 
2268
- class DefinitionModifier {
2269
- constructor(definitionWalker, state, configuration) {
2290
+ class FolderPathDefinitionModifierDependency {
2291
+ constructor(state, definitionWalker) {
2292
+ this.state = state;
2293
+ this.definitionWalker = definitionWalker;
2294
+ }
2295
+ update() {
2296
+ for (let index = 0; index < this.state.folderPath.length; index++) {
2297
+ const stepId = this.state.folderPath[index];
2298
+ const found = this.definitionWalker.findById(this.state.definition, stepId);
2299
+ if (!found) {
2300
+ // We need to update path if any folder is deleted.
2301
+ const newPath = this.state.folderPath.slice(0, index);
2302
+ this.state.setFolderPath(newPath);
2303
+ break;
2304
+ }
2305
+ }
2306
+ }
2307
+ }
2308
+
2309
+ class SelectedStepIdDefinitionModifierDependency {
2310
+ constructor(state, definitionWalker) {
2311
+ this.state = state;
2312
+ this.definitionWalker = definitionWalker;
2313
+ }
2314
+ update() {
2315
+ if (this.state.selectedStepId) {
2316
+ const found = this.definitionWalker.findById(this.state.definition, this.state.selectedStepId);
2317
+ if (!found) {
2318
+ // We need to unselect step when it's deleted.
2319
+ this.state.setSelectedStepId(null);
2320
+ }
2321
+ }
2322
+ }
2323
+ }
2324
+
2325
+ class StateModifier {
2326
+ static create(definitionWalker, state, configuration) {
2327
+ const dependencies = [];
2328
+ dependencies.push(new SelectedStepIdDefinitionModifierDependency(state, definitionWalker));
2329
+ dependencies.push(new FolderPathDefinitionModifierDependency(state, definitionWalker));
2330
+ return new StateModifier(definitionWalker, state, configuration, dependencies);
2331
+ }
2332
+ constructor(definitionWalker, state, configuration, dependencies) {
2270
2333
  this.definitionWalker = definitionWalker;
2271
2334
  this.state = state;
2272
2335
  this.configuration = configuration;
2336
+ this.dependencies = dependencies;
2337
+ }
2338
+ addDependency(dependency) {
2339
+ this.dependencies.push(dependency);
2340
+ }
2341
+ isSelectable(step, parentSequence) {
2342
+ return this.configuration.steps.isSelectable ? this.configuration.steps.isSelectable(step, parentSequence) : true;
2343
+ }
2344
+ trySelectStep(step, parentSequence) {
2345
+ if (this.isSelectable(step, parentSequence)) {
2346
+ this.state.setSelectedStepId(step.id);
2347
+ }
2348
+ }
2349
+ trySelectStepById(stepId) {
2350
+ if (this.configuration.steps.isSelectable) {
2351
+ const result = this.definitionWalker.getParentSequence(this.state.definition, stepId);
2352
+ this.trySelectStep(result.step, result.parentSequence);
2353
+ }
2354
+ else {
2355
+ this.state.setSelectedStepId(stepId);
2356
+ }
2273
2357
  }
2274
2358
  isDeletable(stepId) {
2275
2359
  if (this.configuration.steps.isDeletable) {
@@ -2288,7 +2372,7 @@
2288
2372
  }
2289
2373
  SequenceModifier.deleteStep(result.step, result.parentSequence);
2290
2374
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepDeleted, result.step.id);
2291
- this.updateDependantFields();
2375
+ this.updateDependencies();
2292
2376
  return true;
2293
2377
  }
2294
2378
  tryInsert(step, targetSequence, targetIndex) {
@@ -2301,7 +2385,7 @@
2301
2385
  SequenceModifier.insertStep(step, targetSequence, targetIndex);
2302
2386
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepInserted, step.id);
2303
2387
  if (!this.configuration.steps.isAutoSelectDisabled) {
2304
- this.state.setSelectedStepId(step.id);
2388
+ this.trySelectStepById(step.id);
2305
2389
  }
2306
2390
  return true;
2307
2391
  }
@@ -2322,7 +2406,7 @@
2322
2406
  apply();
2323
2407
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepMoved, step.id);
2324
2408
  if (!this.configuration.steps.isAutoSelectDisabled) {
2325
- this.state.setSelectedStepId(step.id);
2409
+ this.trySelectStep(step, targetSequence);
2326
2410
  }
2327
2411
  return true;
2328
2412
  }
@@ -2341,26 +2425,10 @@
2341
2425
  throw new Error('Definition is empty');
2342
2426
  }
2343
2427
  this.state.setDefinition(definition);
2344
- this.updateDependantFields();
2428
+ this.updateDependencies();
2345
2429
  }
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
- }
2430
+ updateDependencies() {
2431
+ this.dependencies.forEach(dependency => dependency.update());
2364
2432
  }
2365
2433
  }
2366
2434
 
@@ -2447,7 +2515,7 @@
2447
2515
  }
2448
2516
 
2449
2517
  class HistoryController {
2450
- static create(initialStack, state, definitionModifier, configuration) {
2518
+ static create(initialStack, state, stateModifier, configuration) {
2451
2519
  if (!configuration.undoStackSize || configuration.undoStackSize < 1) {
2452
2520
  throw new Error('Invalid undo stack size');
2453
2521
  }
@@ -2455,7 +2523,7 @@
2455
2523
  index: 0,
2456
2524
  items: []
2457
2525
  };
2458
- const controller = new HistoryController(stack, state, definitionModifier, configuration.undoStackSize);
2526
+ const controller = new HistoryController(stack, state, stateModifier, configuration.undoStackSize);
2459
2527
  if (!initialStack) {
2460
2528
  controller.rememberCurrent(exports.DefinitionChangeType.rootReplaced, null);
2461
2529
  }
@@ -2466,10 +2534,10 @@
2466
2534
  });
2467
2535
  return controller;
2468
2536
  }
2469
- constructor(stack, state, definitionModifier, stackSize) {
2537
+ constructor(stack, state, stateModifier, stackSize) {
2470
2538
  this.stack = stack;
2471
2539
  this.state = state;
2472
- this.definitionModifier = definitionModifier;
2540
+ this.stateModifier = stateModifier;
2473
2541
  this.stackSize = stackSize;
2474
2542
  }
2475
2543
  canUndo() {
@@ -2521,7 +2589,7 @@
2521
2589
  }
2522
2590
  commit() {
2523
2591
  const definition = ObjectCloner.deepClone(this.stack.items[this.stack.index - 1].definition);
2524
- this.definitionModifier.replaceDefinition(definition);
2592
+ this.stateModifier.replaceDefinition(definition);
2525
2593
  }
2526
2594
  }
2527
2595
  function areItemsEqual(item, changeType, stepId) {
@@ -2588,27 +2656,29 @@
2588
2656
  const state = new DesignerState(definition, isReadonly, isToolboxCollapsed, isEditorCollapsed);
2589
2657
  const workspaceController = new WorkspaceControllerWrapper();
2590
2658
  const behaviorController = new BehaviorController();
2659
+ const customActionController = new CustomActionController(configuration, state);
2591
2660
  const stepExtensionResolver = StepExtensionResolver.create(services);
2592
2661
  const definitionWalker = (_c = configuration.definitionWalker) !== null && _c !== void 0 ? _c : new DefinitionWalker();
2593
- const definitionModifier = new DefinitionModifier(definitionWalker, state, configuration);
2662
+ const stateModifier = StateModifier.create(definitionWalker, state, configuration);
2594
2663
  let historyController = undefined;
2595
2664
  if (configuration.undoStackSize) {
2596
- historyController = HistoryController.create(configuration.undoStack, state, definitionModifier, configuration);
2665
+ historyController = HistoryController.create(configuration.undoStack, state, stateModifier, configuration);
2597
2666
  }
2598
2667
  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);
2668
+ return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController);
2600
2669
  }
2601
- constructor(theme, state, configuration, services, componentContext, definitionWalker, definitionModifier, layoutController, workspaceController, behaviorController, historyController) {
2670
+ constructor(theme, state, configuration, services, componentContext, definitionWalker, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController) {
2602
2671
  this.theme = theme;
2603
2672
  this.state = state;
2604
2673
  this.configuration = configuration;
2605
2674
  this.services = services;
2606
2675
  this.componentContext = componentContext;
2607
2676
  this.definitionWalker = definitionWalker;
2608
- this.definitionModifier = definitionModifier;
2677
+ this.stateModifier = stateModifier;
2609
2678
  this.layoutController = layoutController;
2610
2679
  this.workspaceController = workspaceController;
2611
2680
  this.behaviorController = behaviorController;
2681
+ this.customActionController = customActionController;
2612
2682
  this.historyController = historyController;
2613
2683
  }
2614
2684
  setWorkspaceController(controller) {
@@ -2754,18 +2824,24 @@
2754
2824
  }
2755
2825
 
2756
2826
  class MoveViewportBehavior {
2757
- static create(state, resetSelectedStep) {
2758
- return new MoveViewportBehavior(state.viewport.position, resetSelectedStep, state);
2827
+ static create(resetSelectedStep, context) {
2828
+ return new MoveViewportBehavior(context.state.viewport.position, resetSelectedStep, context.state, context.stateModifier);
2759
2829
  }
2760
- constructor(startPosition, resetSelectedStep, state) {
2830
+ constructor(startPosition, resetSelectedStep, state, stateModifier) {
2761
2831
  this.startPosition = startPosition;
2762
2832
  this.resetSelectedStep = resetSelectedStep;
2763
2833
  this.state = state;
2834
+ this.stateModifier = stateModifier;
2764
2835
  }
2765
2836
  onStart() {
2766
2837
  if (this.resetSelectedStep) {
2767
- const stepId = this.state.tryGetLastStepIdFromFolderPath();
2768
- this.state.setSelectedStepId(stepId);
2838
+ const stepIdOrNull = this.state.tryGetLastStepIdFromFolderPath();
2839
+ if (stepIdOrNull) {
2840
+ this.stateModifier.trySelectStepById(stepIdOrNull);
2841
+ }
2842
+ else {
2843
+ this.state.setSelectedStepId(null);
2844
+ }
2769
2845
  }
2770
2846
  }
2771
2847
  onMove(delta) {
@@ -2783,14 +2859,15 @@
2783
2859
  static create(pressedStepComponent, isMiddleButton, context) {
2784
2860
  const isDragDisabled = isMiddleButton ||
2785
2861
  context.state.isDragDisabled ||
2786
- !context.definitionModifier.isDraggable(pressedStepComponent.step, pressedStepComponent.parentSequence);
2787
- return new SelectStepBehavior(pressedStepComponent, isDragDisabled, context, context.state);
2862
+ !context.stateModifier.isDraggable(pressedStepComponent.step, pressedStepComponent.parentSequence);
2863
+ return new SelectStepBehavior(pressedStepComponent, isDragDisabled, context.state, context.stateModifier, context);
2788
2864
  }
2789
- constructor(pressedStepComponent, isDragDisabled, context, state) {
2865
+ constructor(pressedStepComponent, isDragDisabled, state, stateModifier, context) {
2790
2866
  this.pressedStepComponent = pressedStepComponent;
2791
2867
  this.isDragDisabled = isDragDisabled;
2792
- this.context = context;
2793
2868
  this.state = state;
2869
+ this.stateModifier = stateModifier;
2870
+ this.context = context;
2794
2871
  }
2795
2872
  onStart() {
2796
2873
  // Nothing to do.
@@ -2803,13 +2880,13 @@
2803
2880
  return DragStepBehavior.create(this.context, this.pressedStepComponent.step, this.pressedStepComponent);
2804
2881
  }
2805
2882
  else {
2806
- return MoveViewportBehavior.create(this.state, false);
2883
+ return MoveViewportBehavior.create(false, this.context);
2807
2884
  }
2808
2885
  }
2809
2886
  }
2810
2887
  onEnd(interrupt) {
2811
2888
  if (!interrupt) {
2812
- this.state.setSelectedStepId(this.pressedStepComponent.step.id);
2889
+ this.stateModifier.trySelectStep(this.pressedStepComponent.step, this.pressedStepComponent.parentSequence);
2813
2890
  }
2814
2891
  }
2815
2892
  }
@@ -2856,54 +2933,32 @@
2856
2933
  }
2857
2934
 
2858
2935
  class TriggerCustomActionPressingBehaviorHandler {
2859
- constructor(command, designerContext) {
2936
+ constructor(command, customActionController) {
2860
2937
  this.command = command;
2861
- this.designerContext = designerContext;
2938
+ this.customActionController = customActionController;
2862
2939
  }
2863
2940
  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);
2941
+ this.customActionController.trigger(this.command.action, this.command.step, this.command.sequence);
2886
2942
  }
2887
2943
  }
2888
2944
 
2889
2945
  class ClickBehaviorResolver {
2890
- constructor(designerContext, state) {
2891
- this.designerContext = designerContext;
2892
- this.state = state;
2946
+ constructor(context) {
2947
+ this.context = context;
2893
2948
  }
2894
2949
  resolve(commandOrNull, element, isMiddleButton) {
2895
2950
  if (!commandOrNull) {
2896
- return MoveViewportBehavior.create(this.state, !isMiddleButton);
2951
+ return MoveViewportBehavior.create(!isMiddleButton, this.context);
2897
2952
  }
2898
2953
  switch (commandOrNull.type) {
2899
2954
  case exports.ClickCommandType.selectStep:
2900
- return SelectStepBehavior.create(commandOrNull.component, isMiddleButton, this.designerContext);
2955
+ return SelectStepBehavior.create(commandOrNull.component, isMiddleButton, this.context);
2901
2956
  case exports.ClickCommandType.rerenderStep:
2902
- return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.designerContext));
2957
+ return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.context));
2903
2958
  case exports.ClickCommandType.openFolder:
2904
- return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.designerContext));
2959
+ return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.context));
2905
2960
  case exports.ClickCommandType.triggerCustomAction:
2906
- return PressingBehavior.create(element, new TriggerCustomActionPressingBehaviorHandler(commandOrNull, this.designerContext));
2961
+ return PressingBehavior.create(element, new TriggerCustomActionPressingBehaviorHandler(commandOrNull, this.context.customActionController));
2907
2962
  default:
2908
2963
  throw new Error('Not supported behavior type');
2909
2964
  }
@@ -2930,12 +2985,12 @@
2930
2985
  for (let index = 0; index < items.length; index++) {
2931
2986
  const item = items[index];
2932
2987
  const element = document.createElement('div');
2933
- if (typeof item === 'string') {
2934
- element.className = 'sqd-context-menu-group';
2935
- element.innerText = item;
2988
+ if (item.callback) {
2989
+ element.className = 'sqd-context-menu-item';
2990
+ element.innerText = item.label;
2936
2991
  }
2937
2992
  else {
2938
- element.className = 'sqd-context-menu-item';
2993
+ element.className = 'sqd-context-menu-group';
2939
2994
  element.innerText = item.label;
2940
2995
  }
2941
2996
  elements.push(element);
@@ -2976,7 +3031,7 @@
2976
3031
  const index = this.findIndex(e.target);
2977
3032
  if (index !== null) {
2978
3033
  const item = this.items[index];
2979
- if (typeof item !== 'string') {
3034
+ if (item.callback) {
2980
3035
  item.callback();
2981
3036
  }
2982
3037
  }
@@ -3006,91 +3061,122 @@
3006
3061
  }
3007
3062
  }
3008
3063
 
3064
+ class ContextMenuController {
3065
+ constructor(theme, configuration, itemsBuilder) {
3066
+ this.theme = theme;
3067
+ this.configuration = configuration;
3068
+ this.itemsBuilder = itemsBuilder;
3069
+ }
3070
+ tryOpen(position, commandOrNull) {
3071
+ if (this.configuration.contextMenu === false) {
3072
+ // Context menu is disabled.
3073
+ return;
3074
+ }
3075
+ if (this.current) {
3076
+ this.current.tryDestroy();
3077
+ }
3078
+ const items = this.itemsBuilder.build(commandOrNull);
3079
+ this.current = ContextMenu.create(position, this.theme, items);
3080
+ }
3081
+ destroy() {
3082
+ if (this.current) {
3083
+ this.current.tryDestroy();
3084
+ }
3085
+ }
3086
+ }
3087
+
3009
3088
  class ContextMenuItemsBuilder {
3010
- static build(commandOrNull, viewportApi, definitionModifier, state) {
3089
+ constructor(viewportApi, stateModifier, state, customMenuItemsProvider) {
3090
+ this.viewportApi = viewportApi;
3091
+ this.stateModifier = stateModifier;
3092
+ this.state = state;
3093
+ this.customMenuItemsProvider = customMenuItemsProvider;
3094
+ }
3095
+ build(commandOrNull) {
3011
3096
  const items = [];
3012
3097
  if (commandOrNull && commandOrNull.type === exports.ClickCommandType.selectStep) {
3013
3098
  const ssc = commandOrNull;
3014
3099
  const step = ssc.component.step;
3015
3100
  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
- });
3101
+ items.push({
3102
+ label: step.name,
3103
+ order: 0
3104
+ });
3105
+ this.tryAppendCustomItems(items, step, parentSequence);
3106
+ if (this.stateModifier.isSelectable(step, parentSequence)) {
3107
+ if (this.state.selectedStepId === step.id) {
3108
+ items.push({
3109
+ label: `Unselect`,
3110
+ order: 10,
3111
+ callback: () => {
3112
+ this.state.setSelectedStepId(null);
3113
+ }
3114
+ });
3115
+ }
3116
+ else {
3117
+ items.push({
3118
+ label: 'Select',
3119
+ order: 20,
3120
+ callback: () => {
3121
+ this.stateModifier.trySelectStepById(step.id);
3122
+ }
3123
+ });
3124
+ }
3032
3125
  }
3033
- if (!state.isReadonly) {
3034
- if (definitionModifier.isDeletable(step.id)) {
3126
+ if (!this.state.isReadonly) {
3127
+ if (this.stateModifier.isDeletable(step.id)) {
3035
3128
  items.push({
3036
3129
  label: 'Delete',
3130
+ order: 30,
3037
3131
  callback: () => {
3038
- definitionModifier.tryDelete(step.id);
3132
+ this.stateModifier.tryDelete(step.id);
3039
3133
  }
3040
3134
  });
3041
3135
  }
3042
- if (definitionModifier.isDuplicable(step, parentSequence)) {
3136
+ if (this.stateModifier.isDuplicable(step, parentSequence)) {
3043
3137
  items.push({
3044
3138
  label: 'Duplicate',
3139
+ order: 40,
3045
3140
  callback: () => {
3046
- definitionModifier.tryDuplicate(step, parentSequence);
3141
+ this.stateModifier.tryDuplicate(step, parentSequence);
3047
3142
  }
3048
3143
  });
3049
3144
  }
3050
3145
  }
3051
3146
  }
3147
+ else {
3148
+ this.tryAppendCustomItems(items, null, this.state.definition.sequence);
3149
+ }
3052
3150
  items.push({
3053
3151
  label: 'Reset view',
3152
+ order: 50,
3054
3153
  callback: () => {
3055
- viewportApi.resetViewport();
3154
+ this.viewportApi.resetViewport();
3056
3155
  }
3057
3156
  });
3157
+ items.sort((a, b) => a.order - b.order);
3058
3158
  return items;
3059
3159
  }
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();
3160
+ tryAppendCustomItems(items, step, parentSequence) {
3161
+ if (this.customMenuItemsProvider) {
3162
+ const customItems = this.customMenuItemsProvider.getItems(step, parentSequence);
3163
+ for (const customItem of customItems) {
3164
+ items.push(customItem);
3165
+ }
3084
3166
  }
3085
3167
  }
3086
3168
  }
3087
3169
 
3088
3170
  class Workspace {
3089
3171
  static create(parent, designerContext, api) {
3172
+ var _a;
3090
3173
  const view = WorkspaceView.create(parent, designerContext.componentContext);
3091
- const clickBehaviorResolver = new ClickBehaviorResolver(designerContext, designerContext.state);
3174
+ const clickBehaviorResolver = new ClickBehaviorResolver(designerContext);
3092
3175
  const wheelController = designerContext.services.wheelController.create(api.workspace);
3093
- const contextMenuController = new ContextMenuController(designerContext.theme, api.viewport, designerContext.definitionModifier, designerContext.state, designerContext.configuration);
3176
+ const contextMenuItemsBuilder = new ContextMenuItemsBuilder(api.viewport, designerContext.stateModifier, designerContext.state, ((_a = designerContext.services.contextMenu) === null || _a === void 0 ? void 0 : _a.createItemsProvider)
3177
+ ? designerContext.services.contextMenu.createItemsProvider(designerContext.customActionController)
3178
+ : undefined);
3179
+ const contextMenuController = new ContextMenuController(designerContext.theme, designerContext.configuration, contextMenuItemsBuilder);
3094
3180
  const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
3095
3181
  setTimeout(() => {
3096
3182
  workspace.updateRootComponent();
@@ -3578,7 +3664,7 @@
3578
3664
  if (configuration.globalEditorProvider) {
3579
3665
  throw new Error('globalEditorProvider is renamed to rootEditorProvider');
3580
3666
  }
3581
- const editor = Editor.create(root, api, 'sqd-editor sqd-step-editor', configuration.stepEditorProvider, 'sqd-editor sqd-root-editor', configuration.rootEditorProvider);
3667
+ const editor = Editor.create(root, api, 'sqd-editor sqd-step-editor', configuration.stepEditorProvider, 'sqd-editor sqd-root-editor', configuration.rootEditorProvider, null);
3582
3668
  return new SmartEditorView(root, toggle, editor);
3583
3669
  }
3584
3670
  constructor(root, toggle, editor) {
@@ -4241,7 +4327,7 @@
4241
4327
  static resolve(extensions, configuration) {
4242
4328
  const services = {};
4243
4329
  merge(services, extensions || []);
4244
- setDefault(services, configuration);
4330
+ setDefaults(services, configuration);
4245
4331
  return services;
4246
4332
  }
4247
4333
  }
@@ -4283,12 +4369,15 @@
4283
4369
  if (ext.sequenceComponent) {
4284
4370
  services.sequenceComponent = ext.sequenceComponent;
4285
4371
  }
4372
+ if (ext.contextMenu) {
4373
+ services.contextMenu = ext.contextMenu;
4374
+ }
4286
4375
  if (ext.daemons) {
4287
4376
  services.daemons = (services.daemons || []).concat(ext.daemons);
4288
4377
  }
4289
4378
  }
4290
4379
  }
4291
- function setDefault(services, configuration) {
4380
+ function setDefaults(services, configuration) {
4292
4381
  if (!services.steps) {
4293
4382
  services.steps = [];
4294
4383
  }
@@ -4396,7 +4485,7 @@
4396
4485
  const designerContext = DesignerContext.create(placeholder, startDefinition, config, services);
4397
4486
  const designerApi = DesignerApi.create(designerContext);
4398
4487
  const view = DesignerView.create(placeholder, designerContext, designerApi);
4399
- const designer = new Designer(view, designerContext.state, designerContext.definitionWalker, designerContext.historyController, designerApi);
4488
+ const designer = new Designer(view, designerContext.state, designerContext.stateModifier, designerContext.definitionWalker, designerContext.historyController, designerApi);
4400
4489
  view.workspace.onRendered.first().then(designer.onReady.forward);
4401
4490
  race(0, designerContext.state.onDefinitionChanged, designerContext.state.onSelectedStepIdChanged).subscribe(([definition, selectedStepId]) => {
4402
4491
  if (definition !== undefined) {
@@ -4411,9 +4500,10 @@
4411
4500
  designerContext.state.onIsEditorCollapsedChanged.subscribe(designer.onIsEditorCollapsedChanged.forward);
4412
4501
  return designer;
4413
4502
  }
4414
- constructor(view, state, walker, historyController, api) {
4503
+ constructor(view, state, stateModifier, walker, historyController, api) {
4415
4504
  this.view = view;
4416
4505
  this.state = state;
4506
+ this.stateModifier = stateModifier;
4417
4507
  this.walker = walker;
4418
4508
  this.historyController = historyController;
4419
4509
  this.api = api;
@@ -4476,7 +4566,7 @@
4476
4566
  * @description Selects a step by the id.
4477
4567
  */
4478
4568
  selectStepById(stepId) {
4479
- this.state.setSelectedStepId(stepId);
4569
+ this.stateModifier.trySelectStepById(stepId);
4480
4570
  }
4481
4571
  /**
4482
4572
  * @returns the current viewport.
@@ -4503,12 +4593,6 @@
4503
4593
  moveViewportToStep(stepId) {
4504
4594
  this.api.viewport.moveViewportToStep(stepId);
4505
4595
  }
4506
- /**
4507
- * @deprecated Use `moveViewportToStep` instead.
4508
- */
4509
- moveViewPortToStep(stepId) {
4510
- this.moveViewportToStep(stepId);
4511
- }
4512
4596
  /**
4513
4597
  * @description Rerender the root component and all its children.
4514
4598
  */
@@ -4618,11 +4702,6 @@
4618
4702
  constructor(steps) {
4619
4703
  this.steps = steps;
4620
4704
  }
4621
- }
4622
- /**
4623
- * @deprecated Use `StepsDesignerExtension` instead.
4624
- */
4625
- class StepsExtension extends StepsDesignerExtension {
4626
4705
  }
4627
4706
 
4628
4707
  exports.Badges = Badges;
@@ -4630,6 +4709,7 @@
4630
4709
  exports.ClassicWheelControllerExtension = ClassicWheelControllerExtension;
4631
4710
  exports.ComponentContext = ComponentContext;
4632
4711
  exports.ControlBarApi = ControlBarApi;
4712
+ exports.CustomActionController = CustomActionController;
4633
4713
  exports.DefaultSequenceComponent = DefaultSequenceComponent;
4634
4714
  exports.DefaultSequenceComponentView = DefaultSequenceComponentView;
4635
4715
  exports.DefaultViewportController = DefaultViewportController;
@@ -4659,7 +4739,6 @@
4659
4739
  exports.StepComponent = StepComponent;
4660
4740
  exports.StepExtensionResolver = StepExtensionResolver;
4661
4741
  exports.StepsDesignerExtension = StepsDesignerExtension;
4662
- exports.StepsExtension = StepsExtension;
4663
4742
  exports.ToolboxApi = ToolboxApi;
4664
4743
  exports.Uid = Uid;
4665
4744
  exports.ValidationErrorBadgeExtension = ValidationErrorBadgeExtension;