feat: widgets and ai chat
This commit is contained in:
@@ -7,6 +7,12 @@ import TableOfContentsIcon from '@lucide/svelte/icons/table-of-contents';
|
||||
export type ContentItem = CourseContentItem;
|
||||
export type ContentSection = CourseContentSection;
|
||||
|
||||
export type MentionableContent = {
|
||||
id: string;
|
||||
title: string;
|
||||
type: CourseContentType;
|
||||
};
|
||||
|
||||
export const CONTENT_DEFINITIONS = {
|
||||
[CourseContentType.Section]: {
|
||||
label: 'Section',
|
||||
@@ -28,7 +34,7 @@ const EMPTY_CONTENT = {
|
||||
items: [] as ContentItem[]
|
||||
};
|
||||
|
||||
export function getContentRoute(courseId: string, item: ContentItem) {
|
||||
export function getContentRoute(courseId: string, item: { id: string; type: string }) {
|
||||
if (item.type === CourseContentType.Lesson) {
|
||||
return `/courses/${courseId}/lessons/${item.id}`;
|
||||
}
|
||||
@@ -37,6 +43,10 @@ export function getContentRoute(courseId: string, item: ContentItem) {
|
||||
return `/courses/${courseId}/exercises/${item.id}`;
|
||||
}
|
||||
|
||||
if (item.type === CourseContentType.Section) {
|
||||
return `/courses/${courseId}/lessons#section-${item.id}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -53,3 +63,33 @@ export function getOrderedNavigableContent(course: Course | null): ContentItem[]
|
||||
NAVIGABLE_CONTENT_TYPES.includes(item.type as (typeof NAVIGABLE_CONTENT_TYPES)[number])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flat list of mentionable content for the AI chat @ menu.
|
||||
* Includes sections (when grouped) interleaved with their lessons/exercises in display order.
|
||||
*/
|
||||
export function getMentionableContent(course: Course | null): MentionableContent[] {
|
||||
const content = getCourseContent(course);
|
||||
|
||||
if (!content.grouped) {
|
||||
return content.items
|
||||
.filter((item) => NAVIGABLE_CONTENT_TYPES.includes(item.type as (typeof NAVIGABLE_CONTENT_TYPES)[number]))
|
||||
.map((item) => ({ id: item.id, title: item.title, type: item.type as CourseContentType }));
|
||||
}
|
||||
|
||||
const result: MentionableContent[] = [];
|
||||
|
||||
for (const section of content.sections) {
|
||||
if (section.id !== 'ungrouped' && section.title) {
|
||||
result.push({ id: section.id, title: section.title, type: CourseContentType.Section });
|
||||
}
|
||||
|
||||
for (const item of section.items) {
|
||||
if (NAVIGABLE_CONTENT_TYPES.includes(item.type as (typeof NAVIGABLE_CONTENT_TYPES)[number])) {
|
||||
result.push({ id: item.id, title: item.title, type: item.type as CourseContentType });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user