feat: RTL/i18n, AI translate+undo, no-refresh saves, settings perf
- RTL: force dir=rtl on LabelFilter, NotesViewToggle, LabelManagementDialog - i18n: add missing keys (notifications, privacy, edit/preview, AI translate/undo) - Settings pages: convert to Server Components (general, appearance) + loading skeleton - AI menu: add Translate option (10 languages) + Undo AI button in toolbar - Fix: saveInline uses REST API instead of Server Action → eliminates all implicit refreshes in list mode - Fix: NotesTabsView notes sync effect preserves selected note on content changes - Fix: auto-tag suggestions now filter already-assigned labels - Fix: color change in card view uses local state (no refresh) - Fix: nav links use <Link> for prefetching (Settings, Admin) - Fix: suppress duplicate label suggestions already on note - Route: add /api/ai/translate endpoint
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
"reminders": "Reminders",
|
||||
"labels": "Labels",
|
||||
"editLabels": "Edit labels",
|
||||
"newNoteTabs": "New Note",
|
||||
"newNoteTabsHint": "Create note in this notebook",
|
||||
"noLabelsInNotebook": "No labels in this notebook yet",
|
||||
"archive": "Archive",
|
||||
"trash": "Trash"
|
||||
@@ -104,7 +106,7 @@
|
||||
"large": "Large",
|
||||
"shareWithCollaborators": "Share with collaborators",
|
||||
"view": "View Note",
|
||||
"edit": "Edit Note",
|
||||
"edit": "Edit",
|
||||
"readOnly": "Read Only",
|
||||
"preview": "Preview",
|
||||
"noContent": "No content",
|
||||
@@ -128,6 +130,7 @@
|
||||
"dragToReorder": "Drag to reorder",
|
||||
"more": "More options",
|
||||
"emptyState": "No notes yet. Create your first note!",
|
||||
"emptyStateTabs": "No notes here yet. Use \"New note\" in the sidebar to add one (AI title suggestions appear in the composer).",
|
||||
"inNotebook": "In notebook",
|
||||
"moveFailed": "Failed to move note. Please try again.",
|
||||
"clarifyFailed": "Failed to clarify text",
|
||||
@@ -137,7 +140,15 @@
|
||||
"markdown": "Markdown",
|
||||
"unpinned": "Unpinned",
|
||||
"redoShortcut": "Redo (Ctrl+Y)",
|
||||
"undoShortcut": "Undo (Ctrl+Z)"
|
||||
"undoShortcut": "Undo (Ctrl+Z)",
|
||||
"viewCards": "Cards View",
|
||||
"viewCardsTooltip": "Card grid with drag-and-drop reorder",
|
||||
"viewTabs": "Tabs View",
|
||||
"viewTabsTooltip": "Tabs on top, note below — drag tabs to reorder",
|
||||
"viewModeGroup": "Notes display mode",
|
||||
"reorderTabs": "Reorder tab",
|
||||
"modified": "Modified",
|
||||
"created": "Created"
|
||||
},
|
||||
"pagination": {
|
||||
"previous": "←",
|
||||
@@ -175,7 +186,8 @@
|
||||
"loading": "Loading...",
|
||||
"notebookRequired": "⚠️ Labels are only available in notebooks. Move this note to a notebook first.",
|
||||
"count": "{count} labels",
|
||||
"noLabels": "No labels"
|
||||
"noLabels": "No labels",
|
||||
"confirmDeleteShort": "Confirm?"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Search",
|
||||
@@ -290,7 +302,21 @@
|
||||
"notebookSummary": {
|
||||
"regenerate": "Regenerate Summary",
|
||||
"regenerating": "Regenerating summary..."
|
||||
}
|
||||
},
|
||||
"clarifyDesc": "Make the text clearer and easier to understand",
|
||||
"shortenDesc": "Summarize the text and get to the point",
|
||||
"improve": "Improve writing",
|
||||
"improveDesc": "Fix grammar and enhance style",
|
||||
"toMarkdown": "Format as Markdown",
|
||||
"toMarkdownDesc": "Add headings, bullet points and structure the text",
|
||||
"translate": "Translate",
|
||||
"translateDesc": "Change the text language",
|
||||
"translateBack": "Back",
|
||||
"translationApplied": "Translation applied",
|
||||
"translationFailed": "Translation failed",
|
||||
"undo": "Undo AI",
|
||||
"undoAI": "Undo AI transformation",
|
||||
"undoApplied": "Original text restored"
|
||||
},
|
||||
"titleSuggestions": {
|
||||
"available": "Title suggestions",
|
||||
@@ -397,7 +423,7 @@
|
||||
"nav": {
|
||||
"home": "Home",
|
||||
"notes": "Notes",
|
||||
"notebooks": "Notebooks",
|
||||
"notebooks": "NOTEBOOKS",
|
||||
"generalNotes": "General Notes",
|
||||
"archive": "Archive",
|
||||
"settings": "Settings",
|
||||
@@ -461,7 +487,15 @@
|
||||
"semanticIndexingDescription": "Generate vectors for all notes to enable intent-based search",
|
||||
"profile": "Profile",
|
||||
"searchNoResults": "No settings found",
|
||||
"languageAuto": "Language set to Auto"
|
||||
"languageAuto": "Language set to Auto",
|
||||
"emailNotifications": "Email notifications",
|
||||
"emailNotificationsDesc": "Receive important notifications by email",
|
||||
"desktopNotifications": "Desktop notifications",
|
||||
"desktopNotificationsDesc": "Receive notifications in your browser",
|
||||
"anonymousAnalytics": "Anonymous analytics",
|
||||
"anonymousAnalyticsDesc": "Share anonymous usage data to help improve the app",
|
||||
"notificationsDesc": "Manage your notification preferences",
|
||||
"privacyDesc": "Control your data and privacy"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profile",
|
||||
@@ -907,7 +941,11 @@
|
||||
},
|
||||
"appearance": {
|
||||
"title": "Appearance",
|
||||
"description": "Customize how the app looks"
|
||||
"description": "Customize how the app looks",
|
||||
"notesViewDescription": "Choose how notes are shown on home and in notebooks.",
|
||||
"notesViewLabel": "Notes layout",
|
||||
"notesViewTabs": "Tabs (OneNote-style)",
|
||||
"notesViewMasonry": "Cards (grid)"
|
||||
},
|
||||
"generalSettings": {
|
||||
"title": "General Settings",
|
||||
@@ -1022,5 +1060,65 @@
|
||||
"open": "Open",
|
||||
"expand": "Expand",
|
||||
"collapse": "Collapse"
|
||||
},
|
||||
"mcpSettings": {
|
||||
"title": "MCP Settings",
|
||||
"description": "Manage API keys and configure external tools",
|
||||
"whatIsMcp": {
|
||||
"title": "What is MCP?",
|
||||
"description": "The Model Context Protocol (MCP) is an open protocol that enables AI models to securely interact with external tools and data sources. With MCP, you can connect tools like Claude Code, Cursor, or N8N to your Keep Notes instance to read, create, and organize your notes programmatically.",
|
||||
"learnMore": "Learn more about MCP"
|
||||
},
|
||||
"serverStatus": {
|
||||
"title": "Server Status",
|
||||
"running": "Running",
|
||||
"stopped": "Stopped",
|
||||
"mode": "Mode",
|
||||
"url": "URL"
|
||||
},
|
||||
"apiKeys": {
|
||||
"title": "API Keys",
|
||||
"description": "API keys allow external tools to access your notes via MCP. Keep your keys secret.",
|
||||
"generate": "Generate a new key",
|
||||
"empty": "No API keys yet. Generate one to get started.",
|
||||
"active": "Active",
|
||||
"revoked": "Revoked",
|
||||
"revoke": "Revoke",
|
||||
"delete": "Delete",
|
||||
"createdAt": "Created",
|
||||
"lastUsed": "Last used",
|
||||
"never": "Never",
|
||||
"confirmRevoke": "Are you sure you want to revoke this key? Tools using it will lose access.",
|
||||
"confirmDelete": "Are you sure you want to permanently delete this key?"
|
||||
},
|
||||
"createDialog": {
|
||||
"title": "Generate API Key",
|
||||
"description": "Create a new API key to connect external tools to your notes.",
|
||||
"nameLabel": "Key name",
|
||||
"namePlaceholder": "e.g. Claude Code, Cursor, N8N",
|
||||
"generating": "Generating...",
|
||||
"generate": "Generate",
|
||||
"successTitle": "API Key Generated",
|
||||
"successDescription": "Copy your API key now. You won't be able to see it again.",
|
||||
"copy": "Copy",
|
||||
"copied": "Copied!",
|
||||
"done": "Done"
|
||||
},
|
||||
"configInstructions": {
|
||||
"title": "Configuration Instructions",
|
||||
"description": "Use your API key to configure these tools.",
|
||||
"claudeCode": {
|
||||
"title": "Claude Code",
|
||||
"description": "Add this to your Claude Code MCP configuration file:"
|
||||
},
|
||||
"cursor": {
|
||||
"title": "Cursor",
|
||||
"description": "Add this to your Cursor MCP settings:"
|
||||
},
|
||||
"n8n": {
|
||||
"title": "N8N",
|
||||
"description": "Use these credentials in your N8N MCP node:"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user