From 79743f66a5e4968e805e31d0d683f586a5375b44 Mon Sep 17 00:00:00 2001 From: afonso Date: Tue, 23 Apr 2024 22:44:21 +0100 Subject: [PATCH] CELE-17 feat: Add view mode property --- applications/visualizer/frontend/src/App.tsx | 75 +++++++++++++++++-- .../frontend/src/components/Workspace.tsx | 23 +----- .../frontend/src/contexts/GlobalContext.tsx | 14 +++- .../visualizer/frontend/src/models.ts | 6 ++ 4 files changed, 89 insertions(+), 29 deletions(-) diff --git a/applications/visualizer/frontend/src/App.tsx b/applications/visualizer/frontend/src/App.tsx index cd72b659..8bb454f8 100644 --- a/applications/visualizer/frontend/src/App.tsx +++ b/applications/visualizer/frontend/src/App.tsx @@ -1,15 +1,62 @@ import {Provider} from "react-redux"; import {ThemeProvider} from '@mui/material/styles'; -import {CssBaseline} from "@mui/material"; +import {Box, Button, CssBaseline, Typography} from "@mui/material"; import '@metacell/geppetto-meta-ui/flex-layout/style/dark.scss'; import theme from './theme/index.tsx'; import './App.css' import {useGlobalContext} from "./contexts/GlobalContext.tsx"; import AppLauncher from "./components/AppLauncher.tsx"; import Workspace from "./components/Workspace.tsx"; +import React from "react"; +import {createEmptyWorkspace} from "./helpers/initialWorkspacesHelper.ts"; +import {ViewMode} from "./models.ts"; function App() { - const {workspaces, currentWorkspaceId} = useGlobalContext(); + const { + workspaces, + currentWorkspaceId, + switchWorkspace, + addWorkspace, + viewMode, + setViewMode, + selectedWorkspacesIds, + setSelectedWorkspacesIds + } = useGlobalContext(); + + + const TEST_toggleViewMode = () => { + if (viewMode === ViewMode.Default) { + setViewMode(ViewMode.Compare); + // Ensure at least two workspaces are selected for comparison + const keys = Object.keys(workspaces); + if (selectedWorkspacesIds.size < 2) { + if (keys.length < 2) { + // Create a new workspace if there aren't enough + const newWorkspace = createEmptyWorkspace(`Workspace ${keys.length + 1}`); + addWorkspace(newWorkspace); + setSelectedWorkspacesIds(new Set([currentWorkspaceId, newWorkspace.id])); + } else { + setSelectedWorkspacesIds(new Set([currentWorkspaceId, keys.find(key => key !== currentWorkspaceId)])); + } + } + } else { + setViewMode(ViewMode.Default); + setSelectedWorkspacesIds(new Set([currentWorkspaceId])); + } + }; + const TEST_change_workspace = () => { + + const keys = Object.keys(workspaces); + const otherKeys = keys.filter(key => key !== currentWorkspaceId); + + if (otherKeys.length > 0) { + switchWorkspace(otherKeys[0]); + } else { + const newWorkspace = createEmptyWorkspace(`Workspace ${Object.keys(workspaces).length + 1}`); + addWorkspace(newWorkspace); + switchWorkspace(newWorkspace.id); + } + } const hasLaunched = currentWorkspaceId != undefined @@ -18,9 +65,27 @@ function App() { {hasLaunched ? ( - - - + + + + {viewMode === ViewMode.Compare ? + Array.from(selectedWorkspacesIds).map(id => ( + + + + )) + : + + + + } + + + ) : } diff --git a/applications/visualizer/frontend/src/components/Workspace.tsx b/applications/visualizer/frontend/src/components/Workspace.tsx index 73c6f998..34f4d7c4 100644 --- a/applications/visualizer/frontend/src/components/Workspace.tsx +++ b/applications/visualizer/frontend/src/components/Workspace.tsx @@ -1,13 +1,12 @@ import {useDispatch} from "react-redux"; import React, {useEffect, useState} from "react"; import {ThemeProvider} from '@mui/material/styles'; -import {Box, Button, CircularProgress, CssBaseline, Typography} from "@mui/material"; +import {Box, CircularProgress, CssBaseline} from "@mui/material"; import {addWidget} from '@metacell/geppetto-meta-client/common/layout/actions'; import '@metacell/geppetto-meta-ui/flex-layout/style/dark.scss'; import {leftComponentWidget, rightComponentWidget} from "../layout-manager/widgets.ts"; import theme from '../theme'; import {useGlobalContext} from "../contexts/GlobalContext.tsx"; -import {createEmptyWorkspace} from "../helpers/initialWorkspacesHelper.ts"; function Workspace({workspaceId}) { @@ -16,7 +15,7 @@ function Workspace({workspaceId}) { const dispatch = useDispatch(); const [LayoutComponent, setLayoutComponent] = useState(undefined); - const {workspaces, switchWorkspace, addWorkspace} = useGlobalContext(); + const {workspaces} = useGlobalContext(); const workspace = workspaces[workspaceId] @@ -33,18 +32,6 @@ function Workspace({workspaceId}) { dispatch(addWidget(rightComponentWidget())); }, [LayoutComponent, dispatch]) - const TEST_change_workspace = () => { - const keys = Object.keys(workspaces); - const otherKeys = keys.filter(key => key !== workspaceId); - - if (otherKeys.length > 0) { - switchWorkspace(otherKeys[0]); - } else { - const newWorkspace = createEmptyWorkspace(`Workspace ${Object.keys(workspaces).length + 1}`); - addWorkspace(newWorkspace); - switchWorkspace(newWorkspace.id); - } - } const isLoading = LayoutComponent === undefined return ( @@ -54,12 +41,6 @@ function Workspace({workspaceId}) { {isLoading ? : - - {workspace.name} - - } diff --git a/applications/visualizer/frontend/src/contexts/GlobalContext.tsx b/applications/visualizer/frontend/src/contexts/GlobalContext.tsx index fd45e249..0edaecf6 100644 --- a/applications/visualizer/frontend/src/contexts/GlobalContext.tsx +++ b/applications/visualizer/frontend/src/contexts/GlobalContext.tsx @@ -1,5 +1,5 @@ -import React, {createContext, useState, useContext, ReactNode, useEffect} from 'react'; -import {Dataset, Neuron, Workspace} from "../models.ts"; +import React, {createContext, ReactNode, useContext, useEffect, useState} from 'react'; +import {Dataset, Neuron, ViewMode, Workspace} from "../models.ts"; import {DatasetsService, NeuronsService} from "../rest"; import {mapDatasetFromRequestToContext, mapNeuronFromRequestToContext} from "../helpers/mappers.ts"; @@ -12,6 +12,8 @@ export interface GlobalContextType { updateWorkspace: (workspaceId: string, workspace: Workspace) => void; removeWorkspace: (workspaceId: string) => void; switchWorkspace: (workspaceId: string) => void; + + viewMode: ViewMode; } interface GlobalContextProviderProps { @@ -25,6 +27,8 @@ export const GlobalContextProvider: React.FC = ({chi const [neurons, setNeurons] = useState>({}); const [datasets, setDatasets] = useState>({}); const [currentWorkspaceId, setCurrentWorkspaceId] = useState(undefined); + const [viewMode, setViewMode] = useState(ViewMode.Default); + const [selectedWorkspacesIds, setSelectedWorkspacesIds] = useState>(new Set()); useEffect(() => { @@ -83,7 +87,11 @@ export const GlobalContextProvider: React.FC = ({chi addWorkspace, updateWorkspace, removeWorkspace, - switchWorkspace + switchWorkspace, + viewMode, + setViewMode, + selectedWorkspacesIds, + setSelectedWorkspacesIds, }}> {children} diff --git a/applications/visualizer/frontend/src/models.ts b/applications/visualizer/frontend/src/models.ts index 4ea7442e..638ba457 100644 --- a/applications/visualizer/frontend/src/models.ts +++ b/applications/visualizer/frontend/src/models.ts @@ -1,5 +1,11 @@ import {createStore} from "@reduxjs/toolkit"; + +export enum ViewMode { + Default = 'Default', + Compare = 'Compare', +} + export enum ViewerType { Graph = 'Graph', ThreeD = '3D',