Compare commits

..

37 Commits

Author SHA1 Message Date
Philip Okugbe 696aa430f4 New translations translation.json (Portuguese, Brazilian)
[ci skip]
2026-05-04 23:55:59 +01:00
Philip Okugbe ed9d85ca95 New translations translation.json (English)
[ci skip]
2026-05-04 23:55:58 +01:00
Philip Okugbe d992abf8d8 New translations translation.json (Chinese Simplified)
[ci skip]
2026-05-04 23:55:57 +01:00
Philip Okugbe 149bcc14f1 New translations translation.json (Ukrainian)
[ci skip]
2026-05-04 23:55:55 +01:00
Philip Okugbe 8ed4f4b7aa New translations translation.json (Russian)
[ci skip]
2026-05-04 23:55:54 +01:00
Philip Okugbe fd0200331c New translations translation.json (Dutch)
[ci skip]
2026-05-04 23:55:53 +01:00
Philip Okugbe 44ab6e5485 New translations translation.json (Korean)
[ci skip]
2026-05-04 23:55:51 +01:00
Philip Okugbe 505d7923db New translations translation.json (Japanese)
[ci skip]
2026-05-04 23:55:50 +01:00
Philip Okugbe 3112709d03 New translations translation.json (Italian)
[ci skip]
2026-05-04 23:55:48 +01:00
Philip Okugbe 8c9d0389f4 New translations translation.json (Spanish)
[ci skip]
2026-05-04 23:55:47 +01:00
Philip Okugbe afafc8451f New translations translation.json (French)
[ci skip]
2026-05-04 23:55:46 +01:00
Philip Okugbe 0a4bbd5d30 New translations translation.json (German)
[ci skip]
2026-05-04 23:55:44 +01:00
Philip Okugbe c802222562 New translations translation.json (Portuguese, Brazilian)
[ci skip]
2026-05-04 22:16:52 +01:00
Philip Okugbe be2d93877a New translations translation.json (English)
[ci skip]
2026-05-04 22:16:50 +01:00
Philip Okugbe 34da8d3fb4 New translations translation.json (Chinese Simplified)
[ci skip]
2026-05-04 22:16:49 +01:00
Philip Okugbe f55bd21b08 New translations translation.json (Ukrainian)
[ci skip]
2026-05-04 22:16:47 +01:00
Philip Okugbe f6f9cc14df New translations translation.json (Russian)
[ci skip]
2026-05-04 22:16:45 +01:00
Philip Okugbe 1790ee8f6f New translations translation.json (Dutch)
[ci skip]
2026-05-04 22:16:44 +01:00
Philip Okugbe 58840da7f4 New translations translation.json (Korean)
[ci skip]
2026-05-04 22:16:43 +01:00
Philip Okugbe db77b31782 New translations translation.json (Japanese)
[ci skip]
2026-05-04 22:16:41 +01:00
Philip Okugbe 77ba4facb1 New translations translation.json (Italian)
[ci skip]
2026-05-04 22:16:40 +01:00
Philip Okugbe 6fa08e487e New translations translation.json (Spanish)
[ci skip]
2026-05-04 22:16:38 +01:00
Philip Okugbe 979e8faeee New translations translation.json (French)
[ci skip]
2026-05-04 22:16:37 +01:00
Philip Okugbe 1839418430 New translations translation.json (German)
[ci skip]
2026-05-04 22:16:35 +01:00
Philip Okugbe 94461e90a3 New translations translation.json (Portuguese, Brazilian)
[ci skip]
2026-05-01 16:02:26 +01:00
Philip Okugbe 58aa02340e New translations translation.json (English)
[ci skip]
2026-05-01 16:02:24 +01:00
Philip Okugbe 592e6a39e8 New translations translation.json (Chinese Simplified)
[ci skip]
2026-05-01 16:02:23 +01:00
Philip Okugbe 56526c6c1c New translations translation.json (Ukrainian)
[ci skip]
2026-05-01 16:02:21 +01:00
Philip Okugbe 6f9387b8b4 New translations translation.json (Russian)
[ci skip]
2026-05-01 16:02:20 +01:00
Philip Okugbe aa2ca3ef91 New translations translation.json (Dutch)
[ci skip]
2026-05-01 16:02:18 +01:00
Philip Okugbe 21848b91bf New translations translation.json (Korean)
[ci skip]
2026-05-01 16:02:17 +01:00
Philip Okugbe 989231d818 New translations translation.json (Japanese)
[ci skip]
2026-05-01 16:02:15 +01:00
Philip Okugbe d50986453b New translations translation.json (Italian)
[ci skip]
2026-05-01 16:02:14 +01:00
Philip Okugbe 2c21af4e91 New translations translation.json (Spanish)
[ci skip]
2026-05-01 16:02:12 +01:00
Philip Okugbe 574f687335 New translations translation.json (French)
[ci skip]
2026-05-01 16:02:10 +01:00
Philip Okugbe 9956a98d1f New translations translation.json (German)
[ci skip]
2026-05-01 16:02:08 +01:00
Philip Okugbe 14fd3eb956 New translations translation.json (German)
[ci skip]
2026-05-01 00:49:11 +01:00
34 changed files with 1786 additions and 1314 deletions
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "client",
"private": true,
"version": "0.80.1",
"version": "0.80.0",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
@@ -31,8 +31,8 @@
"emoji-mart": "^5.6.0",
"file-saver": "^2.0.5",
"highlightjs-sap-abap": "^0.3.0",
"i18next": "25.10.1",
"i18next-http-backend": "3.0.6",
"i18next": "^25.10.1",
"i18next-http-backend": "^3.0.2",
"jotai": "^2.18.1",
"jotai-optics": "^0.4.0",
"js-cookie": "^3.0.5",
@@ -42,7 +42,7 @@
"mantine-form-zod-resolver": "^1.3.0",
"mermaid": "^11.13.0",
"mitt": "^3.0.1",
"posthog-js": "1.372.2",
"posthog-js": "1.363.1",
"react": "^18.3.1",
"react-arborist": "3.4.0",
"react-clear-modal": "^2.0.18",
@@ -50,7 +50,7 @@
"react-drawio": "^1.0.7",
"react-error-boundary": "^6.1.1",
"react-helmet-async": "^3.0.0",
"react-i18next": "16.5.8",
"react-i18next": "^16.5.8",
"react-router-dom": "^7.13.1",
"semver": "^7.7.4",
"socket.io-client": "^4.8.3",
@@ -74,7 +74,7 @@
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^15.13.0",
"optics-ts": "^2.4.1",
"postcss": "^8.5.12",
"postcss": "^8.5.8",
"postcss-preset-mantine": "^1.18.0",
"postcss-simple-vars": "^7.0.1",
"prettier": "^3.8.1",
@@ -391,7 +391,7 @@
"Write anything. Enter \"/\" for commands": "Schreiben Sie etwas. Geben Sie \"/\" für Befehle ein",
"Write...": "\"Schreiben...\"",
"Column count": "Spaltenanzahl",
"{{count}} Columns": "{count, plural, one {# Spalte} other {# Spalten}}",
"{{count}} Columns": "{{count}} Spalten",
"Equal columns": "Gleich breite Spalten",
"Left sidebar": "Linke Seitenleiste",
"Right sidebar": "Rechte Seitenleiste",
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} ist verfügbar",
"Default page edit mode": "Standard-Bearbeitungsmodus für Seiten",
"Choose your preferred page edit mode. Avoid accidental edits.": "Wählen Sie Ihren bevorzugten Seitenbearbeitungsmodus. Vermeiden Sie versehentliche Bearbeitungen.",
"Choose {{format}} file": "{{format}}-Datei auswählen",
"Reading": "Lesen",
"Delete member": "Mitglied löschen",
"Member deleted successfully": "Mitglied erfolgreich gelöscht",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "Bild überschreitet das Limit von 10 MB.",
"Image removed successfully": "Bild erfolgreich entfernt",
"API key": "API-Schlüssel",
"API key created successfully": "API-Schlüssel erfolgreich erstellt",
"API keys": "API-Schlüssel",
"API management": "API-Verwaltung",
"Are you sure you want to revoke this API key": "Sind Sie sicher, dass Sie diesen API-Schlüssel widerrufen möchten?",
"Create API Key": "API-Schlüssel erstellen",
"Custom expiration date": "Benutzerdefiniertes Ablaufdatum",
"Enter a descriptive token name": "Geben Sie einen beschreibenden Token-Namen ein",
"Expiration": "Ablauf",
"Expired": "Abgelaufen",
"Expires": "Läuft ab",
"I've saved my API key": "Ich habe meinen API-Schlüssel gespeichert",
"Last use": "Zuletzt verwendet",
"No API keys found": "Keine API-Schlüssel gefunden",
"No expiration": "Kein Ablauf",
"Revoke API key": "API-Schlüssel widerrufen",
"Revoked successfully": "Erfolgreich widerrufen",
"Select expiration date": "Ablaufdatum wählen",
"This action cannot be undone. Any applications using this API key will stop working.": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Anwendungen, die diesen API-Schlüssel verwenden, werden nicht mehr funktionieren.",
"Update API key": "API-Schlüssel aktualisieren",
"Update": "Aktualisieren",
"Update {{credential}}": "{{credential}} aktualisieren",
"Manage API keys for all users in the workspace": "Verwalten Sie API-Schlüssel für alle Benutzer im Arbeitsbereich",
"Restrict API key creation to admins": "API-Schlüsselerstellung auf Administratoren beschränken",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Nur Administratoren und Eigentümer können neue API-Schlüssel erstellen. Bestehende Mitgliederschlüssel funktionieren weiterhin.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Letzte 7 Tage",
"Previous 30 days": "Letzte 30 Tage",
"Search chats...": "Chats durchsuchen...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Starten Sie einen neuen Chat, damit er hier angezeigt wird.",
"Summarize this page": "Diese Seite zusammenfassen",
"Toggle AI Chat": "KI-Chat umschalten",
@@ -880,5 +879,54 @@
"Try a different search term.": "Versuchen Sie einen anderen Suchbegriff.",
"Try again": "Erneut versuchen",
"Untitled chat": "Chat ohne Titel",
"What can I help you with?": "Womit kann ich Ihnen helfen?"
"What can I help you with?": "Womit kann ich Ihnen helfen?",
"Are you sure you want to revoke this {{credential}}": "Sind Sie sicher, dass Sie diese(n) {{credential}} widerrufen möchten?",
"Automatically provision users and groups from your identity provider via SCIM.": "Stellen Sie Benutzer und Gruppen automatisch über SCIM von Ihrem Identitätsanbieter bereit.",
"Configure your identity provider with this URL to provision users and groups.": "Konfigurieren Sie Ihren Identitätsanbieter mit dieser URL, um Benutzer und Gruppen bereitzustellen.",
"Create {{credential}}": "{{credential}} erstellen",
"{{credential}} created": "{{credential}} erstellt",
"{{credential}} created successfully": "{{credential}} erfolgreich erstellt",
"Created by": "Erstellt von",
"Custom": "Benutzerdefiniert",
"Enable SCIM": "SCIM aktivieren",
"Enter a descriptive name": "Geben Sie einen beschreibenden Namen ein",
"I've saved my {{credential}}": "Ich habe meine(n) {{credential}} gespeichert",
"Important": "Wichtig",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Stellen Sie sicher, dass Sie Ihre(n) {{credential}} jetzt kopieren. Sie können sie/ihn später nicht erneut anzeigen!",
"Never": "Nie",
"Revoke {{credential}}": "{{credential}} widerrufen",
"SCIM endpoint URL": "SCIM-Endpunkt-URL",
"SCIM provisioning": "SCIM-Bereitstellung",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM hat Vorrang vor der SSO-Gruppensynchronisierung, solange es aktiviert ist.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Sie haben die maximale Anzahl von {{max}} SCIM-Token erreicht. Löschen Sie ein vorhandenes Token, um ein neues zu erstellen.",
"SCIM token": "SCIM-Token",
"SCIM tokens": "SCIM-Token",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Diese Aktion kann nicht rückgängig gemacht werden. Ihr Identitätsanbieter wird die Synchronisierung sofort beenden.",
"Toggle SCIM provisioning": "SCIM-Bereitstellung umschalten",
"Token": "Token",
"Page menu": "Seitenmenü",
"Expand": "Erweitern",
"Collapse": "Reduzieren",
"Comment menu": "Kommentarmenü",
"Group menu": "Gruppenmenü",
"Show hidden breadcrumbs": "Ausgeblendete Breadcrumbs anzeigen",
"Breadcrumbs": "Navigationspfade",
"Page actions": "Seitenaktionen",
"Pick emoji": "Emoji auswählen",
"Template menu": "Vorlagenmenü",
"Chat menu": "Chatmenü",
"API key menu": "API-Schlüssel-Menü",
"Jump to comment selection": "Zur Kommentarauswahl springen",
"Slash commands": "Slash-Befehle",
"Mention suggestions": "Erwähnungsvorschläge",
"Link suggestions": "Linkvorschläge",
"Diagram editor": "Diagrammeditor",
"Add comment": "Kommentar hinzufügen",
"Find and replace": "Suchen und ersetzen",
"Main navigation": "Hauptnavigation",
"Space navigation": "Bereichsnavigation",
"Settings navigation": "Einstellungsnavigation",
"AI navigation": "KI-Navigation",
"Breadcrumb": "Navigationspfad",
"Skip to main content": "Zum Hauptinhalt springen"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} is available",
"Default page edit mode": "Default page edit mode",
"Choose your preferred page edit mode. Avoid accidental edits.": "Choose your preferred page edit mode. Avoid accidental edits.",
"Choose {{format}} file": "Choose {{format}} file",
"Reading": "Reading",
"Delete member": "Delete member",
"Member deleted successfully": "Member deleted successfully",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "Image exceeds 10MB limit.",
"Image removed successfully": "Image removed successfully",
"API key": "API key",
"API key created successfully": "API key created successfully",
"API keys": "API keys",
"API management": "API management",
"Are you sure you want to revoke this API key": "Are you sure you want to revoke this API key",
"Create API Key": "Create API Key",
"Custom expiration date": "Custom expiration date",
"Enter a descriptive token name": "Enter a descriptive token name",
"Expiration": "Expiration",
"Expired": "Expired",
"Expires": "Expires",
"I've saved my API key": "I've saved my API key",
"Last use": "Last Used",
"No API keys found": "No API keys found",
"No expiration": "No expiration",
"Revoke API key": "Revoke API key",
"Revoked successfully": "Revoked successfully",
"Select expiration date": "Select expiration date",
"This action cannot be undone. Any applications using this API key will stop working.": "This action cannot be undone. Any applications using this API key will stop working.",
"Update API key": "Update API key",
"Update": "Update",
"Update {{credential}}": "Update {{credential}}",
"Manage API keys for all users in the workspace": "Manage API keys for all users in the workspace",
"Restrict API key creation to admins": "Restrict API key creation to admins",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Only admins and owners can create new API keys. Existing member keys will continue to work.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Previous 7 days",
"Previous 30 days": "Previous 30 days",
"Search chats...": "Search chats...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Start a new chat to see it here.",
"Summarize this page": "Summarize this page",
"Toggle AI Chat": "Toggle AI Chat",
@@ -880,5 +879,54 @@
"Try a different search term.": "Try a different search term.",
"Try again": "Try again",
"Untitled chat": "Untitled chat",
"What can I help you with?": "What can I help you with?"
"What can I help you with?": "What can I help you with?",
"Are you sure you want to revoke this {{credential}}": "Are you sure you want to revoke this {{credential}}",
"Automatically provision users and groups from your identity provider via SCIM.": "Automatically provision users and groups from your identity provider via SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Configure your identity provider with this URL to provision users and groups.",
"Create {{credential}}": "Create {{credential}}",
"{{credential}} created": "{{credential}} created",
"{{credential}} created successfully": "{{credential}} created successfully",
"Created by": "Created by",
"Custom": "Custom",
"Enable SCIM": "Enable SCIM",
"Enter a descriptive name": "Enter a descriptive name",
"I've saved my {{credential}}": "I've saved my {{credential}}",
"Important": "Important",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Make sure to copy your {{credential}} now. You won't be able to see it again!",
"Never": "Never",
"Revoke {{credential}}": "Revoke {{credential}}",
"SCIM endpoint URL": "SCIM endpoint URL",
"SCIM provisioning": "SCIM provisioning",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM takes precedence over SSO group sync while enabled.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.",
"SCIM token": "SCIM token",
"SCIM tokens": "SCIM tokens",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "This action cannot be undone. Your identity provider will stop syncing immediately.",
"Toggle SCIM provisioning": "Toggle SCIM provisioning",
"Token": "Token",
"Page menu": "Page menu",
"Expand": "Expand",
"Collapse": "Collapse",
"Comment menu": "Comment menu",
"Group menu": "Group menu",
"Show hidden breadcrumbs": "Show hidden breadcrumbs",
"Breadcrumbs": "Breadcrumbs",
"Page actions": "Page actions",
"Pick emoji": "Pick emoji",
"Template menu": "Template menu",
"Chat menu": "Chat menu",
"API key menu": "API key menu",
"Jump to comment selection": "Jump to comment selection",
"Slash commands": "Slash commands",
"Mention suggestions": "Mention suggestions",
"Link suggestions": "Link suggestions",
"Diagram editor": "Diagram editor",
"Add comment": "Add comment",
"Find and replace": "Find and replace",
"Main navigation": "Main navigation",
"Space navigation": "Space navigation",
"Settings navigation": "Settings navigation",
"AI navigation": "AI navigation",
"Breadcrumb": "Breadcrumb",
"Skip to main content": "Skip to main content"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} está disponible",
"Default page edit mode": "Modo de edición predeterminado de la página",
"Choose your preferred page edit mode. Avoid accidental edits.": "Elige tu modo de edición de página preferido. Evita ediciones accidentales.",
"Choose {{format}} file": "Elegir archivo {{format}}",
"Reading": "Lectura",
"Delete member": "Eliminar miembro",
"Member deleted successfully": "Miembro eliminado correctamente",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "La imagen excede del límite de 10 MB",
"Image removed successfully": "Imagen eliminada correctamente",
"API key": "Clave API",
"API key created successfully": "Clave API creada correctamente",
"API keys": "Claves API",
"API management": "Gestión de API",
"Are you sure you want to revoke this API key": "¿Está seguro de que desea revocar esta clave API? ",
"Create API Key": "Crear clave API",
"Custom expiration date": "Fecha de vencimiento personalizada",
"Enter a descriptive token name": "Introduce un nombre descriptivo del token",
"Expiration": "Vencimiento",
"Expired": "Vencido",
"Expires": "Vence",
"I've saved my API key": "He guardado mi clave API",
"Last use": "Último uso",
"No API keys found": "No se han encontrado claves API",
"No expiration": "Sin vencimiento",
"Revoke API key": "Revocar clave API",
"Revoked successfully": "Revocada correctamente",
"Select expiration date": "Seleccionar fecha de vencimiento",
"This action cannot be undone. Any applications using this API key will stop working.": "Esta acción no se puede deshacer. Las aplicaciones que utilicen esta clave API dejarán de funcionar.",
"Update API key": "Actualizar clave API",
"Update": "Actualizar",
"Update {{credential}}": "Actualizar {{credential}}",
"Manage API keys for all users in the workspace": "Gestionar claves API para todos los usuarios en el espacio de trabajo",
"Restrict API key creation to admins": "Restringir la creación de claves API a administradores",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Solo los administradores y propietarios pueden crear nuevas claves API. Las claves de miembros existentes seguirán funcionando.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Últimos 7 días",
"Previous 30 days": "Últimos 30 días",
"Search chats...": "Buscar chats...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Inicia un nuevo chat para verlo aquí.",
"Summarize this page": "Resumir esta página",
"Toggle AI Chat": "Alternar chat de IA",
@@ -880,5 +879,54 @@
"Try a different search term.": "Prueba con otro término de búsqueda.",
"Try again": "Intentar de nuevo",
"Untitled chat": "Chat sin título",
"What can I help you with?": "¿En qué puedo ayudarte?"
"What can I help you with?": "¿En qué puedo ayudarte?",
"Are you sure you want to revoke this {{credential}}": "¿Está seguro de que desea revocar esta {{credential}}?",
"Automatically provision users and groups from your identity provider via SCIM.": "Aprovisione automáticamente usuarios y grupos desde su proveedor de identidad mediante SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Configure su proveedor de identidad con esta URL para aprovisionar usuarios y grupos.",
"Create {{credential}}": "Crear {{credential}}",
"{{credential}} created": "{{credential}} creada",
"{{credential}} created successfully": "{{credential}} creada con éxito",
"Created by": "Creado por",
"Custom": "Personalizado",
"Enable SCIM": "Habilitar SCIM",
"Enter a descriptive name": "Introduzca un nombre descriptivo",
"I've saved my {{credential}}": "He guardado mi {{credential}}",
"Important": "Importante",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Asegúrese de copiar su {{credential}} ahora. ¡No podrá volver a verla!",
"Never": "Nunca",
"Revoke {{credential}}": "Revocar {{credential}}",
"SCIM endpoint URL": "URL del endpoint de SCIM",
"SCIM provisioning": "Aprovisionamiento SCIM",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM tiene prioridad sobre la sincronización de grupos de SSO mientras esté habilitado.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Ha alcanzado el máximo de {{max}} tokens SCIM. Elimine un token existente para crear uno nuevo.",
"SCIM token": "Token SCIM",
"SCIM tokens": "Tokens SCIM",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Esta acción no se puede deshacer. Su proveedor de identidad dejará de sincronizarse inmediatamente.",
"Toggle SCIM provisioning": "Activar o desactivar el aprovisionamiento SCIM",
"Token": "Token",
"Page menu": "Menú de la página",
"Expand": "Expandir",
"Collapse": "Contraer",
"Comment menu": "Menú de comentarios",
"Group menu": "Menú del grupo",
"Show hidden breadcrumbs": "Mostrar rutas de navegación ocultas",
"Breadcrumbs": "Rutas de navegación",
"Page actions": "Acciones de la página",
"Pick emoji": "Elegir emoji",
"Template menu": "Menú de plantillas",
"Chat menu": "Menú del chat",
"API key menu": "Menú de la clave API",
"Jump to comment selection": "Ir a la selección de comentarios",
"Slash commands": "Comandos de barra",
"Mention suggestions": "Sugerencias de menciones",
"Link suggestions": "Sugerencias de enlaces",
"Diagram editor": "Editor de diagramas",
"Add comment": "Agregar comentario",
"Find and replace": "Buscar y reemplazar",
"Main navigation": "Navegación principal",
"Space navigation": "Navegación del espacio",
"Settings navigation": "Navegación de configuración",
"AI navigation": "Navegación de IA",
"Breadcrumb": "Ruta de navegación",
"Skip to main content": "Saltar al contenido principal"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} est disponible",
"Default page edit mode": "Mode d’édition par défaut de la page",
"Choose your preferred page edit mode. Avoid accidental edits.": "Choisissez votre mode d'édition de page préféré. Évitez les modifications accidentelles.",
"Choose {{format}} file": "Choisir un fichier {{format}}",
"Reading": "Lecture",
"Delete member": "Supprimer le membre",
"Member deleted successfully": "Membre supprimé avec succès",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "L'image dépasse la limite de 10 Mo.",
"Image removed successfully": "Image supprimée avec succès",
"API key": "Clé API",
"API key created successfully": "Clé API créée avec succès",
"API keys": "Clés API",
"API management": "Gestion des API",
"Are you sure you want to revoke this API key": "Êtes-vous sûr de vouloir révoquer cette clé API",
"Create API Key": "Créer une clé API",
"Custom expiration date": "Date d'expiration personnalisée",
"Enter a descriptive token name": "Entrez un nom descriptif pour le jeton",
"Expiration": "Expiration",
"Expired": "Expiré(e)",
"Expires": "Expire",
"I've saved my API key": "J'ai enregistré ma clé API",
"Last use": "Dernière utilisation",
"No API keys found": "Aucune clé API trouvée",
"No expiration": "Pas d'expiration",
"Revoke API key": "Révoquer la clé API",
"Revoked successfully": "Révoqué(e) avec succès",
"Select expiration date": "Sélectionnez la date d'expiration",
"This action cannot be undone. Any applications using this API key will stop working.": "Cette action ne peut pas être annulée. Toutes les applications utilisant cette clé API cesseront de fonctionner.",
"Update API key": "Mettre à jour la clé API",
"Update": "Mettre à jour",
"Update {{credential}}": "Mettre à jour {{credential}}",
"Manage API keys for all users in the workspace": "Gérer les clés API pour tous les utilisateurs dans l'espace de travail",
"Restrict API key creation to admins": "Restreindre la création de clés API aux administrateurs",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Seuls les administrateurs et les propriétaires peuvent créer de nouvelles clés API. Les clés des membres existants continueront de fonctionner.",
@@ -873,6 +870,8 @@
"Previous 7 days": "7 derniers jours",
"Previous 30 days": "30 derniers jours",
"Search chats...": "Rechercher des discussions...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Commencez une nouvelle discussion pour la voir ici.",
"Summarize this page": "Résumer cette page",
"Toggle AI Chat": "Basculer le chat IA",
@@ -880,5 +879,54 @@
"Try a different search term.": "Essayez un autre terme de recherche.",
"Try again": "Réessayer",
"Untitled chat": "Discussion sans titre",
"What can I help you with?": "Que puis-je faire pour vous aider ?"
"What can I help you with?": "Que puis-je faire pour vous aider ?",
"Are you sure you want to revoke this {{credential}}": "Êtes-vous sûr de vouloir révoquer ce/cette {{credential}}",
"Automatically provision users and groups from your identity provider via SCIM.": "Provisionnez automatiquement les utilisateurs et les groupes depuis votre fournisseur didentité via SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Configurez votre fournisseur didentité avec cette URL pour provisionner les utilisateurs et les groupes.",
"Create {{credential}}": "Créer {{credential}}",
"{{credential}} created": "{{credential}} créé",
"{{credential}} created successfully": "{{credential}} créé avec succès",
"Created by": "Créé par",
"Custom": "Personnalisé",
"Enable SCIM": "Activer SCIM",
"Enter a descriptive name": "Saisissez un nom descriptif",
"I've saved my {{credential}}": "Jai enregistré mon/ma {{credential}}",
"Important": "Important",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Assurez-vous de copier votre {{credential}} maintenant. Vous ne pourrez plus le/la voir ensuite !",
"Never": "Jamais",
"Revoke {{credential}}": "Révoquer {{credential}}",
"SCIM endpoint URL": "URL du point de terminaison SCIM",
"SCIM provisioning": "Provisionnement SCIM",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM a priorité sur la synchronisation des groupes SSO lorsquil est activé.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Vous avez atteint le maximum de {{max}} jetons SCIM. Supprimez un jeton existant pour en créer un nouveau.",
"SCIM token": "Jeton SCIM",
"SCIM tokens": "Jetons SCIM",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Cette action est irréversible. Votre fournisseur didentité cessera immédiatement la synchronisation.",
"Toggle SCIM provisioning": "Activer/désactiver le provisionnement SCIM",
"Token": "Jeton",
"Page menu": "Menu de la page",
"Expand": "Développer",
"Collapse": "Réduire",
"Comment menu": "Menu du commentaire",
"Group menu": "Menu du groupe",
"Show hidden breadcrumbs": "Afficher les fils dAriane masqués",
"Breadcrumbs": "Fils dAriane",
"Page actions": "Actions de la page",
"Pick emoji": "Choisir un emoji",
"Template menu": "Menu du modèle",
"Chat menu": "Menu du chat",
"API key menu": "Menu de la clé API",
"Jump to comment selection": "Aller à la sélection de commentaires",
"Slash commands": "Commandes slash",
"Mention suggestions": "Suggestions de mention",
"Link suggestions": "Suggestions de liens",
"Diagram editor": "Éditeur de diagrammes",
"Add comment": "Ajouter un commentaire",
"Find and replace": "Rechercher et remplacer",
"Main navigation": "Navigation principale",
"Space navigation": "Navigation de lespace",
"Settings navigation": "Navigation des paramètres",
"AI navigation": "Navigation IA",
"Breadcrumb": "Fil dAriane",
"Skip to main content": "Aller au contenu principal"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} è disponibile",
"Default page edit mode": "Modalità di modifica predefinita della pagina",
"Choose your preferred page edit mode. Avoid accidental edits.": "Scegli la tua modalità di modifica della pagina preferita. Evita modifiche accidentali.",
"Choose {{format}} file": "Scegli file {{format}}",
"Reading": "Lettura",
"Delete member": "Elimina membro",
"Member deleted successfully": "Membro eliminato con successo",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "L'immagine supera il limite di 10MB.",
"Image removed successfully": "Immagine rimossa con successo",
"API key": "Chiave API",
"API key created successfully": "Chiave API creata con successo",
"API keys": "Chiavi API",
"API management": "Gestione API",
"Are you sure you want to revoke this API key": "Sei sicuro di voler revocare questa chiave API",
"Create API Key": "Crea Chiave API",
"Custom expiration date": "Data di scadenza personalizzata",
"Enter a descriptive token name": "Inserisci un nome descrittivo del token",
"Expiration": "Scadenza",
"Expired": "Scaduto",
"Expires": "Scade",
"I've saved my API key": "Ho salvato la mia chiave API",
"Last use": "Ultimo utilizzo",
"No API keys found": "Nessuna chiave API trovata",
"No expiration": "Nessuna scadenza",
"Revoke API key": "Revoca chiave API",
"Revoked successfully": "Revocata con successo",
"Select expiration date": "Seleziona la data di scadenza",
"This action cannot be undone. Any applications using this API key will stop working.": "Questa azione non può essere annullata. Qualsiasi applicazione che utilizza questa chiave API smetterà di funzionare.",
"Update API key": "Aggiorna chiave API",
"Update": "Aggiorna",
"Update {{credential}}": "Aggiorna {{credential}}",
"Manage API keys for all users in the workspace": "Gestisci le chiavi API per tutti gli utenti nell'area di lavoro",
"Restrict API key creation to admins": "Limita la creazione delle chiavi API agli amministratori",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Solo gli amministratori e i proprietari possono creare nuove chiavi API. Le chiavi dei membri esistenti continueranno a funzionare.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Ultimi 7 giorni",
"Previous 30 days": "Ultimi 30 giorni",
"Search chats...": "Cerca nelle chat...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Avvia una nuova chat per vederla qui.",
"Summarize this page": "Riassumi questa pagina",
"Toggle AI Chat": "Attiva/disattiva Chat IA",
@@ -880,5 +879,54 @@
"Try a different search term.": "Prova un termine di ricerca diverso.",
"Try again": "Riprova",
"Untitled chat": "Chat senza titolo",
"What can I help you with?": "Con cosa posso aiutarti?"
"What can I help you with?": "Con cosa posso aiutarti?",
"Are you sure you want to revoke this {{credential}}": "Sei sicuro di voler revocare questa {{credential}}",
"Automatically provision users and groups from your identity provider via SCIM.": "Esegui automaticamente il provisioning di utenti e gruppi dal tuo provider di identità tramite SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Configura il tuo provider di identità con questo URL per eseguire il provisioning di utenti e gruppi.",
"Create {{credential}}": "Crea {{credential}}",
"{{credential}} created": "{{credential}} creata",
"{{credential}} created successfully": "{{credential}} creata con successo",
"Created by": "Creata da",
"Custom": "Personalizzato",
"Enable SCIM": "Abilita SCIM",
"Enter a descriptive name": "Inserisci un nome descrittivo",
"I've saved my {{credential}}": "Ho salvato la mia {{credential}}",
"Important": "Importante",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Assicurati di copiare subito la tua {{credential}}. Non potrai più visualizzarla!",
"Never": "Mai",
"Revoke {{credential}}": "Revoca {{credential}}",
"SCIM endpoint URL": "URL dell'endpoint SCIM",
"SCIM provisioning": "Provisioning SCIM",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM ha la precedenza sulla sincronizzazione dei gruppi SSO quando è abilitato.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Hai raggiunto il numero massimo di {{max}} token SCIM. Elimina un token esistente per crearne uno nuovo.",
"SCIM token": "Token SCIM",
"SCIM tokens": "Token SCIM",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Questa azione non può essere annullata. Il tuo provider di identità smetterà di sincronizzarsi immediatamente.",
"Toggle SCIM provisioning": "Attiva/disattiva il provisioning SCIM",
"Token": "Token",
"Page menu": "Menu della pagina",
"Expand": "Espandi",
"Collapse": "Comprimi",
"Comment menu": "Menu dei commenti",
"Group menu": "Menu del gruppo",
"Show hidden breadcrumbs": "Mostra breadcrumb nascosti",
"Breadcrumbs": "Breadcrumb",
"Page actions": "Azioni della pagina",
"Pick emoji": "Scegli emoji",
"Template menu": "Menu del modello",
"Chat menu": "Menu della chat",
"API key menu": "Menu della chiave API",
"Jump to comment selection": "Vai alla selezione dei commenti",
"Slash commands": "Comandi slash",
"Mention suggestions": "Suggerimenti di menzione",
"Link suggestions": "Suggerimenti di link",
"Diagram editor": "Editor di diagrammi",
"Add comment": "Aggiungi commento",
"Find and replace": "Trova e sostituisci",
"Main navigation": "Navigazione principale",
"Space navigation": "Navigazione dello spazio",
"Settings navigation": "Navigazione delle impostazioni",
"AI navigation": "Navigazione AI",
"Breadcrumb": "Percorso di navigazione",
"Skip to main content": "Vai direttamente al contenuto principale"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} が利用可能です",
"Default page edit mode": "デフォルトのページ編集モード",
"Choose your preferred page edit mode. Avoid accidental edits.": "お好みのページ編集モードを選択してください(誤編集を防止します)",
"Choose {{format}} file": "{{format}} ファイルを選択",
"Reading": "閲覧",
"Delete member": "メンバーを削除",
"Member deleted successfully": "メンバーが正常に削除されました",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "画像が10MBの制限を超えています",
"Image removed successfully": "画像を削除しました",
"API key": "APIキー",
"API key created successfully": "APIキーを作成しました",
"API keys": "APIキー",
"API management": "API管理",
"Are you sure you want to revoke this API key": "このAPIキーを無効にしてもよろしいですか",
"Create API Key": "APIキーを作成",
"Custom expiration date": "カスタム有効期限",
"Enter a descriptive token name": "説明的なトークン名を入力してください",
"Expiration": "有効期限",
"Expired": "期限切れ",
"Expires": "期限が切れます",
"I've saved my API key": "APIキーを保存しました",
"Last use": "最終使用",
"No API keys found": "APIキーが見つかりません",
"No expiration": "期限なし",
"Revoke API key": "APIキーを無効にする",
"Revoked successfully": "無効にしました",
"Select expiration date": "有効期限を選択してください",
"This action cannot be undone. Any applications using this API key will stop working.": "この操作は取り消せません。このAPIキーを使用しているアプリケーションは動作しなくなります",
"Update API key": "APIキーを更新",
"Update": "更新",
"Update {{credential}}": "{{credential}}を更新",
"Manage API keys for all users in the workspace": "ワークスペース内のすべてのユーザーのAPIキーを管理",
"Restrict API key creation to admins": "APIキーの作成を管理者のみに制限する",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "新しいAPIキーを作成できるのは管理者とオーナーのみです。既存のメンバーキーは引き続き有効です。",
@@ -873,6 +870,8 @@
"Previous 7 days": "過去 7 日間",
"Previous 30 days": "過去 30 日間",
"Search chats...": "チャットを検索...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "ここに表示するには新しいチャットを開始してください。",
"Summarize this page": "このページを要約",
"Toggle AI Chat": "AI チャットを切り替え",
@@ -880,5 +879,54 @@
"Try a different search term.": "別の検索語を試してください。",
"Try again": "再試行",
"Untitled chat": "無題のチャット",
"What can I help you with?": "何をお手伝いしましょうか?"
"What can I help you with?": "何をお手伝いしましょうか?",
"Are you sure you want to revoke this {{credential}}": "この{{credential}}を無効にしてもよろしいですか",
"Automatically provision users and groups from your identity provider via SCIM.": "SCIM を介して、ID プロバイダーからユーザーとグループを自動的にプロビジョニングします。",
"Configure your identity provider with this URL to provision users and groups.": "この URL を使用して ID プロバイダーを設定し、ユーザーとグループをプロビジョニングします。",
"Create {{credential}}": "{{credential}}を作成",
"{{credential}} created": "{{credential}}を作成しました",
"{{credential}} created successfully": "{{credential}}を正常に作成しました",
"Created by": "作成者",
"Custom": "カスタム",
"Enable SCIM": "SCIM を有効にする",
"Enter a descriptive name": "説明的な名前を入力してください",
"I've saved my {{credential}}": "{{credential}}を保存しました",
"Important": "重要",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "今すぐ {{credential}} をコピーしてください。後でもう一度表示することはできません!",
"Never": "なし",
"Revoke {{credential}}": "{{credential}}を無効にする",
"SCIM endpoint URL": "SCIM エンドポイント URL",
"SCIM provisioning": "SCIM プロビジョニング",
"SCIM takes precedence over SSO group sync while enabled.": "有効になっている間は、SCIM が SSO グループ同期より優先されます。",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "SCIM トークンの上限 {{max}} に達しました。新しいトークンを作成するには、既存のトークンを削除してください。",
"SCIM token": "SCIM トークン",
"SCIM tokens": "SCIM トークン",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "この操作は元に戻せません。ID プロバイダーは直ちに同期を停止します。",
"Toggle SCIM provisioning": "SCIM プロビジョニングを切り替える",
"Token": "トークン",
"Page menu": "ページメニュー",
"Expand": "展開",
"Collapse": "折りたたむ",
"Comment menu": "コメントメニュー",
"Group menu": "グループメニュー",
"Show hidden breadcrumbs": "非表示のパンくずリストを表示",
"Breadcrumbs": "パンくずリスト",
"Page actions": "ページアクション",
"Pick emoji": "絵文字を選択",
"Template menu": "テンプレートメニュー",
"Chat menu": "チャットメニュー",
"API key menu": "API キーメニュー",
"Jump to comment selection": "コメント選択に移動",
"Slash commands": "スラッシュコマンド",
"Mention suggestions": "メンション候補",
"Link suggestions": "リンク候補",
"Diagram editor": "ダイアグラムエディター",
"Add comment": "コメントを追加",
"Find and replace": "検索と置換",
"Main navigation": "メインナビゲーション",
"Space navigation": "スペースナビゲーション",
"Settings navigation": "設定ナビゲーション",
"AI navigation": "AI ナビゲーション",
"Breadcrumb": "パンくずリスト",
"Skip to main content": "メインコンテンツにスキップ"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} 버전을 사용할 수 있습니다",
"Default page edit mode": "기본 페이지 편집 모드",
"Choose your preferred page edit mode. Avoid accidental edits.": "선호하는 페이지 편집 모드를 선택하세요. 실수로 인한 편집을 방지하세요.",
"Choose {{format}} file": "{{format}} 파일 선택",
"Reading": "읽기",
"Delete member": "멤버 삭제",
"Member deleted successfully": "멤버가 성공적으로 삭제되었습니다",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "이미지가 10MB 용량 제한을 초과합니다.",
"Image removed successfully": "이미지가 성공적으로 제거되었습니다",
"API key": "API 키",
"API key created successfully": "API 키 생성 완료",
"API keys": "API 키",
"API management": "API 관리",
"Are you sure you want to revoke this API key": "이 API 키를 취소하시겠습니까?",
"Create API Key": "API 키 생성",
"Custom expiration date": "사용자 정의 만료일",
"Enter a descriptive token name": "토큰 이름을 입력하세요",
"Expiration": "만료",
"Expired": "만료됨",
"Expires": "만료일",
"I've saved my API key": "API 키를 저장했습니다",
"Last use": "최근 사용",
"No API keys found": "API 키를 찾을 수 없습니다",
"No expiration": "유효기간 없음",
"Revoke API key": "API 키 취소",
"Revoked successfully": "성공적으로 취소되었습니다",
"Select expiration date": "만료일 선택",
"This action cannot be undone. Any applications using this API key will stop working.": "이 작업은 되돌릴 수 없습니다. 이 API 키를 사용하는 모든 응용 프로그램이 작동을 멈출 것입니다.",
"Update API key": "API 키 갱신",
"Update": "업데이트",
"Update {{credential}}": "{{credential}} 업데이트",
"Manage API keys for all users in the workspace": "워크스페이스 내 모든 사용자의 API 키 관리",
"Restrict API key creation to admins": "API 키 생성 권한을 관리자에게만 제한합니다",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "새로운 API 키는 관리자와 소유자만 생성할 수 있습니다. 기존 멤버 키는 계속 사용할 수 있습니다.",
@@ -873,6 +870,8 @@
"Previous 7 days": "지난 7일",
"Previous 30 days": "지난 30일",
"Search chats...": "채팅 검색...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "여기에 표시하려면 새 채팅을 시작하세요.",
"Summarize this page": "이 페이지 요약",
"Toggle AI Chat": "AI 채팅 전환",
@@ -880,5 +879,54 @@
"Try a different search term.": "다른 검색어를 사용해 보세요.",
"Try again": "다시 시도",
"Untitled chat": "제목 없는 채팅",
"What can I help you with?": "무엇을 도와드릴까요?"
"What can I help you with?": "무엇을 도와드릴까요?",
"Are you sure you want to revoke this {{credential}}": "이 {{credential}}을 취소하시겠습니까?",
"Automatically provision users and groups from your identity provider via SCIM.": "SCIM을 통해 ID 공급자에서 사용자와 그룹을 자동으로 프로비저닝합니다.",
"Configure your identity provider with this URL to provision users and groups.": "사용자와 그룹을 프로비저닝할 수 있도록 이 URL로 ID 공급자를 구성하세요.",
"Create {{credential}}": "{{credential}} 만들기",
"{{credential}} created": "{{credential}} 생성됨",
"{{credential}} created successfully": "{{credential}} 생성 완료",
"Created by": "생성한 사람",
"Custom": "사용자 지정",
"Enable SCIM": "SCIM 활성화",
"Enter a descriptive name": "설명적인 이름을 입력하세요",
"I've saved my {{credential}}": "내 {{credential}}를 저장했습니다",
"Important": "중요",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "지금 {{credential}}를 복사해 두세요. 다시는 볼 수 없습니다!",
"Never": "안 함",
"Revoke {{credential}}": "{{credential}} 취소",
"SCIM endpoint URL": "SCIM 엔드포인트 URL",
"SCIM provisioning": "SCIM 프로비저닝",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM이 활성화되어 있는 동안에는 SSO 그룹 동기화보다 SCIM이 우선 적용됩니다.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "SCIM 토큰은 최대 {{max}}개까지 만들 수 있습니다. 새 토큰을 만들려면 기존 토큰을 삭제하세요.",
"SCIM token": "SCIM 토큰",
"SCIM tokens": "SCIM 토큰",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "이 작업은 되돌릴 수 없습니다. ID 공급자가 즉시 동기화를 중지합니다.",
"Toggle SCIM provisioning": "SCIM 프로비저닝 전환",
"Token": "토큰",
"Page menu": "페이지 메뉴",
"Expand": "펼치기",
"Collapse": "접기",
"Comment menu": "댓글 메뉴",
"Group menu": "그룹 메뉴",
"Show hidden breadcrumbs": "숨겨진 이동 경로 표시",
"Breadcrumbs": "이동 경로",
"Page actions": "페이지 작업",
"Pick emoji": "이모지 선택",
"Template menu": "템플릿 메뉴",
"Chat menu": "채팅 메뉴",
"API key menu": "API 키 메뉴",
"Jump to comment selection": "댓글 선택으로 이동",
"Slash commands": "슬래시 명령어",
"Mention suggestions": "멘션 추천",
"Link suggestions": "링크 추천",
"Diagram editor": "다이어그램 편집기",
"Add comment": "댓글 추가",
"Find and replace": "찾기 및 바꾸기",
"Main navigation": "기본 탐색",
"Space navigation": "스페이스 탐색",
"Settings navigation": "설정 탐색",
"AI navigation": "AI 탐색",
"Breadcrumb": "이동 경로",
"Skip to main content": "기본 콘텐츠로 건너뛰기"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} is beschikbaar",
"Default page edit mode": "Standaard bewerkingsmodus voor pagina",
"Choose your preferred page edit mode. Avoid accidental edits.": "Kies uw voorkeurs bewerkmodus voor pagina's. Vermijd per ongeluk bewerken.",
"Choose {{format}} file": "Kies {{format}}-bestand",
"Reading": "Lezen",
"Delete member": "Lid verwijderen",
"Member deleted successfully": "Lid succesvol verwijderd",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "Afbeelding overschrijdt de limiet van 10MB.",
"Image removed successfully": "Afbeelding succesvol verwijderd",
"API key": "API-sleutel",
"API key created successfully": "API-sleutel succesvol aangemaakt",
"API keys": "API-sleutels",
"API management": "API-beheer",
"Are you sure you want to revoke this API key": "Weet u zeker dat u deze API-sleutel wilt intrekken",
"Create API Key": "API-sleutel aanmaken",
"Custom expiration date": "Aangepaste vervaldatum",
"Enter a descriptive token name": "Voer een beschrijvende tokennaam in",
"Expiration": "Vervaldatum",
"Expired": "Verlopen",
"Expires": "Verloopt",
"I've saved my API key": "Ik heb mijn API-sleutel opgeslagen",
"Last use": "Laatst gebruikt",
"No API keys found": "Geen API-sleutels gevonden",
"No expiration": "Geen vervaldatum",
"Revoke API key": "API-sleutel intrekken",
"Revoked successfully": "Succesvol ingetrokken",
"Select expiration date": "Selecteer vervaldatum",
"This action cannot be undone. Any applications using this API key will stop working.": "Deze actie kan niet ongedaan worden gemaakt. Alle toepassingen die deze API-sleutel gebruiken, zullen niet meer werken.",
"Update API key": "API-sleutel bijwerken",
"Update": "Bijwerken",
"Update {{credential}}": "{{credential}} bijwerken",
"Manage API keys for all users in the workspace": "Beheer API-sleutels voor alle gebruikers in de werkruimte",
"Restrict API key creation to admins": "Beperk het aanmaken van API-sleutels tot beheerders.",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Alleen beheerders en eigenaren kunnen nieuwe API-sleutels aanmaken. Bestaande leden-sleutels blijven werken.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Afgelopen 7 dagen",
"Previous 30 days": "Afgelopen 30 dagen",
"Search chats...": "Chats zoeken...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Start een nieuwe chat om die hier te zien.",
"Summarize this page": "Vat deze pagina samen",
"Toggle AI Chat": "AI-chat in-/uitschakelen",
@@ -880,5 +879,54 @@
"Try a different search term.": "Probeer een andere zoekterm.",
"Try again": "Probeer opnieuw",
"Untitled chat": "Chat zonder titel",
"What can I help you with?": "Waar kan ik je mee helpen?"
"What can I help you with?": "Waar kan ik je mee helpen?",
"Are you sure you want to revoke this {{credential}}": "Weet u zeker dat u deze {{credential}} wilt intrekken",
"Automatically provision users and groups from your identity provider via SCIM.": "Voorzie gebruikers en groepen automatisch vanuit uw identiteitsprovider via SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Configureer uw identiteitsprovider met deze URL om gebruikers en groepen te provisioneren.",
"Create {{credential}}": "{{credential}} maken",
"{{credential}} created": "{{credential}} aangemaakt",
"{{credential}} created successfully": "{{credential}} succesvol aangemaakt",
"Created by": "Aangemaakt door",
"Custom": "Aangepast",
"Enable SCIM": "SCIM inschakelen",
"Enter a descriptive name": "Voer een beschrijvende naam in",
"I've saved my {{credential}}": "Ik heb mijn {{credential}} opgeslagen",
"Important": "Belangrijk",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Zorg ervoor dat u uw {{credential}} nu kopieert. U kunt deze niet meer bekijken!",
"Never": "Nooit",
"Revoke {{credential}}": "{{credential}} intrekken",
"SCIM endpoint URL": "SCIM-eindpunt-URL",
"SCIM provisioning": "SCIM-provisioning",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM heeft voorrang op SSO-groepssynchronisatie zolang het is ingeschakeld.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "U heeft het maximum van {{max}} SCIM-tokens bereikt. Verwijder een bestaand token om een nieuw token aan te maken.",
"SCIM token": "SCIM-token",
"SCIM tokens": "SCIM-tokens",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Deze actie kan niet ongedaan worden gemaakt. Uw identiteitsprovider stopt onmiddellijk met synchroniseren.",
"Toggle SCIM provisioning": "SCIM-provisioning in-/uitschakelen",
"Token": "Token",
"Page menu": "Paginamenu",
"Expand": "Uitvouwen",
"Collapse": "Samenvouwen",
"Comment menu": "Reactiemenu",
"Group menu": "Groepsmenu",
"Show hidden breadcrumbs": "Verborgen broodkruimels weergeven",
"Breadcrumbs": "Broodkruimels",
"Page actions": "Pagina-acties",
"Pick emoji": "Emoji kiezen",
"Template menu": "Sjabloonmenu",
"Chat menu": "Chatmenu",
"API key menu": "API-sleutelmenu",
"Jump to comment selection": "Naar reactieselectie springen",
"Slash commands": "Slash-opdrachten",
"Mention suggestions": "Vermeldingssuggesties",
"Link suggestions": "Linksuggesties",
"Diagram editor": "Diagrameditor",
"Add comment": "Reactie toevoegen",
"Find and replace": "Zoeken en vervangen",
"Main navigation": "Hoofdnavigatie",
"Space navigation": "Ruimtenavigatie",
"Settings navigation": "Instellingennavigatie",
"AI navigation": "AI-navigatie",
"Breadcrumb": "Broodkruimel",
"Skip to main content": "Naar hoofdinhoud springen"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} está disponível",
"Default page edit mode": "Modo padrão de edição da página",
"Choose your preferred page edit mode. Avoid accidental edits.": "Escolha o modo de edição de página preferido. Evite edições acidentais.",
"Choose {{format}} file": "Escolher arquivo {{format}}",
"Reading": "Leitura",
"Delete member": "Excluir membro",
"Member deleted successfully": "Membro excluído com sucesso",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "A imagem excede o limite de 10MB.",
"Image removed successfully": "Imagem removida com sucesso",
"API key": "Chave API",
"API key created successfully": "Chave API criada com sucesso",
"API keys": "Chaves API",
"API management": "Gestão de API",
"Are you sure you want to revoke this API key": "Tem certeza de que deseja revogar esta chave API",
"Create API Key": "Criar Chave API",
"Custom expiration date": "Data de expiração personalizada",
"Enter a descriptive token name": "Insira um nome descritivo para o token",
"Expiration": "Expiração",
"Expired": "Expirado",
"Expires": "Expira",
"I've saved my API key": "Salvei minha chave API",
"Last use": "Último uso",
"No API keys found": "Nenhuma chave API encontrada",
"No expiration": "Sem expiração",
"Revoke API key": "Revogar chave API",
"Revoked successfully": "Revogada com sucesso",
"Select expiration date": "Selecionar data de expiração",
"This action cannot be undone. Any applications using this API key will stop working.": "Esta ação não pode ser desfeita. Qualquer aplicação usando esta chave API deixará de funcionar.",
"Update API key": "Atualizar chave API",
"Update": "Atualizar",
"Update {{credential}}": "Atualizar {{credential}}",
"Manage API keys for all users in the workspace": "Gerenciar chaves API para todos os usuários no espaço de trabalho",
"Restrict API key creation to admins": "Restringir a criação de chave de API aos administradores",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Somente administradores e proprietários podem criar novas chaves de API. As chaves de membros já existentes continuarão funcionando.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Últimos 7 dias",
"Previous 30 days": "Últimos 30 dias",
"Search chats...": "Pesquisar chats...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Inicie um novo chat para vê-lo aqui.",
"Summarize this page": "Resumir esta página",
"Toggle AI Chat": "Alternar chat com IA",
@@ -880,5 +879,54 @@
"Try a different search term.": "Tente um termo de pesquisa diferente.",
"Try again": "Tentar novamente",
"Untitled chat": "Chat sem título",
"What can I help you with?": "Com o que posso ajudar você?"
"What can I help you with?": "Com o que posso ajudar você?",
"Are you sure you want to revoke this {{credential}}": "Tem certeza de que deseja revogar esta {{credential}}",
"Automatically provision users and groups from your identity provider via SCIM.": "Provisione automaticamente usuários e grupos do seu provedor de identidade via SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Configure seu provedor de identidade com esta URL para provisionar usuários e grupos.",
"Create {{credential}}": "Criar {{credential}}",
"{{credential}} created": "{{credential}} criada",
"{{credential}} created successfully": "{{credential}} criada com sucesso",
"Created by": "Criado por",
"Custom": "Personalizado",
"Enable SCIM": "Ativar SCIM",
"Enter a descriptive name": "Insira um nome descritivo",
"I've saved my {{credential}}": "Salvei minha {{credential}}",
"Important": "Importante",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Copie sua {{credential}} agora. Você não poderá vê-la novamente!",
"Never": "Nunca",
"Revoke {{credential}}": "Revogar {{credential}}",
"SCIM endpoint URL": "URL do endpoint SCIM",
"SCIM provisioning": "Provisionamento SCIM",
"SCIM takes precedence over SSO group sync while enabled.": "O SCIM tem precedência sobre a sincronização de grupos por SSO enquanto estiver ativado.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Você atingiu o máximo de {{max}} tokens SCIM. Exclua um token existente para criar um novo.",
"SCIM token": "Token SCIM",
"SCIM tokens": "Tokens SCIM",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Esta ação não pode ser desfeita. Seu provedor de identidade deixará de sincronizar imediatamente.",
"Toggle SCIM provisioning": "Alternar provisionamento SCIM",
"Token": "Token",
"Page menu": "Menu da página",
"Expand": "Expandir",
"Collapse": "Recolher",
"Comment menu": "Menu de comentários",
"Group menu": "Menu do grupo",
"Show hidden breadcrumbs": "Mostrar breadcrumbs ocultos",
"Breadcrumbs": "Trilhas de navegação",
"Page actions": "Ações da página",
"Pick emoji": "Escolher emoji",
"Template menu": "Menu do modelo",
"Chat menu": "Menu do chat",
"API key menu": "Menu da chave de API",
"Jump to comment selection": "Ir para a seleção de comentários",
"Slash commands": "Comandos de barra",
"Mention suggestions": "Sugestões de menção",
"Link suggestions": "Sugestões de links",
"Diagram editor": "Editor de diagramas",
"Add comment": "Adicionar comentário",
"Find and replace": "Localizar e substituir",
"Main navigation": "Navegação principal",
"Space navigation": "Navegação do espaço",
"Settings navigation": "Navegação de configurações",
"AI navigation": "Navegação de IA",
"Breadcrumb": "Trilha de navegação",
"Skip to main content": "Pular para o conteúdo principal"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "Доступна версия {{latestVersion}}",
"Default page edit mode": "Режим редактирования страницы по умолчанию",
"Choose your preferred page edit mode. Avoid accidental edits.": "Выберите предпочитаемый режим редактирования страницы. Избегайте случайных изменений.",
"Choose {{format}} file": "Выберите файл {{format}}",
"Reading": "Чтение",
"Delete member": "Удалить участника",
"Member deleted successfully": "Участник успешно удалён",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "Изображение превышает предел 10MB.",
"Image removed successfully": "Изображение успешно удалено",
"API key": "API ключ",
"API key created successfully": "API ключ успешно создан",
"API keys": "API ключи",
"API management": "Управление API",
"Are you sure you want to revoke this API key": "Вы уверены, что хотите отозвать этот API ключ",
"Create API Key": "Создать API ключ",
"Custom expiration date": "Пользовательская дата срока действия",
"Enter a descriptive token name": "Введите понятное имя токена",
"Expiration": "Срок действия",
"Expired": "Истек",
"Expires": "Истекает",
"I've saved my API key": "Я сохранил мой API ключ",
"Last use": "Последнее использование",
"No API keys found": "API ключи не найдены",
"No expiration": "Не истекает",
"Revoke API key": "Отозвать API ключ",
"Revoked successfully": "Отозван успешно",
"Select expiration date": "Выберете срок действия",
"This action cannot be undone. Any applications using this API key will stop working.": "Это действие необратимо. Любые приложения, использующие этот API ключ, перестанут работать.",
"Update API key": "Обновить API ключ",
"Update": "Обновить",
"Update {{credential}}": "Обновить {{credential}}",
"Manage API keys for all users in the workspace": "Управлять API ключами для всех пользователей в рабочей области",
"Restrict API key creation to admins": "Ограничить создание API-ключей только администраторами.",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Только администраторы и владельцы могут создавать новые API-ключи. Существующие ключи участников продолжат работать.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Предыдущие 7 дней",
"Previous 30 days": "Предыдущие 30 дней",
"Search chats...": "Поиск чатов...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Начните новый чат, чтобы увидеть его здесь.",
"Summarize this page": "Суммировать эту страницу",
"Toggle AI Chat": "Переключить чат с ИИ",
@@ -880,5 +879,54 @@
"Try a different search term.": "Попробуйте другой поисковый запрос.",
"Try again": "Попробовать снова",
"Untitled chat": "Чат без названия",
"What can I help you with?": "Чем я могу вам помочь?"
"What can I help you with?": "Чем я могу вам помочь?",
"Are you sure you want to revoke this {{credential}}": "Вы уверены, что хотите отозвать этот {{credential}}",
"Automatically provision users and groups from your identity provider via SCIM.": "Автоматически предоставляйте доступ пользователям и группам из вашего провайдера удостоверений через SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Настройте ваш провайдер удостоверений с этим URL для предоставления доступа пользователям и группам.",
"Create {{credential}}": "Создать {{credential}}",
"{{credential}} created": "{{credential}} создан",
"{{credential}} created successfully": "{{credential}} успешно создан",
"Created by": "Создан",
"Custom": "Пользовательский",
"Enable SCIM": "Включить SCIM",
"Enter a descriptive name": "Введите понятное имя",
"I've saved my {{credential}}": "Я сохранил свой {{credential}}",
"Important": "Важно",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Обязательно скопируйте ваш {{credential}} сейчас. Позже вы не сможете увидеть его снова!",
"Never": "Никогда",
"Revoke {{credential}}": "Отозвать {{credential}}",
"SCIM endpoint URL": "URL конечной точки SCIM",
"SCIM provisioning": "SCIM-подготовка учетных записей",
"SCIM takes precedence over SSO group sync while enabled.": "Пока SCIM включен, он имеет приоритет над синхронизацией групп через SSO.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Вы достигли максимального количества токенов SCIM: {{max}}. Удалите существующий токен, чтобы создать новый.",
"SCIM token": "Токен SCIM",
"SCIM tokens": "Токены SCIM",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Это действие нельзя отменить. Ваш провайдер удостоверений немедленно прекратит синхронизацию.",
"Toggle SCIM provisioning": "Переключить подготовку учетных записей SCIM",
"Token": "Токен",
"Page menu": "Меню страницы",
"Expand": "Развернуть",
"Collapse": "Свернуть",
"Comment menu": "Меню комментария",
"Group menu": "Меню группы",
"Show hidden breadcrumbs": "Показать скрытые хлебные крошки",
"Breadcrumbs": "Хлебные крошки",
"Page actions": "Действия со страницей",
"Pick emoji": "Выбрать эмодзи",
"Template menu": "Меню шаблона",
"Chat menu": "Меню чата",
"API key menu": "Меню API-ключа",
"Jump to comment selection": "Перейти к выбору комментария",
"Slash commands": "Команды со слешем",
"Mention suggestions": "Подсказки упоминаний",
"Link suggestions": "Подсказки ссылок",
"Diagram editor": "Редактор диаграмм",
"Add comment": "Добавить комментарий",
"Find and replace": "Найти и заменить",
"Main navigation": "Основная навигация",
"Space navigation": "Навигация по пространству",
"Settings navigation": "Навигация по настройкам",
"AI navigation": "Навигация ИИ",
"Breadcrumb": "Хлебная крошка",
"Skip to main content": "Перейти к основному содержимому"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "Доступна версія {{latestVersion}}",
"Default page edit mode": "Режим редагування сторінки за замовчуванням",
"Choose your preferred page edit mode. Avoid accidental edits.": "Виберіть бажаний режим редагування сторінки. Уникайте випадкових редагувань.",
"Choose {{format}} file": "Виберіть файл {{format}}",
"Reading": "Читання",
"Delete member": "Видалити учасника",
"Member deleted successfully": "Учасника успішно видалено",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "Зображення має займати менше, ніж 10 МБ.",
"Image removed successfully": "Зображення видалено",
"API key": "Ключ API",
"API key created successfully": "Ключ API успішно створено",
"API keys": "Ключі API",
"API management": "Управління API",
"Are you sure you want to revoke this API key": "Ви впевнені, що хочете відкликати цей ключ API",
"Create API Key": "Створити ключ API",
"Custom expiration date": "Користувацька дата закінчення",
"Enter a descriptive token name": "Введіть описову назву токена",
"Expiration": "Термін дії",
"Expired": "Закінчився",
"Expires": "Закінчується",
"I've saved my API key": "Я зберіг свій ключ API",
"Last use": "Останнє використання",
"No API keys found": "Ключі API не знайдено",
"No expiration": "Без терміну дії",
"Revoke API key": "Відкликати ключ API",
"Revoked successfully": "Успішно відкликано",
"Select expiration date": "Виберіть дату закінчення",
"This action cannot be undone. Any applications using this API key will stop working.": "Цю дію не можна скасувати. Будь-які додатки, що використовують цей ключ API, перестануть працювати.",
"Update API key": "Оновити ключ API",
"Update": "Оновити",
"Update {{credential}}": "Оновити {{credential}}",
"Manage API keys for all users in the workspace": "Керувати ключами API для всіх користувачів у робочій області",
"Restrict API key creation to admins": "Обмежити створення API-ключів лише для адміністраторів",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "Тільки адміністратори та власники можуть створювати нові API-ключі. Існуючі ключі учасників і надалі працюватимуть.",
@@ -873,6 +870,8 @@
"Previous 7 days": "Попередні 7 днів",
"Previous 30 days": "Попередні 30 днів",
"Search chats...": "Шукати чати...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "Почніть новий чат, щоб побачити його тут.",
"Summarize this page": "Підсумувати цю сторінку",
"Toggle AI Chat": "Перемкнути AI-чат",
@@ -880,5 +879,54 @@
"Try a different search term.": "Спробуйте інший пошуковий запит.",
"Try again": "Спробувати ще раз",
"Untitled chat": "Чат без назви",
"What can I help you with?": "Чим я можу вам допомогти?"
"What can I help you with?": "Чим я можу вам допомогти?",
"Are you sure you want to revoke this {{credential}}": "Ви впевнені, що хочете відкликати цей {{credential}}",
"Automatically provision users and groups from your identity provider via SCIM.": "Автоматично надавайте користувачів і групи від вашого постачальника ідентифікації через SCIM.",
"Configure your identity provider with this URL to provision users and groups.": "Налаштуйте свого постачальника ідентифікації за допомогою цієї URL-адреси для надання користувачів і груп.",
"Create {{credential}}": "Створити {{credential}}",
"{{credential}} created": "{{credential}} створено",
"{{credential}} created successfully": "{{credential}} успішно створено",
"Created by": "Створено",
"Custom": "Користувацький",
"Enable SCIM": "Увімкнути SCIM",
"Enter a descriptive name": "Введіть описову назву",
"I've saved my {{credential}}": "Я зберіг(ла) свій {{credential}}",
"Important": "Важливо",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "Обов’язково скопіюйте свій {{credential}} зараз. Ви більше не зможете побачити його знову!",
"Never": "Ніколи",
"Revoke {{credential}}": "Відкликати {{credential}}",
"SCIM endpoint URL": "URL-адреса кінцевої точки SCIM",
"SCIM provisioning": "Надання SCIM",
"SCIM takes precedence over SSO group sync while enabled.": "SCIM має пріоритет над синхронізацією груп SSO, коли його ввімкнено.",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "Ви досягли максимальної кількості токенів SCIM: {{max}}. Видаліть наявний токен, щоб створити новий.",
"SCIM token": "Токен SCIM",
"SCIM tokens": "Токени SCIM",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "Цю дію не можна скасувати. Ваш постачальник ідентифікації негайно припинить синхронізацію.",
"Toggle SCIM provisioning": "Перемкнути надання SCIM",
"Token": "Токен",
"Page menu": "Меню сторінки",
"Expand": "Розгорнути",
"Collapse": "Згорнути",
"Comment menu": "Меню коментаря",
"Group menu": "Меню групи",
"Show hidden breadcrumbs": "Показати приховані \"хлібні крихти\"",
"Breadcrumbs": "\"Хлібні крихти\"",
"Page actions": "Дії сторінки",
"Pick emoji": "Вибрати емодзі",
"Template menu": "Меню шаблону",
"Chat menu": "Меню чату",
"API key menu": "Меню ключа API",
"Jump to comment selection": "Перейти до вибору коментаря",
"Slash commands": "Слеш-команди",
"Mention suggestions": "Підказки згадок",
"Link suggestions": "Підказки посилань",
"Diagram editor": "Редактор діаграм",
"Add comment": "Додати коментар",
"Find and replace": "Знайти й замінити",
"Main navigation": "Основна навігація",
"Space navigation": "Навігація простору",
"Settings navigation": "Навігація налаштувань",
"AI navigation": "Навігація AI",
"Breadcrumb": "Хлібна крихта",
"Skip to main content": "Перейти до основного вмісту"
}
@@ -416,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} 可用",
"Default page edit mode": "默认页面编辑模式",
"Choose your preferred page edit mode. Avoid accidental edits.": "选择您偏好的页面编辑模式。避免意外编辑。",
"Choose {{format}} file": "选择 {{format}} 文件",
"Reading": "阅读",
"Delete member": "删除成员",
"Member deleted successfully": "成员删除成功",
@@ -608,25 +609,21 @@
"Image exceeds 10MB limit.": "图片超过10MB限制。",
"Image removed successfully": "图片删除成功",
"API key": "API密钥",
"API key created successfully": "API密钥创建成功",
"API keys": "API密钥",
"API management": "API管理",
"Are you sure you want to revoke this API key": "确定要撤销此API密钥吗",
"Create API Key": "创建API密钥",
"Custom expiration date": "自定义到期日期",
"Enter a descriptive token name": "输入描述性令牌名称",
"Expiration": "到期",
"Expired": "已过期",
"Expires": "到期",
"I've saved my API key": "我已保存我的API密钥",
"Last use": "上次使用",
"No API keys found": "找不到API密钥",
"No expiration": "无到期",
"Revoke API key": "撤销API密钥",
"Revoked successfully": "撤销成功",
"Select expiration date": "选择到期日期",
"This action cannot be undone. Any applications using this API key will stop working.": "此操作无法撤销。使用此API密钥的任何应用程序将停止工作。",
"Update API key": "更新API密钥",
"Update": "更新",
"Update {{credential}}": "更新{{credential}}",
"Manage API keys for all users in the workspace": "管理工作空间中所有用户的API密钥",
"Restrict API key creation to admins": "仅限管理员创建 API 密钥。",
"Only admins and owners can create new API keys. Existing member keys will continue to work.": "只有管理员和所有者可以创建新的 API 密钥。现有成员密钥将继续有效。",
@@ -873,6 +870,8 @@
"Previous 7 days": "前 7 天",
"Previous 30 days": "前 30 天",
"Search chats...": "搜索聊天...",
"Search chats": "Search chats",
"Ask anything... Use @ to mention pages": "Ask anything... Use @ to mention pages",
"Start a new chat to see it here.": "开始新的聊天后会显示在这里。",
"Summarize this page": "总结此页面",
"Toggle AI Chat": "切换 AI 聊天",
@@ -880,5 +879,54 @@
"Try a different search term.": "请尝试其他搜索词。",
"Try again": "重试",
"Untitled chat": "未命名聊天",
"What can I help you with?": "我能帮您做什么?"
"What can I help you with?": "我能帮您做什么?",
"Are you sure you want to revoke this {{credential}}": "确定要撤销此{{credential}}吗",
"Automatically provision users and groups from your identity provider via SCIM.": "通过 SCIM 从您的身份提供商自动预配用户和群组。",
"Configure your identity provider with this URL to provision users and groups.": "使用此 URL 配置您的身份提供商以预配用户和群组。",
"Create {{credential}}": "创建{{credential}}",
"{{credential}} created": "已创建{{credential}}",
"{{credential}} created successfully": "已成功创建{{credential}}",
"Created by": "创建者",
"Custom": "自定义",
"Enable SCIM": "启用 SCIM",
"Enter a descriptive name": "输入描述性名称",
"I've saved my {{credential}}": "我已保存我的{{credential}}",
"Important": "重要",
"Make sure to copy your {{credential}} now. You won't be able to see it again!": "请务必立即复制您的{{credential}}。之后您将无法再次查看!",
"Never": "从不",
"Revoke {{credential}}": "撤销{{credential}}",
"SCIM endpoint URL": "SCIM 端点 URL",
"SCIM provisioning": "SCIM 预配",
"SCIM takes precedence over SSO group sync while enabled.": "启用后,SCIM 的优先级高于 SSO 群组同步。",
"You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "您已达到 {{max}} 个 SCIM 令牌的上限。请删除一个现有令牌以创建新令牌。",
"SCIM token": "SCIM 令牌",
"SCIM tokens": "SCIM 令牌",
"This action cannot be undone. Your identity provider will stop syncing immediately.": "此操作无法撤销。您的身份提供商将立即停止同步。",
"Toggle SCIM provisioning": "切换 SCIM 预配",
"Token": "令牌",
"Page menu": "页面菜单",
"Expand": "展开",
"Collapse": "折叠",
"Comment menu": "评论菜单",
"Group menu": "群组菜单",
"Show hidden breadcrumbs": "显示隐藏的面包屑",
"Breadcrumbs": "面包屑",
"Page actions": "页面操作",
"Pick emoji": "选择表情符号",
"Template menu": "模板菜单",
"Chat menu": "聊天菜单",
"API key menu": "API 密钥菜单",
"Jump to comment selection": "跳转到评论选择",
"Slash commands": "斜杠命令",
"Mention suggestions": "提及建议",
"Link suggestions": "链接建议",
"Diagram editor": "图表编辑器",
"Add comment": "添加评论",
"Find and replace": "查找和替换",
"Main navigation": "主导航",
"Space navigation": "空间导航",
"Settings navigation": "设置导航",
"AI navigation": "AI 导航",
"Breadcrumb": "面包屑",
"Skip to main content": "跳转到主要内容"
}
-1
View File
@@ -8,7 +8,6 @@ export const Feature = {
AI: 'ai',
CONFLUENCE_IMPORT: 'import:confluence',
DOCX_IMPORT: 'import:docx',
PDF_IMPORT: 'import:pdf',
ATTACHMENT_INDEXING: 'attachment:indexing',
SECURITY_SETTINGS: 'security:settings',
MCP: 'mcp',
@@ -140,7 +140,7 @@ export function PagePermissionList({
)}
</Group>
<ScrollArea.Autosize mah={400} viewportRef={viewportRef}>
<ScrollArea mah={250} viewportRef={viewportRef}>
{sortedMembers.map((member) => (
<PagePermissionItem
key={`${member.type}-${member.id}`}
@@ -158,7 +158,7 @@ export function PagePermissionList({
<Loader size="xs" />
</Center>
)}
</ScrollArea.Autosize>
</ScrollArea>
</>
);
}
@@ -19,9 +19,7 @@ export const uploadAttachmentAction = handleAttachmentUpload({
},
validateFn: (file, allowMedia: boolean) => {
if (
(file.type.includes("image/") ||
file.type.includes("video/") ||
file.type === "application/pdf") &&
(file.type.includes("image/") || file.type.includes("video/")) &&
!allowMedia
) {
return false;
@@ -12,7 +12,6 @@ import {
IconCheck,
IconFileCode,
IconFileTypeDocx,
IconFileTypePdf,
IconFileTypeZip,
IconMarkdown,
IconX,
@@ -91,14 +90,12 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) {
const markdownFileRef = useRef<() => void>(null);
const htmlFileRef = useRef<() => void>(null);
const docxFileRef = useRef<() => void>(null);
const pdfFileRef = useRef<() => void>(null);
const notionFileRef = useRef<() => void>(null);
const confluenceFileRef = useRef<() => void>(null);
const zipFileRef = useRef<() => void>(null);
const canUseConfluence = useHasFeature(Feature.CONFLUENCE_IMPORT);
const canUseDocx = useHasFeature(Feature.DOCX_IMPORT);
const canUsePdf = useHasFeature(Feature.PDF_IMPORT);
const upgradeLabel = useUpgradeLabel();
const handleZipUpload = async (selectedFile: File, source: string) => {
@@ -247,7 +244,7 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) {
}, 3000);
}, [fileTaskId]);
const maxSingleFileSize = bytes("30mb");
const maxSingleFileSize = bytes("20mb");
const handleFileUpload = async (selectedFiles: File[]) => {
if (!selectedFiles) {
@@ -301,7 +298,6 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) {
if (markdownFileRef.current) markdownFileRef.current();
if (htmlFileRef.current) htmlFileRef.current();
if (docxFileRef.current) docxFileRef.current();
if (pdfFileRef.current) pdfFileRef.current();
const pageCountText =
pageCount === 1 ? `1 ${t("page")}` : `${pageCount} ${t("pages")}`;
@@ -382,30 +378,6 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) {
)}
</FileButton>
<FileButton
onChange={handleFileUpload}
accept=".pdf"
multiple
resetRef={pdfFileRef}
>
{(props) => (
<Tooltip
label={upgradeLabel}
disabled={canUsePdf}
>
<Button
disabled={!canUsePdf}
justify="start"
variant="default"
leftSection={<IconFileTypePdf size={18} />}
{...props}
>
PDF
</Button>
</Tooltip>
)}
</FileButton>
<FileButton
onChange={(file) => handleZipUpload(file, "notion")}
accept="application/zip"
+18 -22
View File
@@ -1,6 +1,6 @@
{
"name": "server",
"version": "0.80.1",
"version": "0.80.0",
"description": "",
"author": "",
"private": true,
@@ -33,14 +33,13 @@
"@ai-sdk/google": "^3.0.52",
"@ai-sdk/openai": "^3.0.47",
"@ai-sdk/openai-compatible": "^2.0.37",
"@aws-sdk/client-s3": "3.1037.0",
"@aws-sdk/lib-storage": "3.1037.0",
"@aws-sdk/s3-request-presigner": "3.1037.0",
"@aws-sdk/client-s3": "3.1014.0",
"@aws-sdk/lib-storage": "3.1014.0",
"@aws-sdk/s3-request-presigner": "3.1014.0",
"@clickhouse/client": "^1.18.2",
"@docmost/pdf-inspector": "1.9.4",
"@fastify/cookie": "^11.0.2",
"@fastify/multipart": "^10.0.0",
"@fastify/static": "^9.1.3",
"@fastify/multipart": "^9.4.0",
"@fastify/static": "^9.0.0",
"@keyv/redis": "^5.1.6",
"@langchain/core": "1.1.39",
"@langchain/textsplitters": "1.0.1",
@@ -49,19 +48,19 @@
"@nestjs-labs/nestjs-ioredis": "^11.0.4",
"@nestjs/bullmq": "^11.0.4",
"@nestjs/cache-manager": "^3.1.0",
"@nestjs/common": "^11.1.19",
"@nestjs/config": "^4.0.4",
"@nestjs/core": "^11.1.19",
"@nestjs/common": "^11.1.18",
"@nestjs/config": "^4.0.3",
"@nestjs/core": "^11.1.18",
"@nestjs/event-emitter": "^3.0.1",
"@nestjs/jwt": "11.0.2",
"@nestjs/mapped-types": "^2.1.1",
"@nestjs/passport": "^11.0.5",
"@nestjs/platform-fastify": "^11.1.19",
"@nestjs/platform-socket.io": "^11.1.19",
"@nestjs/schedule": "^6.1.3",
"@nestjs/platform-fastify": "^11.1.18",
"@nestjs/platform-socket.io": "^11.1.18",
"@nestjs/schedule": "^6.1.1",
"@nestjs/terminus": "^11.1.1",
"@nestjs/throttler": "^6.5.0",
"@nestjs/websockets": "^11.1.19",
"@nestjs/websockets": "^11.1.18",
"@node-saml/passport-saml": "^5.1.0",
"@react-email/components": "1.0.10",
"@react-email/render": "2.0.4",
@@ -70,7 +69,7 @@
"ai-sdk-ollama": "^3.8.1",
"bcrypt": "^6.0.0",
"bowser": "^2.14.1",
"bullmq": "^5.76.0",
"bullmq": "^5.71.0",
"cache-manager": "^7.2.8",
"cheerio": "^1.2.0",
"class-transformer": "^0.5.1",
@@ -101,6 +100,7 @@
"p-limit": "^7.3.0",
"passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1",
"pdfjs-dist": "^5.5.207",
"pg-tsquery": "^8.4.2",
"pgvector": "^0.2.1",
"pino-http": "^11.0.0",
@@ -110,23 +110,22 @@
"react": "^18.3.1",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2",
"sanitize-filename": "1.6.3",
"sanitize-filename-ts": "1.0.2",
"socket.io": "^4.8.3",
"stripe": "^17.7.0",
"tlds": "^1.261.0",
"tmp-promise": "^3.0.3",
"tseep": "^1.3.1",
"typesense": "^3.0.5",
"undici": "7.24.0",
"ws": "^8.20.0",
"yauzl": "^3.2.1",
"zod": "^4.3.6"
},
"devDependencies": {
"@eslint/js": "^9.28.0",
"@nestjs/cli": "^11.0.21",
"@nestjs/cli": "^11.0.18",
"@nestjs/schematics": "^11.0.10",
"@nestjs/testing": "^11.1.19",
"@nestjs/testing": "^11.1.18",
"@types/bcrypt": "^6.0.0",
"@types/debounce": "^1.2.4",
"@types/fs-extra": "^11.0.4",
@@ -166,9 +165,6 @@
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"transformIgnorePatterns": [
"/node_modules/(?!(\\.pnpm/)?(nanoid|uuid|image-dimensions|marked)(@|/))"
],
"collectCoverageFrom": [
"**/*.(t|j)s"
],
-1
View File
@@ -8,7 +8,6 @@ export const Feature = {
AI: 'ai',
CONFLUENCE_IMPORT: 'import:confluence',
DOCX_IMPORT: 'import:docx',
PDF_IMPORT: 'import:pdf',
ATTACHMENT_INDEXING: 'attachment:indexing',
SECURITY_SETTINGS: 'security:settings',
MCP: 'mcp',
Binary file not shown.
+6 -28
View File
@@ -1,6 +1,6 @@
import * as path from 'path';
import * as bcrypt from 'bcrypt';
import sanitize = require('sanitize-filename');
import { sanitize } from 'sanitize-filename-ts';
import { FastifyRequest } from 'fastify';
import { Readable, Transform } from 'stream';
@@ -72,33 +72,11 @@ export function extractDateFromUuid7(uuid7: string) {
return new Date(timestamp);
}
export type SanitizeFileNameOptions = {
/** Keep spaces and `#` instead of replacing them with `_`. Useful for
* download filenames where readability matters. Defaults to false. */
preserveSpaces?: boolean;
};
export function sanitizeFileName(
fileName: string,
options: SanitizeFileNameOptions = {},
): string {
// Decode percent-encoded sequences so that bypasses like "..%2F" reach
// sanitize() as literal "../" and get stripped. sanitize-filename only
// strips literal characters and won't catch encoded path separators
// on its own.
const decoded = fileName.replace(/%[0-9a-fA-F]{2}/g, (m) => {
try {
return decodeURIComponent(m);
} catch {
return m;
}
});
const sanitized = sanitize(decoded);
if (options.preserveSpaces) {
return sanitized;
}
return sanitized.replace(/ /g, '_').replace(/#/g, '_');
export function sanitizeFileName(fileName: string): string {
const sanitizedFilename = sanitize(fileName)
.replace(/ /g, '_')
.replace(/#/g, '_');
return sanitizedFilename.slice(0, 255);
}
export function removeAccent(str: string): string {
@@ -356,19 +356,9 @@ export class AttachmentController {
throw new BadRequestException('Invalid image attachment type');
}
if (!fileName) {
throw new BadRequestException('Invalid file name');
}
const ext = path.extname(fileName);
const filenameWithoutExt = path.basename(fileName, ext);
if (
!ext ||
!isValidUUID(filenameWithoutExt) ||
`${filenameWithoutExt}${ext}` !== fileName
) {
throw new BadRequestException('Invalid file name');
const filenameWithoutExt = path.basename(fileName, path.extname(fileName));
if (!isValidUUID(filenameWithoutExt)) {
throw new BadRequestException('Invalid file id');
}
const filePath = `${getAttachmentFolderPath(attachmentType, workspace.id)}/${fileName}`;
@@ -13,6 +13,10 @@ import { CreateUserDto } from '../../auth/dto/create-user.dto';
export class UpdateUserDto extends PartialType(
OmitType(CreateUserDto, ['password'] as const),
) {
@IsOptional()
@IsString()
avatarUrl: string;
@IsOptional()
@IsBoolean()
fullPageWidth: boolean;
@@ -110,6 +110,10 @@ export class UserService {
user.email = updateUserDto.email;
}
if (updateUserDto.avatarUrl) {
user.avatarUrl = updateUserDto.avatarUrl;
}
if (updateUserDto.locale) {
user.locale = updateUserDto.locale;
}
@@ -5,10 +5,15 @@ import {
IsBoolean,
IsInt,
IsOptional,
IsString,
Min,
} from 'class-validator';
export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) {
@IsOptional()
@IsString()
logo: string;
@IsOptional()
@IsArray()
emailDomains: string[];
@@ -23,12 +23,9 @@ import {
SpaceCaslSubject,
} from '../../core/casl/interfaces/space-ability.type';
import { FastifyReply } from 'fastify';
import { sanitize } from 'sanitize-filename-ts';
import { getExportExtension } from './utils';
import {
getMimeType,
getPageTitle,
sanitizeFileName,
} from '../../common/helpers';
import { getMimeType, getPageTitle } from '../../common/helpers';
import * as path from 'path';
import { AuditEvent, AuditResource } from '../../common/events/audit-events';
import {
@@ -88,9 +85,7 @@ export class ExportController {
if (result.type === 'file') {
const ext = getExportExtension(dto.format);
const fileName =
sanitizeFileName(page.title || 'untitled', { preserveSpaces: true }) +
ext;
const fileName = sanitize(page.title || 'untitled') + ext;
const contentType = getMimeType(path.extname(fileName));
res.headers({
@@ -101,9 +96,7 @@ export class ExportController {
res.send(result.content);
} else {
const fileName =
sanitizeFileName(page.title || 'untitled', { preserveSpaces: true }) +
'.zip';
const fileName = sanitize(page.title || 'untitled') + '.zip';
res.headers({
'Content-Type': 'application/zip',
@@ -151,9 +144,7 @@ export class ExportController {
'Content-Type': 'application/zip',
'Content-Disposition':
'attachment; filename="' +
encodeURIComponent(
sanitizeFileName(exportFile.fileName, { preserveSpaces: true }),
) +
encodeURIComponent(sanitize(exportFile.fileName)) +
'"',
});
@@ -39,8 +39,6 @@ import {
} from '../../common/helpers/prosemirror/utils';
import { htmlToMarkdown } from '@docmost/editor-ext';
type AllowedAttachment = { id: string; fileName: string; filePath: string };
@Injectable()
export class ExportService {
private readonly logger = new Logger(ExportService.name);
@@ -274,12 +272,6 @@ export class ExportService {
computeLocalPath(tree, format, null, '', slugIdToPath);
// Batch resolve attachments once for the whole export so we only run the
// owning-page view check a single time, regardless of page count.
const allowedAttachments = includeAttachments
? await this.resolveAccessibleAttachments(tree, userId, ignorePermissions)
: new Map<string, AllowedAttachment>();
const stack: { folder: JSZip; parentPageId: string | null }[] = [
{ folder: zip, parentPageId: null },
];
@@ -309,7 +301,7 @@ export class ExportService {
);
if (includeAttachments) {
await this.zipAttachments(updatedJsonContent, folder, allowedAttachments);
await this.zipAttachments(updatedJsonContent, page.spaceId, folder);
updatedJsonContent =
updateAttachmentUrlsToLocalPaths(updatedJsonContent);
}
@@ -355,80 +347,31 @@ export class ExportService {
zip.file('docmost-metadata.json', JSON.stringify(metadata, null, 2));
}
async zipAttachments(
prosemirrorJson: any,
zip: JSZip,
allowed: Map<string, AllowedAttachment>,
) {
async zipAttachments(prosemirrorJson: any, spaceId: string, zip: JSZip) {
const attachmentIds = getAttachmentIds(prosemirrorJson);
await Promise.all(
attachmentIds.map(async (id) => {
const attachment = allowed.get(id);
if (!attachment) return;
try {
const fileBuffer = await this.storageService.read(
attachment.filePath,
);
const filePath = `/files/${attachment.id}/${attachment.fileName}`;
zip.file(filePath, fileBuffer);
} catch (err) {
this.logger.debug(`Attachment export error ${attachment.id}`, err);
}
}),
);
}
if (attachmentIds.length > 0) {
const attachments = await this.db
.selectFrom('attachments')
.select(['id', 'fileName', 'filePath'])
.where('id', 'in', attachmentIds)
.where('spaceId', '=', spaceId)
.execute();
private async resolveAccessibleAttachments(
tree: PageExportTree,
userId: string | undefined,
ignorePermissions: boolean,
): Promise<Map<string, AllowedAttachment>> {
const allAttachmentIds = new Set<string>();
let spaceId: string | undefined;
for (const siblings of Object.values(tree)) {
for (const page of siblings) {
if (!spaceId) spaceId = page.spaceId;
for (const id of getAttachmentIds(getProsemirrorContent(page.content))) {
allAttachmentIds.add(id);
}
}
}
if (allAttachmentIds.size === 0 || !spaceId) {
return new Map();
}
const attachments = await this.db
.selectFrom('attachments')
.select(['id', 'fileName', 'filePath', 'pageId'])
.where('id', 'in', [...allAttachmentIds])
.where('spaceId', '=', spaceId)
.execute();
let visible = attachments;
if (!ignorePermissions && userId) {
const ownerPageIds = [
...new Set(
attachments
.map((a) => a.pageId)
.filter((id): id is string => !!id),
),
];
const accessible = ownerPageIds.length
? await this.pagePermissionRepo.filterAccessiblePageIds({
pageIds: ownerPageIds,
userId,
spaceId,
})
: [];
const accessibleSet = new Set(accessible);
visible = attachments.filter(
(a) => a.pageId && accessibleSet.has(a.pageId),
await Promise.all(
attachments.map(async (attachment) => {
try {
const fileBuffer = await this.storageService.read(
attachment.filePath,
);
const filePath = `/files/${attachment.id}/${attachment.fileName}`;
zip.file(filePath, fileBuffer);
} catch (err) {
this.logger.debug(`Attachment export error ${attachment.id}`, err);
}
}),
);
}
return new Map(visible.map((a) => [a.id, a]));
}
async turnPageMentionsToLinks(
@@ -51,9 +51,9 @@ export class ImportController {
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
) {
const validFileExtensions = ['.md', '.html', '.docx', '.pdf'];
const validFileExtensions = ['.md', '.html', '.docx'];
const maxFileSize = bytes('30mb');
const maxFileSize = bytes('20mb');
let file = null;
try {
@@ -102,7 +102,6 @@ export class ImportController {
'.md': 'markdown',
'.html': 'html',
'.docx': 'docx',
'.pdf': 'pdf',
};
if (createdPage) {
@@ -1,6 +1,7 @@
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import { PageRepo } from '@docmost/db/repos/page/page.repo';
import { MultipartFile } from '@fastify/multipart';
import { sanitize } from 'sanitize-filename-ts';
import * as path from 'path';
import {
htmlToJson,
@@ -52,8 +53,8 @@ export class ImportService {
const file = await filePromise;
const fileBuffer = await file.toBuffer();
const fileExtension = path.extname(file.filename).toLowerCase();
const fileName = sanitizeFileName(
path.basename(file.filename, fileExtension),
const fileName = sanitize(
path.basename(file.filename, fileExtension).slice(0, 255),
);
const fileContent = fileBuffer.toString();
@@ -61,10 +62,7 @@ export class ImportService {
let createdPage = null;
// For DOCX, we need the page ID upfront so images can reference it
const pageId =
fileExtension === '.docx' || fileExtension === '.pdf'
? uuid7()
: undefined;
const pageId = fileExtension === '.docx' ? uuid7() : undefined;
try {
if (fileExtension.endsWith('.md')) {
@@ -79,14 +77,6 @@ export class ImportService {
pageId,
userId,
);
} else if (fileExtension.endsWith('.pdf')) {
prosemirrorState = await this.processPdf(
fileBuffer,
workspaceId,
spaceId,
pageId,
userId,
);
}
} catch (err) {
const message = 'Error processing file content';
@@ -163,7 +153,7 @@ export class ImportService {
let DocxImportModule: any;
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
DocxImportModule = require('./../../../ee/document-import/docx-import.service');
DocxImportModule = require('./../../../ee/docx-import/docx-import.service');
} catch (err) {
this.logger.error(
'DOCX import requested but EE module not bundled in this build',
@@ -189,42 +179,6 @@ export class ImportService {
return this.processHTML(html);
}
async processPdf(
fileBuffer: Buffer,
workspaceId: string,
spaceId: string,
pageId: string,
userId: string,
): Promise<any> {
let PdfImportModule: any;
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
PdfImportModule = require('./../../../ee/document-import/pdf-import.service');
} catch (err) {
this.logger.error(
'PDF import requested but EE module not bundled in this build',
);
throw new BadRequestException(
'This feature requires a valid enterprise license.',
);
}
const pdfImportService = this.moduleRef.get(
PdfImportModule.PdfImportService,
{ strict: false },
);
const html = await pdfImportService.convertPdfToHtml(
fileBuffer,
workspaceId,
spaceId,
pageId,
userId,
);
return this.processHTML(html);
}
async createYdoc(prosemirrorJson: any): Promise<Buffer | null> {
if (prosemirrorJson) {
// this.logger.debug(`Converting prosemirror json state to ydoc`);
@@ -1,67 +0,0 @@
import { resolve, sep } from 'path';
import { LocalDriver } from './local.driver';
type FullPath = (filePath: string) => string;
describe('LocalDriver._fullPath', () => {
const ROOT = resolve('/data/storage');
const driver = new LocalDriver({ storagePath: ROOT });
const fullPath = ((driver as any)._fullPath as FullPath).bind(driver);
describe('legitimate inputs (behavior preserved)', () => {
it.each([
['workspace-id/avatars/uuid.png', `${ROOT}${sep}workspace-id${sep}avatars${sep}uuid.png`],
['workspace-id/files/uuid/file.pdf', `${ROOT}${sep}workspace-id${sep}files${sep}uuid${sep}file.pdf`],
['a/b/c/d/e.bin', `${ROOT}${sep}a${sep}b${sep}c${sep}d${sep}e.bin`],
['', ROOT],
['.', ROOT],
['./x/y.png', `${ROOT}${sep}x${sep}y.png`],
['a//b', `${ROOT}${sep}a${sep}b`],
['a/b/../c', `${ROOT}${sep}a${sep}c`],
])('resolves %j to %j', (input, expected) => {
expect(fullPath(input)).toBe(expected);
});
});
describe('traversal rejected', () => {
it.each([
'../etc/passwd',
'../../../etc/passwd',
'workspace/../../../etc/passwd',
'..',
'../..',
'a/../../..',
])('throws for %j', (input) => {
expect(() => fullPath(input)).toThrow('Invalid file path');
});
});
describe('absolute path rejected', () => {
it.each([
'/etc/passwd',
'/root/.ssh/id_rsa',
sep + 'absolute',
])('throws for %j', (input) => {
expect(() => fullPath(input)).toThrow('Invalid file path');
});
});
describe('prefix-confusion rejected', () => {
it('rejects a sibling directory whose name starts with the storage root', () => {
const siblingDriver = new LocalDriver({ storagePath: '/data/storage' });
const siblingFullPath = ((siblingDriver as any)._fullPath as FullPath).bind(siblingDriver);
// Attempt to reach /data/storage-evil/secret by traversal:
// resolve('/data/storage', '../storage-evil/secret') === '/data/storage-evil/secret'
// Without the `+ sep` guard, a startsWith check would match.
expect(() => siblingFullPath('../storage-evil/secret')).toThrow('Invalid file path');
});
});
describe('storage root itself', () => {
it('accepts the root when input resolves to it', () => {
expect(fullPath('')).toBe(ROOT);
expect(fullPath('.')).toBe(ROOT);
expect(fullPath('a/..')).toBe(ROOT);
});
});
});
@@ -3,7 +3,7 @@ import {
LocalStorageConfig,
StorageOption,
} from '../interfaces';
import { dirname, resolve, sep } from 'path';
import { join, dirname } from 'path';
import * as fs from 'fs-extra';
import { Readable } from 'stream';
import { createReadStream, createWriteStream } from 'node:fs';
@@ -17,12 +17,7 @@ export class LocalDriver implements StorageDriver {
}
private _fullPath(filePath: string): string {
const storageRoot = resolve(this.config.storagePath);
const fullPath = resolve(storageRoot, filePath);
if (fullPath !== storageRoot && !fullPath.startsWith(storageRoot + sep)) {
throw new Error('Invalid file path');
}
return fullPath;
return join(this.config.storagePath, filePath);
}
async upload(filePath: string, file: Buffer | Readable): Promise<void> {
+9 -10
View File
@@ -1,7 +1,7 @@
{
"name": "docmost",
"homepage": "https://docmost.com",
"version": "0.80.1",
"version": "0.80.0",
"private": true,
"scripts": {
"build": "nx run-many -t build",
@@ -62,7 +62,7 @@
"cross-env": "^10.1.0",
"date-fns": "^4.1.0",
"diff": "8.0.3",
"dompurify": "3.4.1",
"dompurify": "^3.3.3",
"fractional-indexing-jittered": "^1.0.0",
"highlight.js": "^11.11.1",
"image-dimensions": "^2.5.0",
@@ -72,7 +72,7 @@
"ms": "3.0.0-canary.1",
"qrcode": "^1.5.4",
"rfc6902": "5.2.0",
"uuid": "^14.0.0",
"uuid": "^13.0.0",
"y-indexeddb": "^9.0.12",
"y-prosemirror": "1.3.7",
"yjs": "^13.6.30"
@@ -102,9 +102,9 @@
"y-prosemirror": "1.3.7",
"glob": "13.0.6",
"ws": "8.20.0",
"dompurify": "3.4.1",
"dompurify": "3.3.3",
"tmp": "0.2.5",
"hono": "4.12.14",
"hono": "4.12.12",
"mermaid": "11.13.0",
"nanoid@^3": "3.3.8",
"socket.io-parser": "4.2.6",
@@ -123,17 +123,16 @@
"flatted": "3.4.2",
"picomatch@<2.3.2": "2.3.2",
"picomatch@>=4.0.0 <4.0.4": "4.0.4",
"fastify": "5.8.5",
"fastify": "5.8.3",
"yaml@>=1.0.0 <1.10.3": "1.10.3",
"yaml@>=2.0.0 <2.8.3": "2.8.3",
"path-to-regexp@^8": "8.4.0",
"brace-expansion@^5": "5.0.5",
"@xmldom/xmldom": "0.8.13",
"@xmldom/xmldom": "0.8.12",
"handlebars": "4.7.9",
"axios": "1.15.0",
"langsmith": "0.5.19",
"follow-redirects": "1.16.0",
"protobufjs": "7.5.5"
"langsmith": "0.5.18",
"follow-redirects": "1.16.0"
},
"neverBuiltDependencies": []
}
+1030 -893
View File
File diff suppressed because it is too large Load Diff