Merge branch 'int' of https://github.com/valueonag/frontend_nyla into int
This commit is contained in:
commit
44d65992bf
3 changed files with 59 additions and 5 deletions
|
|
@ -83,6 +83,7 @@ export interface StartSessionRequest {
|
||||||
backgroundImageUrl?: string;
|
backgroundImageUrl?: string;
|
||||||
connectionId?: string;
|
connectionId?: string;
|
||||||
joinMode?: TeamsbotJoinMode;
|
joinMode?: TeamsbotJoinMode;
|
||||||
|
sessionContext?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfigUpdateRequest {
|
export interface ConfigUpdateRequest {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export const TeamsbotDashboardView: React.FC = () => {
|
||||||
const [meetingLink, setMeetingLink] = useState('');
|
const [meetingLink, setMeetingLink] = useState('');
|
||||||
const [botName, setBotName] = useState('');
|
const [botName, setBotName] = useState('');
|
||||||
const [joinMode, setJoinMode] = useState<TeamsbotJoinMode>('anonymous');
|
const [joinMode, setJoinMode] = useState<TeamsbotJoinMode>('anonymous');
|
||||||
|
const [sessionContext, setSessionContext] = useState('');
|
||||||
const [isStarting, setIsStarting] = useState(false);
|
const [isStarting, setIsStarting] = useState(false);
|
||||||
|
|
||||||
const _loadSessions = useCallback(async () => {
|
const _loadSessions = useCallback(async () => {
|
||||||
|
|
@ -65,6 +66,7 @@ export const TeamsbotDashboardView: React.FC = () => {
|
||||||
meetingLink: meetingLink.trim(),
|
meetingLink: meetingLink.trim(),
|
||||||
botName: botName.trim() || undefined,
|
botName: botName.trim() || undefined,
|
||||||
joinMode: joinMode,
|
joinMode: joinMode,
|
||||||
|
sessionContext: sessionContext.trim() || undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
await teamsbotApi.startSession(instanceId, request);
|
await teamsbotApi.startSession(instanceId, request);
|
||||||
|
|
@ -170,6 +172,23 @@ export const TeamsbotDashboardView: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.formGroup}>
|
||||||
|
<label className={styles.label}>Session-Kontext (optional)</label>
|
||||||
|
<textarea
|
||||||
|
className={styles.textarea || styles.input}
|
||||||
|
placeholder="Agenda, Hintergrundinformationen, Dokumente oder andere Informationen fuer den Bot..."
|
||||||
|
value={sessionContext}
|
||||||
|
onChange={(e) => setSessionContext(e.target.value)}
|
||||||
|
disabled={isStarting}
|
||||||
|
rows={4}
|
||||||
|
style={{ resize: 'vertical', minHeight: '80px' }}
|
||||||
|
/>
|
||||||
|
<span style={{ fontSize: '12px', color: '#888' }}>
|
||||||
|
Kontext den der Bot waehrend der Sitzung nutzen kann (z.B. Meeting-Agenda, Projektinfos).
|
||||||
|
{sessionContext.length > 0 && ` (${sessionContext.length} Zeichen)`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={styles.startButton}
|
className={styles.startButton}
|
||||||
onClick={_handleStartSession}
|
onClick={_handleStartSession}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export const TeamsbotSessionView: React.FC = () => {
|
||||||
const sessionId = searchParams.get('sessionId') || '';
|
const sessionId = searchParams.get('sessionId') || '';
|
||||||
|
|
||||||
const [session, setSession] = useState<TeamsbotSession | null>(null);
|
const [session, setSession] = useState<TeamsbotSession | null>(null);
|
||||||
|
const [allSessions, setAllSessions] = useState<TeamsbotSession[]>([]);
|
||||||
const [transcripts, setTranscripts] = useState<TeamsbotTranscript[]>([]);
|
const [transcripts, setTranscripts] = useState<TeamsbotTranscript[]>([]);
|
||||||
const [botResponses, setBotResponses] = useState<TeamsbotBotResponse[]>([]);
|
const [botResponses, setBotResponses] = useState<TeamsbotBotResponse[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
@ -32,19 +33,23 @@ export const TeamsbotSessionView: React.FC = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setNoSessions(false);
|
setNoSessions(false);
|
||||||
|
|
||||||
|
// Always load the full session list for the switcher
|
||||||
|
const listResult = await teamsbotApi.listSessions(instanceId, true);
|
||||||
|
const sessions = listResult.sessions || [];
|
||||||
|
setAllSessions(sessions);
|
||||||
|
|
||||||
let targetSessionId = sessionId;
|
let targetSessionId = sessionId;
|
||||||
|
|
||||||
// No sessionId in URL -> find the most recent session
|
// No sessionId in URL -> find the most recent active or latest session
|
||||||
if (!targetSessionId) {
|
if (!targetSessionId) {
|
||||||
const listResult = await teamsbotApi.listSessions(instanceId, true);
|
|
||||||
const sessions = listResult.sessions || [];
|
|
||||||
if (sessions.length === 0) {
|
if (sessions.length === 0) {
|
||||||
setNoSessions(true);
|
setNoSessions(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Pick the most recent (first in list, sorted by creation date desc)
|
// Prefer active sessions, then most recent
|
||||||
targetSessionId = sessions[0].id;
|
const activeSession = sessions.find(s => ['active', 'joining', 'pending'].includes(s.status));
|
||||||
|
targetSessionId = activeSession ? activeSession.id : sessions[0].id;
|
||||||
setSearchParams({ sessionId: targetSessionId }, { replace: true });
|
setSearchParams({ sessionId: targetSessionId }, { replace: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,8 +183,37 @@ export const TeamsbotSessionView: React.FC = () => {
|
||||||
);
|
);
|
||||||
if (!session) return <div className={styles.errorBanner}>Sitzung nicht gefunden</div>;
|
if (!session) return <div className={styles.errorBanner}>Sitzung nicht gefunden</div>;
|
||||||
|
|
||||||
|
const _switchSession = (newSessionId: string) => {
|
||||||
|
setSearchParams({ sessionId: newSessionId });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.sessionContainer}>
|
<div className={styles.sessionContainer}>
|
||||||
|
{/* Session Switcher (if multiple sessions exist) */}
|
||||||
|
{allSessions.length > 1 && (
|
||||||
|
<div style={{ display: 'flex', gap: '8px', marginBottom: '12px', flexWrap: 'wrap' }}>
|
||||||
|
{allSessions.map((s) => (
|
||||||
|
<button
|
||||||
|
key={s.id}
|
||||||
|
onClick={() => _switchSession(s.id)}
|
||||||
|
style={{
|
||||||
|
padding: '6px 12px',
|
||||||
|
borderRadius: '6px',
|
||||||
|
border: s.id === sessionId ? '2px solid #4A90D9' : '1px solid #ddd',
|
||||||
|
background: s.id === sessionId ? '#EBF3FC' : '#fff',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '13px',
|
||||||
|
fontWeight: s.id === sessionId ? 600 : 400,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{s.botName}
|
||||||
|
{['active', 'joining', 'pending'].includes(s.status) && ' (aktiv)'}
|
||||||
|
{s.status === 'ended' && ' (beendet)'}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Session Header */}
|
{/* Session Header */}
|
||||||
<div className={styles.sessionViewHeader}>
|
<div className={styles.sessionViewHeader}>
|
||||||
<div className={styles.sessionInfo}>
|
<div className={styles.sessionInfo}>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue