added being able to assign sessions to projects via the sessions modal

This commit is contained in:
Storme-bit
2026-04-13 20:36:42 -07:00
parent e3f6b9a9db
commit 649ed2b350
8 changed files with 163 additions and 121 deletions

View File

@@ -1,116 +1,128 @@
// SessionModal.jsx
import React, {useState, useEffect, useRef} from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { updateSession } from '../api/orchestration';
export default function SessionModal({ session, mode = 'settings', onRename, onDelete, onClose }) {
const [name, setName] = useState(session?.name || '');
const inputRef = useRef(null);
export default function SessionModal({ session, mode = 'settings', onRename, onDelete, onClose, projects = [] }) {
const [name, setName] = useState(session?.name || '');
const [projectId, setProjectId] = useState(session?.project_id ?? '');
const inputRef = useRef(null);
useEffect(() => {
if (mode === 'settings') {
inputRef.current?.focus();
inputRef.current?.select();
}
}, [mode]);
function handleSubmit() {
const trimmed = name.trim();
if (!trimmed) return;
onRename(session, trimmed);
onClose();
useEffect(() => {
if (mode === 'settings') {
inputRef.current?.focus();
inputRef.current?.select();
}
}, [mode]);
function handleKeyDown(e) {
if (e.key === 'Enter' && mode === 'settings') handleSubmit();
if (e.key === 'Escape') onClose();
}
function handleSubmit() {
const trimmed = name.trim();
if (!trimmed) return;
onRename(session, trimmed, projectId || null);
onClose();
}
if (!session) return null;
function handleKeyDown(e) {
if (e.key === 'Enter' && mode === 'settings') handleSubmit();
if (e.key === 'Escape') onClose();
}
return (
<div onClick={onClose} style={{
position: 'fixed',
inset: 0,
background: 'rgba(0,0,0,0.5)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 100,
}}>
<div onClick={e => e.stopPropagation()} onKeyDown={handleKeyDown} style={{
background: 'var(--bg-surface)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-lg)',
padding: '24px',
width: '360px',
display: 'flex',
flexDirection: 'column',
gap: '16px',
}}>
{mode === 'settings' ? (
<>
<h2 style={{ fontSize: '15px', fontWeight: 600, color: 'var(--text-primary)' }}>
Session Settings
</h2>
<div className="flex-col" style={{ gap: '8px' }}>
<label className="label-upper">Name</label>
<input
ref={inputRef}
value={name}
onChange={e => setName(e.target.value)}
placeholder="Enter session name..."
style={{
background: 'var(--bg-elevated)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)',
padding: '8px 12px',
color: 'var(--text-primary)',
fontSize: '14px',
outline: 'none',
width: '100%',
}}
/>
</div>
<div className="flex" style={{ gap: '8px', justifyContent: 'flex-end' }}>
<button className="btn-reset text-base text-muted"
onClick={onClose}
style={{ padding: '8px 14px', borderRadius: 'var(--radius-md)' }}
>Cancel</button>
<button className="btn-primary" onClick={handleSubmit}
disabled={!name.trim()}
style={{ padding: '8px 16px' }}
>Save</button>
</div>
</>
) : (
<>
<h2 style={{ fontSize: '15px', fontWeight: 600, color: 'var(--text-primary)' }}>
Delete Session
</h2>
<p className="text-sm text-secondary">
Are you sure you want to delete{' '}
<span style={{ color: 'var(--text-primary)', fontWeight: 500 }}>
{session.name || session.external_id}
</span>
? This will permanently remove all messages in this conversation.
</p>
<div className="flex" style={{ gap: '8px', justifyContent: 'flex-end' }}>
<button className="btn-reset text-base text-muted"
onClick={onClose}
style={{ padding: '8px 14px', borderRadius: 'var(--radius-md)' }}
>Cancel</button>
<button className="btn-reset text-base"
onClick={() => { onDelete(session); onClose(); }}
style={{
padding: '8px 16px',
borderRadius: 'var(--radius-md)',
background: '#c0392b',
color: 'white',
}}
>Delete</button>
</div>
</>
)}
if (!session) return null;
return (
<div onClick={onClose} style={{
position: 'fixed', inset: 0,
background: 'rgba(0,0,0,0.5)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
zIndex: 100,
}}>
<div onClick={e => e.stopPropagation()} onKeyDown={handleKeyDown} style={{
background: 'var(--bg-surface)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-lg)',
padding: '24px', width: '360px',
display: 'flex', flexDirection: 'column', gap: '16px',
}}>
{mode === 'settings' ? (
<>
<h2 style={{ fontSize: '15px', fontWeight: 600, color: 'var(--text-primary)' }}>
Session Settings
</h2>
{/* Name */}
<div className="flex-col" style={{ gap: '6px' }}>
<label className="label-upper">Name</label>
<input
ref={inputRef}
value={name}
onChange={e => setName(e.target.value)}
placeholder="Enter session name..."
style={{
background: 'var(--bg-elevated)', border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)', padding: '8px 12px',
color: 'var(--text-primary)', fontSize: '14px', outline: 'none', width: '100%',
}}
/>
</div>
</div>
);
{/* Project assignment */}
<div className="flex-col" style={{ gap: '6px' }}>
<label className="label-upper">Project <span style={{ opacity: 0.5 }}>(optional)</span></label>
<select
value={projectId}
onChange={e => setProjectId(e.target.value)}
style={{
width: '100%', padding: '8px 10px',
background: 'var(--bg-elevated)', border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)', color: 'var(--text-primary)',
fontSize: '13px', cursor: 'pointer', outline: 'none',
}}
>
<option value=''>No project</option>
{projects.map(p => (
<option key={p.id} value={p.id}>{p.name}</option>
))}
</select>
</div>
<div className="flex" style={{ gap: '8px', justifyContent: 'flex-end' }}>
<button className="btn-reset text-base text-muted"
onClick={onClose}
style={{ padding: '8px 14px', borderRadius: 'var(--radius-md)' }}>
Cancel
</button>
<button className="btn-primary" onClick={handleSubmit}
disabled={!name.trim()}
style={{ padding: '8px 16px' }}>
Save
</button>
</div>
</>
) : (
<>
<h2 style={{ fontSize: '15px', fontWeight: 600, color: 'var(--text-primary)' }}>
Delete Session
</h2>
<p className="text-sm text-secondary">
Are you sure you want to delete{' '}
<span style={{ color: 'var(--text-primary)', fontWeight: 500 }}>
{session.name || session.external_id}
</span>
? This will permanently remove all messages in this conversation.
</p>
<div className="flex" style={{ gap: '8px', justifyContent: 'flex-end' }}>
<button className="btn-reset text-base text-muted"
onClick={onClose}
style={{ padding: '8px 14px', borderRadius: 'var(--radius-md)' }}>
Cancel
</button>
<button className="btn-reset text-base"
onClick={() => { onDelete(session); onClose(); }}
style={{ padding: '8px 16px', borderRadius: 'var(--radius-md)', background: '#c0392b', color: 'white' }}>
Delete
</button>
</div>
</>
)}
</div>
</div>
);
}