Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2866b63
Enhance CreateModelModal and ToolsPanel components with new features
TsotneMikadze Sep 10, 2025
5250c7a
Enhance application layout and flow components with new features
TsotneMikadze Sep 15, 2025
d5ba7e9
Merge branch 'develop' into develop
TsotneMikadze Sep 15, 2025
8118dd5
Refactor App component and enhance authentication handling
TsotneMikadze Sep 15, 2025
1a80931
Merge branch 'develop' of https://github.com/TsotneMikadze/Vitruv-UI-…
TsotneMikadze Sep 15, 2025
a2043f7
Fix closing tag in ToolsPanel component for proper layout rendering
TsotneMikadze Sep 15, 2025
7b8ced0
Update App.test.tsx to use getByRole for title element selection in t…
TsotneMikadze Sep 15, 2025
96657c0
Refactor MainLayout and KeywordTagsInput components for improved clar…
TsotneMikadze Sep 15, 2025
f963eda
Update sonar-project.properties and enhance Header component for impr…
TsotneMikadze Sep 15, 2025
608cace
Merge pull request #30 from TsotneMikadze/develop
ma-mirzaei Sep 15, 2025
837d28b
Refactor Header, CreateModelModal, ToolsPanel, HomePage, ProjectPage,…
TsotneMikadze Sep 15, 2025
baad4de
Refactor ToolsPanel component to optimize API filter building and enh…
TsotneMikadze Sep 15, 2025
bc19880
Merge pull request #31 from TsotneMikadze/develop
ma-mirzaei Sep 16, 2025
7893484
Refactor App, HomePage, and ProjectPage components to enhance layout …
TsotneMikadze Sep 16, 2025
db2fe61
Refactor App component to enable ProtectedRoute for enhanced route se…
TsotneMikadze Sep 16, 2025
39d5834
Remove unused useLocation hook from Header component to streamline co…
TsotneMikadze Sep 16, 2025
6aeadbc
Merge pull request #32 from TsotneMikadze/develop
ma-mirzaei Sep 17, 2025
393ad26
Refactor SignUp, MainLayout, MetaModelsPanel, ToolsPanel, VsumsPanel,…
TsotneMikadze Sep 18, 2025
a900b8e
Refactor VsumTabs component to simplify state management
TsotneMikadze Sep 18, 2025
93133fe
Refactor VsumTabs component to remove loading state management
TsotneMikadze Sep 18, 2025
3a95446
Merge pull request #41 from TsotneMikadze/develop
ma-mirzaei Sep 22, 2025
4b2f241
Fixed - Using correct api to fetch user information #39
TsotneMikadze Sep 23, 2025
be964a8
Fixed - Delete meta model from library #18
TsotneMikadze Sep 23, 2025
fbf08ba
Fixed - Add loading bar in uploading new metamodel #27
TsotneMikadze Sep 23, 2025
194fdde
Fixed - Create Vsum page #43
TsotneMikadze Sep 23, 2025
ed321fb
Merge pull request #50 from TsotneMikadze/develop
ma-mirzaei Sep 25, 2025
884aa78
Refactor layout components for improved sidebar handling and styling
TsotneMikadze Sep 25, 2025
8d78f58
Enhance error handling in CreateModelModal
TsotneMikadze Sep 26, 2025
9de554c
Remove unused styles from MetaModelsPanel, ToolsPanel, and VsumsPanel…
TsotneMikadze Sep 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/assets/22098030.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Mandatory configuration
sonar.projectKey=vitruv-tools_Vitruv-UI-Methodologist
sonar.organization=vitruv-tools
sonar.host.url=https://sonarcloud.io

