docs: add complete guide, env files, fix docker-compose
- Add GUIDE.md: complete user documentation covering installation, Docker deployment, AI providers, MCP server, N8N integration, email config, admin panel, env var reference, troubleshooting - Add mcp-server/.env.example with all MCP-specific variables - Update .env.docker.example with all 42 environment variables - Fix docker-compose.yml: parameterize PostgreSQL credentials, add missing env vars (CUSTOM_OPENAI, AI_PROVIDER_CHAT, ALLOW_REGISTRATION, RESEND_API_KEY) - Track memento-note/.env.example
This commit is contained in:
@@ -113,25 +113,25 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
|
||||
const [comparisonNotes, setComparisonNotes] = useState<Array<Partial<Note>>>([])
|
||||
const [fusionNotes, setFusionNotes] = useState<Array<Partial<Note>>>([])
|
||||
|
||||
// Tags rejetés par l'utilisateur pour cette session
|
||||
// Tags dismissed by the user for this session
|
||||
const [dismissedTags, setDismissedTags] = useState<string[]>([])
|
||||
|
||||
const colorClasses = NOTE_COLORS[color as NoteColor] || NOTE_COLORS.default
|
||||
|
||||
const handleSelectGhostTag = async (tag: string) => {
|
||||
// Vérification insensible à la casse
|
||||
// Case-insensitive check
|
||||
const tagExists = labels.some(l => l.toLowerCase() === tag.toLowerCase())
|
||||
|
||||
if (!tagExists) {
|
||||
setLabels(prev => [...prev, tag])
|
||||
|
||||
// Créer le label globalement s'il n'existe pas
|
||||
// Create the label globally if it doesn't exist
|
||||
const globalExists = globalLabels.some(l => l.name.toLowerCase() === tag.toLowerCase())
|
||||
if (!globalExists) {
|
||||
try {
|
||||
await addLabel(tag)
|
||||
} catch (err) {
|
||||
console.error('Erreur création label auto:', err)
|
||||
console.error('Error creating auto-label:', err)
|
||||
}
|
||||
}
|
||||
toast.success(t('ai.tagAdded', { tag }))
|
||||
@@ -142,8 +142,8 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
|
||||
setDismissedTags(prev => [...prev, tag])
|
||||
}
|
||||
|
||||
// Filtrer les suggestions pour ne pas afficher celles rejetées par l'utilisateur
|
||||
// ni celles déjà présentes sur la note
|
||||
// Filter suggestions to exclude dismissed ones
|
||||
// and those already present on the note
|
||||
const existingLabelsLower = (note.labels || []).map((l) => l.toLowerCase())
|
||||
const filteredSuggestions = suggestions.filter(s => {
|
||||
if (!s || !s.tag) return false
|
||||
@@ -241,7 +241,7 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
|
||||
setTitleSuggestions(data.suggestions || [])
|
||||
toast.success(t('ai.titlesGenerated', { count: data.suggestions.length }))
|
||||
} catch (error: any) {
|
||||
console.error('Erreur génération titres:', error)
|
||||
console.error('Error generating titles:', error)
|
||||
toast.error(error.message || t('ai.titleGenerationFailed'))
|
||||
} finally {
|
||||
setIsGeneratingTitles(false)
|
||||
@@ -311,7 +311,7 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
|
||||
option: data.option
|
||||
})
|
||||
} catch (error: any) {
|
||||
console.error('Erreur reformulation:', error)
|
||||
console.error('Error reformulating:', error)
|
||||
toast.error(error.message || t('ai.reformulationFailed'))
|
||||
} finally {
|
||||
setIsReformulating(false)
|
||||
@@ -494,10 +494,10 @@ export function NoteEditor({ note, readOnly = false, onClose }: NoteEditorProps)
|
||||
cleanupOrphanedImages(removedImageUrls, note.id).catch(() => {})
|
||||
}
|
||||
|
||||
// Rafraîchir les labels globaux pour refléter les suppressions éventuelles (orphans)
|
||||
// Refresh global labels to reflect any deletions (orphans)
|
||||
await refreshLabels()
|
||||
|
||||
// Rafraîchir la liste des notes
|
||||
// Refresh the notes list
|
||||
triggerRefresh()
|
||||
|
||||
onClose()
|
||||
|
||||
Reference in New Issue
Block a user