refactor: redesign settings page with clear section grouping
5 sections organized by purpose: 1. Contenu — theme, categories, summary length 2. Sources — per-source limits, Brave Search 3. Intelligence Artificielle — provider + API keys merged in one visual card 4. Performance — batch size, history, rate limits 5. Import/Export — collapsed by default Sticky save button, smaller number inputs, integrated API key status badge in the AI provider card. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>master
parent
70865a68b3
commit
03f2660163
@ -1,139 +0,0 @@
|
|||||||
import { type Component } from 'solid-js';
|
|
||||||
import { A } from '@solidjs/router';
|
|
||||||
import { useI18n } from '~/i18n';
|
|
||||||
import type { UserSettings } from '~/types';
|
|
||||||
|
|
||||||
interface SettingsAdvancedProps {
|
|
||||||
settings: () => UserSettings;
|
|
||||||
setSettings: (updater: (prev: UserSettings) => UserSettings) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advanced settings section on the Settings page.
|
|
||||||
*
|
|
||||||
* Groups fields that control extraction and pipeline behaviour:
|
|
||||||
* - `article_history_days` — deduplication window
|
|
||||||
* - `batch_size` — number of sources processed per LLM batch
|
|
||||||
* - `search_agent_behavior` — free-text prompt injection for the search agent
|
|
||||||
*/
|
|
||||||
const SettingsAdvanced: Component<SettingsAdvancedProps> = (props) => {
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* articleHistoryDays + batchSize grid */}
|
|
||||||
<div class="grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-2">
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
for="articleHistoryDays"
|
|
||||||
class="block text-sm font-medium text-gray-700"
|
|
||||||
>
|
|
||||||
{t('settings.articleHistoryDays')}
|
|
||||||
</label>
|
|
||||||
<div class="mt-1">
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
id="articleHistoryDays"
|
|
||||||
min="0"
|
|
||||||
max="365"
|
|
||||||
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md py-2 px-3 border"
|
|
||||||
value={props.settings().article_history_days}
|
|
||||||
onInput={(e) =>
|
|
||||||
props.setSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
article_history_days:
|
|
||||||
parseInt(e.currentTarget.value) || 90,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="mt-2">
|
|
||||||
<A href="/article-history" class="text-sm text-indigo-600 hover:text-indigo-800 underline">
|
|
||||||
{t('articleHistory.viewHistory')}
|
|
||||||
</A>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
for="batchSize"
|
|
||||||
class="block text-sm font-medium text-gray-700"
|
|
||||||
>
|
|
||||||
{t('settings.batchSize')}
|
|
||||||
</label>
|
|
||||||
<p class="text-xs text-gray-500 mb-1">{t('settings.batchSizeHelp')}</p>
|
|
||||||
<div class="mt-1">
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
id="batchSize"
|
|
||||||
min="1"
|
|
||||||
max="20"
|
|
||||||
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md py-2 px-3 border"
|
|
||||||
value={props.settings().batch_size}
|
|
||||||
onInput={(e) =>
|
|
||||||
props.setSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
batch_size:
|
|
||||||
parseInt(e.currentTarget.value) || 5,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="sourceExtractionWindow" class="block text-sm font-medium text-gray-700">
|
|
||||||
{t('settings.sourceExtractionWindow')}
|
|
||||||
</label>
|
|
||||||
<p class="text-xs text-gray-500 mb-1">{t('settings.sourceExtractionWindowHelp')}</p>
|
|
||||||
<div class="mt-1">
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
id="sourceExtractionWindow"
|
|
||||||
min="1"
|
|
||||||
max="10"
|
|
||||||
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md py-2 px-3 border"
|
|
||||||
value={props.settings().source_extraction_window}
|
|
||||||
onInput={(e) =>
|
|
||||||
props.setSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
source_extraction_window: parseInt(e.currentTarget.value) || 3,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Search agent behavior */}
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
for="searchAgentBehavior"
|
|
||||||
class="block text-sm font-medium text-gray-700"
|
|
||||||
>
|
|
||||||
{t('settings.searchBehavior')}
|
|
||||||
</label>
|
|
||||||
<div class="mt-1">
|
|
||||||
<textarea
|
|
||||||
id="searchAgentBehavior"
|
|
||||||
rows={3}
|
|
||||||
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md py-2 px-3 border"
|
|
||||||
value={props.settings().search_agent_behavior}
|
|
||||||
onInput={(e) =>
|
|
||||||
props.setSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
search_agent_behavior: e.currentTarget.value,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
placeholder={t('settings.searchBehaviorPlaceholder')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p class="mt-2 text-sm text-gray-500">
|
|
||||||
{t('settings.searchBehaviorHelp')}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SettingsAdvanced;
|
|
||||||
Loading…
Reference in New Issue