# Source and coverage paths
sonar.sources=src
Expand Down
4 changes: 2 additions & 2 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ afterEach(() => {

test('renders Vitruvius Modeler title', () => {
render(<App />);
const titleElement = screen.getByText(/vitruvius modeler/i);
expect(titleElement).toBeInTheDocument();
const titleHeading = screen.getByRole('heading', { name: /vitruvius modeler/i });
expect(titleHeading).toBeInTheDocument();
});
19 changes: 18 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { MainLayout, AuthPage } from './components';
import { AuthPage } from './components/auth/AuthPage';
import { HomePage } from './pages/HomePage';
import { ProjectPage } from './pages/ProjectPage';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import { apiService } from './services/api';
import { exportFlowData } from './utils';
import { Node, Edge } from 'reactflow';
import './App.css';
import { SidebarTabs, MainLayout } from './components';

function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useAuth();
Expand All @@ -32,6 +35,8 @@ function ProtectedRoute({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}

// Render MainLayout immediately without lazy loading for consistent UX across routes

function AppContent() {
const { user, signOut } = useAuth();

Expand Down Expand Up @@ -78,6 +83,8 @@ function AppContent() {
onNew={handleNew}
user={user}
onLogout={handleLogout}
leftSidebar={<SidebarTabs />}
leftSidebarInitialWidth={350}
/>
);
}
Expand All @@ -90,7 +97,17 @@ function App() {
<Route path="/auth" element={<AuthPage />} />
<Route path="/" element={
<ProtectedRoute>
<HomePage />
</ProtectedRoute>
} />
<Route path="/mml" element={
<ProtectedRoute>
<AppContent />
</ProtectedRoute>
} />
<Route path="/project" element={
<ProtectedRoute>
<ProjectPage />
</ProtectedRoute>
} />
</Routes>
Expand Down
13 changes: 0 additions & 13 deletions src/components/auth/SignUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,19 +214,6 @@ export function SignUp({ onSignUpSuccess, onSwitchToSignIn }: SignUpProps) {
</button>
</p>
</div>

<div className="auth-divider">
<span>or</span>
</div>

<div className="demo-credentials">
<p className="demo-title">API Endpoint</p>
<div className="demo-info">
<p>This application connects to the backend API at:</p>
<p><code>http://localhost:9811/api/v1/users/sign-up</code></p>
<p>Make sure your backend server is running on port 9811.</p>
</div>
</div>
</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/flow/EcoreFileBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,8 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({

<ConfirmDialog
isOpen={showDeleteConfirm}
title="Delete ECORE File"
message={`Are you sure you want to delete "${fileName}"? This action will remove the file from the workspace but will not affect the original uploaded file.`}
title="Delete ECORE File from Workspace"
message={`Do you want to delete "${fileName}" from workspace?`}
confirmText="Delete"
cancelText="Cancel"
onConfirm={confirmDelete}
Expand Down
45 changes: 43 additions & 2 deletions src/components/flow/FlowCanvas.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useRef, useState, forwardRef, useImperativeHandle, useEffect } from 'react';
import ReactFlow, {
MiniMap,
Controls,
Background,
ReactFlowInstance,
Node,
Expand Down Expand Up @@ -54,6 +53,7 @@ export const FlowCanvas = forwardRef<{
const reactFlowWrapper = useRef<HTMLDivElement>(null);
const [reactFlowInstance, setReactFlowInstance] = useState<ReactFlowInstance | null>(null);
const [isDragOver, setIsDragOver] = useState(false);
const [isInteractive, setIsInteractive] = useState(true);
const [selectedFileId, setSelectedFileId] = useState<string | null>(null);
const [expandedFileId, setExpandedFileId] = useState<string | null>(null);

Expand Down Expand Up @@ -350,9 +350,15 @@ export const FlowCanvas = forwardRef<{
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
onInit={setReactFlowInstance}
nodesDraggable={isInteractive}
nodesConnectable={isInteractive}
elementsSelectable={isInteractive}
panOnDrag={isInteractive}
panOnScroll={isInteractive}
zoomOnScroll={isInteractive}
zoomOnPinch={isInteractive}
>
<MiniMap position="bottom-right" style={{ bottom: 16, right: 16, zIndex: 30 }} />
<Controls position="bottom-left" />
<Background />
</ReactFlow>

Expand Down Expand Up @@ -384,6 +390,41 @@ export const FlowCanvas = forwardRef<{
/>
))}

{/* Canvas Controls anchored to wrapper so they move with sidebar resizing */}
<div style={{ position: 'absolute', left: 16, bottom: 16, zIndex: 31, display: 'flex', flexDirection: 'column', gap: 6 }}>
<button
onClick={() => reactFlowInstance?.zoomIn?.()}
style={{ width: 36, height: 36, borderRadius: 6, border: '1px solid #e5e7eb', background: '#ffffff', cursor: 'pointer' }}
title="Zoom in"
>
+
</button>
<button
onClick={() => reactFlowInstance?.zoomOut?.()}
style={{ width: 36, height: 36, borderRadius: 6, border: '1px solid #e5e7eb', background: '#ffffff', cursor: 'pointer' }}
title="Zoom out"
>
</button>
<button
onClick={() => reactFlowInstance?.fitView?.({ padding: 0.2 })}
style={{ width: 36, height: 36, borderRadius: 6, border: '1px solid #e5e7eb', background: '#ffffff', cursor: 'pointer' }}
title="Fit view"
>
</button>
<button
onClick={() => {
const next = !isInteractive;
setIsInteractive(next);
}}
style={{ width: 36, height: 36, borderRadius: 6, border: '1px solid #e5e7eb', background: '#ffffff', cursor: 'pointer' }}
title={isInteractive ? 'Lock interactions' : 'Unlock interactions'}
>
{isInteractive ? '🔓' : '🔒'}
</button>
</div>

{isDragOver && (
<div style={{
position: 'absolute',
Expand Down
3 changes: 3 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ export { EcoreFileBox } from './flow/EcoreFileBox';

// UI components
export { ToolsPanel } from './ui/ToolsPanel';
export { SidebarTabs } from './ui/SidebarTabs';
export { ConfirmDialog } from './ui/ConfirmDialog';
export { CreateModelModal } from './ui/CreateModelModal';
export { KeywordTagsInput } from './ui/KeywordTagsInput';
export { ToastProvider, useToast } from './ui/ToastProvider';


// Auth components
Expand Down
21 changes: 11 additions & 10 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ export function Header({ title = 'Vitruvius Modeler', user, onLogout }: HeaderPr
right: 0,
zIndex: 20,
}}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<h1 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>{title}</h1>

</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<div ref={menuRef} style={{ position: 'relative' }}>
Expand All @@ -72,9 +73,9 @@ export function Header({ title = 'Vitruvius Modeler', user, onLogout }: HeaderPr
aria-haspopup="menu"
aria-expanded={isMenuOpen}
title={
user?.name || `${user?.givenName || ''} ${user?.familyName || ''}`.trim() ||
user?.email ||
user?.username ||
user?.name || `${user?.givenName || ''} ${user?.familyName || ''}`.trim() ||
user?.email ||
user?.username ||
'User menu'
}
style={{
Expand Down Expand Up @@ -120,14 +121,14 @@ export function Header({ title = 'Vitruvius Modeler', user, onLogout }: HeaderPr
borderRadius: 8,
boxShadow: '0 8px 24px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08)',
padding: 0,
zIndex: 30,
zIndex: 50,
border: '1px solid #e8e8e8',
overflow: 'hidden',
animation: 'slideDown 0.2s ease-out',
}}
>
{/* User Info Section */}
<div style={{
<div style={{
background: '#f8f9fa',
padding: '20px',
color: '#2c3e50',
Expand Down Expand Up @@ -168,7 +169,7 @@ export function Header({ title = 'Vitruvius Modeler', user, onLogout }: HeaderPr
)}
</div>
</div>

{/* Status Badge */}
{user?.emailVerified !== undefined && (
<div style={{
Expand All @@ -189,9 +190,9 @@ export function Header({ title = 'Vitruvius Modeler', user, onLogout }: HeaderPr

{/* Menu Actions */}
<div style={{ padding: '16px' }}>
<div style={{
display: 'flex',
flexDirection: 'column',
<div style={{
display: 'flex',
flexDirection: 'column',
gap: 8,
}}>
<button
Expand Down
Loading
Loading