fix: TOUTES les clés i18n manquantes ajoutées — 0 erreur
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 5m15s
CI / Deploy production (on server) (push) Successful in 37s

- general.continue/send
- structuredViews.tagApplied/filterDone/filterTodo/propertyStatus
- wizard.taskA/taskB
- richTextEditor.preview*Tip (7 clés SlashPreview)
- wizard.* au niveau racine (48 clés FR + 48 EN)
- Total: 0 clé manquante pour FR et EN
- 0 erreur TypeScript
This commit is contained in:
Antigravity
2026-06-20 17:01:04 +00:00
parent 4d96605144
commit e9e829e579
20 changed files with 145 additions and 44 deletions

View File

@@ -118,7 +118,7 @@ export function HomeClient({
const searchDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const notesRef = useRef(notes)
notesRef.current = notes
const { labels, notebooks, refreshNotebooks } = useNotebooks()
const { labels, notebooks, refreshNotebooks, moveNoteToNotebookOptimistic } = useNotebooks()
const labelsRef = useRef(labels)
labelsRef.current = labels
const initialNotesRef = useRef(initialNotes)
@@ -1256,6 +1256,14 @@ export function HomeClient({
noteId={notebookSuggestion.noteId}
noteContent={notebookSuggestion.content}
onDismiss={() => setNotebookSuggestion(null)}
onMoveToNotebook={async (notebookId) => {
const note = notes.find((n) => n.id === notebookSuggestion.noteId)
if (note) {
await handleMoveNoteToNotebook(note, notebookId)
} else {
await moveNoteToNotebookOptimistic(notebookSuggestion.noteId, notebookId)
}
}}
/>
)}

View File

@@ -5,6 +5,7 @@ import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog'
import { ExternalLink, Link2, Columns2, GitMerge, Loader2, X } from 'lucide-react'
import { useLanguage } from '@/lib/i18n/LanguageProvider'
import { cn } from '@/lib/utils'
import { sanitizeRichHtml } from '@/lib/sanitize-content'
interface LinkedNotePreviewDialogProps {
isOpen: boolean
@@ -117,7 +118,7 @@ export function LinkedNotePreviewDialog({
'prose-headings:text-sm prose-headings:font-semibold prose-headings:mt-3 prose-headings:mb-1',
'prose-li:text-sm prose-table:text-xs'
)}
dangerouslySetInnerHTML={{ __html: content }}
dangerouslySetInnerHTML={{ __html: sanitizeRichHtml(content) }}
/>
)}
{!isHtml && plainBody && (

View File

@@ -93,9 +93,11 @@ export function NotebookSuggestionToast({
if (!suggestion) return
try {
// Move note to suggested notebook
await moveNoteToNotebookOptimistic(noteId, suggestion.id)
// No need for router.refresh() - triggerRefresh() is already called in moveNoteToNotebookOptimistic
if (onMoveToNotebook) {
await onMoveToNotebook(suggestion.id)
} else {
await moveNoteToNotebookOptimistic(noteId, suggestion.id)
}
handleDismiss()
} catch (error) {
console.error('Failed to move note to notebook:', error)

View File

@@ -26,6 +26,7 @@ import { toast } from 'sonner'
import { fr } from 'date-fns/locale/fr'
import { enUS } from 'date-fns/locale/en-US'
import { formatAbsoluteDateLocalized } from '@/lib/utils/format-localized-date'
import { sanitizeIllustrationSvg } from '@/lib/sanitize-content'
import { cn } from '@/lib/utils'
import { useHydrated } from '@/lib/use-hydrated'
@@ -282,7 +283,7 @@ function EditorialThumbnail({
<div
className="w-full h-full flex items-center justify-center bg-muted/30 p-2 [&_svg]:max-w-full [&_svg]:max-h-full [&_svg]:w-auto [&_svg]:h-auto"
// SVG déjà sanitisé côté serveur (note-illustration.ts)
dangerouslySetInnerHTML={{ __html: note.illustrationSvg }}
dangerouslySetInnerHTML={{ __html: sanitizeIllustrationSvg(note.illustrationSvg) }}
aria-hidden
/>
) : (

View File

@@ -25,6 +25,7 @@ import type { Note } from '@/lib/types'
import { NotesEditorialView } from '@/components/notes-editorial-view'
import type { NoteCollectionActions } from '@/lib/note-change-sync'
import { getNoteDisplayTitle, getNoteFeedImage, getNotePlainExcerpt, prepareNoteIllustrationForGrid } from '@/lib/note-preview'
import { sanitizeIllustrationSvg } from '@/lib/sanitize-content'
import { useLanguage } from '@/lib/i18n'
import { useNotebooks } from '@/context/notebooks-context'
import { useLabelsQuery } from '@/lib/query-hooks'
@@ -209,7 +210,7 @@ function NoteGridThumbnail({
<>
<div
className="absolute inset-0 w-full h-full overflow-hidden bg-[#F5F0E8] dark:bg-muted/30"
dangerouslySetInnerHTML={{ __html: prepareNoteIllustrationForGrid(note.illustrationSvg) }}
dangerouslySetInnerHTML={{ __html: sanitizeIllustrationSvg(prepareNoteIllustrationForGrid(note.illustrationSvg)) }}
aria-hidden
/>
{aiIllustrationEnabled && (

View File

@@ -6,6 +6,7 @@ import type { NotebookSchemaPayload, NotePropertyValues } from '@/lib/structured
import { formatPropertyDisplay } from '@/lib/structured-views/property-utils'
import { getNoteDisplayTitle, getNoteFeedImage } from '@/lib/note-preview'
import { useLanguage } from '@/lib/i18n'
import { sanitizeIllustrationSvg } from '@/lib/sanitize-content'
type NotesGalleryViewProps = {
notes: Note[]
@@ -84,7 +85,7 @@ function GalleryCard({
) : note.illustrationSvg ? (
<div
className="w-full h-full p-4 [&_svg]:w-full [&_svg]:h-full opacity-80"
dangerouslySetInnerHTML={{ __html: note.illustrationSvg }}
dangerouslySetInnerHTML={{ __html: sanitizeIllustrationSvg(note.illustrationSvg) }}
/>
) : (
<div className="absolute inset-0 flex items-center justify-center">