@eclipse-glsp/client 2.6.0-next.5 → 2.6.0-next.7

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.
Files changed (55) hide show
  1. package/lib/base/messages.json +68 -57
  2. package/lib/base/tool-manager/tool-manager.d.ts +2 -2
  3. package/lib/base/tool-manager/tool-manager.d.ts.map +1 -1
  4. package/lib/base/tool-manager/tool-manager.js +4 -4
  5. package/lib/base/tool-manager/tool-manager.js.map +1 -1
  6. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.d.ts +1 -1
  7. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.js +1 -1
  8. package/lib/features/accessibility/keyboard/keyboard-module.d.ts +1 -1
  9. package/lib/features/accessibility/keyboard/keyboard-module.js +1 -1
  10. package/lib/features/accessibility/keyboard-grid/keyboard-grid-search-palette.d.ts +1 -1
  11. package/lib/features/accessibility/keyboard-grid/keyboard-grid-search-palette.js +1 -1
  12. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.d.ts +1 -1
  13. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.js +1 -1
  14. package/lib/features/change-bounds/movement-restrictor.d.ts +12 -4
  15. package/lib/features/change-bounds/movement-restrictor.d.ts.map +1 -1
  16. package/lib/features/change-bounds/movement-restrictor.js +44 -17
  17. package/lib/features/change-bounds/movement-restrictor.js.map +1 -1
  18. package/lib/features/context-menu/delete-element-context-menu.d.ts +4 -4
  19. package/lib/features/context-menu/delete-element-context-menu.d.ts.map +1 -1
  20. package/lib/features/context-menu/delete-element-context-menu.js +6 -2
  21. package/lib/features/context-menu/delete-element-context-menu.js.map +1 -1
  22. package/lib/features/context-menu/server-context-menu-provider.d.ts +4 -4
  23. package/lib/features/context-menu/server-context-menu-provider.d.ts.map +1 -1
  24. package/lib/features/context-menu/server-context-menu-provider.js +4 -5
  25. package/lib/features/context-menu/server-context-menu-provider.js.map +1 -1
  26. package/lib/features/copy-paste/copy-paste-context-menu.d.ts +22 -5
  27. package/lib/features/copy-paste/copy-paste-context-menu.d.ts.map +1 -1
  28. package/lib/features/copy-paste/copy-paste-context-menu.js +16 -11
  29. package/lib/features/copy-paste/copy-paste-context-menu.js.map +1 -1
  30. package/lib/features/validation/marker-navigator.d.ts +3 -3
  31. package/lib/features/validation/marker-navigator.d.ts.map +1 -1
  32. package/lib/features/validation/marker-navigator.js +8 -7
  33. package/lib/features/validation/marker-navigator.js.map +1 -1
  34. package/lib/index.d.ts +2 -0
  35. package/lib/index.d.ts.map +1 -1
  36. package/lib/index.js +2 -0
  37. package/lib/index.js.map +1 -1
  38. package/lib/utils/gmodel-util.d.ts +32 -2
  39. package/lib/utils/gmodel-util.d.ts.map +1 -1
  40. package/lib/utils/gmodel-util.js +29 -1
  41. package/lib/utils/gmodel-util.js.map +1 -1
  42. package/package.json +3 -3
  43. package/src/base/messages.json +68 -57
  44. package/src/base/tool-manager/tool-manager.ts +4 -4
  45. package/src/features/accessibility/edge-autocomplete/edge-autocomplete-palette.ts +1 -1
  46. package/src/features/accessibility/keyboard/keyboard-module.ts +1 -1
  47. package/src/features/accessibility/keyboard-grid/keyboard-grid-search-palette.ts +1 -1
  48. package/src/features/accessibility/keyboard-grid/keyboard-node-grid.ts +1 -1
  49. package/src/features/change-bounds/movement-restrictor.ts +72 -19
  50. package/src/features/context-menu/delete-element-context-menu.ts +9 -5
  51. package/src/features/context-menu/server-context-menu-provider.ts +8 -9
  52. package/src/features/copy-paste/copy-paste-context-menu.ts +21 -17
  53. package/src/features/validation/marker-navigator.ts +9 -8
  54. package/src/index.ts +2 -0
  55. package/src/utils/gmodel-util.ts +59 -1
