fix: scope instructor chat threads to the selected course

This commit is contained in:
2026-08-11 14:19:52 +09:00
parent 5d2c93dd40
commit 4869dbe4c1
5 changed files with 12 additions and 10 deletions
+5 -4
View File
@@ -15,6 +15,7 @@ import type { AuthSession } from '../types/auth';
type InstructorChatPanelProps = {
session: AuthSession;
courseId: string;
open: boolean;
initialThreadId?: string | null;
initialThreadRequestId?: number;
@@ -30,7 +31,7 @@ type ChatNotificationPayload = {
createdAt: string;
};
export function InstructorChatPanel({ session, open, initialThreadId = null, initialThreadRequestId = 0, onClose }: InstructorChatPanelProps) {
export function InstructorChatPanel({ session, courseId, open, initialThreadId = null, initialThreadRequestId = 0, onClose }: InstructorChatPanelProps) {
const [threads, setThreads] = useState<InstructorChatThread[]>([]);
const [selectedThreadId, setSelectedThreadId] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
@@ -45,7 +46,7 @@ export function InstructorChatPanel({ session, open, initialThreadId = null, ini
if (showLoading) setLoading(true);
setError(null);
const request = listInstructorChatThreads(session.accessToken)
const request = listInstructorChatThreads(session.accessToken, courseId)
.then((items) => {
if (!cancelled) setThreads(items);
})
@@ -91,7 +92,7 @@ export function InstructorChatPanel({ session, open, initialThreadId = null, ini
return () => {
refresh.cancel();
};
}, [open, session.accessToken]);
}, [courseId, open, session.accessToken]);
useEffect(() => {
if (!open || !initialThreadId) return;
@@ -124,7 +125,7 @@ export function InstructorChatPanel({ session, open, initialThreadId = null, ini
socket.off('chat.message.created', handleMessageCreated);
socket.disconnect();
};
}, [open, selectedThreadId, session.accessToken]);
}, [courseId, open, selectedThreadId, session.accessToken]);
useEffect(() => {
if (!open) setSelectedThreadId(null);
+1
View File
@@ -505,6 +505,7 @@ export function InstructorLayout({ session, route, onNavigate, onLogout, courses
<InstructorChatPanel
session={session}
courseId={selectedCourseId}
open={chatOpen}
initialThreadId={chatThreadId}
initialThreadRequestId={chatThreadRequestId}
+2 -1
View File
@@ -49,8 +49,9 @@ type ChatThreadsPayload = {
data?: unknown[];
};
export async function listInstructorChatThreads(accessToken: string, week?: number): Promise<InstructorChatThread[]> {
export async function listInstructorChatThreads(accessToken: string, courseId: string, week?: number): Promise<InstructorChatThread[]> {
const params = new URLSearchParams();
if (courseId) params.set('courseId', courseId);
if (week) params.set('week', String(week));
const queryString = params.toString();
+3 -4
View File
@@ -26,10 +26,6 @@ function isPlatformEnvironment(config: unknown): boolean {
return target === 'remote-jetson' || target === 'platform';
}
function environmentStorageKey(profile: Pick<CurriculumEnvironmentProfile, 'config' | 'profileType'>): 'local' | 'platform' {
return profile.profileType.toUpperCase() === 'PLATFORM' || isPlatformEnvironment(profile.config) ? 'platform' : 'local';
}
function parseModuleParameter(parameter: string): ModuleParameterDraft {
const separatorIndex = parameter.indexOf(':=');
if (separatorIndex < 0) return { key: parameter.trim(), value: '' };
@@ -1584,3 +1580,6 @@ function formatFileSize(bytes: number): string {
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
}
function environmentStorageKey(profile: Pick<CurriculumEnvironmentProfile, 'config' | 'profileType'>): 'local' | 'platform' {
return profile.profileType.toUpperCase() === 'PLATFORM' || isPlatformEnvironment(profile.config) ? 'platform' : 'local';
}
+1 -1
View File
@@ -40,7 +40,7 @@ export function DashboardPage({ session, selectedCourseId, onNavigate, onOpenCha
Promise.allSettled([
listInstructorPlatforms(session.accessToken),
listInstructorGroups(session.accessToken, selectedCourseId || null),
listInstructorChatThreads(session.accessToken),
listInstructorChatThreads(session.accessToken, selectedCourseId),
])
.then(([platformResult, groupResult, chatResult]) => {
if (cancelled) return;