diff --git a/frontend/src/api/syntheses.ts b/frontend/src/api/syntheses.ts index caba9f3..e8fb545 100644 --- a/frontend/src/api/syntheses.ts +++ b/frontend/src/api/syntheses.ts @@ -74,8 +74,8 @@ export const synthesesApi = { api.delete(`/syntheses/${id}`), /** POST /syntheses/generate -- kick off an async generation job, returns a job ID. */ - generate: (): Promise => - api.post('/syntheses/generate'), + generate: (themeId: string): Promise => + api.post('/syntheses/generate', { theme_id: themeId }), /** Build the SSE endpoint URL for streaming generation progress. */ progressUrl: (jobId: string): string => diff --git a/frontend/src/i18n/fr.ts b/frontend/src/i18n/fr.ts index 0ceb468..e8d1a19 100644 --- a/frontend/src/i18n/fr.ts +++ b/frontend/src/i18n/fr.ts @@ -83,6 +83,9 @@ const fr = { 'generate.model': 'Modele', 'generate.noWebSearchWarning': 'Le fournisseur selectionne ne supporte pas la recherche web. Les resultats seront bases uniquement sur les connaissances du modele.', + 'generate.selectTheme': 'Theme a generer', + 'generate.noThemes': 'Aucun theme configure. Creez un theme pour pouvoir generer une synthese.', + 'generate.createThemeLink': 'Creer un theme', // Synthesis Detail 'synthesis.title': 'Synthese de la Semaine {week}', diff --git a/frontend/src/pages/GenerateSynthesis.tsx b/frontend/src/pages/GenerateSynthesis.tsx index 7781869..7a28776 100644 --- a/frontend/src/pages/GenerateSynthesis.tsx +++ b/frontend/src/pages/GenerateSynthesis.tsx @@ -7,12 +7,13 @@ import { Show, For, } from 'solid-js'; -import { useNavigate } from '@solidjs/router'; +import { useNavigate, A } from '@solidjs/router'; import { AlertCircle, AlertTriangle, CheckCircle, Circle, Loader2 } from 'lucide-solid'; import { useI18n } from '~/i18n'; import { synthesesApi } from '~/api/syntheses'; import { settingsApi } from '~/api/settings'; import { configApi } from '~/api/config'; +import { themesApi, type ThemeResponse } from '~/api/themes'; import { isApiError, DEFAULT_SETTINGS } from '~/types'; import type { UserSettings, ProviderConfig, ProgressEvent } from '~/types'; import { createSSEConnection, type SSEConnection, type SSEStatus } from '~/utils/sse'; @@ -52,6 +53,8 @@ const GenerateSynthesis: Component = () => { const [settings, setSettings] = createSignal({ ...DEFAULT_SETTINGS }); const [providers, setProviders] = createSignal([]); + const [themes, setThemes] = createSignal([]); + const [selectedThemeId, setSelectedThemeId] = createSignal(''); const [loadingSettings, setLoadingSettings] = createSignal(true); const [generating, setGenerating] = createSignal(false); const [error, setError] = createSignal(null); @@ -60,15 +63,20 @@ const GenerateSynthesis: Component = () => { onMount(async () => { try { - const [data, providerList] = await Promise.all([ + const [data, providerList, themeList] = await Promise.all([ settingsApi.get().catch((err) => { if (isApiError(err) && err.status === 404) return null; throw err; }), configApi.listProviders().catch(() => [] as ProviderConfig[]), + themesApi.list().catch(() => [] as ThemeResponse[]), ]); if (data) setSettings(data); setProviders(providerList); + setThemes(themeList); + if (themeList.length > 0) { + setSelectedThemeId(themeList[0].id); + } } catch { // Non-404 settings error — use defaults silently } finally { @@ -210,7 +218,7 @@ const GenerateSynthesis: Component = () => { setSuccess(false); try { - const response = await synthesesApi.generate(); + const response = await synthesesApi.generate(selectedThemeId()); const url = synthesesApi.progressUrl(response.job_id); const conn = createSSEConnection(url); setSSEConnection(conn); @@ -264,6 +272,39 @@ const GenerateSynthesis: Component = () => {

+ {/* Theme selection */} + 0} + fallback={ +
+

+ {t('generate.noThemes')}{' '} + + {t('generate.createThemeLink')} + +

+
+ } + > +
+ + +
+
+ {/* No web search warning */}
@@ -382,7 +423,7 @@ const GenerateSynthesis: Component = () => {