@@ -1,87 +1,98 @@
1
1
  {
2
- "navigation": {
3
- "default_navigation_mode_activated": "Navigation On: Use arrow keys to select preceding (←) or succeding (→) elements. Use the up (↑) and down (↓) arrows to navigate paths. Press 'N' to exit.",
4
- "default_navigation_mode_deactivated": "Navigation Off: Press 'N' for default navigation, 'ALT+N' for position based navigation.",
5
- "local_navigation_mode_activated": "Position based Nav On: Navigate nearest elements using arrow keys: (↑) for above, (↓) for below, (←) for previous, (→) for next element. Press 'ALT+N' to exit.",
6
- "local_navigation_mode_deactivated": "Position based Nav Off: Press 'N' for default navigation, 'ALT+N' for position based navigation.",
7
- "shortcut_local_mode": "Activate local navigation mode",
8
- "shortcut_global_mode": "Activate global navigation mode"
2
+ "autocomplete": {
3
+ "no_suggestions": "No suggestions available"
4
+ },
5
+ "context_menu": {
6
+ "copy": "Copy",
7
+ "cut": "Cut",
8
+ "delete": "Delete",
9
+ "marker": {
10
+ "navigation": "Go to",
11
+ "next": "Next marker",
12
+ "previous": "Previous marker"
13
+ },
14
+ "paste": "Paste"
15
+ },
16
+ "diagram": {
17
+ "label": "Diagram"
9
18
  },
10
19
  "focus": {
11
20
  "focus_not_set": "Focus not set",
12
- "focus_on": "Currently focused: ",
13
21
  "focus_off": "Currently no element is focused.",
22
+ "focus_on": "Currently focused: ",
14
23
  "focus_within": "Within",
15
- "shortcut_focus_palette": "Focus on tool palette",
16
- "shortcut_focus_graph": "Focus on graph"
24
+ "shortcut_focus_graph": "Focus on graph",
25
+ "shortcut_focus_palette": "Focus on tool palette"
26
+ },
27
+ "grid": {
28
+ "shortcut_zoom_in": "Zoom in via grid",
29
+ "zoom_in_grid": "Select a digit from 1-9 to zoom in on the respective box."
30
+ },
31
+ "issue_marker": {
32
+ "severity_error": "ERROR",
33
+ "severity_info": "INFO",
34
+ "severity_warning": "WARNING"
35
+ },
36
+ "move": {
37
+ "shortcut_move": "Move element"
38
+ },
39
+ "navigation": {
40
+ "default_navigation_mode_activated": "Navigation On: Use arrow keys to select preceding (←) or succeding (→) elements. Use the up (↑) and down (↓) arrows to navigate paths. Press 'N' to exit.",
41
+ "default_navigation_mode_deactivated": "Navigation Off: Press 'N' for default navigation, 'ALT+N' for position based navigation.",
42
+ "local_navigation_mode_activated": "Position based Nav On: Navigate nearest elements using arrow keys: (↑) for above, (↓) for below, (←) for previous, (→) for next element. Press 'ALT+N' to exit.",
43
+ "local_navigation_mode_deactivated": "Position based Nav Off: Press 'N' for default navigation, 'ALT+N' for position based navigation.",
44
+ "shortcut_global_mode": "Activate global navigation mode",
45
+ "shortcut_local_mode": "Activate local navigation mode"
17
46
  },
18
47
  "resize": {
19
48
  "resize_mode_activated": "Resize On: Use plus(+) and minus(-) to resize, 'CTRL'+'0' for default size. Press 'ESC' to exit.",
20
49
  "resize_mode_deactivated": "Resize Off: Press 'ALT'+'A' for resize mode.",
21
50
  "shortcut_activate": "Activate resize mode for selected element",
22
51
  "shortcut_deactivate": "Deactivate resize handler",
23
- "shortcut_increase": "Increase size of element",
24
52
  "shortcut_decrease": "Decrease size of element",
53
+ "shortcut_increase": "Increase size of element",
25
54
  "shortcut_reset": "Set element size to default"
26
55
  },
27
- "move": {
28
- "shortcut_move": "Move element"
29
- },
30
- "grid": {
31
- "zoom_in_grid": "Select a digit from 1-9 to zoom in on the respective box.",
32
- "shortcut_zoom_in": "Zoom in via grid"
33
- },
34
56
  "search": {
35
- "shortcut_activate": "Activate search for elements",
57
+ "label": "Search Field",
36
58
  "placeholder": "Search for elements...",
37
- "label": "Search Field"
59
+ "shortcut_activate": "Activate search for elements"
60
+ },
61
+ "shortcut": {
62
+ "group_focus": "Focus",
63
+ "group_graph": "Graph",
64
+ "group_grid": "Grid",
65
+ "group_move": "Move",
66
+ "group_navigation": "Navigation",
67
+ "group_resize": "Resize",
68
+ "group_search": "Search",
69
+ "group_tool_palette": "Tool Palette",
70
+ "group_viewport": "Viewport",
71
+ "group_zoom": "Zoom",
72
+ "header_command": "Command",
73
+ "header_shortcut": "Keybinding",
74
+ "menu_title": "Shortcut Menu",
75
+ "title": "Keyboard Shortcuts"
38
76
  },
39
77
  "tool_palette": {
40
- "label": "Tool Palette",
78
+ "debug_mode_button": "Debug Mode",
41
79
  "delete_button": "Enable deletion tool",
80
+ "label": "Tool Palette",
42
81
  "marquee_button": "Enable marquee tool",
43
82
  "marquee_message": "Currently marquee tool is only usable with mouse.",
44
- "search_placeholder": "Search...",
83
+ "maximize": "Maximize palette",
84
+ "minimize": "Minimize palette",
85
+ "no_items": "No results found.",
86
+ "reset_viewport_button": "Reset Viewport",
45
87
  "search_button": "Filter palette entries",
88
+ "search_placeholder": "Search...",
46
89
  "selection_button": "Enable selection tool",
47
- "validate_button": "Validate model",
48
- "reset_viewport_button": "Reset Viewport",
49
90
  "toggle_grid_button": "Toggle Grid",
50
- "debug_mode_button": "Debug Mode",
51
- "minimize": "Minimize palette",
52
- "maximize": "Maximize palette",
53
- "no_items": "No results found."
91
+ "validate_button": "Validate model"
54
92
  },
55
93
  "viewport": {
56
94
  "shortcut_move_viewport": "Move viewport",
57
- "shortcut_zoom_viewport": "Zoom viewport",
58
- "shortcut_zoom_element": "Zoom element"
59
- },
60
- "shortcut": {
61
- "title": "Keyboard Shortcuts",
62
- "header_command": "Command",
63
- "header_shortcut": "Keybinding",
64
- "menu_title": "Shortcut Menu",
65
- "group_move": "Move",
66
- "group_graph": "Graph",
67
- "group_resize": "Resize",
68
- "group_focus": "Focus",
69
- "group_zoom": "Zoom",
70
- "group_navigation": "Navigation",
71
- "group_grid": "Grid",
72
- "group_search": "Search",
73
- "group_tool_palette": "Tool Palette",
74
- "group_viewport": "Viewport"
75
- },
76
- "diagram": {
77
- "label": "Diagram"
78
- },
79
- "autocomplete": {
80
- "no_suggestions": "No suggestions available"
81
- },
82
- "issue_marker": {
83
- "severity_error": "ERROR",
84
- "severity_warning": "WARNING",
85
- "severity_info": "INFO"
95
+ "shortcut_zoom_element": "Zoom element",
96
+ "shortcut_zoom_viewport": "Zoom viewport"
86
97
  }
87
98
  }
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2019-2024 EclipseSource and others.
2
+ * Copyright (c) 2019-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -133,8 +133,8 @@ export class ToolManager implements IToolManager, IDiagramStartup, IEditModeList
133
133
  this.actives.splice(0, this.actives.length);
134
134
  }
