feat: smart note history with manual/auto modes, delete entries, i18n fixes
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m16s

- Add noteHistoryMode setting (manual default / auto) with DB migration
- Manual mode: commit button in editor toolbar creates snapshots on demand
- Auto mode: smart snapshots with 20-char diff threshold + 5min cooldown,
  structural changes (color, pin, archive, labels) bypass cooldown
- Add delete individual history entries from history modal
- Fix sidebar: Notes nav no longer active on notebook pages
- Fix sidebar icon: replace filled Lightbulb with outlined FileText
- Fix title suggestions: change from amber to sky blue color scheme
- Fix hydration mismatch: add suppressHydrationWarning on locale dates
- Complete i18n: add history, sort, and AI chat translations for all 16 languages
- Translate French AI assistant section (40+ keys) from English to French
- Update README with new features and stack info

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 21:05:55 +02:00
parent ed807d3b2a
commit 69ea064ca8
40 changed files with 2110 additions and 250 deletions

View File

@@ -24,6 +24,8 @@ interface AISettingsPanelProps {
demoMode: boolean
languageDetection: boolean
autoLabeling: boolean
noteHistory: boolean
noteHistoryMode: 'manual' | 'auto'
}
}
@@ -179,6 +181,53 @@ export function AISettingsPanel({ initialSettings }: AISettingsPanelProps) {
onChange={(checked) => handleToggle('autoLabeling', checked)}
/>
<FeatureToggle
name="Historique des notes"
description="Active les snapshots de versions et la restauration depuis History"
checked={settings.noteHistory ?? false}
onChange={(checked) => handleToggle('noteHistory', checked)}
/>
{settings.noteHistory && (
<div className="space-y-2 rounded-lg border border-border/50 bg-muted/30 p-3">
<p className="text-sm font-medium">{t('notes.historyMode') || 'Mode d\'historique'}</p>
<RadioGroup
value={settings.noteHistoryMode ?? 'manual'}
onValueChange={(value) => {
const mode = value as 'manual' | 'auto'
setSettings((s) => ({ ...s, noteHistoryMode: mode }))
updateAISettings({ noteHistoryMode: mode }).then(() => {
toast.success(t('settings.settingsSaved') || 'Saved')
})
}}
className="space-y-2"
>
<div className="flex items-start gap-2">
<RadioGroupItem value="manual" id="history-manual" />
<div className="grid gap-0.5 leading-none">
<Label htmlFor="history-manual" className="text-sm font-medium">
{t('notes.historyModeManual') || 'Manuel'}
</Label>
<p className="text-xs text-muted-foreground">
{t('notes.historyModeManualDesc') || 'Créer des snapshots avec le bouton commit'}
</p>
</div>
</div>
<div className="flex items-start gap-2">
<RadioGroupItem value="auto" id="history-auto" />
<div className="grid gap-0.5 leading-none">
<Label htmlFor="history-auto" className="text-sm font-medium">
{t('notes.historyModeAuto') || 'Automatique'}
</Label>
<p className="text-xs text-muted-foreground">
{t('notes.historyModeAutoDesc') || 'Snapshots automatiques avec détection intelligente'}
</p>
</div>
</div>
</RadioGroup>
</div>
)}
{/* Demo Mode Toggle */}
<DemoModeToggle
demoMode={settings.demoMode}