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/lib/cjs/index.cjs CHANGED
@@ -194,8 +194,8 @@ function race(timeout, a, b, c) {
194
194
  }
195
195
 
196
196
  class ControlBarApi {
197
- static create(state, historyController, definitionModifier, viewportApi) {
198
- const api = new ControlBarApi(state, historyController, definitionModifier, viewportApi);
197
+ static create(state, historyController, stateModifier, viewportApi) {
198
+ const api = new ControlBarApi(state, historyController, stateModifier, viewportApi);
199
199
  state.onIsReadonlyChanged.subscribe(api.onStateChanged.forward);
200
200
  state.onSelectedStepIdChanged.subscribe(api.onStateChanged.forward);
201
201
  state.onIsDragDisabledChanged.subscribe(api.onStateChanged.forward);
@@ -204,19 +204,13 @@ class ControlBarApi {
204
204
  }
205
205
  return api;
206
206
  }
207
- constructor(state, historyController, definitionModifier, viewportApi) {
207
+ constructor(state, historyController, stateModifier, viewportApi) {
208
208
  this.state = state;
209
209
  this.historyController = historyController;
210
- this.definitionModifier = definitionModifier;
210
+ this.stateModifier = stateModifier;
211
211
  this.viewportApi = viewportApi;
212
212
  this.onStateChanged = new SimpleEvent();
213
213
  }
214
- /**
215
- * @deprecated Don't use this method
216
- */
217
- subscribe(handler) {
218
- this.onStateChanged.subscribe(handler);
219
- }
220
214
  resetViewport() {
221
215
  this.viewportApi.resetViewport();
222
216
  }
@@ -257,7 +251,7 @@ class ControlBarApi {
257
251
  }
258
252
  tryDelete() {
259
253
  if (this.canDelete() && this.state.selectedStepId) {
260
- this.definitionModifier.tryDelete(this.state.selectedStepId);
254
+ this.stateModifier.tryDelete(this.state.selectedStepId);
261
255
  return true;
262
256
  }
263
257
  return false;
@@ -266,7 +260,7 @@ class ControlBarApi {
266
260
  return (!!this.state.selectedStepId &&
267
261
  !this.state.isReadonly &&
268
262
  !this.state.isDragging &&
269
- this.definitionModifier.isDeletable(this.state.selectedStepId));
263
+ this.stateModifier.isDeletable(this.state.selectedStepId));
270
264
  }
271
265
  }
272
266
 
@@ -287,29 +281,30 @@ exports.DefinitionChangeType = void 0;
287
281
  })(exports.DefinitionChangeType || (exports.DefinitionChangeType = {}));
288
282
 
