+
+
+
+
+
+ {this.toolBarButtonProvider
+ .map(provider => provider.button())
+ .filter(isNotUndefined)
+ .filter(button => button.location === ToolBarButtonLocation.Middle)
+ .filter(button => !this.editorContext.isReadonly || button.readonly)
+ .sort(compareButtons)
+ .map(button => (
+
+ ))}
+
+
+ );
+ }
+
protected createHeader(): void {
const headerCompartment = createElement('div', ['tool-bar-header']);
headerCompartment.appendChild(this.createLeftButtons());
diff --git a/packages/editor/src/ui-tools/viewport/viewport-bar.ts b/packages/editor/src/ui-tools/viewport/viewport-bar.ts
deleted file mode 100644
index 59d696651..000000000
--- a/packages/editor/src/ui-tools/viewport/viewport-bar.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import {
- Action,
- EditorContextService,
- IActionHandler,
- isViewport,
- IToolManager,
- SetUIExtensionVisibilityAction,
- SetViewportAction,
- TYPES,
- SelectionService,
- GLSPAbstractUIExtension,
- type IActionDispatcher
-} from '@eclipse-glsp/client';
-import { inject, injectable } from 'inversify';
-import { CenterButton, FitToScreenButton, OriginScreenButton, ViewportBarButton } from './button';
-
-import { createElement, createIcon } from '../../utils/ui-utils';
-import { QuickActionUI } from '../quick-action/quick-action-ui';
-import { EnableViewportAction, SetViewportZoomAction } from '@axonivy/process-editor-protocol';
-
-@injectable()
-export class ViewportBar extends GLSPAbstractUIExtension implements IActionHandler {
- static readonly ID = 'ivy-viewport-bar';
-
- @inject(TYPES.IActionDispatcher) protected readonly actionDispatcher: IActionDispatcher;
- @inject(TYPES.IToolManager) protected readonly toolManager: IToolManager;
- @inject(EditorContextService) protected readonly editorContext: EditorContextService;
- @inject(SelectionService) protected selectionService: SelectionService;
-
- protected zoomLevel = '100%';
- protected zoomLevelElement?: HTMLElement;
-
- id(): string {
- return ViewportBar.ID;
- }
- containerClass(): string {
- return ViewportBar.ID;
- }
-
- protected initializeContents(containerElement: HTMLElement): void {
- this.createBar();
- containerElement.onwheel = ev => (ev.ctrlKey ? ev.preventDefault() : true);
- }
-
- protected createBar(): void {
- const headerCompartment = createElement('div', ['viewport-bar']);
- headerCompartment.appendChild(this.createViewportTools());
- this.containerElement.appendChild(headerCompartment);
- }
-
- private createViewportTools(): HTMLElement {
- const viewportTools = createElement('div', ['viewport-bar-tools']);
-
- viewportTools.appendChild(this.createViewportButton(new OriginScreenButton()));
- viewportTools.appendChild(this.createViewportButton(new FitToScreenButton()));
- viewportTools.appendChild(this.createViewportButton(new CenterButton(() => [...this.selectionService.getSelectedElementIDs()])));
-
- this.zoomLevelElement = document.createElement('label');
- this.zoomLevelElement.textContent = this.zoomLevel;
- viewportTools.appendChild(this.zoomLevelElement);
- return viewportTools;
- }
-
- protected createViewportButton(toolButton: ViewportBarButton): HTMLElement {
- const button = createElement('button');
- button.appendChild(createIcon(toolButton.icon));
- button.id = toolButton.id;
- button.title = toolButton.title;
- button.onclick = () =>
- this.actionDispatcher.dispatch(toolButton.action()).then(() => {
- const model = this.editorContext.modelRoot;
- if (isViewport(model)) {
- this.actionDispatcher.dispatchAll([
- SetUIExtensionVisibilityAction.create({
- extensionId: QuickActionUI.ID,
- visible: true,
- contextElementsId: [...this.selectionService.getSelectedElementIDs()]
- }),
- SetViewportAction.create(model.id, model, {})
- ]);
- }
- });
- return button;
- }
-
- handle(action: Action) {
- if (EnableViewportAction.is(action)) {
- this.actionDispatcher.dispatch(SetUIExtensionVisibilityAction.create({ extensionId: ViewportBar.ID, visible: true }));
- }
- if (SetViewportAction.is(action)) {
- this.updateZoomLevel(action.newViewport.zoom);
- } else if (SetViewportZoomAction.is(action)) {
- this.updateZoomLevel(action.zoom);
- }
- }
-
- private updateZoomLevel(zoom: number): void {
- this.zoomLevel = (zoom * 100).toFixed(0).toString() + '%';
- if (this.zoomLevelElement) {
- this.zoomLevelElement.textContent = this.zoomLevel;
- }
- }
-}
diff --git a/packages/editor/src/ui-tools/viewport/viewport-bar.tsx b/packages/editor/src/ui-tools/viewport/viewport-bar.tsx
new file mode 100644
index 000000000..dd8e4693f
--- /dev/null
+++ b/packages/editor/src/ui-tools/viewport/viewport-bar.tsx
@@ -0,0 +1,102 @@
+import {
+ Action,
+ IActionHandler,
+ isViewport,
+ IToolManager,
+ SetUIExtensionVisibilityAction,
+ SetViewportAction,
+ TYPES,
+ SelectionService,
+ type IActionDispatcher
+} from '@eclipse-glsp/client';
+import { inject, injectable } from 'inversify';
+import { CenterButton, FitToScreenButton, OriginScreenButton, ViewportBarButton } from './button';
+
+import { QuickActionUI } from '../quick-action/quick-action-ui';
+import { EnableViewportAction, SetViewportZoomAction } from '@axonivy/process-editor-protocol';
+import { ReactUIExtension } from '../../utils/react-ui-extension';
+import React from 'react';
+import IvyIcon from '../../utils/ui-components';
+
+const JSX = { createElement: React.createElement };
+
+@injectable()
+export class ViewportBar extends ReactUIExtension implements IActionHandler {
+ static readonly ID = 'ivy-viewport-bar';
+
+ @inject(TYPES.IActionDispatcher) protected readonly actionDispatcher: IActionDispatcher;
+ @inject(TYPES.IToolManager) protected readonly toolManager: IToolManager;
+ @inject(SelectionService) protected selectionService: SelectionService;
+
+ protected zoomLevel = '100%';
+ protected zoomLevelElement?: HTMLElement;
+
+ id(): string {
+ return ViewportBar.ID;
+ }
+ containerClass(): string {
+ return ViewportBar.ID;
+ }
+
+ protected initializeContainer(container: HTMLElement): void {
+ super.initializeContainer(container);
+ container.onwheel = ev => (ev.ctrlKey ? ev.preventDefault() : true);
+ }
+
+ protected render(): React.ReactNode {
+ return (
+