135
135
 
136
- enableDefaultTools(): void {
137
- if (this.defaultToolsEnabled) {
136
+ enableDefaultTools(force = false): void {
137
+ if (this.defaultToolsEnabled && !force) {
138
138
  return;
139
139
  }
140
140
  this.enable(pluck(this.defaultTools, 'id'));
@@ -171,7 +171,7 @@ export class ToolManager implements IToolManager, IDiagramStartup, IEditModeList
171
171
  if (newValue === EditMode.READONLY) {
172
172
  this.disableEditTools();
173
173
  } else if (newValue === EditMode.EDITABLE) {
174
- this.enableDefaultTools();
174
+ this.enableDefaultTools(true);
175
175
  }
176
176
  }
177
177
  }
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2019-2024 EclipseSource and others.
2
+ * Copyright (c) 2019-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -13,11 +13,23 @@
13
13
  *
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
- import { Bounds, Dimension, GModelElement, GNode, GParentElement, Point, isBoundsAware, isMoveable } from '@eclipse-glsp/sprotty';
16
+ import {
17
+ Bounds,
18
+ Dimension,
19
+ GChildElement,
20
+ GModelElement,
21
+ GNode,
22
+ GParentElement,
23
+ isBoundsAware,
24
+ isMoveable,
25
+ Point,
26
+ toTypeGuard
27
+ } from '@eclipse-glsp/sprotty';
17
28
  import { injectable } from 'inversify';
18
- import { ModifyCSSFeedbackAction } from '../../base/feedback/css-feedback';
19
- import { BoundsAwareModelElement } from '../../utils/gmodel-util';
29
+ import { CSS_GHOST_ELEMENT, ModifyCSSFeedbackAction } from '../../base/feedback/css-feedback';
30
+ import { BoundsAwareModelElement, getChildren, getParents } from '../../utils/gmodel-util';
20
31
  import { toAbsoluteBounds } from '../../utils/viewpoint-util';
32
+ import { ContainerElement, isContainable } from '../hints/model';
21
33
  import { GResizeHandle } from './model';
22
34
 
23
35
  /**
@@ -39,34 +51,75 @@ export interface IMovementRestrictor {
39
51
  cssClasses?: string[];
40
52
  }
41
53
 
54
+ export interface MoveElementContext {
55
+ element: GModelElement;
56
+ elementAtNewLocation: BoundsAwareModelElement;
57
+ parentContainers: ContainerElement[];
58
+ childNodes: GNode[];
59
+ }
60
+
42
61
  /**
43
62
  * A `IMovementRestrictor` that checks for overlapping elements. Move operations
44
- * are only valid if the element does not collide with another element after moving.
63
+ * are only valid if the element does not collide with another element/node after moving.
45
64
  */
46
65
  @injectable()
47
66
  export class NoOverlapMovementRestrictor implements IMovementRestrictor {
48
67
  cssClasses = ['movement-not-allowed'];
49
68
 
50
69
  validate(element: GModelElement, newLocation?: Point): boolean {
51
- if (!isMoveable(element) || !newLocation) {
70
+ if (!(element instanceof GChildElement) || !isMoveable(element) || !newLocation) {
52
71
  return false;
53
72
  }
54
- // Create ghost element at the newLocation
73
+
74
+ const moveContext = this.createMoveElementContext(element, newLocation);
75
+ const elementsToValidate = Array.from(element.root.index.all()).filter(e =>
76
+ this.isBoundsRelevant(e, moveContext)
77
+ ) as BoundsAwareModelElement[];
78
+
79
+ const valid = !elementsToValidate.some(e => this.areOverlapping(e, moveContext.elementAtNewLocation));
80
+ return valid;
81
+ }
82
+
83
+ protected createMoveElementContext(element: GModelElement, newLocation: Point): MoveElementContext {
84
+ const parentContainers = getParents(element, isContainable);
85
+ const childNodes = getChildren(element, toTypeGuard(GNode));
86
+ // Create a mock element at the newLocation for overlap checking
55
87
  const dimensions: Dimension = isBoundsAware(element) ? element.bounds : { width: 1, height: 1 };
56
- const ghostElement = Object.create(element) as BoundsAwareModelElement;
57
- ghostElement.bounds = { ...dimensions, ...newLocation };
58
- ghostElement.type = 'Ghost';
59
- ghostElement.id = element.id;
60
- return !Array.from(
61
- element.root.index
62
- .all()
63
- .filter(node => node.id !== ghostElement.id && node !== ghostElement.root && node instanceof GNode)
64
- .map(node => node as BoundsAwareModelElement)
65
- ).some(e => this.areOverlapping(e, ghostElement));
88
+ const elementAtNewLocation = Object.create(element) as BoundsAwareModelElement as BoundsAwareModelElement;
89
+ elementAtNewLocation.bounds = { ...dimensions, ...newLocation };
90
+
91
+ return {
92
+ element,
93
+ elementAtNewLocation,
94
+ parentContainers,
95
+ childNodes
96
+ };
66
97
  }
67
98
 
68
- protected isBoundsRelevant(element: GModelElement, ghostElement: BoundsAwareModelElement): element is BoundsAwareModelElement {
69
- return element.id !== ghostElement.id && element !== ghostElement.root && element instanceof GNode && isBoundsAware(element);
99
+ protected isBoundsRelevant(element: GModelElement, moveContext: MoveElementContext): element is BoundsAwareModelElement {
100
+ // Only consider GNodes that are not the element being moved (or one of its children)
101
+ if (
102
+ !(element instanceof GNode) ||
103
+ element.id === moveContext.element.id ||
104
+ moveContext.childNodes.some(child => child.id === element.id)
105
+ ) {
106
+ return false;
107
+ }
108
+
109
+ // Do not consider parent containers of the element being moved
110
+ if (moveContext.parentContainers.length > 0 && moveContext.parentContainers.some(container => container.id === element.id)) {
111
+ return false;
112
+ }
113
+
114
+ // If the element is a ghost element (node creation), don't consider overlap checks for potential parent containers
115
+ if (
116
+ moveContext.element.cssClasses?.includes(CSS_GHOST_ELEMENT) &&
117
+ isContainable(element) &&
118
+ element.isContainableElement(moveContext.element.type)
119
+ ) {
120
+ return false;
121
+ }
122
+ return true;
70
123
  }
71
124
 
72
125
  protected areOverlapping(element1: BoundsAwareModelElement, element2: BoundsAwareModelElement): boolean {
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2019-2024 EclipseSource and others.
2
+ * Copyright (c) 2019-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -13,9 +13,10 @@
13
13
  *
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
- import { DeleteElementOperation, GModelRoot, IContextMenuItemProvider, MenuItem, Point, TYPES } from '@eclipse-glsp/sprotty';
16
+ import { ClientMenuItem, DeleteElementOperation, GModelRoot, IContextMenuItemProvider, Point, TYPES } from '@eclipse-glsp/sprotty';
17
17
  import { inject, injectable } from 'inversify';
18
18
  import { EditorContextService, EditorContextServiceProvider } from '../../base/editor-context-service';
19
+ import { messages } from '../../base/messages';
19
20
 
20
21
  @injectable()
21
22
  export class DeleteElementContextMenuItemProvider implements IContextMenuItemProvider {
@@ -26,14 +27,17 @@ export class DeleteElementContextMenuItemProvider implements IContextMenuItemPro
26
27
  @inject(EditorContextService)
27
28
  protected editorContext: EditorContextService;
28
29
 
29
- async getItems(_root: Readonly<GModelRoot>, _lastMousePosition?: Point): Promise<MenuItem[]> {
30
+ async getItems(_root: Readonly<GModelRoot>, _lastMousePosition?: Point): Promise<ClientMenuItem[]> {
31
+ if (this.editorContext.isReadonly) {
32
+ return [];
33
+ }
30
34
  return [this.createDeleteMenuItem()];
31
35
  }
32
36
 
33
- protected createDeleteMenuItem(): MenuItem {
37
+ protected createDeleteMenuItem(): ClientMenuItem {
34
38
  return {
35
39
  id: 'delete',
36
- label: 'Delete',
40
+ label: messages.context_menu.delete,
37
41
  sortString: 'd',
38
42
  group: 'edit',
39
43
  actions: [DeleteElementOperation.create(this.editorContext.selectedElements.map(e => e.id))],
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2019-2024 EclipseSource and others.
2
+ * Copyright (c) 2019-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,11 +14,11 @@
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
16
  import {
17
- Action,
17
+ ClientMenuItem,
18
18
  GModelElement,
19
19
  IActionDispatcher,
20
20
  IContextMenuItemProvider,
21
- LabeledAction,
21
+ MenuItem,
22
22
  Point,
23
23
  RequestContextActions,
24
24
  SetContextActions,
@@ -37,7 +37,7 @@ export class ServerContextMenuItemProvider implements IContextMenuItemProvider {
37
37
  @inject(TYPES.IActionDispatcher) protected actionDispatcher: IActionDispatcher;
38
38
  @inject(EditorContextService) protected editorContext: EditorContextService;
39
39
 
40
- async getItems(root: Readonly<GModelElement>, _lastMousePosition?: Point): Promise<LabeledAction[]> {
40
+ async getItems(root: Readonly<GModelElement>, _lastMousePosition?: Point): Promise<ClientMenuItem[]> {
41
41
  const selectedElementIds = Array.from(
42
42
  root.index
43
43
  .all()
@@ -50,10 +50,9 @@ export class ServerContextMenuItemProvider implements IContextMenuItemProvider {
50
50
  return response ? this.getContextActionsFromResponse(response) : [];
51
51
  }
52
52
 
53
- getContextActionsFromResponse(action: Action): LabeledAction[] {
54
- if (SetContextActions.is(action)) {
55
- return action.actions;
56
- }
57
- return [];
53
+ getContextActionsFromResponse(action: SetContextActions): ClientMenuItem[] {
54
+ return action.actions
55
+ .filter(item => MenuItem.is(item)) //
56
+ .map(item => ClientMenuItem.convert(item));
58
57
  }
59
58
  }
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2020-2023 EclipseSource and others.
2
+ * Copyright (c) 2020-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,21 +14,23 @@
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
16
  /* eslint-disable deprecation/deprecation */
17
- import { inject, injectable } from 'inversify';
18
17
  import {
19
18
  Action,
19
+ ClientMenuItem,
20
+ GModelRoot,
20
21
  IActionDispatcher,
21
22
  IActionHandler,
22
23
  IContextMenuItemProvider,
23
- MenuItem,
24
- Point,
25
- GModelRoot,
26
24
  MessageAction,
25
+ Point,
27
26
  StatusAction,
28
27
  TYPES,
29
28
  hasStringProp,
30
29
  isSelected
31
30
  } from '@eclipse-glsp/sprotty';
31
+ import { inject, injectable } from 'inversify';
32
+ import { EditorContextService } from '../../base/editor-context-service';
33
+ import { messages } from '../../base/messages';
32
34
 
33
35
  /**
34
36
  * An `InvokeCopyPasteAction` is dispatched by the client to initiate a cut, copy or paste operation.
@@ -89,39 +91,41 @@ export class InvokeCopyPasteActionHandler implements IActionHandler {
89
91
 
90
92
  @injectable()
91
93
  export class CopyPasteContextMenuItemProvider implements IContextMenuItemProvider {
92
- getItems(root: Readonly<GModelRoot>, _lastMousePosition?: Point): Promise<MenuItem[]> {
94
+ @inject(EditorContextService)
95
+ protected editorContext: EditorContextService;
96
+
97
+ async getItems(root: Readonly<GModelRoot>, _lastMousePosition?: Point): Promise<ClientMenuItem[]> {
98
+ if (this.editorContext.isReadonly) {
99
+ return [];
100
+ }
93
101
  const hasSelectedElements = Array.from(root.index.all().filter(isSelected)).length > 0;
94
- return Promise.resolve([
95
- this.createCopyMenuItem(hasSelectedElements),
96
- this.createCutMenuItem(hasSelectedElements),
97
- this.createPasteMenuItem()
98
- ]);
102
+ return [this.createCopyMenuItem(hasSelectedElements), this.createCutMenuItem(hasSelectedElements), this.createPasteMenuItem()];
99
103
  }
100
104
 
101
- protected createPasteMenuItem(): MenuItem {
105
+ protected createPasteMenuItem(): ClientMenuItem {
102
106
  return {
103
107
  id: 'paste',
104
- label: 'Paste',
108
+ label: messages.context_menu.paste,
105
109
  group: 'copy-paste',
106
110
  actions: [InvokeCopyPasteAction.create('paste')],
107
111
  isEnabled: () => true
108
112
  };
109
113
  }
110
114
 
111
- protected createCutMenuItem(hasSelectedElements: boolean): MenuItem {
115
+ protected createCutMenuItem(hasSelectedElements: boolean): ClientMenuItem {
112
116
  return {
113
117
  id: 'cut',
114
- label: 'Cut',
118
+ label: messages.context_menu.cut,
115
119
  group: 'copy-paste',
116
120
  actions: [InvokeCopyPasteAction.create('cut')],
117
121
  isEnabled: () => hasSelectedElements
118
122
  };
119
123
  }
120
124
 
121
- protected createCopyMenuItem(hasSelectedElements: boolean): MenuItem {
125
+ protected createCopyMenuItem(hasSelectedElements: boolean): ClientMenuItem {
122
126
  return {
123
127
  id: 'copy',
124
- label: 'Copy',
128
+ label: messages.context_menu.copy,
125
129
  group: 'copy-paste',
126
130
  actions: [InvokeCopyPasteAction.create('copy')],
127
131
  isEnabled: () => hasSelectedElements
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2020-2024 EclipseSource and others.
2
+ * Copyright (c) 2020-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -16,6 +16,7 @@
16
16
  import {
17
17
  Action,
18
18
  CenterAction,
19
+ ClientMenuItem,
19
20
  GIssueSeverity,
20
21
  GModelElement,
21
22
  GModelRoot,
@@ -23,7 +24,6 @@ import {
23
24
  IActionHandler,
24
25
  IContextMenuItemProvider,
25
26
  KeyListener,
26
- MenuItem,
27
27
  Point,
28
28
  SelectAction,
29
29
  TYPES,
@@ -35,6 +35,7 @@ import {
35
35
  matchesKeystroke
36
36
  } from '@eclipse-glsp/sprotty';
37
37
  import { inject, injectable } from 'inversify';
38
+ import { messages } from '../../base/messages';
38
39
  import { SelectionService } from '../../base/selection-service';
39
40
  import { BoundsAwareModelElement, SelectableElement, getElements, isSelectableAndBoundsAware } from '../../utils/gmodel-util';
40
41
  import { MarkerPredicates, collectIssueMarkers } from '../../utils/marker';
@@ -206,33 +207,33 @@ export class NavigateToMarkerActionHandler implements IActionHandler {
206
207
  export class MarkerNavigatorContextMenuItemProvider implements IContextMenuItemProvider {
207
208
  @inject(SelectionService) protected selectionService: SelectionService;
208
209
 
209
- getItems(root: Readonly<GModelRoot>, lastMousePosition?: Point): Promise<MenuItem[]> {
210
+ async getItems(root: Readonly<GModelRoot>, lastMousePosition?: Point): Promise<ClientMenuItem[]> {
210
211
  const selectedElementIds = Array.from(this.selectionService.getSelectedElementIDs());
211
212
  const hasMarkers = collectIssueMarkers(root).length > 0;
212
- return Promise.resolve([
213
+ return [
213
214
  {
214
215
  id: 'navigate',
215
- label: 'Go to',
216
+ label: messages.context_menu.marker.navigation,
216
217
  group: 'navigate',
217
218
  actions: [],
218
219
  children: [
219
220
  {
220
221
  id: 'next-marker',
221
- label: 'Next marker',
222
+ label: messages.context_menu.marker.next,
222
223
  group: 'marker',
223
224
  actions: [NavigateToMarkerAction.create({ direction: 'next', selectedElementIds })],
224
225
  isEnabled: () => hasMarkers
225
226
  },
226
227
  {
227
228
  id: 'previous-marker',
228
- label: 'Previous marker',
229
+ label: messages.context_menu.marker.previous,
229
230
  group: 'marker',
230
231
  actions: [NavigateToMarkerAction.create({ direction: 'previous', selectedElementIds })],
231
232
  isEnabled: () => hasMarkers
232
233
  }
233
234
  ]
234
235
  }
235
- ]);
236
+ ];
236
237
  }
237
238
  }
238
239
 
package/src/index.ts CHANGED
@@ -170,6 +170,8 @@ export * from './features/save/save-module';
170
170
  export * from './features/search-palette/search-palette';
171
171
  export * from './features/search-palette/search-palette-key-listener';
172
172
  export * from './features/search-palette/search-palette-module';
173
+ export * from './features/search-palette/suggestions/edge-element-suggestions';
174
+ export * from './features/search-palette/suggestions/named-element-suggestions';
173
175
  export * from './features/select/select-feedback-command';
174
176
  export * from './features/select/select-module';
175
177
  export * from './features/select/select-mouse-listener';