From 88effedda8814ea4e85dbbd22d19e4df646a7867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20B=C3=A9gaudeau?= Date: Wed, 3 Feb 2021 16:26:06 +0100 Subject: [PATCH] [292] Make the workbench reusable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://github.com/eclipse-sirius/sirius-components/issues/292 Signed-off-by: Stéphane Bégaudeau --- .../src/diagram/DiagramWebSocketContainer.tsx | 11 +- .../DiagramWebSocketContainer.types.ts | 7 +- frontend/src/diagram/Toolbar.module.css | 56 --- frontend/src/diagram/Toolbar.tsx | 128 ++++-- .../src/diagram/__tests__/reducer.test.ts | 20 +- frontend/src/diagram/reducer.ts | 2 +- frontend/src/index.ts | 7 +- .../__tests__/reducer.test.ts | 113 ------ .../PropertiesWebSocketContainer.tsx | 15 +- .../edit-project/EditProjectLoadedView.tsx | 102 ----- .../EditProjectNavbar.module.css | 0 .../EditProjectNavbar/EditProjectNavbar.tsx | 37 +- .../EditProjectNavbarContextMenu.tsx | 0 .../EditProjectNavbar/machine.ts | 0 .../EditProjectNavbar/reducer.ts | 0 .../views/edit-project/EditProjectView.tsx | 258 ++++++------ .../edit-project/EditProjectView.types.ts | 46 ++- .../edit-project/EditProjectViewMachine.ts | 157 ++++++++ .../edit-project/__tests__/reducer.test.ts | 368 ------------------ frontend/src/views/edit-project/machine.tsx | 49 --- frontend/src/views/edit-project/reducer.tsx | 215 ---------- .../OnboardArea.module.css | 0 .../OnboardArea.tsx | 0 .../RepresentationArea.module.css | 0 .../RepresentationArea.tsx | 10 +- .../RepresentationNavigation.module.css | 0 .../RepresentationNavigation.tsx | 7 +- frontend/src/workbench/Workbench.tsx | 95 +++++ .../Workbench.types.ts} | 32 +- frontend/src/workbench/WorkbenchMachine.ts | 88 +++++ 30 files changed, 662 insertions(+), 1161 deletions(-) delete mode 100644 frontend/src/diagram/Toolbar.module.css delete mode 100644 frontend/src/navbar/EditProjectNavbar/__tests__/reducer.test.ts delete mode 100644 frontend/src/views/edit-project/EditProjectLoadedView.tsx rename frontend/src/{navbar => views/edit-project}/EditProjectNavbar/EditProjectNavbar.module.css (100%) rename frontend/src/{navbar => views/edit-project}/EditProjectNavbar/EditProjectNavbar.tsx (79%) rename frontend/src/{navbar => views/edit-project/EditProjectNavbar}/EditProjectNavbarContextMenu.tsx (100%) rename frontend/src/{navbar => views/edit-project}/EditProjectNavbar/machine.ts (100%) rename frontend/src/{navbar => views/edit-project}/EditProjectNavbar/reducer.ts (100%) create mode 100644 frontend/src/views/edit-project/EditProjectViewMachine.ts delete mode 100644 frontend/src/views/edit-project/__tests__/reducer.test.ts delete mode 100644 frontend/src/views/edit-project/machine.tsx delete mode 100644 frontend/src/views/edit-project/reducer.tsx rename frontend/src/{views/edit-project => workbench}/OnboardArea.module.css (100%) rename frontend/src/{views/edit-project => workbench}/OnboardArea.tsx (100%) rename frontend/src/{views/edit-project => workbench}/RepresentationArea.module.css (100%) rename frontend/src/{views/edit-project => workbench}/RepresentationArea.tsx (83%) rename frontend/src/{views/edit-project => workbench}/RepresentationNavigation.module.css (100%) rename frontend/src/{views/edit-project => workbench}/RepresentationNavigation.tsx (90%) create mode 100644 frontend/src/workbench/Workbench.tsx rename frontend/src/{views/edit-project/EditProjectLoadedView.module.css => workbench/Workbench.types.ts} (55%) create mode 100644 frontend/src/workbench/WorkbenchMachine.ts diff --git a/frontend/src/diagram/DiagramWebSocketContainer.tsx b/frontend/src/diagram/DiagramWebSocketContainer.tsx index 234e62db631..c30d3be2cf3 100644 --- a/frontend/src/diagram/DiagramWebSocketContainer.tsx +++ b/frontend/src/diagram/DiagramWebSocketContainer.tsx @@ -70,7 +70,6 @@ const propTypes = { kind: PropTypes.string.isRequired, }), setSelection: PropTypes.func.isRequired, - setSubscribers: PropTypes.func.isRequired, }; /** @@ -227,7 +226,6 @@ export const DiagramWebSocketContainer = ({ readOnly, selection, setSelection, - setSubscribers, }: DiagramWebSocketContainerProps) => { const diagramDomElement = useRef(null); @@ -477,14 +475,6 @@ export const DiagramWebSocketContainer = ({ dispatch({ type: HANDLE_ERROR__ACTION, message: error }); } - /** - * Each time the list of subscribers is updated, this will trigger the listener used to display the - * subscribers outside of this component. - */ - useEffect(() => { - setSubscribers(subscribers); - }, [setSubscribers, subscribers]); - const onZoomIn = () => { if (diagramServer) { diagramServer.actionDispatcher.dispatch({ kind: ZOOM_IN_ACTION }); @@ -610,6 +600,7 @@ export const DiagramWebSocketContainer = ({ onFitToScreen={onFitToScreen} setZoomLevel={setZoomLevel} zoomLevel={zoomLevel} + subscribers={subscribers} /> {content} diff --git a/frontend/src/diagram/DiagramWebSocketContainer.types.ts b/frontend/src/diagram/DiagramWebSocketContainer.types.ts index 8fe40466d08..dfbf66a1871 100644 --- a/frontend/src/diagram/DiagramWebSocketContainer.types.ts +++ b/frontend/src/diagram/DiagramWebSocketContainer.types.ts @@ -10,7 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -import { Selection, Subscriber } from 'views/edit-project/EditProjectView.types'; +import { Selection } from 'workbench/Workbench.types'; export type DiagramWebSocketContainerProps = { projectId: string; @@ -18,5 +18,8 @@ export type DiagramWebSocketContainerProps = { readOnly: boolean; selection: Selection; setSelection: (newSelection: Selection) => void; - setSubscribers: (newSubscribers: Subscriber[]) => void; +}; + +export type Subscriber = { + username: string; }; diff --git a/frontend/src/diagram/Toolbar.module.css b/frontend/src/diagram/Toolbar.module.css deleted file mode 100644 index e001b193719..00000000000 --- a/frontend/src/diagram/Toolbar.module.css +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Obeo - initial API and implementation - *******************************************************************************/ -.toolbar { - display: flex; - flex-direction: row; - justify-content: flex-end; - height: 32px; - - grid-column-start: 1; - grid-column-end: 4; - border-bottom: 1px solid var(--daintree-lighten-70); - - fill: none; - stroke: var(--daintree); -} - -.toolbar > * { - height: 30px; - width: 30px; -} - -.toolbar > *:last-child { - height: 30px; - width: 70px; -} - -.icon { - fill: var(--daintree); -} - -.icon:hover { - background-color: var(--blue-lagoon-lighten-95); -} - -.icon:focus { - background-color: var(--blue-lagoon-lighten-90); -} - -.separator { - height: 24px; - width: 1px; - border-color: var(--daintree); - border-left-style: solid; - border-left-width: 1px; - margin: 4px; -} diff --git a/frontend/src/diagram/Toolbar.tsx b/frontend/src/diagram/Toolbar.tsx index 8003c16614c..88b65a5bbf5 100644 --- a/frontend/src/diagram/Toolbar.tsx +++ b/frontend/src/diagram/Toolbar.tsx @@ -10,27 +10,20 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -import { IconButton } from 'core/button/Button'; -import { Select } from 'core/select/Select'; -import { FitToScreen, Share, ZoomIn, ZoomOut } from 'icons'; +import Avatar from '@material-ui/core/Avatar'; +import FormControl from '@material-ui/core/FormControl'; +import IconButton from '@material-ui/core/IconButton'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; +import { makeStyles } from '@material-ui/core/styles'; +import Tooltip from '@material-ui/core/Tooltip'; +import AspectRatioIcon from '@material-ui/icons/AspectRatio'; +import ShareIcon from '@material-ui/icons/Share'; +import ZoomInIcon from '@material-ui/icons/ZoomIn'; +import ZoomOutIcon from '@material-ui/icons/ZoomOut'; import { ShareDiagramModal } from 'modals/share-diagram/ShareDiagramModal'; import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; -import styles from './Toolbar.module.css'; - -const zooms = [ - { id: '4', label: '400%' }, - { id: '2', label: '200%' }, - { id: '1.75', label: '175%' }, - { id: '1.5', label: '150%' }, - { id: '1.25', label: '125%' }, - { id: '1', label: '100%' }, - { id: '0.75', label: '75%' }, - { id: '0.5', label: '50%' }, - { id: '0.25', label: '25%' }, - { id: '0.1', label: '10%' }, - { id: '0.05', label: '5%' }, -]; const propTypes = { onZoomIn: PropTypes.func.isRequired, @@ -38,9 +31,44 @@ const propTypes = { onFitToScreen: PropTypes.func.isRequired, setZoomLevel: PropTypes.func.isRequired, zoomLevel: PropTypes.string, + subscribers: PropTypes.array.isRequired, }; -export const Toolbar = ({ onZoomIn, onZoomOut, onFitToScreen, setZoomLevel, zoomLevel }) => { - const [state, setState] = useState({ modal: undefined, currentZoomLevel: undefined }); + +const useToolbarStyles = makeStyles((theme) => ({ + toolbar: { + display: 'flex', + flexDirection: 'row', + height: theme.spacing(4), + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1), + borderBottomWidth: '1px', + borderBottomStyle: 'solid', + borderBottomColor: theme.palette.divider, + }, + selectFormControl: { + minWidth: 70, + }, + subscribers: { + marginLeft: 'auto', + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + '& > *': { + marginLeft: theme.spacing(0.5), + marginRight: theme.spacing(0.5), + }, + }, + avatar: { + fontSize: '1rem', + width: theme.spacing(3), + height: theme.spacing(3), + backgroundColor: theme.palette.primary.main, + }, +})); + +export const Toolbar = ({ onZoomIn, onZoomOut, onFitToScreen, setZoomLevel, zoomLevel, subscribers }) => { + const classes = useToolbarStyles(); + const [state, setState] = useState({ modal: undefined, currentZoomLevel: zoomLevel }); const onShare = () => setState({ modal: 'ShareDiagramModal', currentZoomLevel: state.currentZoomLevel }); const closeModal = () => setState({ modal: undefined, currentZoomLevel: state.currentZoomLevel }); @@ -62,28 +90,52 @@ export const Toolbar = ({ onZoomIn, onZoomOut, onFitToScreen, setZoomLevel, zoom } return ( <> -
- - +
+ + + + + -
- - + + - - + + - - + + -