289
283
  class EditorRenderer {
290
- static create(state, definitionWalker, handler) {
291
- const raceEvent = race(0, state.onDefinitionChanged, state.onSelectedStepIdChanged, state.onIsReadonlyChanged);
292
- const listener = new EditorRenderer(state, definitionWalker, handler, raceEvent);
284
+ static create(state, selectedStepIdProvider, definitionWalker, handler) {
285
+ const raceEvent = race(0, state.onDefinitionChanged, selectedStepIdProvider.onSelectedStepIdChanged, state.onIsReadonlyChanged);
286
+ const listener = new EditorRenderer(state, selectedStepIdProvider, definitionWalker, handler, raceEvent);
293
287
  raceEvent.subscribe(listener.raceEventHandler);
294
- listener.renderIfStepChanged(state.selectedStepId);
288
+ listener.renderIfStepChanged(selectedStepIdProvider.selectedStepId);
295
289
  return listener;
296
290
  }
297
- constructor(state, definitionWalker, handler, raceEvent) {
291
+ constructor(state, selectedStepIdProvider, definitionWalker, handler, raceEvent) {
298
292
  this.state = state;
293
+ this.selectedStepIdProvider = selectedStepIdProvider;
299
294
  this.definitionWalker = definitionWalker;
300
295
  this.handler = handler;
301
296
  this.raceEvent = raceEvent;
302
297
  this.currentStepId = undefined;
303
298
  this.raceEventHandler = ([definitionChanged, selectedStepId, isReadonlyChanged]) => {
304
299
  if (isReadonlyChanged !== undefined) {
305
- this.render(this.state.selectedStepId);
300
+ this.render(this.selectedStepIdProvider.selectedStepId);
306
301
  }
307
302
  else if (definitionChanged) {
308
303
  if (definitionChanged.changeType === exports.DefinitionChangeType.rootReplaced) {
309
- this.render(this.state.selectedStepId);
304
+ this.render(this.selectedStepIdProvider.selectedStepId);
310
305
  }
311
306
  else {
312
- this.renderIfStepChanged(this.state.selectedStepId);
307
+ this.renderIfStepChanged(this.selectedStepIdProvider.selectedStepId);
313
308
  }
314
309
  }
315
310
  else if (selectedStepId !== undefined) {
@@ -333,10 +328,10 @@ class EditorRenderer {
333
328
  }
334
329
 
335
330
  class EditorApi {
336
- constructor(state, definitionWalker, definitionModifier) {
331
+ constructor(state, definitionWalker, stateModifier) {
337
332
  this.state = state;
338
333
  this.definitionWalker = definitionWalker;
339
- this.definitionModifier = definitionModifier;
334
+ this.stateModifier = stateModifier;
340
335
  }
341
336
  isCollapsed() {
342
337
  return this.state.isEditorCollapsed;
@@ -353,8 +348,12 @@ class EditorApi {
353
348
  getDefinition() {
354
349
  return this.state.definition;
355
350
  }
356
- runRenderer(rendererHandler) {
357
- return EditorRenderer.create(this.state, this.definitionWalker, rendererHandler);
351
+ addDefinitionModifierDependency(dependency) {
352
+ this.stateModifier.addDependency(dependency);
353
+ }
354
+ runRenderer(rendererHandler, customSelectedStepIdProvider) {
355
+ const selectedStepIdProvider = customSelectedStepIdProvider || this.state;
356
+ return EditorRenderer.create(this.state, selectedStepIdProvider, this.definitionWalker, rendererHandler);
358
357
  }
359
358
  createStepEditorContext(stepId) {
360
359
  if (!stepId) {
@@ -369,7 +368,7 @@ class EditorApi {
369
368
  },
370
369
  notifyChildrenChanged: () => {
371
370
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepChildrenChanged, stepId);
372
- this.definitionModifier.updateDependantFields();
371
+ this.stateModifier.updateDependencies();
373
372
  }
374
373
  };
375
374
  }
@@ -388,12 +387,6 @@ class PathBarApi {
388
387
  this.definitionWalker = definitionWalker;
389
388
  this.onStateChanged = race(0, this.state.onFolderPathChanged, this.state.onDefinitionChanged);
390
389
  }
391
- /**
392
- * @deprecated Don't use this method
393
- */
394
- subscribe(handler) {
395
- this.onStateChanged.subscribe(handler);
396
- }
397
390
  setFolderPath(path) {
398
391
  this.state.setFolderPath(path);
399
392
  }
@@ -474,14 +467,14 @@ class PlaceholderFinder {
474
467
  class DragStepBehavior {
475
468
  static create(designerContext, step, draggedStepComponent) {
476
469
  const view = DragStepView.create(step, designerContext.theme, designerContext.componentContext);
477
- return new DragStepBehavior(view, designerContext.workspaceController, designerContext.state, step, designerContext.definitionModifier, draggedStepComponent);
470
+ return new DragStepBehavior(view, designerContext.workspaceController, designerContext.state, step, designerContext.stateModifier, draggedStepComponent);
478
471
  }
479
- constructor(view, workspaceController, designerState, step, definitionModifier, draggedStepComponent) {
472
+ constructor(view, workspaceController, designerState, step, stateModifier, draggedStepComponent) {
480
473
  this.view = view;
481
474
  this.workspaceController = workspaceController;
482
475
  this.designerState = designerState;
483
476
  this.step = step;
484
- this.definitionModifier = definitionModifier;
477
+ this.stateModifier = stateModifier;
485
478
  this.draggedStepComponent = draggedStepComponent;
486
479
  }
487
480
  onStart(position) {
@@ -536,10 +529,10 @@ class DragStepBehavior {
536
529
  let modified = false;
537
530
  if (!interrupt && this.currentPlaceholder) {
538
531
  if (this.draggedStepComponent) {
539
- modified = this.definitionModifier.tryMove(this.draggedStepComponent.parentSequence, this.draggedStepComponent.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
532
+ modified = this.stateModifier.tryMove(this.draggedStepComponent.parentSequence, this.draggedStepComponent.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
540
533
  }
541
534
  else {
542
- modified = this.definitionModifier.tryInsert(this.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
535
+ modified = this.stateModifier.tryInsert(this.step, this.currentPlaceholder.parentSequence, this.currentPlaceholder.index);
543
536
  }
544
537
  }
545
538
  if (!modified) {
@@ -712,15 +705,16 @@ class DesignerApi {
712
705
  const viewportController = context.services.viewportController.create(workspace);
713
706
  const viewport = new ViewportApi(context.workspaceController, viewportController);
714
707
  const toolboxDataProvider = new ToolboxDataProvider(context.componentContext.iconProvider, context.configuration.toolbox);
715
- 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));
708
+ 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);
716
709
  }
717
- constructor(controlBar, toolbox, editor, workspace, viewport, pathBar) {
710
+ constructor(controlBar, toolbox, editor, workspace, viewport, pathBar, definitionWalker) {
718
711
  this.controlBar = controlBar;
719
712
  this.toolbox = toolbox;
720
713
  this.editor = editor;
721
714
  this.workspace = workspace;
722
715
  this.viewport = viewport;
723
716
  this.pathBar = pathBar;
717
+ this.definitionWalker = definitionWalker;
724
718
  }
725
719
  }
726
720
 
@@ -967,6 +961,41 @@ class ComponentContext {
967
961
  }
968
962
  }
969
963
 
964
+ class CustomActionController {
965
+ constructor(configuration, state, stateModifier) {
966
+ this.configuration = configuration;
967
+ this.state = state;
968
+ this.stateModifier = stateModifier;
969
+ }
970
+ trigger(action, step, sequence) {
971
+ const handler = this.configuration.customActionHandler;
972
+ if (!handler) {
973
+ console.warn(`Custom action handler is not defined (action type: ${action.type})`);
974
+ return;
975
+ }
976
+ const context = this.createCustomActionHandlerContext();
977
+ handler(action, step, sequence, context);
978
+ }
979
+ createCustomActionHandlerContext() {
980
+ return {
981
+ notifyStepNameChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepNameChanged, stepId, false),
982
+ notifyStepPropertiesChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepPropertyChanged, stepId, false),
983
+ notifyStepInserted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepInserted, stepId, true),
984
+ notifyStepMoved: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepMoved, stepId, true),
985
+ notifyStepDeleted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepDeleted, stepId, true)
986
+ };
987
+ }
988
+ notifyStepChanged(changeType, stepId, updateDependencies) {
989
+ if (!stepId) {
990
+ throw new Error('Step id is empty');
991
+ }
992
+ this.state.notifyDefinitionChanged(changeType, stepId);
993
+ if (updateDependencies) {
994
+ this.stateModifier.updateDependencies();
995
+ }
996
+ }
997
+ }
998
+
970
999
  class EditorView {
971
1000
  static create(parent) {
972
1001
  return new EditorView(parent);
@@ -994,7 +1023,7 @@ class EditorView {
994
1023
  }
995
1024
 
996
1025
  class Editor {
997
- static create(parent, api, stepEditorClassName, stepEditorProvider, rootEditorClassName, rootEditorProvider) {
1026
+ static create(parent, api, stepEditorClassName, stepEditorProvider, rootEditorClassName, rootEditorProvider, customSelectedStepIdProvider) {
998
1027
  const view = EditorView.create(parent);
999
1028
  function render(step) {
1000
1029
  const definition = api.getDefinition();
@@ -1012,7 +1041,7 @@ class Editor {
1012
1041
  }
1013
1042
  view.setContent(content, className);
1014
1043
  }
1015
- const renderer = api.runRenderer(step => render(step));
1044
+ const renderer = api.runRenderer(step => render(step), customSelectedStepIdProvider);
1016
1045
  return new Editor(view, renderer);
1017
1046
  }
1018
1047
  constructor(view, renderer) {
@@ -2080,11 +2109,73 @@ class StepDuplicator {
2080
2109
  }
2081
2110
  }
2082
2111
 
2083
- class DefinitionModifier {
2084
- constructor(definitionWalker, state, configuration) {
2112
+ class FolderPathDefinitionModifierDependency {
2113
+ constructor(state, definitionWalker) {
2114
+ this.state = state;
2115
+ this.definitionWalker = definitionWalker;
2116
+ }
2117
+ update() {
2118
+ for (let index = 0; index < this.state.folderPath.length; index++) {
2119
+ const stepId = this.state.folderPath[index];
2120
+ const found = this.definitionWalker.findById(this.state.definition, stepId);
2121
+ if (!found) {
2122
+ // We need to update path if any folder is deleted.
2123
+ const newPath = this.state.folderPath.slice(0, index);
2124
+ this.state.setFolderPath(newPath);
2125
+ break;
2126
+ }
2127
+ }
2128
+ }
2129
+ }
2130
+
2131
+ class SelectedStepIdDefinitionModifierDependency {
2132
+ constructor(state, definitionWalker) {
2133
+ this.state = state;
2134
+ this.definitionWalker = definitionWalker;
2135
+ }
2136
+ update() {
2137
+ if (this.state.selectedStepId) {
2138
+ const found = this.definitionWalker.findById(this.state.definition, this.state.selectedStepId);
2139
+ if (!found) {
2140
+ // We need to unselect step when it's deleted.
2141
+ this.state.setSelectedStepId(null);
2142
+ }
2143
+ }
2144
+ }
2145
+ }
2146
+
2147
+ class StateModifier {
2148
+ static create(definitionWalker, state, configuration) {
2149
+ const dependencies = [];
2150
+ dependencies.push(new SelectedStepIdDefinitionModifierDependency(state, definitionWalker));
2151
+ dependencies.push(new FolderPathDefinitionModifierDependency(state, definitionWalker));
2152
+ return new StateModifier(definitionWalker, state, configuration, dependencies);
2153
+ }
2154
+ constructor(definitionWalker, state, configuration, dependencies) {
2085
2155
  this.definitionWalker = definitionWalker;
2086
2156
  this.state = state;
2087
2157
  this.configuration = configuration;
2158
+ this.dependencies = dependencies;
2159
+ }
2160
+ addDependency(dependency) {
2161
+ this.dependencies.push(dependency);
2162
+ }
2163
+ isSelectable(step, parentSequence) {
2164
+ return this.configuration.steps.isSelectable ? this.configuration.steps.isSelectable(step, parentSequence) : true;
2165
+ }
2166
+ trySelectStep(step, parentSequence) {
2167
+ if (this.isSelectable(step, parentSequence)) {
2168
+ this.state.setSelectedStepId(step.id);
2169
+ }
2170
+ }
2171
+ trySelectStepById(stepId) {
2172
+ if (this.configuration.steps.isSelectable) {
2173
+ const result = this.definitionWalker.getParentSequence(this.state.definition, stepId);
2174
+ this.trySelectStep(result.step, result.parentSequence);
2175
+ }
2176
+ else {
2177
+ this.state.setSelectedStepId(stepId);
2178
+ }
2088
2179
  }
2089
2180
  isDeletable(stepId) {
2090
2181
  if (this.configuration.steps.isDeletable) {
@@ -2103,7 +2194,7 @@ class DefinitionModifier {
2103
2194
  }
2104
2195
  SequenceModifier.deleteStep(result.step, result.parentSequence);
2105
2196
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepDeleted, result.step.id);
2106
- this.updateDependantFields();
2197
+ this.updateDependencies();
2107
2198
  return true;
2108
2199
  }
2109
2200
  tryInsert(step, targetSequence, targetIndex) {
@@ -2116,7 +2207,7 @@ class DefinitionModifier {
2116
2207
  SequenceModifier.insertStep(step, targetSequence, targetIndex);
2117
2208
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepInserted, step.id);
2118
2209
  if (!this.configuration.steps.isAutoSelectDisabled) {
2119
- this.state.setSelectedStepId(step.id);
2210
+ this.trySelectStepById(step.id);
2120
2211
  }
2121
2212
  return true;
2122
2213
  }
@@ -2137,7 +2228,7 @@ class DefinitionModifier {
2137
2228
  apply();
2138
2229
  this.state.notifyDefinitionChanged(exports.DefinitionChangeType.stepMoved, step.id);
2139
2230
  if (!this.configuration.steps.isAutoSelectDisabled) {
2140
- this.state.setSelectedStepId(step.id);
2231
+ this.trySelectStep(step, targetSequence);
2141
2232
  }
2142
2233
  return true;
2143
2234
  }
@@ -2156,26 +2247,10 @@ class DefinitionModifier {
2156
2247
  throw new Error('Definition is empty');
2157
2248
  }
2158
2249
  this.state.setDefinition(definition);
2159
- this.updateDependantFields();
2250
+ this.updateDependencies();
2160
2251
  }
2161
- updateDependantFields() {
2162
- if (this.state.selectedStepId) {
2163
- const found = this.definitionWalker.findById(this.state.definition, this.state.selectedStepId);
2164
- if (!found) {
2165
- // We need to unselect step when it's deleted.
2166
- this.state.setSelectedStepId(null);
2167
- }
2168
- }
2169
- for (let index = 0; index < this.state.folderPath.length; index++) {
2170
- const stepId = this.state.folderPath[index];
2171
- const found = this.definitionWalker.findById(this.state.definition, stepId);
2172
- if (!found) {
2173
- // We need to update path if any folder is deleted.
2174
- const newPath = this.state.folderPath.slice(0, index);
2175
- this.state.setFolderPath(newPath);
2176
- break;
2177
- }
2178
- }
2252
+ updateDependencies() {
2253
+ this.dependencies.forEach(dependency => dependency.update());
2179
2254
  }
2180
2255
  }
2181
2256
 
@@ -2262,7 +2337,7 @@ class DesignerState {
2262
2337
  }
2263
2338
 
2264
2339
  class HistoryController {
2265
- static create(initialStack, state, definitionModifier, configuration) {
2340
+ static create(initialStack, state, stateModifier, configuration) {
2266
2341
  if (!configuration.undoStackSize || configuration.undoStackSize < 1) {
2267
2342
  throw new Error('Invalid undo stack size');
2268
2343
  }
@@ -2270,7 +2345,7 @@ class HistoryController {
2270
2345
  index: 0,
2271
2346
  items: []
2272
2347
  };
2273
- const controller = new HistoryController(stack, state, definitionModifier, configuration.undoStackSize);
2348
+ const controller = new HistoryController(stack, state, stateModifier, configuration.undoStackSize);
2274
2349
  if (!initialStack) {
2275
2350
  controller.rememberCurrent(exports.DefinitionChangeType.rootReplaced, null);
2276
2351
  }
@@ -2281,10 +2356,10 @@ class HistoryController {
2281
2356
  });
2282
2357
  return controller;
2283
2358
  }
2284
- constructor(stack, state, definitionModifier, stackSize) {
2359
+ constructor(stack, state, stateModifier, stackSize) {
2285
2360
  this.stack = stack;
2286
2361
  this.state = state;
2287
- this.definitionModifier = definitionModifier;
2362
+ this.stateModifier = stateModifier;
2288
2363
  this.stackSize = stackSize;
2289
2364
  }
2290
2365
  canUndo() {
@@ -2336,7 +2411,7 @@ class HistoryController {
2336
2411
  }
2337
2412
  commit() {
2338
2413
  const definition = ObjectCloner.deepClone(this.stack.items[this.stack.index - 1].definition);
2339
- this.definitionModifier.replaceDefinition(definition);
2414
+ this.stateModifier.replaceDefinition(definition);
2340
2415
  }
2341
2416
  }
2342
2417
  function areItemsEqual(item, changeType, stepId) {
@@ -2405,25 +2480,27 @@ class DesignerContext {
2405
2480
  const behaviorController = new BehaviorController();
2406
2481
  const stepExtensionResolver = StepExtensionResolver.create(services);
2407
2482
  const definitionWalker = (_c = configuration.definitionWalker) !== null && _c !== void 0 ? _c : new sequentialWorkflowModel.DefinitionWalker();
2408
- const definitionModifier = new DefinitionModifier(definitionWalker, state, configuration);
2483
+ const stateModifier = StateModifier.create(definitionWalker, state, configuration);
2484
+ const customActionController = new CustomActionController(configuration, state, stateModifier);
2409
2485
  let historyController = undefined;
2410
2486
  if (configuration.undoStackSize) {
2411
- historyController = HistoryController.create(configuration.undoStack, state, definitionModifier, configuration);
2487
+ historyController = HistoryController.create(configuration.undoStack, state, stateModifier, configuration);
2412
2488
  }
2413
2489
  const componentContext = ComponentContext.create(configuration.steps, configuration.validator, state, stepExtensionResolver, services);
2414
- return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, definitionModifier, layoutController, workspaceController, behaviorController, historyController);
2490
+ return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController);
2415
2491
  }
2416
- constructor(theme, state, configuration, services, componentContext, definitionWalker, definitionModifier, layoutController, workspaceController, behaviorController, historyController) {
2492
+ constructor(theme, state, configuration, services, componentContext, definitionWalker, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController) {
2417
2493
  this.theme = theme;
2418
2494
  this.state = state;
2419
2495
  this.configuration = configuration;
2420
2496
  this.services = services;
2421
2497
  this.componentContext = componentContext;
2422
2498
  this.definitionWalker = definitionWalker;
2423
- this.definitionModifier = definitionModifier;
2499
+ this.stateModifier = stateModifier;
2424
2500
  this.layoutController = layoutController;
2425
2501
  this.workspaceController = workspaceController;
2426
2502
  this.behaviorController = behaviorController;
2503
+ this.customActionController = customActionController;
2427
2504
  this.historyController = historyController;
2428
2505
  }
2429
2506
  setWorkspaceController(controller) {
@@ -2569,18 +2646,24 @@ class WorkspaceView {
2569
2646
  }
2570
2647
 
2571
2648
  class MoveViewportBehavior {
2572
- static create(state, resetSelectedStep) {
2573
- return new MoveViewportBehavior(state.viewport.position, resetSelectedStep, state);
2649
+ static create(resetSelectedStep, context) {
2650
+ return new MoveViewportBehavior(context.state.viewport.position, resetSelectedStep, context.state, context.stateModifier);
2574
2651
  }
2575
- constructor(startPosition, resetSelectedStep, state) {
2652
+ constructor(startPosition, resetSelectedStep, state, stateModifier) {
2576
2653
  this.startPosition = startPosition;
2577
2654
  this.resetSelectedStep = resetSelectedStep;
2578
2655
  this.state = state;
2656
+ this.stateModifier = stateModifier;
2579
2657
  }
2580
2658
  onStart() {
2581
2659
  if (this.resetSelectedStep) {
2582
- const stepId = this.state.tryGetLastStepIdFromFolderPath();
2583
- this.state.setSelectedStepId(stepId);
2660
+ const stepIdOrNull = this.state.tryGetLastStepIdFromFolderPath();
2661
+ if (stepIdOrNull) {
2662
+ this.stateModifier.trySelectStepById(stepIdOrNull);
2663
+ }
2664
+ else {
2665
+ this.state.setSelectedStepId(null);
2666
+ }
2584
2667
  }
2585
2668
  }
2586
2669
  onMove(delta) {
@@ -2598,14 +2681,15 @@ class SelectStepBehavior {
2598
2681
  static create(pressedStepComponent, isMiddleButton, context) {
2599
2682
  const isDragDisabled = isMiddleButton ||
2600
2683
  context.state.isDragDisabled ||
2601
- !context.definitionModifier.isDraggable(pressedStepComponent.step, pressedStepComponent.parentSequence);
2602
- return new SelectStepBehavior(pressedStepComponent, isDragDisabled, context, context.state);
2684
+ !context.stateModifier.isDraggable(pressedStepComponent.step, pressedStepComponent.parentSequence);
2685
+ return new SelectStepBehavior(pressedStepComponent, isDragDisabled, context.state, context.stateModifier, context);
2603
2686
  }
2604
- constructor(pressedStepComponent, isDragDisabled, context, state) {
2687
+ constructor(pressedStepComponent, isDragDisabled, state, stateModifier, context) {
2605
2688
  this.pressedStepComponent = pressedStepComponent;
2606
2689
  this.isDragDisabled = isDragDisabled;
2607
- this.context = context;
2608
2690
  this.state = state;
2691
+ this.stateModifier = stateModifier;
2692
+ this.context = context;
2609
2693
  }
2610
2694
  onStart() {
2611
2695
  // Nothing to do.
@@ -2618,13 +2702,13 @@ class SelectStepBehavior {
2618
2702
  return DragStepBehavior.create(this.context, this.pressedStepComponent.step, this.pressedStepComponent);
2619
2703
  }
2620
2704
  else {
2621
- return MoveViewportBehavior.create(this.state, false);
2705
+ return MoveViewportBehavior.create(false, this.context);
2622
2706
  }
2623
2707
  }
2624
2708
  }
2625
2709
  onEnd(interrupt) {
2626
2710
  if (!interrupt) {
2627
- this.state.setSelectedStepId(this.pressedStepComponent.step.id);
2711
+ this.stateModifier.trySelectStep(this.pressedStepComponent.step, this.pressedStepComponent.parentSequence);
2628
2712
  }
2629
2713
  }
2630
2714
  }
@@ -2671,54 +2755,32 @@ class OpenFolderPressingBehaviorHandler {
2671
2755
  }
2672
2756
 
2673
2757
  class TriggerCustomActionPressingBehaviorHandler {
2674
- constructor(command, designerContext) {
2758
+ constructor(command, customActionController) {
2675
2759
  this.command = command;
2676
- this.designerContext = designerContext;
2760
+ this.customActionController = customActionController;
2677
2761
  }
2678
2762
  handle() {
2679
- const customActionHandler = this.designerContext.configuration.customActionHandler;
2680
- if (!customActionHandler) {
2681
- console.warn(`Custom action handler is not defined (action type: ${this.command.action.type})`);
2682
- return;
2683
- }
2684
- const context = this.createContext();
2685
- customActionHandler(this.command.action, this.command.step, this.command.sequence, context);
2686
- }
2687
- createContext() {
2688
- return {
2689
- notifyStepNameChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepNameChanged, stepId),
2690
- notifyStepPropertiesChanged: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepPropertyChanged, stepId),
2691
- notifyStepInserted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepInserted, stepId),
2692
- notifyStepMoved: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepMoved, stepId),
2693
- notifyStepDeleted: (stepId) => this.notifyStepChanged(exports.DefinitionChangeType.stepDeleted, stepId)
2694
- };
2695
- }
2696
- notifyStepChanged(changeType, stepId) {
2697
- if (!stepId) {
2698
- throw new Error('Step id is empty');
2699
- }
2700
- this.designerContext.state.notifyDefinitionChanged(changeType, stepId);
2763
+ this.customActionController.trigger(this.command.action, this.command.step, this.command.sequence);
2701
2764
  }
2702
2765
  }
2703
2766
 
2704
2767
  class ClickBehaviorResolver {
2705
- constructor(designerContext, state) {
2706
- this.designerContext = designerContext;
2707
- this.state = state;
2768
+ constructor(context) {
2769
+ this.context = context;
2708
2770
  }
2709
2771
  resolve(commandOrNull, element, isMiddleButton) {
2710
2772
  if (!commandOrNull) {
2711
- return MoveViewportBehavior.create(this.state, !isMiddleButton);
2773
+ return MoveViewportBehavior.create(!isMiddleButton, this.context);
2712
2774
  }
2713
2775
  switch (commandOrNull.type) {
2714
2776
  case exports.ClickCommandType.selectStep:
2715
- return SelectStepBehavior.create(commandOrNull.component, isMiddleButton, this.designerContext);
2777
+ return SelectStepBehavior.create(commandOrNull.component, isMiddleButton, this.context);
2716
2778
  case exports.ClickCommandType.rerenderStep:
2717
- return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.designerContext));
2779
+ return PressingBehavior.create(element, new RerenderStepPressingBehaviorHandler(this.context));
2718
2780
  case exports.ClickCommandType.openFolder:
2719
- return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.designerContext));
2781
+ return PressingBehavior.create(element, new OpenFolderPressingBehaviorHandler(commandOrNull, this.context));
2720
2782
  case exports.ClickCommandType.triggerCustomAction:
2721
- return PressingBehavior.create(element, new TriggerCustomActionPressingBehaviorHandler(commandOrNull, this.designerContext));
2783
+ return PressingBehavior.create(element, new TriggerCustomActionPressingBehaviorHandler(commandOrNull, this.context.customActionController));
2722
2784
  default:
2723
2785
  throw new Error('Not supported behavior type');
2724
2786
  }
@@ -2745,12 +2807,12 @@ class ContextMenu {
2745
2807
  for (let index = 0; index < items.length; index++) {
2746
2808
  const item = items[index];
2747
2809
  const element = document.createElement('div');
2748
- if (typeof item === 'string') {
2749
- element.className = 'sqd-context-menu-group';
2750
- element.innerText = item;
2810
+ if (item.callback) {
2811
+ element.className = 'sqd-context-menu-item';
2812
+ element.innerText = item.label;
2751
2813
  }
2752
2814
  else {
2753
- element.className = 'sqd-context-menu-item';
2815
+ element.className = 'sqd-context-menu-group';
2754
2816
  element.innerText = item.label;
2755
2817
  }
2756
2818
  elements.push(element);
@@ -2791,7 +2853,7 @@ class ContextMenu {
2791
2853
  const index = this.findIndex(e.target);
2792
2854
  if (index !== null) {
2793
2855
  const item = this.items[index];
2794
- if (typeof item !== 'string') {
2856
+ if (item.callback) {
2795
2857
  item.callback();
2796
2858
  }
2797
2859
  }
@@ -2821,91 +2883,122 @@ class ContextMenu {
2821
2883
  }
2822
2884
  }
2823
2885
 
2886
+ class ContextMenuController {
2887
+ constructor(theme, configuration, itemsBuilder) {
2888
+ this.theme = theme;
2889
+ this.configuration = configuration;
2890
+ this.itemsBuilder = itemsBuilder;
2891
+ }
2892
+ tryOpen(position, commandOrNull) {
2893
+ if (this.configuration.contextMenu === false) {
2894
+ // Context menu is disabled.
2895
+ return;
2896
+ }
2897
+ if (this.current) {
2898
+ this.current.tryDestroy();
2899
+ }
2900
+ const items = this.itemsBuilder.build(commandOrNull);
2901
+ this.current = ContextMenu.create(position, this.theme, items);
2902
+ }
2903
+ destroy() {
2904
+ if (this.current) {
2905
+ this.current.tryDestroy();
2906
+ }
2907
+ }
2908
+ }
2909
+
2824
2910
  class ContextMenuItemsBuilder {
2825
- static build(commandOrNull, viewportApi, definitionModifier, state) {
2911
+ constructor(viewportApi, stateModifier, state, customMenuItemsProvider) {
2912
+ this.viewportApi = viewportApi;
2913
+ this.stateModifier = stateModifier;
2914
+ this.state = state;
2915
+ this.customMenuItemsProvider = customMenuItemsProvider;
2916
+ }
2917
+ build(commandOrNull) {
2826
2918
  const items = [];
2827
2919
  if (commandOrNull && commandOrNull.type === exports.ClickCommandType.selectStep) {
2828
2920
  const ssc = commandOrNull;
2829
2921
  const step = ssc.component.step;
2830
2922
  const parentSequence = ssc.component.parentSequence;
2831
- items.push(step.name);
2832
- if (state.selectedStepId === step.id) {
2833
- items.push({
2834
- label: `Unselect`,
2835
- callback: () => {
2836
- state.setSelectedStepId(null);
2837
- }
2838
- });
2839
- }
2840
- else {
2841
- items.push({
2842
- label: 'Select',
2843
- callback: () => {
2844
- state.setSelectedStepId(step.id);
2845
- }
2846
- });
2923
+ items.push({
2924
+ label: step.name,
2925
+ order: 0
2926
+ });
2927
+ this.tryAppendCustomItems(items, step, parentSequence);
2928
+ if (this.stateModifier.isSelectable(step, parentSequence)) {
2929
+ if (this.state.selectedStepId === step.id) {
2930
+ items.push({
2931
+ label: `Unselect`,
2932
+ order: 10,
2933
+ callback: () => {
2934
+ this.state.setSelectedStepId(null);
2935
+ }
2936
+ });
2937
+ }
2938
+ else {
2939
+ items.push({
2940
+ label: 'Select',
2941
+ order: 20,
2942
+ callback: () => {
2943
+ this.stateModifier.trySelectStepById(step.id);
2944
+ }
2945
+ });
2946
+ }
2847
2947
  }
2848
- if (!state.isReadonly) {
2849
- if (definitionModifier.isDeletable(step.id)) {
2948
+ if (!this.state.isReadonly) {
2949
+ if (this.stateModifier.isDeletable(step.id)) {
2850
2950
  items.push({
2851
2951
  label: 'Delete',
2952
+ order: 30,
2852
2953
  callback: () => {
2853
- definitionModifier.tryDelete(step.id);
2954
+ this.stateModifier.tryDelete(step.id);
2854
2955
  }
2855
2956
  });
2856
2957
  }
2857
- if (definitionModifier.isDuplicable(step, parentSequence)) {
2958
+ if (this.stateModifier.isDuplicable(step, parentSequence)) {
2858
2959
  items.push({
2859
2960
  label: 'Duplicate',
2961
+ order: 40,
2860
2962
  callback: () => {
2861
- definitionModifier.tryDuplicate(step, parentSequence);
2963
+ this.stateModifier.tryDuplicate(step, parentSequence);
2862
2964
  }
2863
2965
  });
2864
2966
  }
2865
2967
  }
2866
2968
  }
2969
+ else {
2970
+ this.tryAppendCustomItems(items, null, this.state.definition.sequence);
2971
+ }
2867
2972
  items.push({
2868
2973
  label: 'Reset view',
2974
+ order: 50,
2869
2975
  callback: () => {
2870
- viewportApi.resetViewport();
2976
+ this.viewportApi.resetViewport();
2871
2977
  }
2872
2978
  });
2979
+ items.sort((a, b) => a.order - b.order);
2873
2980
  return items;
2874
2981
  }
2875
- }
2876
-
2877
- class ContextMenuController {
2878
- constructor(theme, viewportApi, definitionModifier, state, configuration) {
2879
- this.theme = theme;
2880
- this.viewportApi = viewportApi;
2881
- this.definitionModifier = definitionModifier;
2882
- this.state = state;
2883
- this.configuration = configuration;
2884
- }
2885
- tryOpen(position, commandOrNull) {
2886
- if (this.configuration.contextMenu === false) {
2887
- // Context menu is disabled.
2888
- return;
2889
- }
2890
- if (this.last) {
2891
- this.last.tryDestroy();
2892
- }
2893
- const items = ContextMenuItemsBuilder.build(commandOrNull, this.viewportApi, this.definitionModifier, this.state);
2894
- this.last = ContextMenu.create(position, this.theme, items);
2895
- }
2896
- destroy() {
2897
- if (this.last) {
2898
- this.last.tryDestroy();
2982
+ tryAppendCustomItems(items, step, parentSequence) {
2983
+ if (this.customMenuItemsProvider) {
2984
+ const customItems = this.customMenuItemsProvider.getItems(step, parentSequence);
2985
+ for (const customItem of customItems) {
2986
+ items.push(customItem);
2987
+ }
2899
2988
  }
2900
2989
  }
2901
2990
  }
2902
2991
 
2903
2992
  class Workspace {
2904
2993
  static create(parent, designerContext, api) {
2994
+ var _a;
2905
2995
  const view = WorkspaceView.create(parent, designerContext.componentContext);
2906
- const clickBehaviorResolver = new ClickBehaviorResolver(designerContext, designerContext.state);
2996
+ const clickBehaviorResolver = new ClickBehaviorResolver(designerContext);
2907
2997
  const wheelController = designerContext.services.wheelController.create(api.workspace);
2908
- const contextMenuController = new ContextMenuController(designerContext.theme, api.viewport, designerContext.definitionModifier, designerContext.state, designerContext.configuration);
2998
+ const contextMenuItemsBuilder = new ContextMenuItemsBuilder(api.viewport, designerContext.stateModifier, designerContext.state, ((_a = designerContext.services.contextMenu) === null || _a === void 0 ? void 0 : _a.createItemsProvider)
2999
+ ? designerContext.services.contextMenu.createItemsProvider(designerContext.customActionController)
3000
+ : undefined);
3001
+ const contextMenuController = new ContextMenuController(designerContext.theme, designerContext.configuration, contextMenuItemsBuilder);
2909
3002
  const workspace = new Workspace(view, designerContext.definitionWalker, designerContext.state, designerContext.behaviorController, wheelController, contextMenuController, clickBehaviorResolver, api.viewport, designerContext.services);
2910
3003
  setTimeout(() => {
2911
3004
  workspace.updateRootComponent();
@@ -3393,7 +3486,7 @@ class SmartEditorView {
3393
3486
  if (configuration.globalEditorProvider) {
3394
3487
  throw new Error('globalEditorProvider is renamed to rootEditorProvider');
3395
3488
  }
3396
- const editor = Editor.create(root, api, 'sqd-editor sqd-step-editor', configuration.stepEditorProvider, 'sqd-editor sqd-root-editor', configuration.rootEditorProvider);
3489
+ const editor = Editor.create(root, api, 'sqd-editor sqd-step-editor', configuration.stepEditorProvider, 'sqd-editor sqd-root-editor', configuration.rootEditorProvider, null);
3397
3490
  return new SmartEditorView(root, toggle, editor);
3398
3491
  }
3399
3492
  constructor(root, toggle, editor) {
@@ -4056,7 +4149,7 @@ class ServicesResolver {
4056
4149
  static resolve(extensions, configuration) {
4057
4150
  const services = {};
4058
4151
  merge(services, extensions || []);
4059
- setDefault(services, configuration);
4152
+ setDefaults(services, configuration);
4060
4153
  return services;
4061
4154
  }
4062
4155
  }
@@ -4098,12 +4191,15 @@ function merge(services, extensions) {
4098
4191
  if (ext.sequenceComponent) {
4099
4192
  services.sequenceComponent = ext.sequenceComponent;
4100
4193
  }
4194
+ if (ext.contextMenu) {
4195
+ services.contextMenu = ext.contextMenu;
4196
+ }
4101
4197
  if (ext.daemons) {
4102
4198
  services.daemons = (services.daemons || []).concat(ext.daemons);
4103
4199
  }
4104
4200
  }
4105
4201
  }
4106
- function setDefault(services, configuration) {
4202
+ function setDefaults(services, configuration) {
4107
4203
  if (!services.steps) {
4108
4204
  services.steps = [];
4109
4205
  }
@@ -4211,7 +4307,7 @@ class Designer {
4211
4307
  const designerContext = DesignerContext.create(placeholder, startDefinition, config, services);
4212
4308
  const designerApi = DesignerApi.create(designerContext);
4213
4309
  const view = DesignerView.create(placeholder, designerContext, designerApi);
4214
- const designer = new Designer(view, designerContext.state, designerContext.definitionWalker, designerContext.historyController, designerApi);
4310
+ const designer = new Designer(view, designerContext.state, designerContext.stateModifier, designerContext.definitionWalker, designerContext.historyController, designerApi);
4215
4311
  view.workspace.onRendered.first().then(designer.onReady.forward);
4216
4312
  race(0, designerContext.state.onDefinitionChanged, designerContext.state.onSelectedStepIdChanged).subscribe(([definition, selectedStepId]) => {
4217
4313
  if (definition !== undefined) {
@@ -4226,9 +4322,10 @@ class Designer {
4226
4322
  designerContext.state.onIsEditorCollapsedChanged.subscribe(designer.onIsEditorCollapsedChanged.forward);
4227
4323
  return designer;
4228
4324
  }
4229
- constructor(view, state, walker, historyController, api) {
4325
+ constructor(view, state, stateModifier, walker, historyController, api) {
4230
4326
  this.view = view;
4231
4327
  this.state = state;
4328
+ this.stateModifier = stateModifier;
4232
4329
  this.walker = walker;
4233
4330
  this.historyController = historyController;
4234
4331
  this.api = api;
@@ -4291,7 +4388,7 @@ class Designer {
4291
4388
  * @description Selects a step by the id.
4292
4389
  */
4293
4390
  selectStepById(stepId) {
4294
- this.state.setSelectedStepId(stepId);
4391
+ this.stateModifier.trySelectStepById(stepId);
4295
4392
  }
4296
4393
  /**
4297
4394
  * @returns the current viewport.
@@ -4318,12 +4415,6 @@ class Designer {
4318
4415
  moveViewportToStep(stepId) {
4319
4416
  this.api.viewport.moveViewportToStep(stepId);
4320
4417
  }
4321
- /**
4322
- * @deprecated Use `moveViewportToStep` instead.
4323
- */
4324
- moveViewPortToStep(stepId) {
4325
- this.moveViewportToStep(stepId);
4326
- }
4327
4418
  /**
4328
4419
  * @description Rerender the root component and all its children.
4329
4420
  */
@@ -4433,11 +4524,6 @@ class StepsDesignerExtension {
4433
4524
  constructor(steps) {
4434
4525
  this.steps = steps;
4435
4526
  }
4436
- }
4437
- /**
4438
- * @deprecated Use `StepsDesignerExtension` instead.
4439
- */
4440
- class StepsExtension extends StepsDesignerExtension {
4441
4527
  }
4442
4528
 
4443
4529
  exports.Badges = Badges;
@@ -4445,6 +4531,7 @@ exports.CenteredViewportCalculator = CenteredViewportCalculator;
4445
4531
  exports.ClassicWheelControllerExtension = ClassicWheelControllerExtension;
4446
4532
  exports.ComponentContext = ComponentContext;
4447
4533
  exports.ControlBarApi = ControlBarApi;
4534
+ exports.CustomActionController = CustomActionController;
4448
4535
  exports.DefaultSequenceComponent = DefaultSequenceComponent;
4449
4536
  exports.DefaultSequenceComponentView = DefaultSequenceComponentView;
4450
4537
  exports.DefaultViewportController = DefaultViewportController;
@@ -4473,7 +4560,6 @@ exports.SimpleEvent = SimpleEvent;
4473
4560
  exports.StepComponent = StepComponent;
4474
4561
  exports.StepExtensionResolver = StepExtensionResolver;
4475
4562
  exports.StepsDesignerExtension = StepsDesignerExtension;
4476
- exports.StepsExtension = StepsExtension;
4477
4563
  exports.ToolboxApi = ToolboxApi;
4478
4564
  exports.Uid = Uid;
4479
4565
  exports.ValidationErrorBadgeExtension = ValidationErrorBadgeExtension;