Skip to content

Commit 0207ff6

Browse files
committed
fixes to views
1 parent e1f920c commit 0207ff6

7 files changed

Lines changed: 3247 additions & 589 deletions

File tree

src/components/DigitalColleagues/ManagementSidebar.tsx

Lines changed: 104 additions & 328 deletions
Large diffs are not rendered by default.

src/components/Projects/EpicsView.tsx

Lines changed: 92 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react'
1+
import React, { useState, useRef, useEffect } from 'react'
22
import { Card } from '@/components/ui/card'
33
import { Badge } from '@/components/ui/badge'
44
import { Button } from '@/components/ui/button'
@@ -7,13 +7,6 @@ import { TaskCard } from './TaskCard'
77
import { Plus, Move, Edit2, Trash2, Check, X } from 'lucide-react'
88
import { Input } from '@/components/ui/input'
99
import { Textarea } from '@/components/ui/textarea'
10-
import {
11-
Select,
12-
SelectContent,
13-
SelectItem,
14-
SelectTrigger,
15-
SelectValue,
16-
} from '@/components/ui/select'
1710
import { DashboardHero } from '../Heros/DashboardHero/DashboardHero'
1811

1912
interface EpicsViewProps {
@@ -42,6 +35,51 @@ export const EpicsView: React.FC<EpicsViewProps> = ({
4235
const [draggedTask, setDraggedTask] = useState<Task | null>(null)
4336
const [editingEpic, setEditingEpic] = useState<string | null>(null)
4437
const [editForm, setEditForm] = useState<Partial<Epic>>({})
38+
const [heroHeight, setHeroHeight] = useState(0)
39+
40+
const heroRef = useRef<HTMLDivElement>(null)
41+
const containerRef = useRef<HTMLDivElement>(null)
42+
43+
// Measure hero height and adjust when it changes
44+
useEffect(() => {
45+
const measureHeroHeight = () => {
46+
if (heroRef.current) {
47+
const height = heroRef.current.offsetHeight
48+
setHeroHeight(height)
49+
}
50+
}
51+
52+
// Initial measurement
53+
measureHeroHeight()
54+
55+
// Set up ResizeObserver to watch for changes in hero height
56+
const resizeObserver = new ResizeObserver(measureHeroHeight)
57+
if (heroRef.current) {
58+
resizeObserver.observe(heroRef.current)
59+
}
60+
61+
// Also listen for storage events in case the minimized state changes in another tab
62+
const handleStorageChange = () => {
63+
setTimeout(measureHeroHeight, 100) // Small delay to let the animation complete
64+
}
65+
window.addEventListener('storage', handleStorageChange)
66+
67+
return () => {
68+
resizeObserver.disconnect()
69+
window.removeEventListener('storage', handleStorageChange)
70+
}
71+
}, [])
72+
73+
// Re-measure when the hero content might change
74+
useEffect(() => {
75+
const timer = setTimeout(() => {
76+
if (heroRef.current) {
77+
setHeroHeight(heroRef.current.offsetHeight)
78+
}
79+
}, 300) // Wait for any animations to complete
80+
81+
return () => clearTimeout(timer)
82+
}, [editingEpic]) // Re-measure when editing states change
4583

4684
const handleDragStart = (task: Task) => {
4785
setDraggedTask(task)
@@ -128,30 +166,44 @@ export const EpicsView: React.FC<EpicsViewProps> = ({
128166
}
129167

130168
return (
131-
<div className="px-2 md:px-4 py-4 space-y-8">
132-
<DashboardHero
133-
title="Epic Planning"
134-
description="Organize and manage your project epics, track progress, and assign tasks."
135-
gradient="bg-gradient-to-r from-rose-600 via-pink-600 to-fuchsia-600"
136-
primaryAction={{
137-
label: 'Add epic',
138-
onClick: onAddEpic,
139-
}}
140-
/>
141-
<div className="flex-1">
142-
<div className="w-full">
169+
<div ref={containerRef} className="h-full flex flex-col px-2 md:px-4 py-4">
170+
<div ref={heroRef} className="flex-shrink-0">
171+
<DashboardHero
172+
title="Epic Planning"
173+
description="Organize and manage your project epics, track progress, and assign tasks."
174+
gradient="bg-gradient-to-r from-rose-600 via-pink-600 to-fuchsia-600"
175+
primaryAction={{
176+
label: 'Add epic',
177+
onClick: onAddEpic,
178+
}}
179+
/>
180+
</div>
181+
<div className="flex-1 min-h-0 mt-8">
182+
<div
183+
className="h-full overflow-y-auto"
184+
style={{
185+
height: heroHeight > 0 ? `calc(100vh - ${heroHeight + 120}px)` : 'calc(100vh - 12rem)'
186+
}}
187+
>
143188
{/* Epics Grid */}
144-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
189+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 auto-rows-max">
145190
{epics.map((epic) => {
146191
const epicTasks = getTasksByEpic(epic.id)
147192
const totalPoints = epicTasks.reduce((sum, task) => sum + task.points, 0)
193+
194+
// Calculate dynamic height based on available space
195+
const availableHeight = heroHeight > 0 ? `calc(100vh - ${heroHeight + 200}px)` : 'calc(100vh - 14rem)'
148196

149197
return (
150198
<Card
151199
key={epic.id}
152200
className={`flex flex-col ${
153-
editingEpic === epic.id ? 'h-auto' : 'h-[600px]'
201+
editingEpic === epic.id ? 'h-auto' : ''
154202
} bg-card shadow-sm`}
203+
style={{
204+
height: editingEpic === epic.id ? 'auto' : availableHeight,
205+
minHeight: '400px'
206+
}}
155207
onDragOver={handleDragOver}
156208
onDrop={(e) => handleDrop(e, epic.id)}
157209
>
@@ -199,44 +251,36 @@ export const EpicsView: React.FC<EpicsViewProps> = ({
199251
<div className="grid grid-cols-2 gap-2">
200252
<div>
201253
<label className="text-xs text-muted-foreground">Confidence</label>
202-
<Select
254+
<select
203255
value={editForm.confidence || epic.confidence}
204-
onValueChange={(value) =>
256+
onChange={(e) =>
205257
setEditForm({
206258
...editForm,
207-
confidence: value as Epic['confidence'],
259+
confidence: e.target.value as Epic['confidence'],
208260
})
209261
}
262+
className="flex h-8 w-full rounded-md border border-input bg-background px-3 py-2 text-xs ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
210263
>
211-
<SelectTrigger className="text-xs">
212-
<SelectValue />
213-
</SelectTrigger>
214-
<SelectContent>
215-
<SelectItem value="low">Low</SelectItem>
216-
<SelectItem value="medium">Medium</SelectItem>
217-
<SelectItem value="high">High</SelectItem>
218-
</SelectContent>
219-
</Select>
264+
<option value="low">Low</option>
265+
<option value="medium">Medium</option>
266+
<option value="high">High</option>
267+
</select>
220268
</div>
221269
<div>
222270
<label className="text-xs text-muted-foreground">Phase</label>
223-
<Select
271+
<select
224272
value={editForm.phase?.toString() || epic.phase.toString()}
225-
onValueChange={(value) =>
226-
setEditForm({ ...editForm, phase: parseInt(value) })
273+
onChange={(e) =>
274+
setEditForm({ ...editForm, phase: parseInt(e.target.value) })
227275
}
276+
className="flex h-8 w-full rounded-md border border-input bg-background px-3 py-2 text-xs ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
228277
>
229-
<SelectTrigger className="text-xs">
230-
<SelectValue />
231-
</SelectTrigger>
232-
<SelectContent>
233-
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map((phase) => (
234-
<SelectItem key={phase} value={phase.toString()}>
235-
Phase {phase}
236-
</SelectItem>
237-
))}
238-
</SelectContent>
239-
</Select>
278+
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map((phase) => (
279+
<option key={phase} value={phase.toString()}>
280+
Phase {phase}
281+
</option>
282+
))}
283+
</select>
240284
</div>
241285
</div>
242286

0 commit comments

Comments
 (0)