feat: performance dashboard counts per delivery, submission tab shows deliveries, task row hover fix
- Team performance: count each delivery record individually (sent_by + version_number), not per task — R00/R01/R02 by different people all count separately - Performance uses deliveries table directly, EST timezone bucketing, month-gated tabs - TaskDetail Submissions tab: reads from deliveries table, shows R## version, sent_by, sent_at - Submit for Review: writes to deliveries + delivery_files (deliveries bucket), stores version_number - Revision request popup: uses FileAttachment drag-drop component - Task table: only Name and Project columns highlight on hover - deliveries.version_number column added and backfilled Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import { sendEmail } from '../lib/email';
|
||||
import { uploadFilesToRequestInfo, safeName } from '../lib/filebrowserFolders';
|
||||
import { useRefetchOnFocus } from '../hooks/useRefetchOnFocus';
|
||||
import { useRealtimeSubscription } from '../hooks/useRealtimeSubscription';
|
||||
import FileAttachment from '../components/FileAttachment';
|
||||
|
||||
const ACTION_LABEL = {
|
||||
task_created: 'created this task', task_started: 'started this task', task_on_hold: 'placed task on hold',
|
||||
@@ -855,19 +856,7 @@ export default function TaskDetail() {
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: 0.8, color: 'var(--text-secondary)', display: 'block', marginBottom: 6 }}>Attach Files</label>
|
||||
<input ref={revisionFileRef} type="file" multiple style={{ display: 'none' }} onChange={e => setRevisionFiles(prev => [...prev, ...Array.from(e.target.files)])} />
|
||||
<button type="button" className="btn btn-outline" onClick={() => revisionFileRef.current?.click()}>+ Add Files</button>
|
||||
{revisionFiles.length > 0 && (
|
||||
<div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
{revisionFiles.map((f, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', fontSize: 12, color: 'var(--text-secondary)' }}>
|
||||
<span>{f.name}</span>
|
||||
<button type="button" onClick={() => setRevisionFiles(prev => prev.filter((_, idx) => idx !== i))} style={{ background: 'none', border: 'none', color: 'var(--danger)', cursor: 'pointer', fontSize: 14, padding: '0 4px' }}>✕</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<FileAttachment files={revisionFiles} onChange={setRevisionFiles} />
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
|
||||
<button className="btn btn-outline" disabled={revisionSaving} onClick={() => { setRevisionModal(false); setRevisionForm({ description: '', deadline: '' }); setRevisionFiles([]); }}>Cancel</button>
|
||||
|
||||
Reference in New Issue
Block a user