UI: Vertical button stack layout
Browse files
frontend/src/components/ProjectDetail.tsx
CHANGED
|
@@ -688,21 +688,23 @@ const ProjectDetail: React.FC<ProjectDetailProps> = ({ projectId, uiMode, initia
|
|
| 688 |
<h2>{project?.name ?? 'Project'}</h2>
|
| 689 |
<p style={{ color: 'var(--text-dim)' }}>{project?.description || 'No description provided.'}</p>
|
| 690 |
</div>
|
| 691 |
-
<div className="project-actions-container">
|
| 692 |
-
<div className="action-group">
|
| 693 |
-
<button className="btn btn-glass btn-sm" onClick={loadProject}>
|
| 694 |
<RefreshCw size={16} />
|
| 695 |
Refresh
|
| 696 |
</button>
|
| 697 |
{tasks.length > 0 && (
|
| 698 |
-
<button className="btn btn-glass btn-sm" onClick={() => setShowRoadmap(true)}>
|
| 699 |
<MapIcon size={16} />
|
| 700 |
Roadmap
|
| 701 |
</button>
|
| 702 |
)}
|
| 703 |
</div>
|
| 704 |
|
| 705 |
-
<div
|
|
|
|
|
|
|
| 706 |
{allTasksApproved && (
|
| 707 |
<>
|
| 708 |
<button
|
|
@@ -713,34 +715,34 @@ const ProjectDetail: React.FC<ProjectDetailProps> = ({ projectId, uiMode, initia
|
|
| 713 |
background: 'linear-gradient(135deg, var(--accent) 0%, #7c3aed 100%)',
|
| 714 |
boxShadow: '0 4px 15px rgba(124, 58, 237, 0.3)',
|
| 715 |
fontWeight: 700,
|
| 716 |
-
padding: '0.
|
|
|
|
|
|
|
| 717 |
}}
|
| 718 |
>
|
| 719 |
<FileText size={18} />
|
| 720 |
{reportLoading ? 'Building...' : 'Final Report'}
|
| 721 |
</button>
|
| 722 |
-
<
|
| 723 |
-
<
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
<
|
| 728 |
-
|
| 729 |
-
|
| 730 |
-
</button>
|
| 731 |
-
</div>
|
| 732 |
</>
|
| 733 |
)}
|
| 734 |
|
| 735 |
{canModifyProject && tasks.some(t => t.status === 'awaiting_approval') && (
|
| 736 |
-
<button className="btn btn-glass" onClick={handleApproveAll} disabled={approvingAll} style={{ borderColor: 'var(--success)', color: 'var(--success)' }}>
|
| 737 |
<CheckCircle2 size={18} />
|
| 738 |
Approve All
|
| 739 |
</button>
|
| 740 |
)}
|
| 741 |
|
| 742 |
{canModifyProject && (
|
| 743 |
-
<button className="btn btn-primary" onClick={runOrchestrator} disabled={orchestrating}>
|
| 744 |
<PlayCircle size={18} />
|
| 745 |
{orchestrating ? 'Starting...' : retryableTasks > 0 ? `Retry (${retryableTasks})` : 'Run'}
|
| 746 |
</button>
|
|
|
|
| 688 |
<h2>{project?.name ?? 'Project'}</h2>
|
| 689 |
<p style={{ color: 'var(--text-dim)' }}>{project?.description || 'No description provided.'}</p>
|
| 690 |
</div>
|
| 691 |
+
<div className="project-actions-container" style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-md)', alignItems: 'flex-end' }}>
|
| 692 |
+
<div className="action-group" style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-xs)', width: '100%', alignItems: 'flex-end' }}>
|
| 693 |
+
<button className="btn btn-glass btn-sm" onClick={loadProject} style={{ width: 'fit-content' }}>
|
| 694 |
<RefreshCw size={16} />
|
| 695 |
Refresh
|
| 696 |
</button>
|
| 697 |
{tasks.length > 0 && (
|
| 698 |
+
<button className="btn btn-glass btn-sm" onClick={() => setShowRoadmap(true)} style={{ width: 'fit-content' }}>
|
| 699 |
<MapIcon size={16} />
|
| 700 |
Roadmap
|
| 701 |
</button>
|
| 702 |
)}
|
| 703 |
</div>
|
| 704 |
|
| 705 |
+
<div style={{ height: 'var(--space-md)' }} /> {/* Separator */}
|
| 706 |
+
|
| 707 |
+
<div className="action-group reports-group" style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-xs)', width: '100%', alignItems: 'flex-end' }}>
|
| 708 |
{allTasksApproved && (
|
| 709 |
<>
|
| 710 |
<button
|
|
|
|
| 715 |
background: 'linear-gradient(135deg, var(--accent) 0%, #7c3aed 100%)',
|
| 716 |
boxShadow: '0 4px 15px rgba(124, 58, 237, 0.3)',
|
| 717 |
fontWeight: 700,
|
| 718 |
+
padding: '0.8rem 1.5rem',
|
| 719 |
+
width: '100%',
|
| 720 |
+
justifyContent: 'center'
|
| 721 |
}}
|
| 722 |
>
|
| 723 |
<FileText size={18} />
|
| 724 |
{reportLoading ? 'Building...' : 'Final Report'}
|
| 725 |
</button>
|
| 726 |
+
<button className="btn btn-glass btn-sm" onClick={() => openFinalReport('brief')} disabled={reportLoading} style={{ width: '100%', justifyContent: 'center' }}>
|
| 727 |
+
<FileText size={16} />
|
| 728 |
+
Brief Summary
|
| 729 |
+
</button>
|
| 730 |
+
<button className="btn btn-glass btn-sm" onClick={() => openFinalReport('pessimistic')} disabled={reportLoading} style={{ width: '100%', justifyContent: 'center' }}>
|
| 731 |
+
<FileText size={16} />
|
| 732 |
+
Risks Analysis
|
| 733 |
+
</button>
|
|
|
|
|
|
|
| 734 |
</>
|
| 735 |
)}
|
| 736 |
|
| 737 |
{canModifyProject && tasks.some(t => t.status === 'awaiting_approval') && (
|
| 738 |
+
<button className="btn btn-glass" onClick={handleApproveAll} disabled={approvingAll} style={{ borderColor: 'var(--success)', color: 'var(--success)', width: '100%', justifyContent: 'center' }}>
|
| 739 |
<CheckCircle2 size={18} />
|
| 740 |
Approve All
|
| 741 |
</button>
|
| 742 |
)}
|
| 743 |
|
| 744 |
{canModifyProject && (
|
| 745 |
+
<button className="btn btn-primary" onClick={runOrchestrator} disabled={orchestrating} style={{ width: '100%', justifyContent: 'center' }}>
|
| 746 |
<PlayCircle size={18} />
|
| 747 |
{orchestrating ? 'Starting...' : retryableTasks > 0 ? `Retry (${retryableTasks})` : 'Run'}
|
| 748 |
</button>
|