Compare commits

...

79 Commits

Author SHA1 Message Date
Philipinho 7da96185bf update react-email 2026-05-04 22:26:10 +01:00
Philipinho 3c74bb3dee update package 2026-05-04 22:09:19 +01:00
Philip Okugbe dbe6c2d6ba feat: A11y fixes (#2148) 2026-05-04 21:21:37 +01:00
Sarthak Chaturvedi fe18f22dc6 fix: prevent code block deletion when adding inline comments in read mode (#2146) 2026-05-04 21:14:21 +01:00
Philipinho fcef0c6b96 fix: S3 2026-05-04 20:57:35 +01:00
Philipinho 17f3158a3b update aws packages 2026-05-01 20:00:20 +01:00
Philipinho b74ca00bfd sync 2026-05-01 14:57:32 +01:00
Philip Okugbe c247d4c1e3 feat(ee): PDF import (#2142)
* feat: replace pdfjs-dist with firecrawl-pdf-inspector

* use modified firecrawl-pdf-inspector

* feat: pdf import

* increase single file upload size limit

* use npm package

* sync

* update package
2026-05-01 14:56:39 +01:00
Philip Okugbe 641ce142df feat(ee): SCIM (#1347)
* SCIM - init (EE)

* accept db transaction

* sync

* Content parser support for scim+json

* patch scimmy

* sync

* return early if userIds is empty

* sync

* SCIM db table

* fixes

* scim tokens

* backfill

* feat(audit): add scim token events

* rename scim migration

* fix

* fix translation

* cleanup
2026-05-01 14:53:30 +01:00
Sarthak Chaturvedi 1d2486455f fix: prevent browser tab fallback in editor (#2123) 2026-05-01 13:58:51 +01:00
Philipinho a0aea43e25 feat(saml): allow disabling RequestedAuthnContext via env var
Adds SAML_DISABLE_REQUESTED_AUTHN_CONTEXT env var, passed through
    to the SAML strategy's disableRequestedAuthnContext option.
    Defaults to existing behavior (element sent). Set to true to omit
    the element when the IdP authenticates the user with a method that
    does not match (e.g. MFA, FIDO, passwordless), which would
    otherwise cause AADSTS75011 with Microsoft Entra ID.
2026-05-01 11:47:03 +01:00
Philip Okugbe 09c69d7a0f feat: properly preserve table width (#2143) 2026-05-01 00:49:31 +01:00
Sarthak Chaturvedi 9943e104a5 fix(i18n): Correct German column count label rendering (#2131) 2026-05-01 00:37:59 +01:00
Peter Tripp b16f1e5a55 fix: ctrl-k behavior on macOS (#2052)
* Improve cmd-k / ctrl-k behavior

Use cmd-k on macOS/iOS for search and keep ctrl-k everywhere else.

Fixes a bug where ctrl-k on macOS, which cuts to the end of the line,
was also triggering the search prompt.

* comment submit: cmd-enter (mac) / ctrl-enter (win/linux)
2026-05-01 00:36:40 +01:00
Philip Okugbe 24be90b95f fix: duplicate PDF uploads (#2139) 2026-04-29 10:01:47 +01:00
Olivier Lambert 3ecf27c6b0 fix(page-permission): make people-with-access list scroll past 4 entries (#2137)
The "People with access" list in the page share modal used
<ScrollArea mah={250}>, which caps the container height but does not
make the inner viewport scroll (no fixed height is given to the
viewport). Items beyond ~4 entries were rendered correctly but clipped
out of view.

Switches to <ScrollArea.Autosize mah={400}>, which is Mantine's
dedicated primitive for "grow with content up to a max, then scroll".

Closes #2135
2026-04-29 09:36:38 +01:00
Philipinho 980521f957 v0.80.1 2026-04-27 16:06:32 +01:00
Philipinho fe44dc92a9 sync 2026-04-27 15:51:23 +01:00
Philip Okugbe fad410ef23 chore: add undici for oidc proxy support (#2132) 2026-04-27 15:50:42 +01:00
Philipinho 15b8908b1a update postcss 2026-04-27 15:23:47 +01:00
Philipinho 8e15b22d8c package updates 2026-04-27 15:22:02 +01:00
Philipinho ec83fc82d5 fix: refactor sanitize 2026-04-27 15:16:26 +01:00
Philipinho a573acedd0 fix: local storage, and package overrides 2026-04-22 14:13:25 +01:00
Philipinho dba8e315ab override 2026-04-14 17:59:59 +01:00
Philipinho 81ae7a17a6 confirm dialog 2026-04-14 17:56:36 +01:00
Philipinho 271f855761 v0.80.0 2026-04-14 17:08:44 +01:00
Philipinho 3e6d915227 sync 2026-04-14 16:34:44 +01:00
Philip Okugbe a6a7e4370a feat(ee): PDF export api (#2112)
* feat(ee): server side PDF export

* feat: pdf export queue

* sync

* sync
2026-04-14 16:26:54 +01:00
Philip Okugbe cc00e77dfb fix: space overview favorites (#2110) 2026-04-14 02:58:24 +01:00
Philipinho 66c70c0e76 fix print 2026-04-14 00:40:17 +01:00
Philip Okugbe 0e8b3bbfb3 New Crowdin updates (#2109)
* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Italian)

* New translations translation.json (Japanese)

* New translations translation.json (Korean)

* New translations translation.json (Dutch)

* New translations translation.json (Russian)

* New translations translation.json (Ukrainian)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)
2026-04-14 00:05:51 +01:00
Philip Okugbe a3a9f35005 fix home flickers (#2108) 2026-04-13 23:54:03 +01:00
Philip Okugbe 4056bd0104 feat: enhancements (#2107)
* refactor
* fix
* update packages
2026-04-13 23:34:40 +01:00
Philip Okugbe bd68e47e03 feat(ee): page verification workflow (#2102)
* feat: page verification workflow

* feat: refactor page-verification

* sync

* fix type

* fix

* fix

* notification icon

* use full word

* accept .license file

* - update templates
- update migration and notification

* fix copy

* update audit labels

* sync

* add space name
2026-04-13 20:20:34 +01:00
Philip Okugbe d6068310b4 Merge commit from fork
Refactor link.ts to simplify HTML parsing and rendering logic.
2026-04-13 01:09:36 +01:00
Philipinho e02661974e sync 2026-04-13 00:13:18 +01:00
Philip Okugbe 1113f17a43 New Crowdin updates (#2104) 2026-04-12 22:46:39 +01:00
Philip Okugbe d42091ccb1 feat: favorites (#2103)
* feat: favorites and templates(ee)

* rename migrations

* fix sidebar

* cleanup tabs

* fix

* turn off templates

* cleanup

* uuid validation
2026-04-12 22:06:25 +01:00
Philip Okugbe 57efb91bd3 feat(ee): ai chat (#2098)
* feat: ai chat

* feat: ai chat

* sync

* cleanup

* view space button
2026-04-10 19:23:47 +01:00
Philip Okugbe da9b43681e feat: watch space (#2096) 2026-04-09 00:37:51 +01:00
Philipinho 4966f9b152 fix(deps): package updates 2026-04-07 10:24:46 +01:00
Philipinho e1bbceb9a6 fix: logs 2026-04-07 10:10:41 +01:00
Philip Okugbe 895c1817ae feat: bug fixes (#2084)
* handle enter in inline code

* fix: duplicate comment cache

* track link nodes (backlinks)

* fix en-US translation

* fix internal a-links

* overrides

* 0.71.1
2026-04-05 13:45:36 +01:00
Philip Okugbe 642024ba9d New Crowdin updates (#2078) 2026-03-31 21:14:41 +01:00
Philipinho 147d028036 v0.71.0 2026-03-31 20:42:37 +01:00
Philipinho 992691e6e0 fix module import 2026-03-31 20:41:09 +01:00
Philip Okugbe 9aaa6c731c feat: add AI_EMBEDDING_SUPPORTS_MRL env var to decouple pgvector dimensions from model API (#2079)
Some embedding models don't accept a `dimensions` parameter. This adds
an optional env var that controls whether the dimension is sent to the
model API, while always using it for pgvector indexing. Preset models
have this handled automatically; the env var allows explicit override
for custom models.
2026-03-31 19:39:49 +01:00
Philipinho fd91b11c6c pin version 2026-03-31 16:06:44 +01:00
Philipinho af8b0ddf3a sync 2026-03-31 16:05:09 +01:00
Philip Okugbe 879aa2c3d8 feat: page update notifications (#2074)
* feat: watchers notification and email preferences

* fix: email copy

* digests

* clean up

* fix

* clean up

* move backlinks queue-up to history processor

* fix

* fix keys

* feat: group notifications

* filter

* adjust email digest window
2026-03-31 16:03:59 +01:00
Philip Okugbe c180d0e487 feat: ratelimits (#2073)
* feat: rate limits

* ip
2026-03-30 15:38:44 +01:00
Philip Okugbe a062f7a165 fix: enhance confluence importer (#2072)
* fix placeholder

* min resize dimensions

* fix media links

* fix
2026-03-30 13:16:40 +01:00
Philip Okugbe cbd0dd4a0b feat: indexes (#2071) 2026-03-29 20:29:12 +01:00
Philip Okugbe 2d6d829581 New translations translation.json (English) (#2066) 2026-03-29 16:25:45 +01:00
Philipinho 5cea30cc5c fix markdown paste 2026-03-29 16:11:21 +01:00
Philipinho bca85a49d6 pin marked version 2026-03-29 03:03:35 +01:00
Philipinho c9cdfa0f17 fix 2026-03-29 02:20:56 +01:00
Philip Okugbe 412962204c fix: editor fixes (#2067)
* autojoiner

* fix marked

* return clipboardTextSerializer as markdown

* fix clipboardTextSerializer for single lines

* cleanup two preceeding spaces in ordered lists item

* fix extra paragraph in task list

* don't zip sinple page exports
2026-03-29 02:19:09 +01:00
Olivier Lambert a42ac3d450 fix: strip trailing whitespace-only paragraphs from pasted content (#2050) 2026-03-28 22:26:47 +00:00
Philipinho 642c92f779 fix select 2026-03-28 20:34:44 +00:00
Philipinho ccb35517bb sync 2026-03-28 20:29:31 +00:00
Philip Okugbe cbdb37ed0a New Crowdin updates (#2061) 2026-03-28 20:29:06 +00:00
Julien Fontanet aa27d57624 fix: notification items are now real links (#2039)
Replace UnstyledButton with UnstyledButton component={Link} so each
notification renders as a real anchor element. Regular left-clicks use
SPA navigation and close the popover; Ctrl/Cmd/middle-click open the
page in a new tab. All click types mark the notification as read.
2026-03-28 20:23:21 +00:00
Philip Okugbe 3829b6cbef feat(ee): viewer comments (#2060) 2026-03-28 19:32:52 +00:00
Philipinho 17da762984 overrides 2026-03-28 19:28:22 +00:00
Philipinho 859f16740b tooltip portal 2026-03-28 19:19:00 +00:00
Philip Okugbe 7981ef462e feat(editor): audio and PDF nodes (#2064)
* use local resizable

* feat: aduio

* support audio imports

* feat: use confluence real file names

* cleanup

* error handling

* hide notice

* add audio

* fix pulse

* Fix import and export

* unify pulse

* hide in readonly mode

* keywords

* keyword

* translations

* better sort

* feat: PDF embed

* cleanup

* remove audio menu

* open active

* hide focus on readonly mode

* increase iframe default dimension
2026-03-28 17:33:29 +00:00
Philip Okugbe 2d835da0e3 New Crowdin updates (#2059) 2026-03-27 22:11:19 +00:00
Philipinho a3559b7c33 sync 2026-03-26 20:01:02 +00:00
Philip Okugbe 803f1f0b81 feat: user session management (#2056)
* user session management

* WIP

* cleanup

* license

* cleanup

* don't cache index

* rename current device property

* fix
2026-03-26 20:00:04 +00:00
Philipinho 4e8f533b91 override 2026-03-26 16:48:33 +00:00
Philipinho 7b0d8fe140 override 2026-03-26 16:46:40 +00:00
Philipinho 2f92278a9d sync 2026-03-26 16:35:05 +00:00
Philipinho 53608eae35 clean up ws 2026-03-26 13:59:17 +00:00
Philipinho 0e4a1e7419 enum validation 2026-03-26 00:41:38 +00:00
Philipinho 9125996e97 sync 2026-03-25 10:08:36 +00:00
Philip Okugbe fa4872e89e fix(deps): package updates (#2041)
* update
* overrides
* override
* fix page update mutation
* fix
* cleanup
* loader
* fix excalidraw package
* override
* fix regex
2026-03-25 10:07:01 +00:00
Philipinho 6d6f3a8a8e merge commit 2026-03-24 10:52:09 +00:00
Philip Okugbe 975b4dcaab feat: auth pages layout (#2042)
* auth pages layout
* exclude home route from redirect
* fix margin
2026-03-22 16:40:50 +00:00
431 changed files with 30092 additions and 7335 deletions
+3
View File
@@ -43,6 +43,9 @@ POSTMARK_TOKEN=
# for custom drawio server # for custom drawio server
DRAWIO_URL= DRAWIO_URL=
# Gotenberg URL for server-side PDF export
GOTENBERG_URL=
DISABLE_TELEMETRY=false DISABLE_TELEMETRY=false
# Enable debug logging in production (default: false) # Enable debug logging in production (default: false)
+39 -39
View File
@@ -1,7 +1,7 @@
{ {
"name": "client", "name": "client",
"private": true, "private": true,
"version": "0.70.3", "version": "0.80.1",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc && vite build", "build": "tsc && vite build",
@@ -10,76 +10,76 @@
"format": "prettier --write \"src/**/*.tsx\" \"src/**/*.ts\"" "format": "prettier --write \"src/**/*.tsx\" \"src/**/*.ts\""
}, },
"dependencies": { "dependencies": {
"@casl/react": "^4.0.0", "@casl/react": "^5.0.1",
"@docmost/editor-ext": "workspace:*", "@docmost/editor-ext": "workspace:*",
"@emoji-mart/data": "^1.2.1", "@emoji-mart/data": "^1.2.1",
"@emoji-mart/react": "^1.1.1", "@emoji-mart/react": "^1.1.1",
"@excalidraw/excalidraw": "0.18.0-3a5ef40", "@excalidraw/excalidraw": "0.18.0-3a5ef40",
"@mantine/core": "^8.3.14", "@mantine/core": "^8.3.18",
"@mantine/dates": "^8.3.14", "@mantine/dates": "^8.3.18",
"@mantine/form": "^8.3.14", "@mantine/form": "^8.3.18",
"@mantine/hooks": "^8.3.14", "@mantine/hooks": "^8.3.18",
"@mantine/modals": "^8.3.14", "@mantine/modals": "^8.3.18",
"@mantine/notifications": "^8.3.14", "@mantine/notifications": "^8.3.18",
"@mantine/spotlight": "^8.3.14", "@mantine/spotlight": "^8.3.18",
"@tabler/icons-react": "^3.36.1", "@tabler/icons-react": "^3.40.0",
"@tanstack/react-query": "^5.90.17", "@tanstack/react-query": "5.90.17",
"alfaaz": "^1.1.0", "alfaaz": "^1.1.0",
"axios": "^1.13.5", "axios": "1.15.0",
"blueimp-load-image": "^5.16.0", "blueimp-load-image": "^5.16.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"emoji-mart": "^5.6.0", "emoji-mart": "^5.6.0",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"highlightjs-sap-abap": "^0.3.0", "highlightjs-sap-abap": "^0.3.0",
"i18next": "^23.16.8", "i18next": "25.10.1",
"i18next-http-backend": "^2.7.3", "i18next-http-backend": "3.0.6",
"jotai": "^2.16.2", "jotai": "^2.18.1",
"jotai-optics": "^0.4.0", "jotai-optics": "^0.4.0",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"katex": "0.16.27", "katex": "0.16.40",
"lowlight": "^3.3.0", "lowlight": "^3.3.0",
"mantine-form-zod-resolver": "^1.3.0", "mantine-form-zod-resolver": "^1.3.0",
"mermaid": "^11.12.2", "mermaid": "^11.13.0",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"posthog-js": "1.345.5", "posthog-js": "1.372.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-arborist": "3.4.0", "react-arborist": "3.4.0",
"react-clear-modal": "^2.0.17", "react-clear-modal": "^2.0.18",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-drawio": "^1.0.7", "react-drawio": "^1.0.7",
"react-error-boundary": "^4.1.2", "react-error-boundary": "^6.1.1",
"react-helmet-async": "^2.0.5", "react-helmet-async": "^3.0.0",
"react-i18next": "^15.0.1", "react-i18next": "16.5.8",
"react-router-dom": "^7.12.0", "react-router-dom": "^7.13.1",
"semver": "^7.7.3", "semver": "^7.7.4",
"socket.io-client": "^4.8.3", "socket.io-client": "^4.8.3",
"tiptap-extension-global-drag-handle": "^0.1.18", "tiptap-extension-global-drag-handle": "^0.1.18",
"zod": "^4.3.6" "zod": "^4.3.6"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.16.0", "@eslint/js": "^9.28.0",
"@tanstack/eslint-plugin-query": "^5.62.1", "@tanstack/eslint-plugin-query": "^5.94.4",
"@types/blueimp-load-image": "^5.16.0", "@types/blueimp-load-image": "^5.16.6",
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/katex": "^0.16.7", "@types/katex": "^0.16.8",
"@types/node": "22.19.1", "@types/node": "22.19.1",
"@types/react": "^18.3.12", "@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1", "@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^5.1.1", "@vitejs/plugin-react": "^6.0.1",
"eslint": "^9.39.2", "eslint": "^9.28.0",
"eslint-plugin-react": "^7.37.2", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.16", "eslint-plugin-react-refresh": "^0.5.2",
"globals": "^15.13.0", "globals": "^15.13.0",
"optics-ts": "^2.4.1", "optics-ts": "^2.4.1",
"postcss": "^8.4.49", "postcss": "^8.5.12",
"postcss-preset-mantine": "^1.17.0", "postcss-preset-mantine": "^1.18.0",
"postcss-simple-vars": "^7.0.1", "postcss-simple-vars": "^7.0.1",
"prettier": "^3.4.1", "prettier": "^3.8.1",
"typescript": "^5.7.2", "typescript": "^5.9.3",
"typescript-eslint": "^8.17.0", "typescript-eslint": "^8.57.1",
"vite": "^7.2.4" "vite": "8.0.5"
} }
} }
+281 -94
View File
@@ -7,6 +7,7 @@
"Add members": "Mitglieder hinzufügen", "Add members": "Mitglieder hinzufügen",
"Add to groups": "Zu Gruppen hinzufügen", "Add to groups": "Zu Gruppen hinzufügen",
"Add space members": "Bereichsmitglieder hinzufügen", "Add space members": "Bereichsmitglieder hinzufügen",
"Add to favorites": "Zu Favoriten hinzufügen",
"Admin": "Administrator", "Admin": "Administrator",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Sind Sie sicher, dass Sie diese Gruppe löschen möchten? Mitglieder verlieren den Zugang zu den Ressourcen, auf die diese Gruppe zugreifen kann.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Sind Sie sicher, dass Sie diese Gruppe löschen möchten? Mitglieder verlieren den Zugang zu den Ressourcen, auf die diese Gruppe zugreifen kann.",
"Are you sure you want to delete this page?": "Sind Sie sicher, dass Sie diese Seite löschen möchten?", "Are you sure you want to delete this page?": "Sind Sie sicher, dass Sie diese Seite löschen möchten?",
@@ -45,21 +46,21 @@
"Description": "Beschreibung", "Description": "Beschreibung",
"Details": "Details", "Details": "Details",
"e.g ACME": "z. B. ACME", "e.g ACME": "z. B. ACME",
"e.g ACME Inc": "z.B. ACME Inc.", "e.g ACME Inc": "z. B. ACME GmbH",
"e.g Developers": "z. B. Entwickler", "e.g Developers": "z. B. Entwickler",
"e.g Group for developers": "z. B. Gruppe für Entwickler", "e.g Group for developers": "z. B. Gruppe für Entwickler",
"e.g product": "z. B. Produkt", "e.g product": "z. B. Produkt",
"e.g Product Team": "z. B. Produktteam", "e.g Product Team": "z. B. Produktteam",
"e.g Sales": "z. B. Vertrieb", "e.g Sales": "z. B. Vertrieb",
"e.g Space for product team": "z. B. Bereich für das Produktteam", "e.g Space for product team": "z. B. Bereich für das Produktteam",
"e.g Space for sales team to collaborate": "z.B. Bereich für das Vertriebsteam zur Zusammenarbeit", "e.g Space for sales team to collaborate": "z. B. Bereich zur Zusammenarbeit für das Vertriebsteam",
"Edit": "Bearbeiten", "Edit": "Bearbeiten",
"Read": "Lesen", "Read": "Lesen",
"Edit group": "Gruppe bearbeiten", "Edit group": "Gruppe bearbeiten",
"Email": "E-Mail", "Email": "E-Mail",
"Enter a strong password": "Geben Sie ein starkes Passwort ein", "Enter a strong password": "Geben Sie ein starkes Passwort ein",
"Enter valid email addresses separated by comma or space max_50": "Geben Sie gültige E-Mail-Adressen ein, getrennt durch Kommas oder Leerzeichen [max: 50]", "Enter valid email addresses separated by comma or space max_50": "Geben Sie gültige E-Mail-Adressen ein, getrennt durch Kommas oder Leerzeichen [max: 50]",
"enter valid emails addresses": "gültige E-Mail-Adressen eingeben", "enter valid emails addresses": "Geben Sie gültige E-Mail-Adressen ein",
"Enter your current password": "Geben Sie Ihr aktuelles Passwort ein", "Enter your current password": "Geben Sie Ihr aktuelles Passwort ein",
"enter your full name": "Geben Sie Ihren vollständigen Namen ein", "enter your full name": "Geben Sie Ihren vollständigen Namen ein",
"Enter your new password": "Geben Sie Ihr neues Passwort ein", "Enter your new password": "Geben Sie Ihr neues Passwort ein",
@@ -74,6 +75,9 @@
"Failed to import pages": "Import der Seiten fehlgeschlagen", "Failed to import pages": "Import der Seiten fehlgeschlagen",
"Failed to load page. An error occurred.": "Seite konnte nicht geladen werden. Es ist ein Fehler aufgetreten.", "Failed to load page. An error occurred.": "Seite konnte nicht geladen werden. Es ist ein Fehler aufgetreten.",
"Failed to update data": "Aktualisierung der Daten fehlgeschlagen", "Failed to update data": "Aktualisierung der Daten fehlgeschlagen",
"Favorite spaces": "Favorisierte Bereiche",
"Favorite spaces appear here": "Favorisierte Bereiche werden hier angezeigt",
"Favorites": "Favoriten",
"Full access": "Voller Zugriff", "Full access": "Voller Zugriff",
"Full page width": "Volle Seitenbreite", "Full page width": "Volle Seitenbreite",
"Full width": "Volle Breite", "Full width": "Volle Breite",
@@ -87,11 +91,12 @@
"Import pages": "Seiten importieren", "Import pages": "Seiten importieren",
"Import pages & space settings": "Seiten und Bereichseinstellungen importieren", "Import pages & space settings": "Seiten und Bereichseinstellungen importieren",
"Importing pages": "Seiten werden importiert", "Importing pages": "Seiten werden importiert",
"invalid invitation link": "ungültiger Einladungslink", "invalid invitation link": "Ungültiger Einladungslink",
"Invitation signup": "Einladung zur Anmeldung", "Invitation signup": "Einladung zur Anmeldung",
"Invite by email": "Einladen per E-Mail", "Invite by email": "Einladen per E-Mail",
"Invite members": "Mitglieder einladen", "Invite members": "Mitglieder einladen",
"Invite new members": "Neue Mitglieder einladen", "Invite new members": "Neue Mitglieder einladen",
"Invite People": "Personen einladen",
"Invited members who are yet to accept their invitation will appear here.": "Eingeladene Mitglieder, die ihre Einladung noch nicht angenommen haben, werden hier angezeigt.", "Invited members who are yet to accept their invitation will appear here.": "Eingeladene Mitglieder, die ihre Einladung noch nicht angenommen haben, werden hier angezeigt.",
"Invited members will be granted access to spaces the groups can access": "Eingeladene Mitglieder erhalten Zugriff auf die Bereiche, auf die die Gruppen zugreifen können", "Invited members will be granted access to spaces the groups can access": "Eingeladene Mitglieder erhalten Zugriff auf die Bereiche, auf die die Gruppen zugreifen können",
"Join the workspace": "Dem Arbeitsbereich beitreten", "Join the workspace": "Dem Arbeitsbereich beitreten",
@@ -139,6 +144,7 @@
"Profile": "Profil", "Profile": "Profil",
"Recently updated": "Kürzlich aktualisiert", "Recently updated": "Kürzlich aktualisiert",
"Remove": "Entfernen", "Remove": "Entfernen",
"Remove from favorites": "Aus Favoriten entfernen",
"Remove group member": "Gruppenmitglied entfernen", "Remove group member": "Gruppenmitglied entfernen",
"Remove space member": "Bereichsmitglied entfernen", "Remove space member": "Bereichsmitglied entfernen",
"Restore": "Wiederherstellen", "Restore": "Wiederherstellen",
@@ -151,12 +157,12 @@
"Search...": "Suche...", "Search...": "Suche...",
"Select language": "Sprache auswählen", "Select language": "Sprache auswählen",
"Select role": "Rolle auswählen", "Select role": "Rolle auswählen",
"Select role to assign to all invited members": "Rolle für alle eingeladenen Mitglieder auswählen", "Select role to assign to all invited members": "Wählen Sie die Rolle aus, die allen eingeladenen Mitgliedern zugewiesen werden soll",
"Select theme": "Design auswählen", "Select theme": "Design auswählen",
"Send invitation": "Einladung senden", "Send invitation": "Einladung senden",
"Invitation sent": "Einladung gesendet", "Invitation sent": "Einladung gesendet",
"Settings": "Einstellungen", "Settings": "Einstellungen",
"Setup workspace": "Arbeitsbereich einrichten", "Setup workspace": "Workspace einrichten",
"Sign In": "Anmelden", "Sign In": "Anmelden",
"Sign Up": "Registrieren", "Sign Up": "Registrieren",
"Slug": "Slug", "Slug": "Slug",
@@ -165,16 +171,17 @@
"Space menu": "Bereichsmenü", "Space menu": "Bereichsmenü",
"Space name": "Bereichsname", "Space name": "Bereichsname",
"Space settings": "Bereichseinstellungen", "Space settings": "Bereichseinstellungen",
"Space slug": "Slug des Bereichs", "Space slug": "Bereichs-Slug",
"Spaces": "Bereiche", "Spaces": "Bereiche",
"Spaces you belong to": "Bereiche, denen Sie angehören", "Spaces you belong to": "Bereiche, zu denen Sie gehören",
"No space found": "Keine Bereiche gefunden", "No space found": "Kein Bereich gefunden",
"Search for spaces": "Nach Bereichen suchen", "Search for spaces": "Nach Bereichen suchen",
"Start typing to search...": "Anfangen zu tippen, um zu suchen...", "Start typing to search...": "Anfangen zu tippen, um zu suchen...",
"Status": "Status", "Status": "Status",
"Successfully imported": "Erfolgreich importiert", "Successfully imported": "Erfolgreich importiert",
"Successfully restored": "Erfolgreich wiederhergestellt", "Successfully restored": "Erfolgreich wiederhergestellt",
"System settings": "Systemeinstellungen", "System settings": "Systemeinstellungen",
"Templates": "Vorlagen",
"Theme": "Design", "Theme": "Design",
"To change your email, you have to enter your password and new email.": "Um Ihre E-Mail-Adresse zu ändern, müssen Sie Ihr Passwort und Ihre neue E-Mail-Adresse eingeben.", "To change your email, you have to enter your password and new email.": "Um Ihre E-Mail-Adresse zu ändern, müssen Sie Ihr Passwort und Ihre neue E-Mail-Adresse eingeben.",
"Toggle full page width": "Volle Seitenbreite umschalten", "Toggle full page width": "Volle Seitenbreite umschalten",
@@ -183,9 +190,9 @@
"Untitled": "Ohne Titel", "Untitled": "Ohne Titel",
"Updated successfully": "Erfolgreich aktualisiert", "Updated successfully": "Erfolgreich aktualisiert",
"User": "Benutzer", "User": "Benutzer",
"Workspace": "Arbeitsbereich", "Workspace": "Workspace",
"Workspace Name": "Arbeitsbereichsname", "Workspace Name": "Workspace-Name",
"Workspace settings": "Arbeitsbereich-Einstellungen", "Workspace settings": "Workspace-Einstellungen",
"You can change your password here.": "Hier können Sie Ihr Passwort ändern.", "You can change your password here.": "Hier können Sie Ihr Passwort ändern.",
"Your Email": "Ihre E-Mail", "Your Email": "Ihre E-Mail",
"Your import is complete.": "Ihr Import ist abgeschlossen.", "Your import is complete.": "Ihr Import ist abgeschlossen.",
@@ -215,6 +222,8 @@
"Edit comment": "Kommentar bearbeiten", "Edit comment": "Kommentar bearbeiten",
"Delete comment": "Kommentar löschen", "Delete comment": "Kommentar löschen",
"Are you sure you want to delete this comment?": "Sind Sie sicher, dass Sie diesen Kommentar löschen möchten?", "Are you sure you want to delete this comment?": "Sind Sie sicher, dass Sie diesen Kommentar löschen möchten?",
"Delete chat": "Chat löschen",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Sind Sie sicher, dass Sie '{{title}}' löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
"Comment created successfully": "Kommentar erfolgreich erstellt", "Comment created successfully": "Kommentar erfolgreich erstellt",
"Error creating comment": "Fehler beim Erstellen des Kommentars", "Error creating comment": "Fehler beim Erstellen des Kommentars",
"Comment updated successfully": "Kommentar erfolgreich aktualisiert", "Comment updated successfully": "Kommentar erfolgreich aktualisiert",
@@ -223,12 +232,12 @@
"Failed to delete comment": "Löschen des Kommentars fehlgeschlagen", "Failed to delete comment": "Löschen des Kommentars fehlgeschlagen",
"Comment resolved successfully": "Kommentar erfolgreich gelöst", "Comment resolved successfully": "Kommentar erfolgreich gelöst",
"Comment re-opened successfully": "Kommentar erfolgreich wieder geöffnet", "Comment re-opened successfully": "Kommentar erfolgreich wieder geöffnet",
"Comment unresolved successfully": "Kommentar erfolgreich ungelöst", "Comment unresolved successfully": "Kommentar erfolgreich als ungelöst markiert",
"Failed to resolve comment": "Lösen des Kommentars fehlgeschlagen", "Failed to resolve comment": "Lösen des Kommentars fehlgeschlagen",
"Resolve comment": "Kommentar lösen", "Resolve comment": "Kommentar lösen",
"Unresolve comment": "Kommentar nicht lösen", "Unresolve comment": "Kommentar als ungelöst markieren",
"Resolve Comment Thread": "Kommentarthread lösen", "Resolve Comment Thread": "Kommentarthread lösen",
"Unresolve Comment Thread": "Kommentarthread nicht lösen", "Unresolve Comment Thread": "Kommentarthread als ungelöst markieren",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Sind Sie sicher, dass Sie diesen Kommentarthread lösen möchten? Dies wird als abgeschlossen markiert.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Sind Sie sicher, dass Sie diesen Kommentarthread lösen möchten? Dies wird als abgeschlossen markiert.",
"Are you sure you want to unresolve this comment thread?": "Sind Sie sicher, dass Sie diesen Kommentarthread nicht lösen möchten?", "Are you sure you want to unresolve this comment thread?": "Sind Sie sicher, dass Sie diesen Kommentarthread nicht lösen möchten?",
"Resolved": "Gelöst", "Resolved": "Gelöst",
@@ -241,7 +250,7 @@
"Anyone with this link can join this workspace.": "Jeder mit diesem Link kann dem Arbeitsbereich beitreten.", "Anyone with this link can join this workspace.": "Jeder mit diesem Link kann dem Arbeitsbereich beitreten.",
"Invite link": "Einladungslink", "Invite link": "Einladungslink",
"Copy": "Kopieren", "Copy": "Kopieren",
"Copy to space": "In Raum kopieren", "Copy to space": "In Bereich kopieren",
"Copied": "Kopiert", "Copied": "Kopiert",
"Duplicate": "Duplizieren", "Duplicate": "Duplizieren",
"Select a user": "Benutzer auswählen", "Select a user": "Benutzer auswählen",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "Sind Sie sicher, dass Sie diesen Bereich löschen möchten?", "Are you sure you want to delete this space?": "Sind Sie sicher, dass Sie diesen Bereich löschen möchten?",
"Delete this space with all its pages and data.": "Diesen Bereich mit allen Seiten und Daten löschen.", "Delete this space with all its pages and data.": "Diesen Bereich mit allen Seiten und Daten löschen.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Alle Seiten, Kommentare, Anhänge und Berechtigungen in diesem Bereich werden unwiderruflich gelöscht.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Alle Seiten, Kommentare, Anhänge und Berechtigungen in diesem Bereich werden unwiderruflich gelöscht.",
"Confirm space name": "Bestätigen Sie den Namen des Arbeitsbereichs", "Confirm space name": "Bereichsnamen bestätigen",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Geben Sie den Namen des Bereichs <b>{{spaceName}}</b> ein, um Ihre Aktion zu bestätigen.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "Geben Sie den Namen des Bereichs <b>{{spaceName}}</b> ein, um Ihre Aktion zu bestätigen.",
"Format": "Format", "Format": "Format",
"Include subpages": "Unterseiten einbeziehen", "Include subpages": "Unterseiten einbeziehen",
@@ -289,6 +298,11 @@
"Save & Exit": "Speichern & Beenden", "Save & Exit": "Speichern & Beenden",
"Double-click to edit Excalidraw diagram": "Zum Bearbeiten des Excalidraw-Diagramms doppelklicken", "Double-click to edit Excalidraw diagram": "Zum Bearbeiten des Excalidraw-Diagramms doppelklicken",
"Paste link": "Link einfügen", "Paste link": "Link einfügen",
"Paste link or search pages": "Link einfügen oder Seiten durchsuchen",
"Link to web page": "Link zur Webseite",
"Recents": "Zuletzt verwendet",
"Page or URL": "Seite oder URL",
"Link title": "Linktitel",
"Edit link": "Link bearbeiten", "Edit link": "Link bearbeiten",
"Remove link": "Link entfernen", "Remove link": "Link entfernen",
"Add link": "Link hinzufügen", "Add link": "Link hinzufügen",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Horizontale Trennlinie einfügen", "Insert horizontal rule divider": "Horizontale Trennlinie einfügen",
"Upload any image from your device.": "Laden Sie ein beliebiges Bild von Ihrem Gerät hoch.", "Upload any image from your device.": "Laden Sie ein beliebiges Bild von Ihrem Gerät hoch.",
"Upload any video from your device.": "Laden Sie ein beliebiges Video von Ihrem Gerät hoch.", "Upload any video from your device.": "Laden Sie ein beliebiges Video von Ihrem Gerät hoch.",
"Upload any audio from your device.": "Laden Sie beliebige Audiodateien von Ihrem Gerät hoch.",
"Upload any file from your device.": "Laden Sie eine beliebige Datei von Ihrem Gerät hoch.", "Upload any file from your device.": "Laden Sie eine beliebige Datei von Ihrem Gerät hoch.",
"Uploading {{name}}": "Lade {{name}} hoch", "Uploading {{name}}": "Lade {{name}} hoch",
"Uploading file": "Datei wird hochgeladen", "Uploading file": "Datei wird hochgeladen",
@@ -346,20 +361,26 @@
"Divider": "Trennlinie", "Divider": "Trennlinie",
"Quote": "Zitat", "Quote": "Zitat",
"Image": "Bild", "Image": "Bild",
"Audio": "Audio",
"Embed PDF": "PDF einbetten",
"Upload and embed a PDF file.": "Laden Sie eine PDF-Datei hoch und betten Sie sie ein.",
"Embed as PDF": "Als PDF einbetten",
"Failed to load PDF": "Fehler beim Laden der PDF",
"Convert to attachment": "In Anhang umwandeln",
"File attachment": "Dateianhang", "File attachment": "Dateianhang",
"Toggle block": "Block umschalten", "Toggle block": "Umschaltblock",
"Callout": "Hinweisbox", "Callout": "Hinweisblock",
"Insert callout notice.": "Hinweisbox einfügen.", "Insert callout notice.": "Hinweisbox einfügen.",
"Math inline": "Mathe inline", "Math inline": "Mathe inline",
"Insert inline math equation.": "Mathe-Gleichung inline einfügen.", "Insert inline math equation.": "Mathe-Gleichung inline einfügen.",
"Math block": "Matheblock", "Math block": "Matheblock",
"Insert math equation": "Mathe-Gleichung einfügen", "Insert math equation": "Mathematische Gleichung einfügen",
"Mermaid diagram": "Mermaid-Diagramm", "Mermaid diagram": "Mermaid-Diagramm",
"Insert mermaid diagram": "Mermaid-Diagramm einfügen", "Insert mermaid diagram": "Mermaid-Diagramm einfügen",
"Insert and design Drawio diagrams": "Drawio-Diagramme einfügen und gestalten", "Insert and design Drawio diagrams": "Drawio-Diagramme einfügen und gestalten",
"Insert current date": "Aktuelles Datum einfügen", "Insert current date": "Aktuelles Datum einfügen",
"Draw and sketch excalidraw diagrams": "Excalidraw-Diagramme zeichnen und skizzieren", "Draw and sketch excalidraw diagrams": "Excalidraw-Diagramme zeichnen und skizzieren",
"Multiple": "Mehrere", "Multiple": "Mehrfach",
"Turn into": "In verwandeln", "Turn into": "In verwandeln",
"Text align": "Text ausrichten", "Text align": "Text ausrichten",
"This page may have been deleted, moved, or you may not have access.": "\"Diese Seite wurde möglicherweise gelöscht, verschoben oder Sie haben keinen Zugriff darauf.\"", "This page may have been deleted, moved, or you may not have access.": "\"Diese Seite wurde möglicherweise gelöscht, verschoben oder Sie haben keinen Zugriff darauf.\"",
@@ -367,10 +388,10 @@
"Pages you create will show up here.": "\"Die von Ihnen erstellten Seiten werden hier angezeigt.\"", "Pages you create will show up here.": "\"Die von Ihnen erstellten Seiten werden hier angezeigt.\"",
"Heading {{level}}": "Überschrift {{level}}", "Heading {{level}}": "Überschrift {{level}}",
"Toggle title": "Titel umschalten", "Toggle title": "Titel umschalten",
"Write anything. Enter \"/\" for commands": "Schreiben Sie irgendetwas. Geben Sie \"/\" für Befehle ein", "Write anything. Enter \"/\" for commands": "Schreiben Sie etwas. Geben Sie \"/\" für Befehle ein",
"Write...": "\"Schreiben...\"", "Write...": "\"Schreiben...\"",
"Column count": "Spaltenanzahl", "Column count": "Spaltenanzahl",
"{{count}} Columns": "{count, plural, one {# Spalte} other {# Spalten}}", "{{count}} Columns": "{{count}} Spalten",
"Equal columns": "Gleich breite Spalten", "Equal columns": "Gleich breite Spalten",
"Left sidebar": "Linke Seitenleiste", "Left sidebar": "Linke Seitenleiste",
"Right sidebar": "Rechte Seitenleiste", "Right sidebar": "Rechte Seitenleiste",
@@ -380,9 +401,9 @@
"Names do not match": "Namen stimmen nicht überein", "Names do not match": "Namen stimmen nicht überein",
"Today, {{time}}": "Heute, {{time}}", "Today, {{time}}": "Heute, {{time}}",
"Yesterday, {{time}}": "Gestern, {{time}}", "Yesterday, {{time}}": "Gestern, {{time}}",
"Space created successfully": "Der Bereich wurde erfolgreich erstellt", "Space created successfully": "Bereich erfolgreich erstellt",
"Space updated successfully": "Der Bereich wurde erfolgreich aktualisiert", "Space updated successfully": "Bereich erfolgreich aktualisiert",
"Space deleted successfully": "Der Bereich wurde erfolgreich gelöscht", "Space deleted successfully": "Bereich erfolgreich gelöscht",
"Members added successfully": "Mitglieder erfolgreich hinzugefügt", "Members added successfully": "Mitglieder erfolgreich hinzugefügt",
"Member removed successfully": "Mitglied erfolgreich entfernt", "Member removed successfully": "Mitglied erfolgreich entfernt",
"Member role updated successfully": "Mitgliederrolle erfolgreich aktualisiert", "Member role updated successfully": "Mitgliederrolle erfolgreich aktualisiert",
@@ -390,10 +411,10 @@
"Created at: {{time}}": "Erstellt am: {{time}}", "Created at: {{time}}": "Erstellt am: {{time}}",
"Edited by {{name}} {{time}}": "Bearbeitet von {{name}} {{time}}", "Edited by {{name}} {{time}}": "Bearbeitet von {{name}} {{time}}",
"Word count: {{wordCount}}": "Wortanzahl: {{wordCount}}", "Word count: {{wordCount}}": "Wortanzahl: {{wordCount}}",
"Character count: {{characterCount}}": "Zeichenzahl: {{characterCount}}", "Character count: {{characterCount}}": "Zeichenanzahl: {{characterCount}}",
"New update": "Neues Update", "New update": "Neues Update",
"{{latestVersion}} is available": "{{latestVersion}} ist verfügbar", "{{latestVersion}} is available": "{{latestVersion}} ist verfügbar",
"Default page edit mode": "Standard-Seitenbearbeitungsmodus", "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 your preferred page edit mode. Avoid accidental edits.": "Wählen Sie Ihren bevorzugten Seitenbearbeitungsmodus. Vermeiden Sie versehentliche Bearbeitungen.",
"Reading": "Lesen", "Reading": "Lesen",
"Delete member": "Mitglied löschen", "Delete member": "Mitglied löschen",
@@ -413,33 +434,35 @@
"Table of contents": "Inhaltsverzeichnis", "Table of contents": "Inhaltsverzeichnis",
"Add headings (H1, H2, H3) to generate a table of contents.": "Fügen Sie Überschriften (H1, H2, H3) hinzu, um ein Inhaltsverzeichnis zu erstellen.", "Add headings (H1, H2, H3) to generate a table of contents.": "Fügen Sie Überschriften (H1, H2, H3) hinzu, um ein Inhaltsverzeichnis zu erstellen.",
"Share": "Teilen", "Share": "Teilen",
"Public sharing": "Öffentliches Teilen", "Public sharing": "Öffentliche Freigabe",
"Shared by": "Geteilt von", "Shared by": "Geteilt von",
"Shared at": "Geteilt am", "Shared at": "Geteilt am",
"Inherits public sharing from": "Erbt das öffentliche Teilen von", "Inherits public sharing from": "Übernimmt öffentliche Freigabe von",
"Share to web": "Im Web teilen", "Share to web": "Im Web teilen",
"Shared to web": "Im Web geteilt", "Shared to web": "Im Web geteilt",
"Anyone with the link can view this page": "Jeder mit dem Link kann diese Seite ansehen", "Anyone with the link can view this page": "Jeder mit dem Link kann diese Seite ansehen",
"Make this page publicly accessible": "Diese Seite öffentlich zugänglich machen", "Make this page publicly accessible": "Diese Seite öffentlich zugänglich machen",
"Include sub-pages": "Unterseiten einbeziehen", "Include sub-pages": "Unterseiten einschließen",
"Make sub-pages public too": "Unterseiten auch öffentlich machen", "Make sub-pages public too": "Unterseiten ebenfalls öffentlich machen",
"Allow search engines to index page": "Suchmaschinen erlauben, die Seite zu indexieren", "Allow search engines to index page": "Suchmaschinen das Indexieren der Seite erlauben",
"Open page": "Seite öffnen", "Open page": "Seite öffnen",
"Page": "Seite", "Page": "Seite",
"Delete public share link": "Öffentlichen Freigabelink löschen", "Delete public share link": "Öffentlichen Freigabelink löschen",
"Delete share": "Freigabe löschen", "Delete share": "Freigabe löschen",
"Are you sure you want to delete this shared link?": "Möchten Sie diesen Freigabelink wirklich löschen?", "Are you sure you want to delete this shared link?": "Möchten Sie diesen Freigabelink wirklich löschen?",
"Publicly shared pages from spaces you are a member of will appear here": "Öffentlich geteilte Seiten aus Bereichen, in denen Sie Mitglied sind, erscheinen hier", "Publicly shared pages from spaces you are a member of will appear here": "Öffentlich freigegebene Seiten aus Bereichen, in denen Sie Mitglied sind, werden hier angezeigt",
"Share deleted successfully": "Freigabe erfolgreich gelöscht", "Share deleted successfully": "Freigabe erfolgreich gelöscht",
"Share not found": "Freigabe nicht gefunden", "Share not found": "Freigabe nicht gefunden",
"Failed to share page": "Fehler beim Teilen der Seite", "Failed to share page": "Seite konnte nicht geteilt werden",
"Disable public sharing": "Öffentliches Teilen deaktivieren", "Disable public sharing": "Öffentliches Teilen deaktivieren",
"Prevent members from sharing pages publicly.": "Verhindern Sie, dass Mitglieder Seiten öffentlich teilen.", "Prevent members from sharing pages publicly.": "Verhindern Sie, dass Mitglieder Seiten öffentlich teilen.",
"Toggle public sharing": "Öffentliches Teilen umschalten", "Toggle public sharing": "Öffentliches Teilen umschalten",
"Toggle space public sharing": "Öffentliches Teilen im Bereich umschalten", "Toggle space public sharing": "Öffentliches Teilen im Bereich umschalten",
"Allow viewers to comment": "Zuschauern erlauben, Kommentare zu hinterlassen",
"Allow viewers to add comments on pages in this space.": "Erlauben Sie Zuschauern, Kommentare auf Seiten in diesem Bereich hinzuzufügen.",
"Toggle viewer comments": "Zuschauerkommentare umschalten",
"Public sharing is disabled at the workspace level": "Öffentliches Teilen ist auf der Arbeitsbereichsebene deaktiviert", "Public sharing is disabled at the workspace level": "Öffentliches Teilen ist auf der Arbeitsbereichsebene deaktiviert",
"Prevent pages in this space from being shared publicly.": "Verhindern Sie, dass Seiten in diesem Bereich öffentlich geteilt werden.", "Prevent pages in this space from being shared publicly.": "Verhindern Sie, dass Seiten in diesem Bereich öffentlich geteilt werden.",
"Requires an enterprise license": "Erfordert eine Unternehmenslizenz",
"Page permissions": "Seitenberechtigungen", "Page permissions": "Seitenberechtigungen",
"Control who can view and edit individual pages. Available with an enterprise license.": "Steuern Sie, wer einzelne Seiten ansehen und bearbeiten kann. Verfügbar mit einer Enterprise-Lizenz.", "Control who can view and edit individual pages. Available with an enterprise license.": "Steuern Sie, wer einzelne Seiten ansehen und bearbeiten kann. Verfügbar mit einer Enterprise-Lizenz.",
"Enable public sharing": "Öffentliches Teilen aktivieren", "Enable public sharing": "Öffentliches Teilen aktivieren",
@@ -454,83 +477,84 @@
"Copy page to a different space.": "Seite in einen anderen Bereich kopieren.", "Copy page to a different space.": "Seite in einen anderen Bereich kopieren.",
"Page copied successfully": "Seite erfolgreich kopiert", "Page copied successfully": "Seite erfolgreich kopiert",
"Page duplicated successfully": "Seite erfolgreich dupliziert", "Page duplicated successfully": "Seite erfolgreich dupliziert",
"Find": "Finden", "Find": "Suchen",
"Not found": "Nicht gefunden", "Not found": "Nicht gefunden",
"Previous Match (Shift+Enter)": "Vorheriger Treffer (Shift+Enter)", "Previous Match (Shift+Enter)": "Vorheriger Treffer (Umschalt+Eingabe)",
"Next match (Enter)": "Nächster Treffer (Enter)", "Next match (Enter)": "Nächster Treffer (Eingabe)",
"Match case (Alt+C)": "Groß-/Kleinschreibung beachten (Alt+C)", "Match case (Alt+C)": "Groß-/Kleinschreibung beachten (Alt+C)",
"Replace": "Ersetzen", "Replace": "Ersetzen",
"Close (Escape)": "Schließen (Escape)", "Close (Escape)": "Schließen (Escape)",
"Replace (Enter)": "Ersetzen (Enter)", "Replace (Enter)": "Ersetzen (Eingabe)",
"Replace all (Ctrl+Alt+Enter)": "Alle ersetzen (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Alle ersetzen (Strg+Alt+Eingabe)",
"Replace all": "Alle ersetzen", "Replace all": "Alle ersetzen",
"View all spaces": "Alle Räume anzeigen", "View all": "Alle anzeigen",
"View all spaces": "Alle Bereiche anzeigen",
"Error": "Fehler", "Error": "Fehler",
"Failed to disable MFA": "Deaktivierung der MFA fehlgeschlagen", "Failed to disable MFA": "MFA konnte nicht deaktiviert werden",
"Disable two-factor authentication": "Zwei-Faktor-Authentifizierung deaktivieren", "Disable two-factor authentication": "Zwei-Faktor-Authentifizierung deaktivieren",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Die Deaktivierung der Zwei-Faktor-Authentifizierung macht Ihr Konto weniger sicher. Sie benötigen nur Ihr Passwort, um sich anzumelden.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Die Deaktivierung der Zwei-Faktor-Authentifizierung macht Ihr Konto weniger sicher. Sie benötigen nur Ihr Passwort, um sich anzumelden.",
"Please enter your password to disable two-factor authentication:": "Bitte geben Sie Ihr Passwort ein, um die Zwei-Faktor-Authentifizierung zu deaktivieren:", "Please enter your password to disable two-factor authentication:": "Bitte geben Sie Ihr Passwort ein, um die Zwei-Faktor-Authentifizierung zu deaktivieren:",
"Two-factor authentication has been enabled": "Zwei-Faktor-Authentifizierung wurde aktiviert", "Two-factor authentication has been enabled": "Die Zwei-Faktor-Authentifizierung wurde aktiviert",
"Two-factor authentication has been disabled": "Zwei-Faktor-Authentifizierung wurde deaktiviert", "Two-factor authentication has been disabled": "Die Zwei-Faktor-Authentifizierung wurde deaktiviert",
"2-step verification": "2-Schritt-Verifizierung", "2-step verification": "Bestätigung in zwei Schritten",
"Protect your account with an additional verification layer when signing in.": "Schützen Sie Ihr Konto mit einer zusätzlichen Verifizierungsschicht beim Anmelden.", "Protect your account with an additional verification layer when signing in.": "Schützen Sie Ihr Konto mit einer zusätzlichen Verifizierungsschicht beim Anmelden.",
"Two-factor authentication is active on your account.": "Die Zwei-Faktor-Authentifizierung ist auf Ihrem Konto aktiv.", "Two-factor authentication is active on your account.": "Die Zwei-Faktor-Authentifizierung ist auf Ihrem Konto aktiv.",
"Add 2FA method": "2FA-Methode hinzufügen", "Add 2FA method": "2FA-Methode hinzufügen",
"Backup codes": "Sicherungscodes", "Backup codes": "Backup-Codes",
"Disable": "Deaktivieren", "Disable": "Deaktivieren",
"Invalid verification code": "Ungültiger Bestätigungscode", "Invalid verification code": "Ungültiger Bestätigungscode",
"New backup codes have been generated": "Neue Sicherungscodes wurden generiert", "New backup codes have been generated": "Neue Backup-Codes wurden erstellt",
"Failed to regenerate backup codes": "Fehler beim Generieren neuer Sicherungscodes", "Failed to regenerate backup codes": "Backup-Codes konnten nicht neu erstellt werden",
"About backup codes": "Über Sicherungscodes", "About backup codes": "Über Backup-Codes",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Sicherungscodes können verwendet werden, um auf Ihr Konto zuzugreifen, wenn Sie den Zugang zu Ihrer Authenticator-App verlieren. Jeder Code kann nur einmal verwendet werden.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Sicherungscodes können verwendet werden, um auf Ihr Konto zuzugreifen, wenn Sie den Zugang zu Ihrer Authenticator-App verlieren. Jeder Code kann nur einmal verwendet werden.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Sie können jederzeit neue Sicherungscodes generieren. Dies wird alle vorhandenen Codes ungültig machen.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Sie können jederzeit neue Sicherungscodes generieren. Dies wird alle vorhandenen Codes ungültig machen.",
"Confirm password": "Passwort bestätigen", "Confirm password": "Passwort bestätigen",
"Generate new backup codes": "Neue Sicherungscodes generieren", "Generate new backup codes": "Neue Backup-Codes erstellen",
"Save your new backup codes": "Speichern Sie Ihre neuen Sicherungscodes", "Save your new backup codes": "Speichern Sie Ihre neuen Backup-Codes",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Speichern Sie diese Codes an einem sicheren Ort. Ihre alten Sicherungscodes sind nicht mehr gültig.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Speichern Sie diese Codes an einem sicheren Ort. Ihre alten Sicherungscodes sind nicht mehr gültig.",
"Your new backup codes": "Ihre neuen Sicherungscodes", "Your new backup codes": "Ihre neuen Backup-Codes",
"I've saved my backup codes": "Ich habe meine Sicherungscodes gespeichert", "I've saved my backup codes": "Ich habe meine Backup-Codes gespeichert",
"Failed to setup MFA": "Fehler beim Einrichten der MFA", "Failed to setup MFA": "MFA konnte nicht eingerichtet werden",
"Setup & Verify": "Einrichten & Überprüfen", "Setup & Verify": "Einrichten und bestätigen",
"Add to authenticator": "Zum Authenticator hinzufügen", "Add to authenticator": "Zum Authenticator hinzufügen",
"1. Scan this QR code with your authenticator app": "1. Scannen Sie diesen QR-Code mit Ihrer Authenticator-App", "1. Scan this QR code with your authenticator app": "1. Scannen Sie diesen QR-Code mit Ihrer Authenticator-App",
"Can't scan the code?": "Code kann nicht gescannt werden?", "Can't scan the code?": "Code kann nicht gescannt werden?",
"Enter this code manually in your authenticator app:": "Geben Sie diesen Code manuell in Ihrer Authenticator-App ein:", "Enter this code manually in your authenticator app:": "Geben Sie diesen Code manuell in Ihrer Authenticator-App ein:",
"2. Enter the 6-digit code from your authenticator": "2. Geben Sie den 6-stelligen Code aus Ihrem Authenticator ein", "2. Enter the 6-digit code from your authenticator": "2. Geben Sie den 6-stelligen Code aus Ihrem Authenticator ein",
"Verify and enable": "Überprüfen und aktivieren", "Verify and enable": "Bestätigen und aktivieren",
"Failed to generate QR code. Please try again.": "Fehler beim Generieren des QR-Codes. Bitte versuchen Sie es erneut.", "Failed to generate QR code. Please try again.": "Fehler beim Generieren des QR-Codes. Bitte versuchen Sie es erneut.",
"Backup": "Sicherung", "Backup": "Backup",
"Save codes": "Codes speichern", "Save codes": "Codes speichern",
"Save your backup codes": "Speichern Sie Ihre Sicherungscodes", "Save your backup codes": "Speichern Sie Ihre Backup-Codes",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Diese Codes können verwendet werden, um auf Ihr Konto zuzugreifen, wenn Sie den Zugang zu Ihrer Authenticator-App verlieren. Jeder Code kann nur einmal verwendet werden.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Diese Codes können verwendet werden, um auf Ihr Konto zuzugreifen, wenn Sie den Zugang zu Ihrer Authenticator-App verlieren. Jeder Code kann nur einmal verwendet werden.",
"Print": "Drucken", "Print": "Drucken",
"Two-factor authentication has been set up. Please log in again.": "Zwei-Faktor-Authentifizierung wurde eingerichtet. Bitte melden Sie sich erneut an.", "Two-factor authentication has been set up. Please log in again.": "Zwei-Faktor-Authentifizierung wurde eingerichtet. Bitte melden Sie sich erneut an.",
"Two-Factor authentication required": "Zwei-Faktor-Authentifizierung erforderlich", "Two-Factor authentication required": "Zwei-Faktor-Authentifizierung erforderlich",
"Your workspace requires two-factor authentication for all users": "Ihr Arbeitsbereich erfordert die Zwei-Faktor-Authentifizierung für alle Benutzer", "Your workspace requires two-factor authentication for all users": "Ihr Workspace erfordert Zwei-Faktor-Authentifizierung für alle Benutzer",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Um weiterhin auf Ihren Arbeitsbereich zuzugreifen, müssen Sie die Zwei-Faktor-Authentifizierung einrichten. Dies fügt Ihrem Konto eine zusätzliche Sicherheitsebene hinzu.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Um weiterhin auf Ihren Arbeitsbereich zuzugreifen, müssen Sie die Zwei-Faktor-Authentifizierung einrichten. Dies fügt Ihrem Konto eine zusätzliche Sicherheitsebene hinzu.",
"Set up two-factor authentication": "Zwei-Faktor-Authentifizierung einrichten", "Set up two-factor authentication": "Zwei-Faktor-Authentifizierung einrichten",
"Cancel and logout": "Abbrechen und abmelden", "Cancel and logout": "Abbrechen und abmelden",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Ihr Arbeitsbereich erfordert eine Zwei-Faktor-Authentifizierung. Bitte richten Sie diese ein, um fortzufahren.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Ihr Arbeitsbereich erfordert eine Zwei-Faktor-Authentifizierung. Bitte richten Sie diese ein, um fortzufahren.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Dadurch wird Ihrem Konto eine zusätzliche Sicherheitsebene hinzugefügt, indem ein Bestätigungscode von Ihrer Authenticator-App verlangt wird.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Dadurch wird Ihrem Konto eine zusätzliche Sicherheitsebene hinzugefügt, indem ein Bestätigungscode von Ihrer Authenticator-App verlangt wird.",
"Password is required": "Passwort erforderlich", "Password is required": "Passwort ist erforderlich",
"Password must be at least 8 characters": "Passwort muss mindestens 8 Zeichen lang sein", "Password must be at least 8 characters": "Das Passwort muss mindestens 8 Zeichen lang sein",
"Please enter a 6-digit code": "Bitte geben Sie einen 6-stelligen Code ein", "Please enter a 6-digit code": "Bitte geben Sie einen 6-stelligen Code ein",
"Code must be exactly 6 digits": "Code muss genau 6-stellig sein", "Code must be exactly 6 digits": "Der Code muss genau 6 Ziffern haben",
"Enter the 6-digit code found in your authenticator app": "Geben Sie den 6-stelligen Code ein, der in Ihrer Authenticator-App zu finden ist", "Enter the 6-digit code found in your authenticator app": "Geben Sie den 6-stelligen Code aus Ihrer Authenticator-App ein",
"Need help authenticating?": "Brauchen Sie Hilfe bei der Authentifizierung?", "Need help authenticating?": "Brauchen Sie Hilfe bei der Authentifizierung?",
"MFA QR Code": "MFA QR-Code", "MFA QR Code": "MFA-QR-Code",
"Account created successfully. Please log in to set up two-factor authentication.": "Konto erfolgreich erstellt. Bitte melden Sie sich an, um die Zwei-Faktor-Authentifizierung einzurichten.", "Account created successfully. Please log in to set up two-factor authentication.": "Konto erfolgreich erstellt. Bitte melden Sie sich an, um die Zwei-Faktor-Authentifizierung einzurichten.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich mit Ihrem neuen Passwort an und führen Sie die Zwei-Faktor-Authentifizierung durch.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich mit Ihrem neuen Passwort an und führen Sie die Zwei-Faktor-Authentifizierung durch.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich mit Ihrem neuen Passwort an, um die Zwei-Faktor-Authentifizierung einzurichten.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich mit Ihrem neuen Passwort an, um die Zwei-Faktor-Authentifizierung einzurichten.",
"Password reset was successful. Please log in with your new password.": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich mit Ihrem neuen Passwort an.", "Password reset was successful. Please log in with your new password.": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich mit Ihrem neuen Passwort an.",
"Two-factor authentication": "Zwei-Faktor-Authentifizierung", "Two-factor authentication": "Zwei-Faktor-Authentifizierung",
"Use authenticator app instead": "Stattdessen Authenticator-App verwenden", "Use authenticator app instead": "Stattdessen Authenticator-App verwenden",
"Verify backup code": "Sicherungscode überprüfen", "Verify backup code": "Backup-Code bestätigen",
"Use backup code": "Sicherungscode verwenden", "Use backup code": "Backup-Code verwenden",
"Enter one of your backup codes": "Geben Sie einen Ihrer Sicherungscodes ein", "Enter one of your backup codes": "Geben Sie einen Ihrer Backup-Codes ein",
"Backup code": "Sicherungscode", "Backup code": "Backup-Code",
"Enter one of your backup codes. Each backup code can only be used once.": "Geben Sie einen Ihrer Sicherungscodes ein. Jeder Sicherungscode kann nur einmal verwendet werden.", "Enter one of your backup codes. Each backup code can only be used once.": "Geben Sie einen Ihrer Sicherungscodes ein. Jeder Sicherungscode kann nur einmal verwendet werden.",
"Verify": "Überprüfen", "Verify": "Bestätigen",
"Trash": "Papierkorb", "Trash": "Papierkorb",
"Pages in trash will be permanently deleted after {{count}} days.": "Seiten im Papierkorb werden nach {{count}} Tagen endgültig gelöscht.", "Pages in trash will be permanently deleted after {{count}} days.": "Seiten im Papierkorb werden nach {{count}} Tagen endgültig gelöscht.",
"Deleted": "Gelöscht", "Deleted": "Gelöscht",
@@ -547,37 +571,37 @@
"Deleted at": "Gelöscht am", "Deleted at": "Gelöscht am",
"Preview": "Vorschau", "Preview": "Vorschau",
"Subpages": "Unterseiten", "Subpages": "Unterseiten",
"Failed to load subpages": "Fehler beim Laden von Unterseiten", "Failed to load subpages": "Unterseiten konnten nicht geladen werden",
"No subpages": "Keine Unterseiten", "No subpages": "Keine Unterseiten",
"Subpages (Child pages)": "Unterseiten (Untergeordnete Seiten)", "Subpages (Child pages)": "Unterseiten (untergeordnete Seiten)",
"List all subpages of the current page": "Alle Unterseiten der aktuellen Seite auflisten", "List all subpages of the current page": "Alle Unterseiten der aktuellen Seite auflisten",
"Attachments": "Anhänge", "Attachments": "Anhänge",
"All spaces": "Alle Bereiche", "All spaces": "Alle Bereiche",
"Unknown": "Unbekannt", "Unknown": "Unbekannt",
"Find a space": "Einen Bereich finden", "Find a space": "Einen Bereich finden",
"Search in all your spaces": "In all deinen Bereichen suchen", "Search in all your spaces": "In all Ihren Bereichen suchen",
"Type": "Art", "Type": "Typ",
"Enterprise": "Unternehmen", "Enterprise": "Enterprise",
"Download attachment": "Anhang herunterladen", "Download attachment": "Anhang herunterladen",
"Allowed email domains": "Erlaubte E-Mail-Domains", "Allowed email domains": "Erlaubte E-Mail-Domains",
"Only users with email addresses from these domains can signup via SSO.": "Nur Benutzer mit E-Mail-Adressen aus diesen Domains können sich über SSO registrieren.", "Only users with email addresses from these domains can signup via SSO.": "Nur Benutzer mit E-Mail-Adressen aus diesen Domains können sich per SSO registrieren.",
"Enter valid domain names separated by comma or space": "Geben Sie gültige Domainnamen ein, durch Kommas oder Leerzeichen getrennt", "Enter valid domain names separated by comma or space": "Geben Sie gültige Domainnamen ein, getrennt durch Komma oder Leerzeichen",
"Enforce two-factor authentication": "Erzwingen der Zwei-Faktor-Authentifizierung", "Enforce two-factor authentication": "Zwei-Faktor-Authentifizierung erzwingen",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Sobald es erzwungen wird, müssen alle Mitglieder die Zwei-Faktor-Authentifizierung aktivieren, um auf den Arbeitsbereich zugreifen zu können.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Sobald es erzwungen wird, müssen alle Mitglieder die Zwei-Faktor-Authentifizierung aktivieren, um auf den Arbeitsbereich zugreifen zu können.",
"Toggle MFA enforcement": "Umschalten der MFA-Erzwingung", "Toggle MFA enforcement": "MFA-Erzwingung umschalten",
"Display name": "Anzeigename", "Display name": "Anzeigename",
"Allow signup": "Registrierung erlauben", "Allow signup": "Registrierung erlauben",
"Enabled": "Aktiviert", "Enabled": "Aktiviert",
"Advanced Settings": "Erweiterte Einstellungen", "Advanced Settings": "Erweiterte Einstellungen",
"Enable TLS/SSL": "TLS/SSL aktivieren", "Enable TLS/SSL": "TLS/SSL aktivieren",
"Use secure connection to LDAP server": "Sichere Verbindung zum LDAP-Server verwenden", "Use secure connection to LDAP server": "Sichere Verbindung zum LDAP-Server verwenden",
"Group sync": "Gruppensynchronisation", "Group sync": "Gruppensynchronisierung",
"No SSO providers found.": "Keine SSO-Anbieter gefunden.", "No SSO providers found.": "Keine SSO-Anbieter gefunden.",
"Delete SSO provider": "SSO-Anbieter löschen", "Delete SSO provider": "SSO-Anbieter löschen",
"Are you sure you want to delete this SSO provider?": "Sind Sie sicher, dass Sie diesen SSO-Anbieter löschen möchten?", "Are you sure you want to delete this SSO provider?": "Sind Sie sicher, dass Sie diesen SSO-Anbieter löschen möchten?",
"Action": "Aktion", "Action": "Aktion",
"{{ssoProviderType}} configuration": "{{ssoProviderType}}-Konfiguration", "{{ssoProviderType}} configuration": "{{ssoProviderType}}-Konfiguration",
"Icon": "Icon", "Icon": "Symbol",
"Upload image": "Bild hochladen", "Upload image": "Bild hochladen",
"Remove image": "Bild entfernen", "Remove image": "Bild entfernen",
"Failed to remove image": "Fehler beim Entfernen des Bildes", "Failed to remove image": "Fehler beim Entfernen des Bildes",
@@ -613,6 +637,7 @@
"AI Answer": "KI-Antwort", "AI Answer": "KI-Antwort",
"Ask AI": "KI fragen", "Ask AI": "KI fragen",
"AI is thinking...": "Die KI überlegt...", "AI is thinking...": "Die KI überlegt...",
"Thinking": "Denkt nach",
"Ask a question...": "Fragen stellen...", "Ask a question...": "Fragen stellen...",
"AI Answers": "KI-Antworten", "AI Answers": "KI-Antworten",
"AI-powered search (AI Answers)": "KI-unterstützte Suche (KI-Antworten)", "AI-powered search (AI Answers)": "KI-unterstützte Suche (KI-Antworten)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "Generative KI (KI fragen)", "Generative AI (Ask AI)": "Generative KI (KI fragen)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Aktivieren Sie die KI-unterstützte Inhaltserstellung im Editor. Ermöglicht Benutzern das Erzeugen, Verbessern, Übersetzen und Transformieren von Text.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Aktivieren Sie die KI-unterstützte Inhaltserstellung im Editor. Ermöglicht Benutzern das Erzeugen, Verbessern, Übersetzen und Transformieren von Text.",
"Toggle generative AI": "Generative KI umschalten", "Toggle generative AI": "Generative KI umschalten",
"Enterprise feature": "Enterprise-Funktion", "Upgrade your plan": "Upgrade Ihres Plans",
"Available with a paid license": "Verfügbar mit einer kostenpflichtigen Lizenz",
"Upgrade your license tier.": "Stufen Sie Ihre Lizenz hoch.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "KI ist nur in der Docmost Enterprise-Edition verfügbar. Kontaktieren Sie sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "KI ist nur in der Docmost Enterprise-Edition verfügbar. Kontaktieren Sie sales@docmost.com.",
"AI & MCP": "KI & MCP", "AI & MCP": "KI & MCP",
"AI": "KI", "AI": "KI",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Model Context Protocol (MCP)", "Model Context Protocol (MCP)": "Model Context Protocol (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Aktivieren Sie den MCP-Server, damit KI-Assistenten und -Tools mit den Inhalten Ihres Arbeitsbereichs interagieren können.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Aktivieren Sie den MCP-Server, damit KI-Assistenten und -Tools mit den Inhalten Ihres Arbeitsbereichs interagieren können.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP ist nur in der Docmost Enterprise-Edition verfügbar. Kontaktieren Sie sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP ist nur in der Docmost Enterprise-Edition verfügbar. Kontaktieren Sie sales@docmost.com.",
"MCP documentation": "MCP-Dokumentation",
"MCP Server URL": "MCP-Server-URL", "MCP Server URL": "MCP-Server-URL",
"Use your API key for authentication. You can manage API keys in your account settings.": "Verwenden Sie Ihren API-Schlüssel zur Authentifizierung. API-Schlüssel können in Ihren Kontoeinstellungen verwaltet werden.", "Use your API key for authentication. You can manage API keys in your account settings.": "Verwenden Sie Ihren API-Schlüssel zur Authentifizierung. API-Schlüssel können in Ihren Kontoeinstellungen verwaltet werden.",
"Supported tools": "Unterstützte Tools", "Supported tools": "Unterstützte Tools",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "In Ihrem Arbeitsbereich ist MCP aktiviert. Verwenden Sie Ihren API-Schlüssel, um KI-Assistenten anzubinden.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "In Ihrem Arbeitsbereich ist MCP aktiviert. Verwenden Sie Ihren API-Schlüssel, um KI-Assistenten anzubinden.",
"MCP server URL:": "MCP-Server-URL:", "MCP server URL:": "MCP-Server-URL:",
"Learn more": "Mehr erfahren", "Learn more": "Mehr erfahren",
"View the": "Anzeigen", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Verwalten Sie API-Schlüssel für alle Nutzer im Arbeitsbereich. Siehe die <anchor>API-Dokumentation</anchor> für Details zur Verwendung.",
"for usage details.": "für Informationen zur Nutzung.", "View the <anchor>API documentation</anchor> for usage details.": "Siehe die <anchor>API-Dokumentation</anchor> für Details zur Verwendung.",
"for setup instructions.": "für Einrichtungshinweise.", "View the <anchor>MCP documentation</anchor>.": "Sehen Sie die <anchor>MCP-Dokumentation</anchor> ein.",
"API documentation": "API-Dokumentation",
"Sources": "Quellen", "Sources": "Quellen",
"AI Answers not available for attachments": "KI-Antworten sind für Anhänge nicht verfügbar", "AI Answers not available for attachments": "KI-Antworten sind für Anhänge nicht verfügbar",
"No answer available": "Keine Antwort verfügbar", "No answer available": "Keine Antwort verfügbar",
@@ -654,12 +679,34 @@
"Mark all as read": "Alle als gelesen markieren", "Mark all as read": "Alle als gelesen markieren",
"Mark as read": "Als gelesen markieren", "Mark as read": "Als gelesen markieren",
"More options": "Weitere Optionen", "More options": "Weitere Optionen",
"mentioned you in a comment": "hat Sie in einem Kommentar erwähnt", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> hat Sie in einem Kommentar erwähnt",
"commented on a page": "hat auf einer Seite kommentiert", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> hat einen Kommentar auf einer Seite hinterlassen",
"resolved a comment": "hat einen Kommentar gelöst", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> hat einen Kommentar gelöst",
"mentioned you on a page": "hat Sie auf einer Seite erwähnt", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> hat Sie auf einer Seite erwähnt",
"gave you edit access to a page": "hat Ihnen Bearbeitungsrechte für eine Seite gegeben", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> hat Ihnen Bearbeitungszugriff auf eine Seite gegeben",
"gave you view access to a page": "hat Ihnen Leserechte für eine Seite gewährt", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> hat Ihnen Ansichtszugriff auf eine Seite gegeben",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> hat eine Seite aktualisiert",
"Watch page": "Seite beobachten",
"Stop watching": "Nicht mehr beobachten",
"Watch space": "Bereich beobachten",
"Stop watching space": "Bereich nicht mehr beobachten",
"Email notifications": "E-Mail-Benachrichtigungen",
"Page updates": "Seitenaktualisierungen",
"Get notified when pages you watch are updated.": "Erhalten Sie eine Benachrichtigung, wenn Seiten, die Sie beobachten, aktualisiert werden.",
"Page mentions": "Seiten-Erwähnungen",
"Get notified when someone mentions you on a page.": "Erhalten Sie eine Benachrichtigung, wenn Sie jemand auf einer Seite erwähnt.",
"Comment mentions": "Kommentar-Erwähnungen",
"Get notified when someone mentions you in a comment.": "Erhalten Sie eine Benachrichtigung, wenn Sie jemand in einem Kommentar erwähnt.",
"New comments": "Neue Kommentare",
"Get notified about new comments on threads you participate in.": "Erhalten Sie eine Benachrichtigung über neue Kommentare in Threads, an denen Sie teilnehmen.",
"Resolved comments": "Erledigte Kommentare",
"Get notified when your comment is resolved.": "Erhalten Sie eine Benachrichtigung, wenn Ihr Kommentar erledigt wurde.",
"You are now watching this page": "Sie beobachten diese Seite jetzt",
"You are no longer watching this page": "Sie beobachten diese Seite nicht mehr",
"You are now watching this space": "Sie beobachten diesen Bereich jetzt",
"You are no longer watching this space": "Sie beobachten diesen Bereich nicht mehr",
"Direct": "Direkt",
"Updates": "Aktualisierungen",
"Today": "Heute", "Today": "Heute",
"Yesterday": "Gestern", "Yesterday": "Gestern",
"This week": "Diese Woche", "This week": "Diese Woche",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Aktualisierung der Aufbewahrungsdauer des Papierkorbs fehlgeschlagen", "Failed to update trash retention": "Aktualisierung der Aufbewahrungsdauer des Papierkorbs fehlgeschlagen",
"Removed page restriction": "Seitenbeschränkung entfernt", "Removed page restriction": "Seitenbeschränkung entfernt",
"Added page permission": "Seitenberechtigung hinzugefügt", "Added page permission": "Seitenberechtigung hinzugefügt",
"Removed page permission": "Seitenberechtigung entfernt" "Removed page permission": "Seitenberechtigung entfernt",
"day": "Tag",
"days": "Tage",
"week": "Woche",
"weeks": "Wochen",
"month": "Monat",
"months": "Monate",
"year": "Jahr",
"years": "Jahre",
"Period": "Zeitraum",
"Fixed date": "Festes Datum",
"Indefinitely": "Unbegrenzt",
"Days": "Tage",
"Weeks": "Wochen",
"Months": "Monate",
"Years": "Jahre",
"Pick a date": "Datum auswählen",
"Maximum is {{max}} {{unit}} for this unit": "Das Maximum für diese Einheit beträgt {{max}} {{unit}}",
"Never expires. Verifiers can re-verify at any time.": "Läuft nie ab. Prüfer können die Seite jederzeit erneut verifizieren.",
"Verified": "Verifiziert",
"Review needed": "Prüfung erforderlich",
"Verification expired": "Verifizierung abgelaufen",
"Draft": "Entwurf",
"In Approval": "In Genehmigung",
"In approval": "In Genehmigung",
"Approved": "Genehmigt",
"Obsolete": "Veraltet",
"Expiring": "Läuft bald ab",
"Set up verification": "Verifizierung einrichten",
"Verify page": "Seite verifizieren",
"Page verification": "Seitenverifizierung",
"Add verification": "Verifizierung hinzufügen",
"Edit verification": "Verifizierung bearbeiten",
"Search by title": "Nach Titel suchen",
"Choose how this page should stay accurate.": "Wählen Sie aus, wie diese Seite aktuell gehalten werden soll.",
"Recurring verification": "Wiederkehrende Verifizierung",
"Verifiers re-confirm this page on a schedule.": "Prüfer bestätigen diese Seite nach einem Zeitplan erneut.",
"Re-verify on a schedule (e.g every 30 days )": "Nach einem Zeitplan erneut verifizieren (z. B. alle 30 Tage)",
"Page stays editable at all times": "Die Seite bleibt jederzeit bearbeitbar",
"Best for runbooks, FAQs, living documentation": "Am besten für Runbooks, FAQs und lebende Dokumentation geeignet",
"Approval workflow": "Genehmigungsworkflow",
"Formal document lifecycle with named approvers.": "Formaler Dokumentenlebenszyklus mit benannten Genehmigern.",
"Draft → In approval → Approved → Obsolete": "Entwurf → In Genehmigung → Genehmigt → Veraltet",
"Locked once approved, with full history": "Nach der Genehmigung gesperrt, mit vollständiger Historie",
"Designed for ISO 9001, ISO 13485, and FDA": "Entwickelt für ISO 9001, ISO 13485 und FDA",
"Best for SOPs and controlled documents": "Am besten für SOPs und kontrollierte Dokumente geeignet",
"Back": "Zurück",
"Quality management": "Qualitätsmanagement",
"Recurring": "Wiederkehrend",
"Pages move through draft, approval, and approved stages.": "Seiten durchlaufen die Phasen Entwurf, Genehmigung und Genehmigt.",
"Verifiers": "Prüfer",
"Add verifier": "Prüfer hinzufügen",
"I've reviewed this page for accuracy": "Ich habe diese Seite auf Richtigkeit geprüft",
"Set up": "Einrichten",
"Remove verification": "Verifizierung entfernen",
"Are you sure you want to remove verification from this page?": "Möchten Sie die Verifizierung wirklich von dieser Seite entfernen?",
"Assigned verifiers must periodically re-verify this page.": "Zugewiesene Prüfer müssen diese Seite regelmäßig erneut verifizieren.",
"Last verified by {{name}} {{time}} (expired)": "Zuletzt von {{name}} {{time}} verifiziert (abgelaufen)",
"The fixed expiration date has passed.": "Das feste Ablaufdatum ist überschritten.",
"Verified by {{name}} {{time}}": "Verifiziert von {{name}} {{time}}",
"Expires {{date}}": "Läuft ab am {{date}}",
"Expired {{date}}": "Abgelaufen am {{date}}",
"Mark as obsolete": "Als veraltet markieren",
"Mark obsolete": "Als veraltet markieren",
"Returned by {{name}} {{time}}": "Zurückgegeben von {{name}} {{time}}",
"No approval has been requested yet.": "Es wurde noch keine Genehmigung angefordert.",
"Submitted by {{name}} {{time}}": "Eingereicht von {{name}} {{time}}",
"Someone": "Jemand",
"Approved by {{name}} {{time}}": "Genehmigt von {{name}} {{time}}",
"This document has been marked as obsolete.": "Dieses Dokument wurde als veraltet markiert.",
"Rejection comment": "Ablehnungskommentar",
"Reason for returning this document...": "Grund für die Rückgabe dieses Dokuments...",
"Confirm rejection": "Ablehnung bestätigen",
"Submit for approval": "Zur Genehmigung einreichen",
"Reject": "Ablehnen",
"Approve": "Genehmigen",
"Re-submit for approval": "Erneut zur Genehmigung einreichen",
"Verified until": "Verifiziert bis",
"QMS": "QMS",
"Verified pages": "Verifizierte Seiten",
"Search pages...": "Seiten suchen...",
"Filter by space": "Nach Bereich filtern",
"Filter by type": "Nach Typ filtern",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> hat eine Seite verifiziert",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> hat eine Seite zu Ihrer Genehmigung eingereicht",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> hat eine Seite zur Überarbeitung zurückgegeben",
"Page verification expires soon": "Die Seitenverifizierung läuft bald ab",
"Page verification has expired": "Die Seitenverifizierung ist abgelaufen",
"Verifying your email": "Ihre E-Mail wird bestätigt",
"Please wait...": "Bitte warten...",
"Verification failed. The link may have expired.": "Überprüfung fehlgeschlagen. Der Link ist möglicherweise abgelaufen.",
"Check your email": "Prüfen Sie Ihre E-Mails",
"We sent a verification link to {{email}}.": "Wir haben einen Bestätigungslink an {{email}} gesendet.",
"We sent a verification link to your email.": "Wir haben einen Bestätigungslink an Ihre E-Mail-Adresse gesendet.",
"Click the link to verify your email and access your workspace.": "Klicken Sie auf den Link, um Ihre E-Mail zu bestätigen und auf Ihren Arbeitsbereich zuzugreifen.",
"Resend verification email": "Bestätigungs-E-Mail erneut senden",
"Verification email sent. Please check your inbox.": "Bestätigungs-E-Mail gesendet. Bitte überprüfen Sie Ihr Postfach.",
"Failed to resend verification email. Please try again.": "Fehler beim erneuten Senden der Bestätigungs-E-Mail. Bitte versuchen Sie es erneut.",
"We've sent you an email with your associated workspaces.": "Wir haben Ihnen eine E-Mail mit Ihren zugehörigen Arbeitsbereichen gesendet.",
"Load more": "Mehr laden",
"Log out of all devices": "Auf allen Geräten abmelden",
"Log out of all sessions except this device": "Von allen Sitzungen außer diesem Gerät abmelden",
"This Device": "Dieses Gerät",
"Unknown device": "Unbekanntes Gerät",
"No active sessions": "Keine aktiven Sitzungen",
"Session revoked": "Sitzung widerrufen",
"All other sessions revoked": "Alle anderen Sitzungen widerrufen",
"Last used": "Zuletzt verwendet",
"Created": "Erstellt",
"Rename": "Umbenennen",
"Publish": "Veröffentlichen",
"Security": "Sicherheit",
"Enforce SSO": "SSO erzwingen",
"Once enforced, members will not be able to login with email and password.": "Sobald dies erzwungen wird, können sich Mitglieder nicht mehr mit E-Mail und Passwort anmelden.",
"AI-generated content may not be accurate.": "KI-generierte Inhalte sind möglicherweise nicht korrekt.",
"AI Chat": "KI-Chat",
"Analyze for insights": "Für Erkenntnisse analysieren",
"Ask anything...": "Fragen Sie irgendetwas...",
"Chat history": "Chatverlauf",
"Chat name": "Chatname",
"Close": "Schließen",
"Docmost AI": "Docmost KI",
"Failed to load chat. An error occurred.": "Chat konnte nicht geladen werden. Ein Fehler ist aufgetreten.",
"Failed to render this message.": "Diese Nachricht konnte nicht dargestellt werden.",
"How can I help you today?": "Wie kann ich Ihnen heute helfen?",
"New chat": "Neuer Chat",
"No chat history": "Kein Chatverlauf",
"No chats found": "Keine Chats gefunden",
"No conversations yet": "Noch keine Unterhaltungen",
"Open full page": "Ganze Seite öffnen",
"Previous 7 days": "Letzte 7 Tage",
"Previous 30 days": "Letzte 30 Tage",
"Search chats...": "Chats durchsuchen...",
"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",
"Translate this page": "Diese Seite übersetzen",
"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?"
} }
@@ -7,6 +7,7 @@
"Add members": "Add members", "Add members": "Add members",
"Add to groups": "Add to groups", "Add to groups": "Add to groups",
"Add space members": "Add space members", "Add space members": "Add space members",
"Add to favorites": "Add to favorites",
"Admin": "Admin", "Admin": "Admin",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Are you sure you want to delete this group? Members will lose access to resources this group has access to.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Are you sure you want to delete this group? Members will lose access to resources this group has access to.",
"Are you sure you want to delete this page?": "Are you sure you want to delete this page?", "Are you sure you want to delete this page?": "Are you sure you want to delete this page?",
@@ -74,6 +75,9 @@
"Failed to import pages": "Failed to import pages", "Failed to import pages": "Failed to import pages",
"Failed to load page. An error occurred.": "Failed to load page. An error occurred.", "Failed to load page. An error occurred.": "Failed to load page. An error occurred.",
"Failed to update data": "Failed to update data", "Failed to update data": "Failed to update data",
"Favorite spaces": "Favorite spaces",
"Favorite spaces appear here": "Favorite spaces appear here",
"Favorites": "Favorites",
"Full access": "Full access", "Full access": "Full access",
"Full page width": "Full page width", "Full page width": "Full page width",
"Full width": "Full width", "Full width": "Full width",
@@ -92,6 +96,7 @@
"Invite by email": "Invite by email", "Invite by email": "Invite by email",
"Invite members": "Invite members", "Invite members": "Invite members",
"Invite new members": "Invite new members", "Invite new members": "Invite new members",
"Invite People": "Invite People",
"Invited members who are yet to accept their invitation will appear here.": "Invited members who are yet to accept their invitation will appear here.", "Invited members who are yet to accept their invitation will appear here.": "Invited members who are yet to accept their invitation will appear here.",
"Invited members will be granted access to spaces the groups can access": "Invited members will be granted access to spaces the groups can access", "Invited members will be granted access to spaces the groups can access": "Invited members will be granted access to spaces the groups can access",
"Join the workspace": "Join the workspace", "Join the workspace": "Join the workspace",
@@ -139,6 +144,7 @@
"Profile": "Profile", "Profile": "Profile",
"Recently updated": "Recently updated", "Recently updated": "Recently updated",
"Remove": "Remove", "Remove": "Remove",
"Remove from favorites": "Remove from favorites",
"Remove group member": "Remove group member", "Remove group member": "Remove group member",
"Remove space member": "Remove space member", "Remove space member": "Remove space member",
"Restore": "Restore", "Restore": "Restore",
@@ -175,6 +181,7 @@
"Successfully imported": "Successfully imported", "Successfully imported": "Successfully imported",
"Successfully restored": "Successfully restored", "Successfully restored": "Successfully restored",
"System settings": "System settings", "System settings": "System settings",
"Templates": "Templates",
"Theme": "Theme", "Theme": "Theme",
"To change your email, you have to enter your password and new email.": "To change your email, you have to enter your password and new email.", "To change your email, you have to enter your password and new email.": "To change your email, you have to enter your password and new email.",
"Toggle full page width": "Toggle full page width", "Toggle full page width": "Toggle full page width",
@@ -215,6 +222,8 @@
"Edit comment": "Edit comment", "Edit comment": "Edit comment",
"Delete comment": "Delete comment", "Delete comment": "Delete comment",
"Are you sure you want to delete this comment?": "Are you sure you want to delete this comment?", "Are you sure you want to delete this comment?": "Are you sure you want to delete this comment?",
"Delete chat": "Delete chat",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Are you sure you want to delete '{{title}}'? This action cannot be undone.",
"Comment created successfully": "Comment created successfully", "Comment created successfully": "Comment created successfully",
"Error creating comment": "Error creating comment", "Error creating comment": "Error creating comment",
"Comment updated successfully": "Comment updated successfully", "Comment updated successfully": "Comment updated successfully",
@@ -341,6 +350,7 @@
"Insert horizontal rule divider": "Insert horizontal rule divider", "Insert horizontal rule divider": "Insert horizontal rule divider",
"Upload any image from your device.": "Upload any image from your device.", "Upload any image from your device.": "Upload any image from your device.",
"Upload any video from your device.": "Upload any video from your device.", "Upload any video from your device.": "Upload any video from your device.",
"Upload any audio from your device.": "Upload any audio from your device.",
"Upload any file from your device.": "Upload any file from your device.", "Upload any file from your device.": "Upload any file from your device.",
"Uploading {{name}}": "Uploading {{name}}", "Uploading {{name}}": "Uploading {{name}}",
"Uploading file": "Uploading file", "Uploading file": "Uploading file",
@@ -351,6 +361,12 @@
"Divider": "Divider", "Divider": "Divider",
"Quote": "Quote", "Quote": "Quote",
"Image": "Image", "Image": "Image",
"Audio": "Audio",
"Embed PDF": "Embed PDF",
"Upload and embed a PDF file.": "Upload and embed a PDF file.",
"Embed as PDF": "Embed as PDF",
"Failed to load PDF": "Failed to load PDF",
"Convert to attachment": "Convert to attachment",
"File attachment": "File attachment", "File attachment": "File attachment",
"Toggle block": "Toggle block", "Toggle block": "Toggle block",
"Callout": "Callout", "Callout": "Callout",
@@ -400,6 +416,7 @@
"{{latestVersion}} is available": "{{latestVersion}} is available", "{{latestVersion}} is available": "{{latestVersion}} is available",
"Default page edit mode": "Default page edit mode", "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 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", "Reading": "Reading",
"Delete member": "Delete member", "Delete member": "Delete member",
"Member deleted successfully": "Member deleted successfully", "Member deleted successfully": "Member deleted successfully",
@@ -442,6 +459,9 @@
"Prevent members from sharing pages publicly.": "Prevent members from sharing pages publicly.", "Prevent members from sharing pages publicly.": "Prevent members from sharing pages publicly.",
"Toggle public sharing": "Toggle public sharing", "Toggle public sharing": "Toggle public sharing",
"Toggle space public sharing": "Toggle space public sharing", "Toggle space public sharing": "Toggle space public sharing",
"Allow viewers to comment": "Allow viewers to comment",
"Allow viewers to add comments on pages in this space.": "Allow viewers to add comments on pages in this space.",
"Toggle viewer comments": "Toggle viewer comments",
"Public sharing is disabled at the workspace level": "Public sharing is disabled at the workspace level", "Public sharing is disabled at the workspace level": "Public sharing is disabled at the workspace level",
"Prevent pages in this space from being shared publicly.": "Prevent pages in this space from being shared publicly.", "Prevent pages in this space from being shared publicly.": "Prevent pages in this space from being shared publicly.",
"Page permissions": "Page permissions", "Page permissions": "Page permissions",
@@ -468,6 +488,7 @@
"Replace (Enter)": "Replace (Enter)", "Replace (Enter)": "Replace (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Replace all (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Replace all (Ctrl+Alt+Enter)",
"Replace all": "Replace all", "Replace all": "Replace all",
"View all": "View all",
"View all spaces": "View all spaces", "View all spaces": "View all spaces",
"Error": "Error", "Error": "Error",
"Failed to disable MFA": "Failed to disable MFA", "Failed to disable MFA": "Failed to disable MFA",
@@ -588,25 +609,21 @@
"Image exceeds 10MB limit.": "Image exceeds 10MB limit.", "Image exceeds 10MB limit.": "Image exceeds 10MB limit.",
"Image removed successfully": "Image removed successfully", "Image removed successfully": "Image removed successfully",
"API key": "API key", "API key": "API key",
"API key created successfully": "API key created successfully",
"API keys": "API keys", "API keys": "API keys",
"API management": "API management", "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", "Custom expiration date": "Custom expiration date",
"Enter a descriptive token name": "Enter a descriptive token name", "Enter a descriptive token name": "Enter a descriptive token name",
"Expiration": "Expiration", "Expiration": "Expiration",
"Expired": "Expired", "Expired": "Expired",
"Expires": "Expires", "Expires": "Expires",
"I've saved my API key": "I've saved my API key",
"Last use": "Last Used", "Last use": "Last Used",
"No API keys found": "No API keys found", "No API keys found": "No API keys found",
"No expiration": "No expiration", "No expiration": "No expiration",
"Revoke API key": "Revoke API key",
"Revoked successfully": "Revoked successfully", "Revoked successfully": "Revoked successfully",
"Select expiration date": "Select expiration date", "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.", "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", "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", "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.", "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.",
@@ -617,6 +634,7 @@
"AI Answer": "AI Answer", "AI Answer": "AI Answer",
"Ask AI": "Ask AI", "Ask AI": "Ask AI",
"AI is thinking...": "AI is thinking...", "AI is thinking...": "AI is thinking...",
"Thinking": "Thinking",
"Ask a question...": "Ask a question...", "Ask a question...": "Ask a question...",
"AI Answers": "AI Answers", "AI Answers": "AI Answers",
"AI-powered search (AI Answers)": "AI-powered search (AI Answers)", "AI-powered search (AI Answers)": "AI-powered search (AI Answers)",
@@ -664,6 +682,28 @@
"<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> mentioned you on a page", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> mentioned you on a page",
"<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> gave you edit access to a page", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> gave you edit access to a page",
"<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> gave you view access to a page", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> gave you view access to a page",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> updated a page",
"Watch page": "Watch page",
"Stop watching": "Stop watching",
"Watch space": "Watch space",
"Stop watching space": "Stop watching space",
"Email notifications": "Email notifications",
"Page updates": "Page updates",
"Get notified when pages you watch are updated.": "Receive notifications when the pages you watch are updated.",
"Page mentions": "Page mentions",
"Get notified when someone mentions you on a page.": "Receive notifications when someone mentions you on a page.",
"Comment mentions": "Comment mentions",
"Get notified when someone mentions you in a comment.": "Receive notifications when someone mentions you in a comment.",
"New comments": "New comments",
"Get notified about new comments on threads you participate in.": "Receive notifications about new comments in threads you are participating in.",
"Resolved comments": "Resolved comments",
"Get notified when your comment is resolved.": "Receive a notification when your comment is resolved.",
"You are now watching this page": "Youre now watching this page",
"You are no longer watching this page": "Youre no longer watching this page",
"You are now watching this space": "Youre now watching this space",
"You are no longer watching this space": "Youre no longer watching this space",
"Direct": "Direct",
"Updates": "Updates",
"Today": "Today", "Today": "Today",
"Yesterday": "Yesterday", "Yesterday": "Yesterday",
"This week": "This week", "This week": "This week",
@@ -698,6 +738,93 @@
"Removed page restriction": "Removed page restriction", "Removed page restriction": "Removed page restriction",
"Added page permission": "Added page permission", "Added page permission": "Added page permission",
"Removed page permission": "Removed page permission", "Removed page permission": "Removed page permission",
"day": "day",
"days": "days",
"week": "week",
"weeks": "weeks",
"month": "month",
"months": "months",
"year": "year",
"years": "years",
"Period": "Period",
"Fixed date": "Fixed date",
"Indefinitely": "Indefinitely",
"Days": "Days",
"Weeks": "Weeks",
"Months": "Months",
"Years": "Years",
"Pick a date": "Pick a date",
"Maximum is {{max}} {{unit}} for this unit": "Maximum is {{max}} {{unit}} for this unit",
"Never expires. Verifiers can re-verify at any time.": "Never expires. Verifiers can re-verify at any time.",
"Verified": "Verified",
"Review needed": "Review needed",
"Verification expired": "Verification expired",
"Draft": "Draft",
"In Approval": "In Approval",
"In approval": "In approval",
"Approved": "Approved",
"Obsolete": "Obsolete",
"Expiring": "Expiring",
"Set up verification": "Set up verification",
"Verify page": "Verify page",
"Page verification": "Page verification",
"Add verification": "Add verification",
"Edit verification": "Edit verification",
"Search by title": "Search by title",
"Choose how this page should stay accurate.": "Choose how this page should stay accurate.",
"Recurring verification": "Recurring verification",
"Verifiers re-confirm this page on a schedule.": "Verifiers re-confirm this page on a schedule.",
"Re-verify on a schedule (e.g every 30 days )": "Re-verify on a schedule (e.g every 30 days )",
"Page stays editable at all times": "Page stays editable at all times",
"Best for runbooks, FAQs, living documentation": "Best for runbooks, FAQs, living documentation",
"Approval workflow": "Approval workflow",
"Formal document lifecycle with named approvers.": "Formal document lifecycle with named approvers.",
"Draft → In approval → Approved → Obsolete": "Draft → In approval → Approved → Obsolete",
"Locked once approved, with full history": "Locked once approved, with full history",
"Designed for ISO 9001, ISO 13485, and FDA": "Designed for ISO 9001, ISO 13485, and FDA",
"Best for SOPs and controlled documents": "Best for SOPs and controlled documents",
"Back": "Back",
"Quality management": "Quality management",
"Recurring": "Recurring",
"Pages move through draft, approval, and approved stages.": "Pages move through draft, approval, and approved stages.",
"Verifiers": "Verifiers",
"Add verifier": "Add verifier",
"I've reviewed this page for accuracy": "I've reviewed this page for accuracy",
"Set up": "Set up",
"Remove verification": "Remove verification",
"Are you sure you want to remove verification from this page?": "Are you sure you want to remove verification from this page?",
"Assigned verifiers must periodically re-verify this page.": "Assigned verifiers must periodically re-verify this page.",
"Last verified by {{name}} {{time}} (expired)": "Last verified by {{name}} {{time}} (expired)",
"The fixed expiration date has passed.": "The fixed expiration date has passed.",
"Verified by {{name}} {{time}}": "Verified by {{name}} {{time}}",
"Expires {{date}}": "Expires {{date}}",
"Expired {{date}}": "Expired {{date}}",
"Mark as obsolete": "Mark as obsolete",
"Mark obsolete": "Mark obsolete",
"Returned by {{name}} {{time}}": "Returned by {{name}} {{time}}",
"No approval has been requested yet.": "No approval has been requested yet.",
"Submitted by {{name}} {{time}}": "Submitted by {{name}} {{time}}",
"Someone": "Someone",
"Approved by {{name}} {{time}}": "Approved by {{name}} {{time}}",
"This document has been marked as obsolete.": "This document has been marked as obsolete.",
"Rejection comment": "Rejection comment",
"Reason for returning this document...": "Reason for returning this document...",
"Confirm rejection": "Confirm rejection",
"Submit for approval": "Submit for approval",
"Reject": "Reject",
"Approve": "Approve",
"Re-submit for approval": "Re-submit for approval",
"Verified until": "Verified until",
"QMS": "QMS",
"Verified pages": "Verified pages",
"Search pages...": "Search pages...",
"Filter by space": "Filter by space",
"Filter by type": "Filter by type",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> verified a page",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> submitted a page for your approval",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> returned a page for revision",
"Page verification expires soon": "Page verification expires soon",
"Page verification has expired": "Page verification has expired",
"Verifying your email": "Verifying your email", "Verifying your email": "Verifying your email",
"Please wait...": "Please wait...", "Please wait...": "Please wait...",
"Verification failed. The link may have expired.": "Verification failed. The link may have expired.", "Verification failed. The link may have expired.": "Verification failed. The link may have expired.",
@@ -708,5 +835,96 @@
"Resend verification email": "Resend verification email", "Resend verification email": "Resend verification email",
"Verification email sent. Please check your inbox.": "Verification email sent. Please check your inbox.", "Verification email sent. Please check your inbox.": "Verification email sent. Please check your inbox.",
"Failed to resend verification email. Please try again.": "Failed to resend verification email. Please try again.", "Failed to resend verification email. Please try again.": "Failed to resend verification email. Please try again.",
"We've sent you an email with your associated workspaces.": "We've sent you an email with your associated workspaces." "We've sent you an email with your associated workspaces.": "We've sent you an email with your associated workspaces.",
"Load more": "Load more",
"Log out of all devices": "Log out of all devices",
"Log out of all sessions except this device": "Log out of all sessions except this device",
"This Device": "This Device",
"Unknown device": "Unknown device",
"No active sessions": "No active sessions",
"Session revoked": "Session revoked",
"All other sessions revoked": "All other sessions revoked",
"Last used": "Last used",
"Created": "Created",
"Rename": "Rename",
"Publish": "Publish",
"Security": "Security",
"Enforce SSO": "Enforce SSO",
"Once enforced, members will not be able to login with email and password.": "Once enforced, members will not be able to login with email and password.",
"AI-generated content may not be accurate.": "AI-generated content may not be accurate.",
"AI Chat": "AI Chat",
"Analyze for insights": "Analyze for insights",
"Ask anything...": "Ask anything...",
"Chat history": "Chat history",
"Chat name": "Chat name",
"Close": "Close",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Failed to load chat. An error occurred.",
"Failed to render this message.": "Failed to render this message.",
"How can I help you today?": "How can I help you today?",
"New chat": "New chat",
"No chat history": "No chat history",
"No chats found": "No chats found",
"No conversations yet": "No conversations yet",
"Open full page": "Open full page",
"Previous 7 days": "Previous 7 days",
"Previous 30 days": "Previous 30 days",
"Search chats...": "Search chats...",
"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",
"Translate this page": "Translate this page",
"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?",
"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"
} }
+310 -123
View File
@@ -7,6 +7,7 @@
"Add members": "Agregar miembros", "Add members": "Agregar miembros",
"Add to groups": "Agregar a grupos", "Add to groups": "Agregar a grupos",
"Add space members": "Agregar miembros al espacio", "Add space members": "Agregar miembros al espacio",
"Add to favorites": "Agregar a favoritos",
"Admin": "Administrador", "Admin": "Administrador",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "¿Estás seguro de que deseas eliminar este grupo? Los miembros perderán acceso a los recursos a los que este grupo tiene acceso.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "¿Estás seguro de que deseas eliminar este grupo? Los miembros perderán acceso a los recursos a los que este grupo tiene acceso.",
"Are you sure you want to delete this page?": "¿Está seguro de que desea eliminar esta página?", "Are you sure you want to delete this page?": "¿Está seguro de que desea eliminar esta página?",
@@ -44,15 +45,15 @@
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "¿Está seguro de que desea eliminar esta página? Esto eliminará sus dependientes y el historial de la página. Esta acción es irreversible.", "Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "¿Está seguro de que desea eliminar esta página? Esto eliminará sus dependientes y el historial de la página. Esta acción es irreversible.",
"Description": "Descripción", "Description": "Descripción",
"Details": "Detalles", "Details": "Detalles",
"e.g ACME": "ej: ACME", "e.g ACME": "p. ej., ACME",
"e.g ACME Inc": "ej: ACME Inc", "e.g ACME Inc": "p. ej., ACME Inc",
"e.g Developers": "ej: Desarrolladores", "e.g Developers": "p. ej., Desarrolladores",
"e.g Group for developers": "ej: Grupo para desarrolladores", "e.g Group for developers": "p. ej., Grupo para desarrolladores",
"e.g product": "ej: producto", "e.g product": "p. ej., producto",
"e.g Product Team": "ej: Equipo de Producto", "e.g Product Team": "p. ej., Equipo de producto",
"e.g Sales": "ej: Ventas", "e.g Sales": "p. ej., Ventas",
"e.g Space for product team": "ej: Espacio para el equipo de producto", "e.g Space for product team": "p. ej., Espacio para el equipo de producto",
"e.g Space for sales team to collaborate": "ej: Espacio para que el equipo de ventas colabore", "e.g Space for sales team to collaborate": "p. ej., Espacio para que el equipo de ventas colabore",
"Edit": "Editar", "Edit": "Editar",
"Read": "Leer", "Read": "Leer",
"Edit group": "Editar grupo", "Edit group": "Editar grupo",
@@ -61,7 +62,7 @@
"Enter valid email addresses separated by comma or space max_50": "Ingrese direcciones de correo electrónico válidas separadas por coma o espacio [max: 50]", "Enter valid email addresses separated by comma or space max_50": "Ingrese direcciones de correo electrónico válidas separadas por coma o espacio [max: 50]",
"enter valid emails addresses": "introduce direcciones de correo electrónico válidas", "enter valid emails addresses": "introduce direcciones de correo electrónico válidas",
"Enter your current password": "Introduce tu contraseña actual", "Enter your current password": "Introduce tu contraseña actual",
"enter your full name": "introduzca su nombre completo", "enter your full name": "introduce tu nombre completo",
"Enter your new password": "Ingrese su nueva contraseña", "Enter your new password": "Ingrese su nueva contraseña",
"Enter your new preferred email": "Introduce tu nuevo correo electrónico preferido", "Enter your new preferred email": "Introduce tu nuevo correo electrónico preferido",
"Enter your password": "Introduce tu contraseña", "Enter your password": "Introduce tu contraseña",
@@ -74,6 +75,9 @@
"Failed to import pages": "No se pudieron importar las páginas", "Failed to import pages": "No se pudieron importar las páginas",
"Failed to load page. An error occurred.": "Error al cargar la página. Se produjo un error.", "Failed to load page. An error occurred.": "Error al cargar la página. Se produjo un error.",
"Failed to update data": "No se pudo actualizar los datos", "Failed to update data": "No se pudo actualizar los datos",
"Favorite spaces": "Espacios favoritos",
"Favorite spaces appear here": "Los espacios favoritos aparecen aquí",
"Favorites": "Favoritos",
"Full access": "Acceso completo", "Full access": "Acceso completo",
"Full page width": "Ancho de página completa", "Full page width": "Ancho de página completa",
"Full width": "Ancho completo", "Full width": "Ancho completo",
@@ -92,6 +96,7 @@
"Invite by email": "Invitar por correo electrónico", "Invite by email": "Invitar por correo electrónico",
"Invite members": "Invitar a miembros", "Invite members": "Invitar a miembros",
"Invite new members": "Invitar a nuevos miembros", "Invite new members": "Invitar a nuevos miembros",
"Invite People": "Invitar personas",
"Invited members who are yet to accept their invitation will appear here.": "Los miembros invitados que aún no han aceptado su invitación aparecerán aquí.", "Invited members who are yet to accept their invitation will appear here.": "Los miembros invitados que aún no han aceptado su invitación aparecerán aquí.",
"Invited members will be granted access to spaces the groups can access": "Los miembros invitados recibirán acceso a los espacios a los que los grupos pueden acceder", "Invited members will be granted access to spaces the groups can access": "Los miembros invitados recibirán acceso a los espacios a los que los grupos pueden acceder",
"Join the workspace": "Unirse al espacio de trabajo", "Join the workspace": "Unirse al espacio de trabajo",
@@ -113,7 +118,7 @@
"New email": "Nuevo correo electrónico", "New email": "Nuevo correo electrónico",
"New page": "Nueva página", "New page": "Nueva página",
"New password": "Nueva contraseña", "New password": "Nueva contraseña",
"No group found": "No se encontró grupo", "No group found": "No se encontró ningún grupo",
"No page history saved yet.": "No hay historial de la página guardado aún.", "No page history saved yet.": "No hay historial de la página guardado aún.",
"No pages yet": "No hay páginas todavía", "No pages yet": "No hay páginas todavía",
"No shared pages": "No hay páginas compartidas", "No shared pages": "No hay páginas compartidas",
@@ -139,6 +144,7 @@
"Profile": "Perfil", "Profile": "Perfil",
"Recently updated": "Recientemente actualizado", "Recently updated": "Recientemente actualizado",
"Remove": "Eliminar", "Remove": "Eliminar",
"Remove from favorites": "Quitar de favoritos",
"Remove group member": "Eliminar miembro del grupo", "Remove group member": "Eliminar miembro del grupo",
"Remove space member": "Eliminar miembro del espacio", "Remove space member": "Eliminar miembro del espacio",
"Restore": "Restaurar", "Restore": "Restaurar",
@@ -151,54 +157,55 @@
"Search...": "Buscar...", "Search...": "Buscar...",
"Select language": "Seleccionar idioma", "Select language": "Seleccionar idioma",
"Select role": "Seleccionar rol", "Select role": "Seleccionar rol",
"Select role to assign to all invited members": "Seleccionar rol para asignar a todos los miembros invitados", "Select role to assign to all invited members": "Selecciona el rol que se asignará a todos los miembros invitados",
"Select theme": "Seleccionar tema", "Select theme": "Seleccionar tema",
"Send invitation": "Enviar invitación", "Send invitation": "Enviar invitación",
"Invitation sent": "Invitación enviada", "Invitation sent": "Invitación enviada",
"Settings": "Ajustes", "Settings": "Configuración",
"Setup workspace": "Configurar espacio de trabajo", "Setup workspace": "Configurar espacio de trabajo",
"Sign In": "Iniciar sesión", "Sign In": "Iniciar sesión",
"Sign Up": "Registrarse", "Sign Up": "Registrarse",
"Slug": "Identificador", "Slug": "Slug",
"Space": "Espacio", "Space": "Espacio",
"Space description": "Descripción del espacio", "Space description": "Descripción del espacio",
"Space menu": "Menú de espacio", "Space menu": "Menú del espacio",
"Space name": "Nombre del espacio", "Space name": "Nombre del espacio",
"Space settings": "Configuración del espacio", "Space settings": "Configuración del espacio",
"Space slug": "Identificador del espacio", "Space slug": "Slug del espacio",
"Spaces": "Espacios", "Spaces": "Espacios",
"Spaces you belong to": "Espacios a los que perteneces", "Spaces you belong to": "Espacios a los que perteneces",
"No space found": "No se encontró espacio", "No space found": "No se encontró ningún espacio",
"Search for spaces": "Buscar espacios", "Search for spaces": "Buscar espacios",
"Start typing to search...": "Empieza a escribir para buscar...", "Start typing to search...": "Empieza a escribir para buscar...",
"Status": "Estado", "Status": "Estado",
"Successfully imported": "Importado con éxito", "Successfully imported": "Importado correctamente",
"Successfully restored": "Restaurado con éxito", "Successfully restored": "Restaurado correctamente",
"System settings": "Configuración del sistema", "System settings": "Configuración del sistema",
"Templates": "Plantillas",
"Theme": "Tema", "Theme": "Tema",
"To change your email, you have to enter your password and new email.": "Para cambiar tu correo electrónico, debes ingresar tu contraseña y nuevo correo electrónico.", "To change your email, you have to enter your password and new email.": "Para cambiar tu correo electrónico, debes ingresar tu contraseña y nuevo correo electrónico.",
"Toggle full page width": "Alternar el ancho de página completa", "Toggle full page width": "Alternar ancho completo de la página",
"Unable to import pages. Please try again.": "No se pueden importar las páginas. Por favor, inténtelo de nuevo.", "Unable to import pages. Please try again.": "No se pueden importar las páginas. Por favor, inténtelo de nuevo.",
"untitled": "sin título", "untitled": "sin título",
"Untitled": "Sin título", "Untitled": "Sin título",
"Updated successfully": "Actualizado con éxito", "Updated successfully": "Actualizado correctamente",
"User": "Usuario", "User": "Usuario",
"Workspace": "Espacio de trabajo", "Workspace": "Espacio de trabajo",
"Workspace Name": "Nombre del espacio de trabajo", "Workspace Name": "Nombre del espacio de trabajo",
"Workspace settings": "Configuración del espacio de trabajo", "Workspace settings": "Configuración del espacio de trabajo",
"You can change your password here.": "Puede cambiar su contraseña aquí.", "You can change your password here.": "Puede cambiar su contraseña aquí.",
"Your Email": "Su correo electrónico", "Your Email": "Tu correo electrónico",
"Your import is complete.": "Su importación está completa.", "Your import is complete.": "Su importación está completa.",
"Your name": "Tu nombre", "Your name": "Tu nombre",
"Your Name": "Tu Nombre", "Your Name": "Tu nombre",
"Your password": "Tu contraseña", "Your password": "Tu contraseña",
"Your password must be a minimum of 8 characters.": "Su contraseña debe tener un mínimo de 8 caracteres.", "Your password must be a minimum of 8 characters.": "Su contraseña debe tener un mínimo de 8 caracteres.",
"Sidebar toggle": "Alternar barra lateral", "Sidebar toggle": "Alternar barra lateral",
"Comments": "Comentarios", "Comments": "Comentarios",
"404 page not found": "404 página no encontrada", "404 page not found": "404 página no encontrada",
"Sorry, we can't find the page you are looking for.": "Lo sentimos, no podemos encontrar la página que buscas.", "Sorry, we can't find the page you are looking for.": "Lo sentimos, no podemos encontrar la página que buscas.",
"Take me back to homepage": "Llévame de vuelta a la página de inicio", "Take me back to homepage": "Llévame de vuelta a la página principal",
"Forgot password": "Olvidó la contraseña", "Forgot password": "Olvidé mi contraseña",
"Forgot your password?": "¿Olvidó su contraseña?", "Forgot your password?": "¿Olvidó su contraseña?",
"A password reset link has been sent to your email. Please check your inbox.": "Se ha enviado un enlace para restablecer la contraseña a tu correo electrónico. Por favor, revisa tu bandeja de entrada.", "A password reset link has been sent to your email. Please check your inbox.": "Se ha enviado un enlace para restablecer la contraseña a tu correo electrónico. Por favor, revisa tu bandeja de entrada.",
"Send reset link": "Enviar enlace de restablecimiento", "Send reset link": "Enviar enlace de restablecimiento",
@@ -215,6 +222,8 @@
"Edit comment": "Editar comentario", "Edit comment": "Editar comentario",
"Delete comment": "Eliminar comentario", "Delete comment": "Eliminar comentario",
"Are you sure you want to delete this comment?": "¿Está seguro de que desea eliminar este comentario?", "Are you sure you want to delete this comment?": "¿Está seguro de que desea eliminar este comentario?",
"Delete chat": "Eliminar chat",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "¿Está seguro de que desea eliminar '{{title}}'? Esta acción no se puede deshacer.",
"Comment created successfully": "Comentario creado con éxito", "Comment created successfully": "Comentario creado con éxito",
"Error creating comment": "Error al crear comentario", "Error creating comment": "Error al crear comentario",
"Comment updated successfully": "Comentario actualizado con éxito", "Comment updated successfully": "Comentario actualizado con éxito",
@@ -222,13 +231,13 @@
"Comment deleted successfully": "Comentario eliminado con éxito", "Comment deleted successfully": "Comentario eliminado con éxito",
"Failed to delete comment": "No se pudo eliminar el comentario", "Failed to delete comment": "No se pudo eliminar el comentario",
"Comment resolved successfully": "Comentario resuelto con éxito", "Comment resolved successfully": "Comentario resuelto con éxito",
"Comment re-opened successfully": "Comentario reabierto con éxito", "Comment re-opened successfully": "Comentario reabierto correctamente",
"Comment unresolved successfully": "Comentario no resuelto con éxito", "Comment unresolved successfully": "Comentario marcado como no resuelto correctamente",
"Failed to resolve comment": "No se pudo resolver el comentario", "Failed to resolve comment": "No se pudo resolver el comentario",
"Resolve comment": "Resolver comentario", "Resolve comment": "Resolver comentario",
"Unresolve comment": "No resolver comentario", "Unresolve comment": "Marcar comentario como no resuelto",
"Resolve Comment Thread": "Resolver hilo de comentarios", "Resolve Comment Thread": "Resolver hilo de comentarios",
"Unresolve Comment Thread": "No resolver hilo de comentarios", "Unresolve Comment Thread": "Marcar hilo de comentarios como no resuelto",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "¿Está seguro de que desea resolver este hilo de comentarios? Esto lo marcará como completado.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "¿Está seguro de que desea resolver este hilo de comentarios? Esto lo marcará como completado.",
"Are you sure you want to unresolve this comment thread?": "¿Está seguro de que desea no resolver este hilo de comentarios?", "Are you sure you want to unresolve this comment thread?": "¿Está seguro de que desea no resolver este hilo de comentarios?",
"Resolved": "Resuelto", "Resolved": "Resuelto",
@@ -289,6 +298,11 @@
"Save & Exit": "Guardar y Salir", "Save & Exit": "Guardar y Salir",
"Double-click to edit Excalidraw diagram": "Doble clic para editar el diagrama de Excalidraw", "Double-click to edit Excalidraw diagram": "Doble clic para editar el diagrama de Excalidraw",
"Paste link": "Pegar enlace", "Paste link": "Pegar enlace",
"Paste link or search pages": "Pega un enlace o busca páginas",
"Link to web page": "Enlazar a una página web",
"Recents": "Recientes",
"Page or URL": "Página o URL",
"Link title": "Título del enlace",
"Edit link": "Editar enlace", "Edit link": "Editar enlace",
"Remove link": "Eliminar enlace", "Remove link": "Eliminar enlace",
"Add link": "Agregar enlace", "Add link": "Agregar enlace",
@@ -307,7 +321,7 @@
"Pink": "Rosa", "Pink": "Rosa",
"Gray": "Gris", "Gray": "Gris",
"Embed link": "Enlace adjunto", "Embed link": "Enlace adjunto",
"Invalid {{provider}} embed link": "Enlace incrustado {{provider}} no válido", "Invalid {{provider}} embed link": "Enlace de inserción de {{provider}} no válido",
"Embed {{provider}}": "Incrustar {{provider}}", "Embed {{provider}}": "Incrustar {{provider}}",
"Enter {{provider}} link to embed": "Introduzca el enlace de {{provider}} para incrustar", "Enter {{provider}} link to embed": "Introduzca el enlace de {{provider}} para incrustar",
"Bold": "Negrita", "Bold": "Negrita",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Insertar regla horizontal", "Insert horizontal rule divider": "Insertar regla horizontal",
"Upload any image from your device.": "Sube cualquier imagen desde tu dispositivo.", "Upload any image from your device.": "Sube cualquier imagen desde tu dispositivo.",
"Upload any video from your device.": "Sube cualquier video desde tu dispositivo.", "Upload any video from your device.": "Sube cualquier video desde tu dispositivo.",
"Upload any audio from your device.": "Sube cualquier audio desde tu dispositivo.",
"Upload any file from your device.": "Sube cualquier archivo desde tu dispositivo.", "Upload any file from your device.": "Sube cualquier archivo desde tu dispositivo.",
"Uploading {{name}}": "Subiendo {{name}}", "Uploading {{name}}": "Subiendo {{name}}",
"Uploading file": "Subiendo archivo", "Uploading file": "Subiendo archivo",
@@ -343,22 +358,28 @@
"Insert a table.": "Insertar una tabla.", "Insert a table.": "Insertar una tabla.",
"Insert collapsible block.": "Insertar bloque desplegable.", "Insert collapsible block.": "Insertar bloque desplegable.",
"Video": "Vídeo", "Video": "Vídeo",
"Divider": "Divisor", "Divider": "Separador",
"Quote": "Cita", "Quote": "Cita",
"Image": "Imagen", "Image": "Imagen",
"File attachment": "Adjunto de archivo", "Audio": "Audio",
"Toggle block": "Alternar bloque", "Embed PDF": "Adjuntar PDF",
"Callout": "Aviso", "Upload and embed a PDF file.": "Sube y adjunta un archivo PDF.",
"Embed as PDF": "Adjuntar como PDF",
"Failed to load PDF": "Error al cargar el PDF",
"Convert to attachment": "Convertir en adjunto",
"File attachment": "Archivo adjunto",
"Toggle block": "Bloque desplegable",
"Callout": "Llamada de atención",
"Insert callout notice.": "Insertar aviso de llamada.", "Insert callout notice.": "Insertar aviso de llamada.",
"Math inline": "Matemáticas en línea", "Math inline": "Matemáticas en línea",
"Insert inline math equation.": "Insertar ecuación matemática en línea.", "Insert inline math equation.": "Insertar ecuación matemática en línea.",
"Math block": "Bloque de matemáticas", "Math block": "Bloque matemático",
"Insert math equation": "Insertar ecuación matemática", "Insert math equation": "Insertar ecuación matemática",
"Mermaid diagram": "Diagrama de Mermaid", "Mermaid diagram": "Diagrama Mermaid",
"Insert mermaid diagram": "Insertar diagrama de Mermaid", "Insert mermaid diagram": "Insertar diagrama Mermaid",
"Insert and design Drawio diagrams": "Insertar y diseñar diagramas Drawio", "Insert and design Drawio diagrams": "Insertar y diseñar diagramas de Drawio",
"Insert current date": "Insertar fecha actual", "Insert current date": "Insertar fecha actual",
"Draw and sketch excalidraw diagrams": "Dibujar y esbozar diagramas de Excalidraw", "Draw and sketch excalidraw diagrams": "Dibujar y crear bocetos de diagramas de Excalidraw",
"Multiple": "Múltiple", "Multiple": "Múltiple",
"Turn into": "Convertir en", "Turn into": "Convertir en",
"Text align": "Alineación del texto", "Text align": "Alineación del texto",
@@ -367,7 +388,7 @@
"Pages you create will show up here.": "Las páginas que crees aparecerán aquí.", "Pages you create will show up here.": "Las páginas que crees aparecerán aquí.",
"Heading {{level}}": "Encabezado {{level}}", "Heading {{level}}": "Encabezado {{level}}",
"Toggle title": "Alternar título", "Toggle title": "Alternar título",
"Write anything. Enter \"/\" for commands": "Escribe cualquier cosa. Ingresa \"/\" para comandos", "Write anything. Enter \"/\" for commands": "Escribe cualquier cosa. Introduce \"/\" para ver los comandos",
"Write...": "Escribe...", "Write...": "Escribe...",
"Column count": "Número de columnas", "Column count": "Número de columnas",
"{{count}} Columns": "{count, plural, one {# columna} other {# columnas}}", "{{count}} Columns": "{count, plural, one {# columna} other {# columnas}}",
@@ -380,24 +401,24 @@
"Names do not match": "Los nombres no coinciden", "Names do not match": "Los nombres no coinciden",
"Today, {{time}}": "Hoy, {{time}}", "Today, {{time}}": "Hoy, {{time}}",
"Yesterday, {{time}}": "Ayer, {{time}}", "Yesterday, {{time}}": "Ayer, {{time}}",
"Space created successfully": "Espacio creado con éxito", "Space created successfully": "Espacio creado correctamente",
"Space updated successfully": "Espacio actualizado con éxito", "Space updated successfully": "Espacio actualizado correctamente",
"Space deleted successfully": "Espacio eliminado con éxito", "Space deleted successfully": "Espacio eliminado correctamente",
"Members added successfully": "Miembros añadidos con éxito", "Members added successfully": "Miembros agregados correctamente",
"Member removed successfully": "Miembro eliminado con éxito", "Member removed successfully": "Miembro eliminado correctamente",
"Member role updated successfully": "Rol de miembro actualizado con éxito", "Member role updated successfully": "Rol del miembro actualizado correctamente",
"Created by: <b>{{creatorName}}</b>": "Creado por: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "Creado por: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Creado a: {{time}}", "Created at: {{time}}": "Creado el: {{time}}",
"Edited by {{name}} {{time}}": "Editado por {{name}} {{time}}", "Edited by {{name}} {{time}}": "Editado por {{name}} {{time}}",
"Word count: {{wordCount}}": "Conteo de palabras: {{wordCount}}", "Word count: {{wordCount}}": "Recuento de palabras: {{wordCount}}",
"Character count: {{characterCount}}": "Recuento de caracteres: {{characterCount}}", "Character count: {{characterCount}}": "Recuento de caracteres: {{characterCount}}",
"New update": "Nueva actualización", "New update": "Nueva actualización",
"{{latestVersion}} is available": "{{latestVersion}} está disponible", "{{latestVersion}} is available": "{{latestVersion}} está disponible",
"Default page edit mode": "Modo de edición de página predeterminado", "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 your preferred page edit mode. Avoid accidental edits.": "Elige tu modo de edición de página preferido. Evita ediciones accidentales.",
"Reading": "Leyendo", "Reading": "Lectura",
"Delete member": "Eliminar miembro", "Delete member": "Eliminar miembro",
"Member deleted successfully": "Miembro eliminado con éxito", "Member deleted successfully": "Miembro eliminado correctamente",
"Are you sure you want to delete this workspace member? This action is irreversible.": "¿Está seguro que desea eliminar este miembro del área de trabajo? Esta acción es irreversible.", "Are you sure you want to delete this workspace member? This action is irreversible.": "¿Está seguro que desea eliminar este miembro del área de trabajo? Esta acción es irreversible.",
"Deactivate member": "Desactivar miembro", "Deactivate member": "Desactivar miembro",
"Activate member": "Activar miembro", "Activate member": "Activar miembro",
@@ -410,36 +431,38 @@
"Move page": "Mover página", "Move page": "Mover página",
"Move page to a different space.": "Mover página a un espacio diferente.", "Move page to a different space.": "Mover página a un espacio diferente.",
"Real-time editor connection lost. Retrying...": "Conexión del editor en tiempo real perdida. Reintentando...", "Real-time editor connection lost. Retrying...": "Conexión del editor en tiempo real perdida. Reintentando...",
"Table of contents": "Índice de contenidos", "Table of contents": "Tabla de contenido",
"Add headings (H1, H2, H3) to generate a table of contents.": "Añadir encabezados (H1, H2, H3) para generar un índice de contenidos.", "Add headings (H1, H2, H3) to generate a table of contents.": "Añadir encabezados (H1, H2, H3) para generar un índice de contenidos.",
"Share": "Compartir", "Share": "Compartir",
"Public sharing": "Compartición pública", "Public sharing": "Uso compartido público",
"Shared by": "Compartido por", "Shared by": "Compartido por",
"Shared at": "Compartido en", "Shared at": "Compartido el",
"Inherits public sharing from": "Hereda la compartición pública de", "Inherits public sharing from": "Hereda el uso compartido público de",
"Share to web": "Compartir en la web", "Share to web": "Compartir en la web",
"Shared to web": "Compartido en la web", "Shared to web": "Compartido en la web",
"Anyone with the link can view this page": "Cualquiera con el enlace puede ver esta página", "Anyone with the link can view this page": "Cualquier persona con el enlace puede ver esta página",
"Make this page publicly accessible": "Hacer esta página accesible públicamente", "Make this page publicly accessible": "Hacer que esta página sea accesible públicamente",
"Include sub-pages": "Incluir subpáginas", "Include sub-pages": "Incluir subpáginas",
"Make sub-pages public too": "Hacer públicas también las subpáginas", "Make sub-pages public too": "Hacer públicas también las subpáginas",
"Allow search engines to index page": "Permitir a los motores de búsqueda indexar la página", "Allow search engines to index page": "Permitir que los motores de búsqueda indexen la página",
"Open page": "Abrir página", "Open page": "Abrir página",
"Page": "Página", "Page": "Página",
"Delete public share link": "Eliminar enlace de compartición pública", "Delete public share link": "Eliminar enlace público compartido",
"Delete share": "Eliminar compartición", "Delete share": "Eliminar recurso compartido",
"Are you sure you want to delete this shared link?": "¿Está seguro de que desea eliminar este enlace compartido?", "Are you sure you want to delete this shared link?": "¿Está seguro de que desea eliminar este enlace compartido?",
"Publicly shared pages from spaces you are a member of will appear here": "Las páginas compartidas públicamente de los espacios a los que pertenece aparecerán aquí", "Publicly shared pages from spaces you are a member of will appear here": "Las páginas compartidas públicamente de los espacios de los que eres miembro aparecerán aquí",
"Share deleted successfully": "Compartición eliminada con éxito", "Share deleted successfully": "Recurso compartido eliminado correctamente",
"Share not found": "Compartición no encontrada", "Share not found": "Recurso compartido no encontrado",
"Failed to share page": "Error al compartir la página", "Failed to share page": "No se pudo compartir la página",
"Disable public sharing": "Desactivar el uso compartido público", "Disable public sharing": "Desactivar el uso compartido público",
"Prevent members from sharing pages publicly.": "Evitar que los miembros compartan páginas públicamente.", "Prevent members from sharing pages publicly.": "Evitar que los miembros compartan páginas públicamente.",
"Toggle public sharing": "Alternar el uso compartido público", "Toggle public sharing": "Alternar el uso compartido público",
"Toggle space public sharing": "Alternar el uso compartido público del espacio", "Toggle space public sharing": "Alternar el uso compartido público del espacio",
"Allow viewers to comment": "Permitir que los espectadores comenten",
"Allow viewers to add comments on pages in this space.": "Permitir que los espectadores agreguen comentarios en las páginas de este espacio.",
"Toggle viewer comments": "Activar/desactivar comentarios de los espectadores",
"Public sharing is disabled at the workspace level": "El uso compartido público está desactivado a nivel de espacio de trabajo", "Public sharing is disabled at the workspace level": "El uso compartido público está desactivado a nivel de espacio de trabajo",
"Prevent pages in this space from being shared publicly.": "Evitar que las páginas en este espacio se compartan públicamente.", "Prevent pages in this space from being shared publicly.": "Evitar que las páginas en este espacio se compartan públicamente.",
"Requires an enterprise license": "Requiere una licencia empresarial",
"Page permissions": "Permisos de la página},{", "Page permissions": "Permisos de la página},{",
"Control who can view and edit individual pages. Available with an enterprise license.": "Controla quién puede ver y editar páginas individuales. Disponible con una licencia empresarial.", "Control who can view and edit individual pages. Available with an enterprise license.": "Controla quién puede ver y editar páginas individuales. Disponible con una licencia empresarial.",
"Enable public sharing": "Activar el uso compartido público", "Enable public sharing": "Activar el uso compartido público",
@@ -452,11 +475,11 @@
"Public sharing has been disabled for this space.": "El uso compartido público se ha desactivado para este espacio.", "Public sharing has been disabled for this space.": "El uso compartido público se ha desactivado para este espacio.",
"Copy page": "Copiar página", "Copy page": "Copiar página",
"Copy page to a different space.": "Copiar página en otro espacio", "Copy page to a different space.": "Copiar página en otro espacio",
"Page copied successfully": "Página copiada exitosamente", "Page copied successfully": "Página copiada correctamente",
"Page duplicated successfully": "Página duplicada con éxito", "Page duplicated successfully": "Página duplicada correctamente",
"Find": "Buscar", "Find": "Buscar",
"Not found": "No encontrado", "Not found": "No encontrado",
"Previous Match (Shift+Enter)": "Coincidencia anterior (Shift+Enter)", "Previous Match (Shift+Enter)": "Coincidencia anterior (Mayús+Enter)",
"Next match (Enter)": "Siguiente coincidencia (Enter)", "Next match (Enter)": "Siguiente coincidencia (Enter)",
"Match case (Alt+C)": "Distinguir mayúsculas y minúsculas (Alt+C)", "Match case (Alt+C)": "Distinguir mayúsculas y minúsculas (Alt+C)",
"Replace": "Reemplazar", "Replace": "Reemplazar",
@@ -464,36 +487,37 @@
"Replace (Enter)": "Reemplazar (Enter)", "Replace (Enter)": "Reemplazar (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Reemplazar todo (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Reemplazar todo (Ctrl+Alt+Enter)",
"Replace all": "Reemplazar todo", "Replace all": "Reemplazar todo",
"View all": "Ver todo",
"View all spaces": "Ver todos los espacios", "View all spaces": "Ver todos los espacios",
"Error": "Error", "Error": "Error",
"Failed to disable MFA": "No se pudo desactivar MFA", "Failed to disable MFA": "No se pudo desactivar la MFA",
"Disable two-factor authentication": "Desactivar la autenticación de dos factores", "Disable two-factor authentication": "Desactivar la autenticación de dos factores",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Desactivar la autenticación de dos factores hará que tu cuenta sea menos segura. Solo necesitarás tu contraseña para iniciar sesión.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Desactivar la autenticación de dos factores hará que tu cuenta sea menos segura. Solo necesitarás tu contraseña para iniciar sesión.",
"Please enter your password to disable two-factor authentication:": "Por favor ingresa tu contraseña para desactivar la autenticación de dos factores:", "Please enter your password to disable two-factor authentication:": "Por favor ingresa tu contraseña para desactivar la autenticación de dos factores:",
"Two-factor authentication has been enabled": "La autenticación de dos factores ha sido activada", "Two-factor authentication has been enabled": "La autenticación de dos factores se ha activado",
"Two-factor authentication has been disabled": "La autenticación de dos factores ha sido desactivada", "Two-factor authentication has been disabled": "La autenticación de dos factores se ha desactivado",
"2-step verification": "Verificación en 2 pasos", "2-step verification": "Verificación en 2 pasos",
"Protect your account with an additional verification layer when signing in.": "Protege tu cuenta con una capa adicional de verificación al iniciar sesión.", "Protect your account with an additional verification layer when signing in.": "Protege tu cuenta con una capa adicional de verificación al iniciar sesión.",
"Two-factor authentication is active on your account.": "La autenticación de dos factores está activa en tu cuenta.", "Two-factor authentication is active on your account.": "La autenticación de dos factores está activa en tu cuenta.",
"Add 2FA method": "Agregar método 2FA", "Add 2FA method": "Agregar método de 2FA",
"Backup codes": "Códigos de seguridad", "Backup codes": "Códigos de respaldo",
"Disable": "Desactivar", "Disable": "Desactivar",
"Invalid verification code": "Código de verificación no válido", "Invalid verification code": "Código de verificación no válido",
"New backup codes have been generated": "Nuevos códigos de seguridad han sido generados", "New backup codes have been generated": "Se han generado nuevos códigos de respaldo",
"Failed to regenerate backup codes": "No se pudo regenerar los códigos de seguridad", "Failed to regenerate backup codes": "No se pudieron regenerar los códigos de respaldo",
"About backup codes": "Acerca de los códigos de seguridad", "About backup codes": "Acerca de los códigos de respaldo",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Los códigos de seguridad pueden usarse para acceder a tu cuenta si pierdes acceso a tu aplicación autenticadora. Cada código solo puede ser usado una vez.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Los códigos de seguridad pueden usarse para acceder a tu cuenta si pierdes acceso a tu aplicación autenticadora. Cada código solo puede ser usado una vez.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Puedes regenerar nuevos códigos de seguridad en cualquier momento. Esto invalidará todos los códigos existentes.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Puedes regenerar nuevos códigos de seguridad en cualquier momento. Esto invalidará todos los códigos existentes.",
"Confirm password": "Confirmar contraseña", "Confirm password": "Confirmar contraseña",
"Generate new backup codes": "Generar nuevos códigos de seguridad", "Generate new backup codes": "Generar nuevos códigos de respaldo",
"Save your new backup codes": "Guarda tus nuevos códigos de seguridad", "Save your new backup codes": "Guarda tus nuevos códigos de respaldo",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Asegúrate de guardar estos códigos en un lugar seguro. Tus viejos códigos de seguridad ya no son válidos.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Asegúrate de guardar estos códigos en un lugar seguro. Tus viejos códigos de seguridad ya no son válidos.",
"Your new backup codes": "Tus nuevos códigos de seguridad", "Your new backup codes": "Tus nuevos códigos de respaldo",
"I've saved my backup codes": "He guardado mis códigos de seguridad", "I've saved my backup codes": "He guardado mis códigos de respaldo",
"Failed to setup MFA": "No se pudo configurar MFA", "Failed to setup MFA": "No se pudo configurar la MFA",
"Setup & Verify": "Configurar y verificar", "Setup & Verify": "Configurar y verificar",
"Add to authenticator": "Agregar al autenticador", "Add to authenticator": "Agregar al autenticador",
"1. Scan this QR code with your authenticator app": "1. Escanea este código QR con tu aplicación autenticadora", "1. Scan this QR code with your authenticator app": "1. Escanea este código QR con tu aplicación de autenticación",
"Can't scan the code?": "¿No puedes escanear el código?", "Can't scan the code?": "¿No puedes escanear el código?",
"Enter this code manually in your authenticator app:": "Introduce este código manualmente en tu aplicación autenticadora:", "Enter this code manually in your authenticator app:": "Introduce este código manualmente en tu aplicación autenticadora:",
"2. Enter the 6-digit code from your authenticator": "2. Introduce el código de 6 dígitos de tu autenticador", "2. Enter the 6-digit code from your authenticator": "2. Introduce el código de 6 dígitos de tu autenticador",
@@ -501,34 +525,34 @@
"Failed to generate QR code. Please try again.": "No se pudo generar el código QR. Por favor, intente de nuevo.", "Failed to generate QR code. Please try again.": "No se pudo generar el código QR. Por favor, intente de nuevo.",
"Backup": "Respaldo", "Backup": "Respaldo",
"Save codes": "Guardar códigos", "Save codes": "Guardar códigos",
"Save your backup codes": "Guarda tus códigos de seguridad", "Save your backup codes": "Guarda tus códigos de respaldo",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Estos códigos pueden usarse para acceder a tu cuenta si pierdes acceso a tu aplicación autenticadora. Cada código solo puede ser usado una vez.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Estos códigos pueden usarse para acceder a tu cuenta si pierdes acceso a tu aplicación autenticadora. Cada código solo puede ser usado una vez.",
"Print": "Imprimir", "Print": "Imprimir",
"Two-factor authentication has been set up. Please log in again.": "La autenticación de dos factores ha sido configurada. Por favor, inicie sesión nuevamente.", "Two-factor authentication has been set up. Please log in again.": "La autenticación de dos factores ha sido configurada. Por favor, inicie sesión nuevamente.",
"Two-Factor authentication required": "Se requiere autenticación de dos factores", "Two-Factor authentication required": "Se requiere autenticación de dos factores",
"Your workspace requires two-factor authentication for all users": "Tu espacio de trabajo requiere autenticación de dos factores para todos los usuarios", "Your workspace requires two-factor authentication for all users": "Tu espacio de trabajo requiere autenticación de dos factores para todos los usuarios",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Para continuar accediendo a tu espacio de trabajo, debes configurar la autenticación de dos factores. Esto añade una capa extra de seguridad a tu cuenta.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Para continuar accediendo a tu espacio de trabajo, debes configurar la autenticación de dos factores. Esto añade una capa extra de seguridad a tu cuenta.",
"Set up two-factor authentication": "Configurar la autenticación de dos factores", "Set up two-factor authentication": "Configurar autenticación de dos factores",
"Cancel and logout": "Cancelar y cerrar sesión", "Cancel and logout": "Cancelar y cerrar sesión",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Tu espacio de trabajo requiere autenticación de dos factores. Por favor, configúralo para continuar.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Tu espacio de trabajo requiere autenticación de dos factores. Por favor, configúralo para continuar.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Esto añade una capa extra de seguridad a tu cuenta al requerir un código de verificación de tu aplicación autenticadora.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Esto añade una capa extra de seguridad a tu cuenta al requerir un código de verificación de tu aplicación autenticadora.",
"Password is required": "Se requiere contraseña", "Password is required": "La contraseña es obligatoria",
"Password must be at least 8 characters": "La contraseña debe tener al menos 8 caracteres", "Password must be at least 8 characters": "La contraseña debe tener al menos 8 caracteres",
"Please enter a 6-digit code": "Por favor, introduce un código de 6 dígitos", "Please enter a 6-digit code": "Introduce un código de 6 dígitos",
"Code must be exactly 6 digits": "El código debe ser exactamente de 6 dígitos", "Code must be exactly 6 digits": "El código debe tener exactamente 6 dígitos",
"Enter the 6-digit code found in your authenticator app": "Introduce el código de 6 dígitos que se encuentra en tu aplicación autenticadora", "Enter the 6-digit code found in your authenticator app": "Introduce el código de 6 dígitos que aparece en tu aplicación de autenticación",
"Need help authenticating?": "¿Necesitas ayuda para autenticar?", "Need help authenticating?": "¿Necesitas ayuda para autenticar?",
"MFA QR Code": "Código QR MFA", "MFA QR Code": "Código QR de MFA",
"Account created successfully. Please log in to set up two-factor authentication.": "Cuenta creada exitosamente. Por favor, inicie sesión para configurar la autenticación de dos factores.", "Account created successfully. Please log in to set up two-factor authentication.": "Cuenta creada exitosamente. Por favor, inicie sesión para configurar la autenticación de dos factores.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Restablecimiento de contraseña exitoso. Por favor, inicie sesión con su nueva contraseña y complete la autenticación de dos factores.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "Restablecimiento de contraseña exitoso. Por favor, inicie sesión con su nueva contraseña y complete la autenticación de dos factores.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Restablecimiento de contraseña exitoso. Por favor, inicie sesión con su nueva contraseña para configurar la autenticación de dos factores.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Restablecimiento de contraseña exitoso. Por favor, inicie sesión con su nueva contraseña para configurar la autenticación de dos factores.",
"Password reset was successful. Please log in with your new password.": "El restablecimiento de contraseña fue exitoso. Por favor, inicie sesión con su nueva contraseña.", "Password reset was successful. Please log in with your new password.": "El restablecimiento de contraseña fue exitoso. Por favor, inicie sesión con su nueva contraseña.",
"Two-factor authentication": "Autenticación de dos factores", "Two-factor authentication": "Autenticación de dos factores",
"Use authenticator app instead": "Usar la aplicación autenticadora en su lugar", "Use authenticator app instead": "Usar la aplicación de autenticación en su lugar",
"Verify backup code": "Verificar código de seguridad", "Verify backup code": "Verificar código de respaldo",
"Use backup code": "Usar código de seguridad", "Use backup code": "Usar código de respaldo",
"Enter one of your backup codes": "Introduce uno de tus códigos de seguridad", "Enter one of your backup codes": "Introduce uno de tus códigos de respaldo",
"Backup code": "Código de seguridad", "Backup code": "Código de respaldo",
"Enter one of your backup codes. Each backup code can only be used once.": "Introduce uno de tus códigos de seguridad. Cada código de seguridad solo puede ser usado una vez.", "Enter one of your backup codes. Each backup code can only be used once.": "Introduce uno de tus códigos de seguridad. Cada código de seguridad solo puede ser usado una vez.",
"Verify": "Verificar", "Verify": "Verificar",
"Trash": "Papelera", "Trash": "Papelera",
@@ -542,35 +566,35 @@
"Move this page to trash?": "¿Mover esta página a la papelera?", "Move this page to trash?": "¿Mover esta página a la papelera?",
"Restore page": "Restaurar página", "Restore page": "Restaurar página",
"Page moved to trash": "Página movida a la papelera", "Page moved to trash": "Página movida a la papelera",
"Page restored successfully": "Página restaurada con éxito", "Page restored successfully": "Página restaurada correctamente",
"Deleted by": "Eliminado por", "Deleted by": "Eliminado por",
"Deleted at": "Eliminado en", "Deleted at": "Eliminado el",
"Preview": "Vista previa", "Preview": "Vista previa",
"Subpages": "Subpáginas", "Subpages": "Subpáginas",
"Failed to load subpages": "Error al cargar subpáginas", "Failed to load subpages": "No se pudieron cargar las subpáginas",
"No subpages": "Sin subpáginas", "No subpages": "No hay subpáginas",
"Subpages (Child pages)": "Subpáginas (Páginas hijas)", "Subpages (Child pages)": "Subpáginas (páginas hijas)",
"List all subpages of the current page": "Listar todas las subpáginas de la página actual", "List all subpages of the current page": "Listar todas las subpáginas de la página actual",
"Attachments": "Adjuntos", "Attachments": "Archivos adjuntos",
"All spaces": "Todos los espacios", "All spaces": "Todos los espacios",
"Unknown": "Desconocido", "Unknown": "Desconocido",
"Find a space": "Encontrar un espacio", "Find a space": "Buscar un espacio",
"Search in all your spaces": "Buscar en todos tus espacios", "Search in all your spaces": "Buscar en todos tus espacios",
"Type": "Tipo", "Type": "Tipo",
"Enterprise": "Empresa", "Enterprise": "Empresarial",
"Download attachment": "Descargar adjunto", "Download attachment": "Descargar archivo adjunto",
"Allowed email domains": "Dominios de correo electrónico permitidos", "Allowed email domains": "Dominios de correo electrónico permitidos",
"Only users with email addresses from these domains can signup via SSO.": "Solo los usuarios con direcciones de correo electrónico de estos dominios pueden registrarse a través de SSO.", "Only users with email addresses from these domains can signup via SSO.": "Solo los usuarios con direcciones de correo electrónico de estos dominios pueden registrarse mediante SSO.",
"Enter valid domain names separated by comma or space": "Introduce nombres de dominio válidos separados por coma o espacio", "Enter valid domain names separated by comma or space": "Introduce nombres de dominio válidos separados por comas o espacios",
"Enforce two-factor authentication": "Aplicar autenticación de dos factores", "Enforce two-factor authentication": "Exigir autenticación de dos factores",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Una vez aplicada, todos los miembros deben habilitar la autenticación de dos factores para acceder al espacio de trabajo.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Una vez aplicada, todos los miembros deben habilitar la autenticación de dos factores para acceder al espacio de trabajo.",
"Toggle MFA enforcement": "Alternar la aplicación de MFA", "Toggle MFA enforcement": "Alternar exigencia de MFA",
"Display name": "Nombre para mostrar", "Display name": "Nombre para mostrar",
"Allow signup": "Permitir registro", "Allow signup": "Permitir registro",
"Enabled": "Habilitado", "Enabled": "Activado",
"Advanced Settings": "Configuración avanzada", "Advanced Settings": "Configuración avanzada",
"Enable TLS/SSL": "Habilitar TLS/SSL", "Enable TLS/SSL": "Activar TLS/SSL",
"Use secure connection to LDAP server": "Usar conexión segura al servidor LDAP", "Use secure connection to LDAP server": "Usar una conexión segura al servidor LDAP",
"Group sync": "Sincronización de grupos", "Group sync": "Sincronización de grupos",
"No SSO providers found.": "No se encontraron proveedores de SSO.", "No SSO providers found.": "No se encontraron proveedores de SSO.",
"Delete SSO provider": "Eliminar proveedor de SSO", "Delete SSO provider": "Eliminar proveedor de SSO",
@@ -613,6 +637,7 @@
"AI Answer": "Respuesta de IA", "AI Answer": "Respuesta de IA",
"Ask AI": "Preguntar a IA", "Ask AI": "Preguntar a IA",
"AI is thinking...": "IA está pensando...", "AI is thinking...": "IA está pensando...",
"Thinking": "Pensando",
"Ask a question...": "Haz una pregunta...", "Ask a question...": "Haz una pregunta...",
"AI Answers": "Respuestas de IA", "AI Answers": "Respuestas de IA",
"AI-powered search (AI Answers)": "Búsqueda impulsada por IA (Respuestas de IA)", "AI-powered search (AI Answers)": "Búsqueda impulsada por IA (Respuestas de IA)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "IA generativa (Preguntar a la IA)", "Generative AI (Ask AI)": "IA generativa (Preguntar a la IA)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Habilitar la generación de contenido impulsada por IA en el editor. Permite a los usuarios generar, mejorar, traducir y transformar texto.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Habilitar la generación de contenido impulsada por IA en el editor. Permite a los usuarios generar, mejorar, traducir y transformar texto.",
"Toggle generative AI": "Activar IA generativa", "Toggle generative AI": "Activar IA generativa",
"Enterprise feature": "Función empresarial", "Upgrade your plan": "Mejora tu plan",
"Available with a paid license": "Disponible con una licencia de pago",
"Upgrade your license tier.": "Mejora el nivel de tu licencia.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "La IA solo está disponible en la edición empresarial de Docmost. Contacte con sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "La IA solo está disponible en la edición empresarial de Docmost. Contacte con sales@docmost.com.",
"AI & MCP": "IA y MCP", "AI & MCP": "IA y MCP",
"AI": "IA", "AI": "IA",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Protocolo de Contexto del Modelo (MCP)", "Model Context Protocol (MCP)": "Protocolo de Contexto del Modelo (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Habilite el servidor MCP para permitir que asistentes de IA y herramientas interactúen con el contenido de su espacio de trabajo.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Habilite el servidor MCP para permitir que asistentes de IA y herramientas interactúen con el contenido de su espacio de trabajo.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP solo está disponible en la edición empresarial de Docmost. Contacte con sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP solo está disponible en la edición empresarial de Docmost. Contacte con sales@docmost.com.",
"MCP documentation": "Documentación de MCP",
"MCP Server URL": "URL del servidor MCP", "MCP Server URL": "URL del servidor MCP",
"Use your API key for authentication. You can manage API keys in your account settings.": "Use su clave API para la autenticación. Puede gestionar las claves API en la configuración de su cuenta.", "Use your API key for authentication. You can manage API keys in your account settings.": "Use su clave API para la autenticación. Puede gestionar las claves API en la configuración de su cuenta.",
"Supported tools": "Herramientas compatibles", "Supported tools": "Herramientas compatibles",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Su espacio de trabajo tiene MCP habilitado. Use su clave API para conectar asistentes de IA.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Su espacio de trabajo tiene MCP habilitado. Use su clave API para conectar asistentes de IA.",
"MCP server URL:": "URL del servidor MCP:", "MCP server URL:": "URL del servidor MCP:",
"Learn more": "Más información", "Learn more": "Más información",
"View the": "Ver la", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Gestiona las claves de API para todos los usuarios en el espacio de trabajo. Consulta la <anchor>documentación de la API</anchor> para detalles de uso.",
"for usage details.": "para detalles de uso.", "View the <anchor>API documentation</anchor> for usage details.": "Consulta la <anchor>documentación de la API</anchor> para detalles de uso.",
"for setup instructions.": "para instrucciones de configuración.", "View the <anchor>MCP documentation</anchor>.": "Consulta la <anchor>documentación de MCP</anchor>.",
"API documentation": "Documentación de la API",
"Sources": "Fuentes", "Sources": "Fuentes",
"AI Answers not available for attachments": "Respuestas de IA no disponibles para archivos adjuntos", "AI Answers not available for attachments": "Respuestas de IA no disponibles para archivos adjuntos",
"No answer available": "No hay respuesta disponible", "No answer available": "No hay respuesta disponible",
@@ -654,12 +679,34 @@
"Mark all as read": "Marcar todo como leído", "Mark all as read": "Marcar todo como leído",
"Mark as read": "Marcar como leído", "Mark as read": "Marcar como leído",
"More options": "Más opciones", "More options": "Más opciones",
"mentioned you in a comment": "te mencionó en un comentario", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> te mencionó en un comentario",
"commented on a page": "comentó en una página", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> comentó en una página",
"resolved a comment": "resolvió un comentario", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> resolvió un comentario",
"mentioned you on a page": "te mencionó en una página", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> te mencionó en una página",
"gave you edit access to a page": "Te dio acceso para editar una página.", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> te dio acceso de edición a una página",
"gave you view access to a page": "Te dio acceso para ver una página.", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> te dio acceso de visualización a una página",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> actualizó una página",
"Watch page": "Seguir página",
"Stop watching": "Dejar de seguir",
"Watch space": "Seguir espacio",
"Stop watching space": "Dejar de seguir espacio",
"Email notifications": "Notificaciones por correo electrónico",
"Page updates": "Actualizaciones de página",
"Get notified when pages you watch are updated.": "Recibe una notificación cuando se actualicen las páginas que sigues.",
"Page mentions": "Menciones en la página",
"Get notified when someone mentions you on a page.": "Recibe una notificación cuando alguien te mencione en una página.",
"Comment mentions": "Menciones en comentarios",
"Get notified when someone mentions you in a comment.": "Recibe una notificación cuando alguien te mencione en un comentario.",
"New comments": "Nuevos comentarios",
"Get notified about new comments on threads you participate in.": "Recibe una notificación sobre nuevos comentarios en los hilos donde participas.",
"Resolved comments": "Comentarios resueltos",
"Get notified when your comment is resolved.": "Recibe una notificación cuando tu comentario sea resuelto.",
"You are now watching this page": "Ahora sigues esta página",
"You are no longer watching this page": "Ya no sigues esta página",
"You are now watching this space": "Ahora sigues este espacio",
"You are no longer watching this space": "Ya no sigues este espacio",
"Direct": "Directo",
"Updates": "Actualizaciones",
"Today": "Hoy", "Today": "Hoy",
"Yesterday": "Ayer", "Yesterday": "Ayer",
"This week": "Esta semana", "This week": "Esta semana",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "No se pudo actualizar la retención de la papelera.", "Failed to update trash retention": "No se pudo actualizar la retención de la papelera.",
"Removed page restriction": "Restricción de página eliminada", "Removed page restriction": "Restricción de página eliminada",
"Added page permission": "Permiso de página añadido", "Added page permission": "Permiso de página añadido",
"Removed page permission": "Permiso de página eliminado" "Removed page permission": "Permiso de página eliminado",
"day": "día",
"days": "días",
"week": "semana",
"weeks": "semanas",
"month": "mes",
"months": "meses",
"year": "año",
"years": "años",
"Period": "Período",
"Fixed date": "Fecha fija",
"Indefinitely": "Indefinidamente",
"Days": "Días",
"Weeks": "Semanas",
"Months": "Meses",
"Years": "Años",
"Pick a date": "Selecciona una fecha",
"Maximum is {{max}} {{unit}} for this unit": "El máximo es {{max}} {{unit}} para esta unidad",
"Never expires. Verifiers can re-verify at any time.": "Nunca caduca. Los verificadores pueden volver a verificar en cualquier momento.",
"Verified": "Verificado",
"Review needed": "Revisión necesaria",
"Verification expired": "La verificación ha caducado",
"Draft": "Borrador",
"In Approval": "En aprobación",
"In approval": "En aprobación",
"Approved": "Aprobado",
"Obsolete": "Obsoleto",
"Expiring": "Próximo a caducar",
"Set up verification": "Configurar verificación",
"Verify page": "Verificar página",
"Page verification": "Verificación de página",
"Add verification": "Añadir verificación",
"Edit verification": "Editar verificación",
"Search by title": "Buscar por título",
"Choose how this page should stay accurate.": "Elige cómo debe mantenerse precisa esta página.",
"Recurring verification": "Verificación periódica",
"Verifiers re-confirm this page on a schedule.": "Los verificadores vuelven a confirmar esta página según una programación.",
"Re-verify on a schedule (e.g every 30 days )": "Volver a verificar según una programación (p. ej., cada 30 días)",
"Page stays editable at all times": "La página permanece editable en todo momento",
"Best for runbooks, FAQs, living documentation": "Ideal para runbooks, preguntas frecuentes y documentación viva",
"Approval workflow": "Flujo de aprobación",
"Formal document lifecycle with named approvers.": "Ciclo de vida formal del documento con aprobadores designados.",
"Draft → In approval → Approved → Obsolete": "Borrador → En aprobación → Aprobado → Obsoleto",
"Locked once approved, with full history": "Bloqueado una vez aprobado, con historial completo",
"Designed for ISO 9001, ISO 13485, and FDA": "Diseñado para ISO 9001, ISO 13485 y FDA",
"Best for SOPs and controlled documents": "Ideal para SOP y documentos controlados",
"Back": "Atrás",
"Quality management": "Gestión de calidad",
"Recurring": "Periódica",
"Pages move through draft, approval, and approved stages.": "Las páginas pasan por las etapas de borrador, aprobación y aprobado.",
"Verifiers": "Verificadores",
"Add verifier": "Añadir verificador",
"I've reviewed this page for accuracy": "He revisado la exactitud de esta página",
"Set up": "Configurar",
"Remove verification": "Eliminar verificación",
"Are you sure you want to remove verification from this page?": "¿Seguro que quieres eliminar la verificación de esta página?",
"Assigned verifiers must periodically re-verify this page.": "Los verificadores asignados deben volver a verificar esta página periódicamente.",
"Last verified by {{name}} {{time}} (expired)": "Última verificación por {{name}} {{time}} (caducada)",
"The fixed expiration date has passed.": "La fecha fija de vencimiento ya pasó.",
"Verified by {{name}} {{time}}": "Verificado por {{name}} {{time}}",
"Expires {{date}}": "Caduca el {{date}}",
"Expired {{date}}": "Caducó el {{date}}",
"Mark as obsolete": "Marcar como obsoleto",
"Mark obsolete": "Marcar como obsoleto",
"Returned by {{name}} {{time}}": "Devuelto por {{name}} {{time}}",
"No approval has been requested yet.": "Aún no se ha solicitado aprobación.",
"Submitted by {{name}} {{time}}": "Enviado por {{name}} {{time}}",
"Someone": "Alguien",
"Approved by {{name}} {{time}}": "Aprobado por {{name}} {{time}}",
"This document has been marked as obsolete.": "Este documento ha sido marcado como obsoleto.",
"Rejection comment": "Comentario de rechazo",
"Reason for returning this document...": "Motivo de la devolución de este documento...",
"Confirm rejection": "Confirmar rechazo",
"Submit for approval": "Enviar para aprobación",
"Reject": "Rechazar",
"Approve": "Aprobar",
"Re-submit for approval": "Volver a enviar para aprobación",
"Verified until": "Verificado hasta",
"QMS": "SGC",
"Verified pages": "Páginas verificadas",
"Search pages...": "Buscar páginas...",
"Filter by space": "Filtrar por espacio",
"Filter by type": "Filtrar por tipo",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> verificó una página",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> envió una página para tu aprobación",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> devolvió una página para revisión",
"Page verification expires soon": "La verificación de la página caduca pronto",
"Page verification has expired": "La verificación de la página ha caducado",
"Verifying your email": "Verificando tu correo electrónico",
"Please wait...": "Por favor, espera...",
"Verification failed. The link may have expired.": "La verificación ha fallado. Es posible que el enlace haya expirado.",
"Check your email": "Revisa tu correo electrónico",
"We sent a verification link to {{email}}.": "Te enviamos un enlace de verificación a {{email}}.",
"We sent a verification link to your email.": "Te enviamos un enlace de verificación a tu correo.",
"Click the link to verify your email and access your workspace.": "Haz clic en el enlace para verificar tu correo electrónico y acceder a tu espacio de trabajo.",
"Resend verification email": "Reenviar correo de verificación",
"Verification email sent. Please check your inbox.": "Correo de verificación enviado. Por favor, revisa tu bandeja de entrada.",
"Failed to resend verification email. Please try again.": "No se pudo reenviar el correo de verificación. Por favor, intente de nuevo.",
"We've sent you an email with your associated workspaces.": "Te hemos enviado un correo electrónico con tus espacios de trabajo asociados.",
"Load more": "Cargar más",
"Log out of all devices": "Cerrar sesión en todos los dispositivos",
"Log out of all sessions except this device": "Cerrar sesión en todas las sesiones excepto en este dispositivo",
"This Device": "Este dispositivo",
"Unknown device": "Dispositivo desconocido",
"No active sessions": "No hay sesiones activas",
"Session revoked": "Sesión revocada",
"All other sessions revoked": "Todas las demás sesiones revocadas",
"Last used": "Último uso",
"Created": "Creado",
"Rename": "Renombrar",
"Publish": "Publicar",
"Security": "Seguridad",
"Enforce SSO": "Exigir SSO",
"Once enforced, members will not be able to login with email and password.": "Una vez que se exija, los miembros no podrán iniciar sesión con correo electrónico y contraseña.",
"AI-generated content may not be accurate.": "Es posible que el contenido generado por IA no sea preciso.",
"AI Chat": "Chat de IA",
"Analyze for insights": "Analizar para obtener información",
"Ask anything...": "Pregunta lo que quieras...",
"Chat history": "Historial de chat",
"Chat name": "Nombre del chat",
"Close": "Cerrar",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "No se pudo cargar el chat. Se produjo un error.",
"Failed to render this message.": "No se pudo mostrar este mensaje.",
"How can I help you today?": "¿Cómo puedo ayudarte hoy?",
"New chat": "Nuevo chat",
"No chat history": "No hay historial de chat",
"No chats found": "No se encontraron chats",
"No conversations yet": "Aún no hay conversaciones",
"Open full page": "Abrir página completa",
"Previous 7 days": "Últimos 7 días",
"Previous 30 days": "Últimos 30 días",
"Search chats...": "Buscar chats...",
"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",
"Translate this page": "Traducir esta página",
"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?"
} }
+305 -118
View File
@@ -7,6 +7,7 @@
"Add members": "Ajouter des membres", "Add members": "Ajouter des membres",
"Add to groups": "Ajouter aux groupes", "Add to groups": "Ajouter aux groupes",
"Add space members": "Ajouter des membres à l'espace", "Add space members": "Ajouter des membres à l'espace",
"Add to favorites": "Ajouter aux favoris",
"Admin": "Admin", "Admin": "Admin",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Êtes-vous sûr de vouloir supprimer ce groupe ? Les membres perdront l'accès aux ressources auxquelles ce groupe a accès.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Êtes-vous sûr de vouloir supprimer ce groupe ? Les membres perdront l'accès aux ressources auxquelles ce groupe a accès.",
"Are you sure you want to delete this page?": "Êtes-vous sûr de vouloir supprimer cette page ?", "Are you sure you want to delete this page?": "Êtes-vous sûr de vouloir supprimer cette page ?",
@@ -44,24 +45,24 @@
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Êtes-vous sûr de vouloir supprimer cette page ? Cela supprimera ses enfants et l'historique de la page. Cette action est irréversible.", "Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Êtes-vous sûr de vouloir supprimer cette page ? Cela supprimera ses enfants et l'historique de la page. Cette action est irréversible.",
"Description": "Description", "Description": "Description",
"Details": "Détails", "Details": "Détails",
"e.g ACME": "par ex. ACME", "e.g ACME": "p. ex. ACME",
"e.g ACME Inc": "par ex. ACME Inc", "e.g ACME Inc": "p. ex. ACME Inc",
"e.g Developers": "par ex. Développeurs", "e.g Developers": "p. ex. Développeurs",
"e.g Group for developers": "par ex. Groupe pour développeurs", "e.g Group for developers": "p. ex. Groupe pour les développeurs",
"e.g product": "par ex. produit", "e.g product": "p. ex. produit",
"e.g Product Team": "par ex. Équipe Produit", "e.g Product Team": "p. ex. Équipe produit",
"e.g Sales": "par ex. Ventes", "e.g Sales": "p. ex. Ventes",
"e.g Space for product team": "par ex. Espace pour l'équipe produit", "e.g Space for product team": "p. ex. Espace pour léquipe produit",
"e.g Space for sales team to collaborate": "par ex. Espace pour l'équipe de vente pour collaborer", "e.g Space for sales team to collaborate": "p. ex. Espace pour que léquipe commerciale collabore",
"Edit": "Modifier", "Edit": "Modifier",
"Read": "Lire", "Read": "Lire",
"Edit group": "Modifier groupe", "Edit group": "Modifier groupe",
"Email": "Email", "Email": "Email",
"Enter a strong password": "Entrez un mot de passe fort", "Enter a strong password": "Entrez un mot de passe fort",
"Enter valid email addresses separated by comma or space max_50": "Entrez des adresses email valides séparées par une virgule ou un espace [max : 50]", "Enter valid email addresses separated by comma or space max_50": "Entrez des adresses email valides séparées par une virgule ou un espace [max : 50]",
"enter valid emails addresses": "entrez des adresses email valides", "enter valid emails addresses": "saisissez des adresses e-mail valides",
"Enter your current password": "Entrez votre mot de passe actuel", "Enter your current password": "Entrez votre mot de passe actuel",
"enter your full name": "entrez votre nom complet", "enter your full name": "saisissez votre nom complet",
"Enter your new password": "Entrez votre nouveau mot de passe", "Enter your new password": "Entrez votre nouveau mot de passe",
"Enter your new preferred email": "Entrez votre nouvel email préféré", "Enter your new preferred email": "Entrez votre nouvel email préféré",
"Enter your password": "Entrez votre mot de passe", "Enter your password": "Entrez votre mot de passe",
@@ -74,6 +75,9 @@
"Failed to import pages": "Échec de l'importation des pages", "Failed to import pages": "Échec de l'importation des pages",
"Failed to load page. An error occurred.": "Échec du chargement de la page. Une erreur s'est produite.", "Failed to load page. An error occurred.": "Échec du chargement de la page. Une erreur s'est produite.",
"Failed to update data": "Échec de la mise à jour des données", "Failed to update data": "Échec de la mise à jour des données",
"Favorite spaces": "Espaces favoris",
"Favorite spaces appear here": "Les espaces favoris apparaissent ici",
"Favorites": "Favoris",
"Full access": "Accès complet", "Full access": "Accès complet",
"Full page width": "Largeur de page complète", "Full page width": "Largeur de page complète",
"Full width": "Largeur complète", "Full width": "Largeur complète",
@@ -87,11 +91,12 @@
"Import pages": "Importer des pages", "Import pages": "Importer des pages",
"Import pages & space settings": "Importer des pages et paramètres de l'espace", "Import pages & space settings": "Importer des pages et paramètres de l'espace",
"Importing pages": "Importation des pages", "Importing pages": "Importation des pages",
"invalid invitation link": "lien d'invitation invalide", "invalid invitation link": "lien dinvitation invalide",
"Invitation signup": "Inscription par invitation", "Invitation signup": "Inscription par invitation",
"Invite by email": "Inviter par email", "Invite by email": "Inviter par email",
"Invite members": "Inviter des membres", "Invite members": "Inviter des membres",
"Invite new members": "Inviter de nouveaux membres", "Invite new members": "Inviter de nouveaux membres",
"Invite People": "Inviter des personnes",
"Invited members who are yet to accept their invitation will appear here.": "Les membres invités qui n'ont pas encore accepté leur invitation apparaîtront ici.", "Invited members who are yet to accept their invitation will appear here.": "Les membres invités qui n'ont pas encore accepté leur invitation apparaîtront ici.",
"Invited members will be granted access to spaces the groups can access": "Les membres invités auront accès aux espaces auxquels les groupes peuvent accéder", "Invited members will be granted access to spaces the groups can access": "Les membres invités auront accès aux espaces auxquels les groupes peuvent accéder",
"Join the workspace": "Rejoindre l'espace de travail", "Join the workspace": "Rejoindre l'espace de travail",
@@ -139,6 +144,7 @@
"Profile": "Profil", "Profile": "Profil",
"Recently updated": "Récemment mis à jour", "Recently updated": "Récemment mis à jour",
"Remove": "Retirer", "Remove": "Retirer",
"Remove from favorites": "Retirer des favoris",
"Remove group member": "Retirer un membre du groupe", "Remove group member": "Retirer un membre du groupe",
"Remove space member": "Retirer un membre de l'espace", "Remove space member": "Retirer un membre de l'espace",
"Restore": "Restaurer", "Restore": "Restaurer",
@@ -151,53 +157,54 @@
"Search...": "Rechercher...", "Search...": "Rechercher...",
"Select language": "Sélectionner la langue", "Select language": "Sélectionner la langue",
"Select role": "Sélectionner un rôle", "Select role": "Sélectionner un rôle",
"Select role to assign to all invited members": "Sélectionner le rôle à attribuer à tous les membres invités", "Select role to assign to all invited members": "Sélectionnez le rôle à attribuer à tous les membres invités",
"Select theme": "Sélectionner le thème", "Select theme": "Sélectionner le thème",
"Send invitation": "Envoyer l'invitation", "Send invitation": "Envoyer linvitation",
"Invitation sent": "Invitation envoyée", "Invitation sent": "Invitation envoyée",
"Settings": "Paramètres", "Settings": "Paramètres",
"Setup workspace": "Configurer l'espace de travail", "Setup workspace": "Configurer lespace de travail",
"Sign In": "Se connecter", "Sign In": "Se connecter",
"Sign Up": "S'inscrire", "Sign Up": "Sinscrire",
"Slug": "Slug", "Slug": "Slug",
"Space": "Espace", "Space": "Espace",
"Space description": "Description de l'espace", "Space description": "Description de lespace",
"Space menu": "Menu de l'espace", "Space menu": "Menu de lespace",
"Space name": "Nom de l'espace", "Space name": "Nom de lespace",
"Space settings": "Paramètres de l'espace", "Space settings": "Paramètres de lespace",
"Space slug": "Slug de l'espace", "Space slug": "Slug de lespace",
"Spaces": "Espaces", "Spaces": "Espaces",
"Spaces you belong to": "Espaces auxquels vous appartenez", "Spaces you belong to": "Espaces auxquels vous appartenez",
"No space found": "Aucun espace trouvé", "No space found": "Aucun espace trouvé",
"Search for spaces": "Rechercher des espaces", "Search for spaces": "Rechercher des espaces",
"Start typing to search...": "Commencez à taper pour rechercher...", "Start typing to search...": "Commencez à taper pour rechercher...",
"Status": "Statut", "Status": "Statut",
"Successfully imported": "Importé avec succès", "Successfully imported": "Importation réussie",
"Successfully restored": "Restauré avec succès", "Successfully restored": "Restauration réussie",
"System settings": "Paramètres système", "System settings": "Paramètres système",
"Templates": "Modèles",
"Theme": "Thème", "Theme": "Thème",
"To change your email, you have to enter your password and new email.": "Pour changer votre email, vous devez entrer votre mot de passe et votre nouvel email.", "To change your email, you have to enter your password and new email.": "Pour changer votre email, vous devez entrer votre mot de passe et votre nouvel email.",
"Toggle full page width": "Basculer sur la largeur complète de la page", "Toggle full page width": "Basculer la largeur complète de la page",
"Unable to import pages. Please try again.": "Impossible d'importer les pages. Veuillez réessayer.", "Unable to import pages. Please try again.": "Impossible d'importer les pages. Veuillez réessayer.",
"untitled": "sans titre", "untitled": "sans titre",
"Untitled": "Sans titre", "Untitled": "Sans titre",
"Updated successfully": "Mis à jour avec succès", "Updated successfully": "Mise à jour réussie",
"User": "Utilisateur", "User": "Utilisateur",
"Workspace": "Espace de travail", "Workspace": "Espace de travail",
"Workspace Name": "Nom de l'espace de travail", "Workspace Name": "Nom de lespace de travail",
"Workspace settings": "Paramètres de l'espace de travail", "Workspace settings": "Paramètres de lespace de travail",
"You can change your password here.": "Vous pouvez changer votre mot de passe ici.", "You can change your password here.": "Vous pouvez changer votre mot de passe ici.",
"Your Email": "Votre Email", "Your Email": "Votre e-mail",
"Your import is complete.": "Votre importation est terminée.", "Your import is complete.": "Votre importation est terminée.",
"Your name": "Votre nom", "Your name": "Votre nom",
"Your Name": "Votre Nom", "Your Name": "Votre nom",
"Your password": "Votre mot de passe", "Your password": "Votre mot de passe",
"Your password must be a minimum of 8 characters.": "Votre mot de passe doit contenir au moins 8 caractères.", "Your password must be a minimum of 8 characters.": "Votre mot de passe doit contenir au moins 8 caractères.",
"Sidebar toggle": "Bascule de la barre latérale", "Sidebar toggle": "Basculer la barre latérale",
"Comments": "Commentaires", "Comments": "Commentaires",
"404 page not found": "404 page non trouvée", "404 page not found": "404 page non trouvée",
"Sorry, we can't find the page you are looking for.": "Désolé, nous ne pouvons pas trouver la page que vous cherchez.", "Sorry, we can't find the page you are looking for.": "Désolé, nous ne pouvons pas trouver la page que vous cherchez.",
"Take me back to homepage": "Ramenez-moi à la page d'accueil", "Take me back to homepage": "Retour à la page daccueil",
"Forgot password": "Mot de passe oublié", "Forgot password": "Mot de passe oublié",
"Forgot your password?": "Mot de passe oublié?", "Forgot your password?": "Mot de passe oublié?",
"A password reset link has been sent to your email. Please check your inbox.": "Un lien de réinitialisation de mot de passe a été envoyé à votre e-mail. Veuillez vérifier votre boîte de réception.", "A password reset link has been sent to your email. Please check your inbox.": "Un lien de réinitialisation de mot de passe a été envoyé à votre e-mail. Veuillez vérifier votre boîte de réception.",
@@ -215,6 +222,8 @@
"Edit comment": "Modifier le commentaire", "Edit comment": "Modifier le commentaire",
"Delete comment": "Supprimer le commentaire", "Delete comment": "Supprimer le commentaire",
"Are you sure you want to delete this comment?": "Êtes-vous sûr de vouloir supprimer ce commentaire ?", "Are you sure you want to delete this comment?": "Êtes-vous sûr de vouloir supprimer ce commentaire ?",
"Delete chat": "Supprimer la conversation",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Êtes-vous sûr de vouloir supprimer '{{title}}' ? Cette action est irréversible.",
"Comment created successfully": "Commentaire créé avec succès", "Comment created successfully": "Commentaire créé avec succès",
"Error creating comment": "Erreur lors de la création du commentaire", "Error creating comment": "Erreur lors de la création du commentaire",
"Comment updated successfully": "Commentaire mis à jour avec succès", "Comment updated successfully": "Commentaire mis à jour avec succès",
@@ -223,12 +232,12 @@
"Failed to delete comment": "Échec de la suppression du commentaire", "Failed to delete comment": "Échec de la suppression du commentaire",
"Comment resolved successfully": "Commentaire résolu avec succès", "Comment resolved successfully": "Commentaire résolu avec succès",
"Comment re-opened successfully": "Commentaire rouvert avec succès", "Comment re-opened successfully": "Commentaire rouvert avec succès",
"Comment unresolved successfully": "Commentaire non résolu avec succès", "Comment unresolved successfully": "Commentaire marqué comme non résolu avec succès",
"Failed to resolve comment": "Échec de la résolution du commentaire", "Failed to resolve comment": "Échec de la résolution du commentaire",
"Resolve comment": "Résoudre le commentaire", "Resolve comment": "Résoudre le commentaire",
"Unresolve comment": "Désorganiser le commentaire", "Unresolve comment": "Marquer le commentaire comme non résolu",
"Resolve Comment Thread": "Résoudre le fil de commentaires", "Resolve Comment Thread": "Résoudre le fil de commentaires",
"Unresolve Comment Thread": "Désorganiser le fil de commentaires", "Unresolve Comment Thread": "Marquer le fil de commentaires comme non résolu",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Êtes-vous sûr de vouloir résoudre ce fil de commentaires ? Cela le marquera comme terminé.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Êtes-vous sûr de vouloir résoudre ce fil de commentaires ? Cela le marquera comme terminé.",
"Are you sure you want to unresolve this comment thread?": "Êtes-vous sûr de vouloir désorganiser ce fil de commentaires ?", "Are you sure you want to unresolve this comment thread?": "Êtes-vous sûr de vouloir désorganiser ce fil de commentaires ?",
"Resolved": "Résolu", "Resolved": "Résolu",
@@ -241,7 +250,7 @@
"Anyone with this link can join this workspace.": "Toute personne ayant ce lien peut rejoindre cet espace de travail.", "Anyone with this link can join this workspace.": "Toute personne ayant ce lien peut rejoindre cet espace de travail.",
"Invite link": "Lien d'invitation", "Invite link": "Lien d'invitation",
"Copy": "Copier", "Copy": "Copier",
"Copy to space": "Copier dans l'espace", "Copy to space": "Copier vers lespace",
"Copied": "Copié", "Copied": "Copié",
"Duplicate": "Dupliquer", "Duplicate": "Dupliquer",
"Select a user": "Sélectionner un utilisateur", "Select a user": "Sélectionner un utilisateur",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "Êtes-vous sûr de vouloir supprimer cet espace ?", "Are you sure you want to delete this space?": "Êtes-vous sûr de vouloir supprimer cet espace ?",
"Delete this space with all its pages and data.": "Supprimer cet espace avec toutes ses pages et données.", "Delete this space with all its pages and data.": "Supprimer cet espace avec toutes ses pages et données.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Toutes les pages, commentaires, pièces jointes et autorisations dans cet espace seront supprimés irréversiblement.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Toutes les pages, commentaires, pièces jointes et autorisations dans cet espace seront supprimés irréversiblement.",
"Confirm space name": "Confirmer le nom de l'espace", "Confirm space name": "Confirmer le nom de lespace",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Tapez le nom de l'espace <b>{{spaceName}}</b> pour confirmer votre action.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "Tapez le nom de l'espace <b>{{spaceName}}</b> pour confirmer votre action.",
"Format": "Format", "Format": "Format",
"Include subpages": "Inclure les sous-pages", "Include subpages": "Inclure les sous-pages",
@@ -289,6 +298,11 @@
"Save & Exit": "Enregistrer & Quitter", "Save & Exit": "Enregistrer & Quitter",
"Double-click to edit Excalidraw diagram": "Double-cliquez pour modifier le diagramme Excalidraw", "Double-click to edit Excalidraw diagram": "Double-cliquez pour modifier le diagramme Excalidraw",
"Paste link": "Coller le lien", "Paste link": "Coller le lien",
"Paste link or search pages": "Coller le lien ou rechercher des pages",
"Link to web page": "Lien vers une page web",
"Recents": "Récents",
"Page or URL": "Page ou URL",
"Link title": "Titre du lien",
"Edit link": "Modifier le lien", "Edit link": "Modifier le lien",
"Remove link": "Supprimer le lien", "Remove link": "Supprimer le lien",
"Add link": "Ajouter un lien", "Add link": "Ajouter un lien",
@@ -307,7 +321,7 @@
"Pink": "Rose", "Pink": "Rose",
"Gray": "Gris", "Gray": "Gris",
"Embed link": "Intégrer un lien", "Embed link": "Intégrer un lien",
"Invalid {{provider}} embed link": "Lien d'intégration {{provider}} non valide", "Invalid {{provider}} embed link": "Lien dintégration {{provider}} invalide",
"Embed {{provider}}": "Intégrer {{provider}}", "Embed {{provider}}": "Intégrer {{provider}}",
"Enter {{provider}} link to embed": "Entrez le lien {{provider}} à intégrer", "Enter {{provider}} link to embed": "Entrez le lien {{provider}} à intégrer",
"Bold": "Gras", "Bold": "Gras",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Insérer un séparateur de règle horizontale", "Insert horizontal rule divider": "Insérer un séparateur de règle horizontale",
"Upload any image from your device.": "Téléchargez n'importe quelle image depuis votre appareil.", "Upload any image from your device.": "Téléchargez n'importe quelle image depuis votre appareil.",
"Upload any video from your device.": "Téléchargez n'importe quelle vidéo depuis votre appareil.", "Upload any video from your device.": "Téléchargez n'importe quelle vidéo depuis votre appareil.",
"Upload any audio from your device.": "Téléchargez n'importe quel fichier audio depuis votre appareil.",
"Upload any file from your device.": "Téléchargez n'importe quel fichier depuis votre appareil.", "Upload any file from your device.": "Téléchargez n'importe quel fichier depuis votre appareil.",
"Uploading {{name}}": "Téléchargement de {{name}}", "Uploading {{name}}": "Téléchargement de {{name}}",
"Uploading file": "Téléchargement du fichier", "Uploading file": "Téléchargement du fichier",
@@ -343,16 +358,22 @@
"Insert a table.": "Insérez un tableau.", "Insert a table.": "Insérez un tableau.",
"Insert collapsible block.": "Insérer un bloc repliable.", "Insert collapsible block.": "Insérer un bloc repliable.",
"Video": "Vidéo", "Video": "Vidéo",
"Divider": "Diviseur", "Divider": "Séparateur",
"Quote": "Citation", "Quote": "Citation",
"Image": "Image", "Image": "Image",
"File attachment": "Pièce jointe", "Audio": "Audio",
"Toggle block": "Basculer le bloc", "Embed PDF": "Intégrer un PDF",
"Callout": "Appel", "Upload and embed a PDF file.": "Téléchargez et intégrez un fichier PDF.",
"Embed as PDF": "Intégrer comme PDF",
"Failed to load PDF": "Échec du chargement du PDF",
"Convert to attachment": "Convertir en pièce jointe",
"File attachment": "Fichier joint",
"Toggle block": "Bloc basculable",
"Callout": "Encadré",
"Insert callout notice.": "Insérer un avis d'appel.", "Insert callout notice.": "Insérer un avis d'appel.",
"Math inline": "Mathématiques en ligne", "Math inline": "Maths en ligne",
"Insert inline math equation.": "Insérez une équation mathématique en ligne.", "Insert inline math equation.": "Insérez une équation mathématique en ligne.",
"Math block": "Bloc mathématiques", "Math block": "Bloc mathématique",
"Insert math equation": "Insérer une équation mathématique", "Insert math equation": "Insérer une équation mathématique",
"Mermaid diagram": "Diagramme Mermaid", "Mermaid diagram": "Diagramme Mermaid",
"Insert mermaid diagram": "Insérer un diagramme Mermaid", "Insert mermaid diagram": "Insérer un diagramme Mermaid",
@@ -366,8 +387,8 @@
"Go to homepage": "Aller à l'accueil", "Go to homepage": "Aller à l'accueil",
"Pages you create will show up here.": "Les pages que vous créez apparaîtront ici.", "Pages you create will show up here.": "Les pages que vous créez apparaîtront ici.",
"Heading {{level}}": "Titre {{level}}", "Heading {{level}}": "Titre {{level}}",
"Toggle title": "Basculer le titre", "Toggle title": "Titre du bloc basculable",
"Write anything. Enter \"/\" for commands": "Écrivez n'importe quoi. Entrez \"/\" pour les commandes", "Write anything. Enter \"/\" for commands": "Écrivez nimporte quoi. Saisissez \"/\" pour les commandes",
"Write...": "Écrire...", "Write...": "Écrire...",
"Column count": "Nombre de colonnes", "Column count": "Nombre de colonnes",
"{{count}} Columns": "{count, plural, one {# colonne} other {# colonnes}}", "{{count}} Columns": "{count, plural, one {# colonne} other {# colonnes}}",
@@ -378,7 +399,7 @@
"Left wide": "Large à gauche", "Left wide": "Large à gauche",
"Right wide": "Large à droite", "Right wide": "Large à droite",
"Names do not match": "Les noms ne correspondent pas", "Names do not match": "Les noms ne correspondent pas",
"Today, {{time}}": "Aujourd'hui, {{time}}", "Today, {{time}}": "Aujourdhui, {{time}}",
"Yesterday, {{time}}": "Hier, {{time}}", "Yesterday, {{time}}": "Hier, {{time}}",
"Space created successfully": "Espace créé avec succès", "Space created successfully": "Espace créé avec succès",
"Space updated successfully": "Espace mis à jour avec succès", "Space updated successfully": "Espace mis à jour avec succès",
@@ -387,13 +408,13 @@
"Member removed successfully": "Membre supprimé avec succès", "Member removed successfully": "Membre supprimé avec succès",
"Member role updated successfully": "Rôle du membre mis à jour avec succès", "Member role updated successfully": "Rôle du membre mis à jour avec succès",
"Created by: <b>{{creatorName}}</b>": "Créé par : <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "Créé par : <b>{{creatorName}}</b>",
"Created at: {{time}}": "Créé à : {{time}}", "Created at: {{time}}": "Créé le : {{time}}",
"Edited by {{name}} {{time}}": "Modifié par {{name}} {{time}}", "Edited by {{name}} {{time}}": "Modifié par {{name}} {{time}}",
"Word count: {{wordCount}}": "Nombre de mots : {{wordCount}}", "Word count: {{wordCount}}": "Nombre de mots : {{wordCount}}",
"Character count: {{characterCount}}": "Nombre de caractères : {{characterCount}}", "Character count: {{characterCount}}": "Nombre de caractères : {{characterCount}}",
"New update": "Nouvelle mise à jour", "New update": "Nouvelle mise à jour",
"{{latestVersion}} is available": "{{latestVersion}} est disponible", "{{latestVersion}} is available": "{{latestVersion}} est disponible",
"Default page edit mode": "Mode d'édition de page par défaut", "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 your preferred page edit mode. Avoid accidental edits.": "Choisissez votre mode d'édition de page préféré. Évitez les modifications accidentelles.",
"Reading": "Lecture", "Reading": "Lecture",
"Delete member": "Supprimer le membre", "Delete member": "Supprimer le membre",
@@ -410,19 +431,19 @@
"Move page": "Déplacer la page", "Move page": "Déplacer la page",
"Move page to a different space.": "Déplacer la page vers un autre espace.", "Move page to a different space.": "Déplacer la page vers un autre espace.",
"Real-time editor connection lost. Retrying...": "Connexion avec l'éditeur en temps réel perdue. Nouvelle tentative...", "Real-time editor connection lost. Retrying...": "Connexion avec l'éditeur en temps réel perdue. Nouvelle tentative...",
"Table of contents": "", "Table of contents": "Table des matières",
"Add headings (H1, H2, H3) to generate a table of contents.": "Ajoutez des titres (H1, H2, H3) pour générer une table des matières.", "Add headings (H1, H2, H3) to generate a table of contents.": "Ajoutez des titres (H1, H2, H3) pour générer une table des matières.",
"Share": "Partager", "Share": "Partager",
"Public sharing": "Partage public", "Public sharing": "Partage public",
"Shared by": "Partagé par", "Shared by": "Partagé par",
"Shared at": "Partagé à", "Shared at": "Partagé le",
"Inherits public sharing from": "Hérite du partage public de", "Inherits public sharing from": "Hérite du partage public de",
"Share to web": "Partager sur le web", "Share to web": "Partager sur le web",
"Shared to web": "Partagé sur le web", "Shared to web": "Partagé sur le web",
"Anyone with the link can view this page": "Toute personne avec le lien peut voir cette page", "Anyone with the link can view this page": "Toute personne disposant du lien peut voir cette page",
"Make this page publicly accessible": "Rendre cette page accessible au public", "Make this page publicly accessible": "Rendre cette page accessible publiquement",
"Include sub-pages": "Inclure les sous-pages", "Include sub-pages": "Inclure les sous-pages",
"Make sub-pages public too": "Rendre également les sous-pages publiques", "Make sub-pages public too": "Rendre aussi les sous-pages publiques",
"Allow search engines to index page": "Autoriser les moteurs de recherche à indexer la page", "Allow search engines to index page": "Autoriser les moteurs de recherche à indexer la page",
"Open page": "Ouvrir la page", "Open page": "Ouvrir la page",
"Page": "Page", "Page": "Page",
@@ -431,15 +452,17 @@
"Are you sure you want to delete this shared link?": "Êtes-vous sûr de vouloir supprimer ce lien partagé ?", "Are you sure you want to delete this shared link?": "Êtes-vous sûr de vouloir supprimer ce lien partagé ?",
"Publicly shared pages from spaces you are a member of will appear here": "Les pages partagées publiquement des espaces dont vous êtes membre apparaîtront ici", "Publicly shared pages from spaces you are a member of will appear here": "Les pages partagées publiquement des espaces dont vous êtes membre apparaîtront ici",
"Share deleted successfully": "Partage supprimé avec succès", "Share deleted successfully": "Partage supprimé avec succès",
"Share not found": "Partage non trouvé", "Share not found": "Partage introuvable",
"Failed to share page": "Échec du partage de la page", "Failed to share page": "Échec du partage de la page",
"Disable public sharing": "Désactiver le partage public", "Disable public sharing": "Désactiver le partage public",
"Prevent members from sharing pages publicly.": "Empêcher les membres de partager des pages publiquement.", "Prevent members from sharing pages publicly.": "Empêcher les membres de partager des pages publiquement.",
"Toggle public sharing": "Basculer le partage public", "Toggle public sharing": "Basculer le partage public",
"Toggle space public sharing": "Basculer le partage public de l'espace", "Toggle space public sharing": "Basculer le partage public de l'espace",
"Allow viewers to comment": "Autoriser les spectateurs à commenter",
"Allow viewers to add comments on pages in this space.": "Autoriser les spectateurs à ajouter des commentaires sur les pages de cet espace.",
"Toggle viewer comments": "Basculer les commentaires des spectateurs",
"Public sharing is disabled at the workspace level": "Le partage public est désactivé au niveau de l'espace de travail", "Public sharing is disabled at the workspace level": "Le partage public est désactivé au niveau de l'espace de travail",
"Prevent pages in this space from being shared publicly.": "Empêcher les pages de cet espace d'être partagées publiquement.", "Prevent pages in this space from being shared publicly.": "Empêcher les pages de cet espace d'être partagées publiquement.",
"Requires an enterprise license": "Nécessite une licence d'entreprise",
"Page permissions": "Autorisations de la page", "Page permissions": "Autorisations de la page",
"Control who can view and edit individual pages. Available with an enterprise license.": "Contrôlez qui peut consulter et modifier chaque page. Disponible avec une licence Entreprise.", "Control who can view and edit individual pages. Available with an enterprise license.": "Contrôlez qui peut consulter et modifier chaque page. Disponible avec une licence Entreprise.",
"Enable public sharing": "Activer le partage public", "Enable public sharing": "Activer le partage public",
@@ -454,81 +477,82 @@
"Copy page to a different space.": "Copier la page dans un autre espace.", "Copy page to a different space.": "Copier la page dans un autre espace.",
"Page copied successfully": "Page copiée avec succès", "Page copied successfully": "Page copiée avec succès",
"Page duplicated successfully": "Page dupliquée avec succès", "Page duplicated successfully": "Page dupliquée avec succès",
"Find": "Trouver", "Find": "Rechercher",
"Not found": "Non trouvé", "Not found": "Introuvable",
"Previous Match (Shift+Enter)": "Correspondance précédente (Shift+Entrée)", "Previous Match (Shift+Enter)": "Occurrence précédente (Maj+Entrée)",
"Next match (Enter)": "Correspondance suivante (Entrée)", "Next match (Enter)": "Occurrence suivante (Entrée)",
"Match case (Alt+C)": "Respecter la casse (Alt+C)", "Match case (Alt+C)": "Respecter la casse (Alt+C)",
"Replace": "Remplacer", "Replace": "Remplacer",
"Close (Escape)": "Fermer (Échapper)", "Close (Escape)": "Fermer (Échap)",
"Replace (Enter)": "Remplacer (Entrée)", "Replace (Enter)": "Remplacer (Entrée)",
"Replace all (Ctrl+Alt+Enter)": "Tout remplacer (Ctrl+Alt+Entrée)", "Replace all (Ctrl+Alt+Enter)": "Remplacer tout (Ctrl+Alt+Entrée)",
"Replace all": "Tout remplacer", "Replace all": "Remplacer tout",
"View all": "Voir tout",
"View all spaces": "Voir tous les espaces", "View all spaces": "Voir tous les espaces",
"Error": "Erreur", "Error": "Erreur",
"Failed to disable MFA": "Impossible de désactiver l'A2F", "Failed to disable MFA": "Échec de la désactivation de lauthentification multifacteur",
"Disable two-factor authentication": "Désactiver l'authentification à deux facteurs", "Disable two-factor authentication": "Désactiver lauthentification à deux facteurs",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "La désactivation de l'authentification à deux facteurs rendra votre compte moins sécurisé. Vous n'aurez besoin que de votre mot de passe pour vous connecter.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "La désactivation de l'authentification à deux facteurs rendra votre compte moins sécurisé. Vous n'aurez besoin que de votre mot de passe pour vous connecter.",
"Please enter your password to disable two-factor authentication:": "Veuillez entrer votre mot de passe pour désactiver l'authentification à deux facteurs :", "Please enter your password to disable two-factor authentication:": "Veuillez entrer votre mot de passe pour désactiver l'authentification à deux facteurs :",
"Two-factor authentication has been enabled": "L'authentification à deux facteurs a été activée", "Two-factor authentication has been enabled": "Lauthentification à deux facteurs a été activée",
"Two-factor authentication has been disabled": "L'authentification à deux facteurs a été désactivée", "Two-factor authentication has been disabled": "Lauthentification à deux facteurs a été désactivée",
"2-step verification": "Vérification en 2 étapes", "2-step verification": "Vérification en 2 étapes",
"Protect your account with an additional verification layer when signing in.": "Protégez votre compte avec une couche de vérification supplémentaire lors de la connexion.", "Protect your account with an additional verification layer when signing in.": "Protégez votre compte avec une couche de vérification supplémentaire lors de la connexion.",
"Two-factor authentication is active on your account.": "L'authentification à deux facteurs est active sur votre compte.", "Two-factor authentication is active on your account.": "L'authentification à deux facteurs est active sur votre compte.",
"Add 2FA method": "Ajouter une méthode A2F", "Add 2FA method": "Ajouter une méthode dA2F",
"Backup codes": "Codes de sauvegarde", "Backup codes": "Codes de secours",
"Disable": "Désactiver", "Disable": "Désactiver",
"Invalid verification code": "Code de vérification invalide", "Invalid verification code": "Code de vérification invalide",
"New backup codes have been generated": "De nouveaux codes de sauvegarde ont été générés", "New backup codes have been generated": "De nouveaux codes de secours ont été générés",
"Failed to regenerate backup codes": "Échec de la régénération des codes de sauvegarde", "Failed to regenerate backup codes": "Échec de la régénération des codes de secours",
"About backup codes": "À propos des codes de sauvegarde", "About backup codes": "À propos des codes de secours",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Les codes de sauvegarde peuvent être utilisés pour accéder à votre compte si vous perdez l'accès à votre application d'authentification. Chaque code ne peut être utilisé qu'une seule fois.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Les codes de sauvegarde peuvent être utilisés pour accéder à votre compte si vous perdez l'accès à votre application d'authentification. Chaque code ne peut être utilisé qu'une seule fois.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Vous pouvez régénérer de nouveaux codes de sauvegarde à tout moment. Cela invalidera tous les codes existants.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Vous pouvez régénérer de nouveaux codes de sauvegarde à tout moment. Cela invalidera tous les codes existants.",
"Confirm password": "Confirmer le mot de passe", "Confirm password": "Confirmer le mot de passe",
"Generate new backup codes": "Générer de nouveaux codes de sauvegarde", "Generate new backup codes": "Générer de nouveaux codes de secours",
"Save your new backup codes": "Enregistrez vos nouveaux codes de sauvegarde", "Save your new backup codes": "Enregistrez vos nouveaux codes de secours",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Assurez-vous d'enregistrer ces codes dans un endroit sécurisé. Vos anciens codes de sauvegarde ne sont plus valides.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Assurez-vous d'enregistrer ces codes dans un endroit sécurisé. Vos anciens codes de sauvegarde ne sont plus valides.",
"Your new backup codes": "Vos nouveaux codes de sauvegarde", "Your new backup codes": "Vos nouveaux codes de secours",
"I've saved my backup codes": "J'ai enregistré mes codes de sauvegarde", "I've saved my backup codes": "Jai enregistré mes codes de secours",
"Failed to setup MFA": "Échec de la configuration de l'A2F", "Failed to setup MFA": "Échec de la configuration de lauthentification multifacteur",
"Setup & Verify": "Configurer et vérifier", "Setup & Verify": "Configurer et vérifier",
"Add to authenticator": "Ajouter à l'authentification", "Add to authenticator": "Ajouter à lapplication dauthentification",
"1. Scan this QR code with your authenticator app": "1. Scannez ce code QR avec votre application d'authentification", "1. Scan this QR code with your authenticator app": "1. Scannez ce code QR avec votre application dauthentification",
"Can't scan the code?": "Impossible de scanner le code ?", "Can't scan the code?": "Impossible de scanner le code ?",
"Enter this code manually in your authenticator app:": "Entrez ce code manuellement dans votre application d'authentification :", "Enter this code manually in your authenticator app:": "Entrez ce code manuellement dans votre application d'authentification :",
"2. Enter the 6-digit code from your authenticator": "2. Entrez le code à 6 chiffres de votre authentificateur", "2. Enter the 6-digit code from your authenticator": "2. Saisissez le code à 6 chiffres de votre application dauthentification",
"Verify and enable": "Vérifier et activer", "Verify and enable": "Vérifier et activer",
"Failed to generate QR code. Please try again.": "Échec de la génération du code QR. Veuillez réessayer.", "Failed to generate QR code. Please try again.": "Échec de la génération du code QR. Veuillez réessayer.",
"Backup": "Sauvegarde", "Backup": "Secours",
"Save codes": "Enregistrer les codes", "Save codes": "Enregistrer les codes",
"Save your backup codes": "Enregistrez vos codes de sauvegarde", "Save your backup codes": "Enregistrez vos codes de secours",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Ces codes peuvent être utilisés pour accéder à votre compte si vous perdez l'accès à votre application d'authentification. Chaque code ne peut être utilisé qu'une seule fois.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Ces codes peuvent être utilisés pour accéder à votre compte si vous perdez l'accès à votre application d'authentification. Chaque code ne peut être utilisé qu'une seule fois.",
"Print": "Imprimer", "Print": "Imprimer",
"Two-factor authentication has been set up. Please log in again.": "L'authentification à deux facteurs a été configurée. Veuillez vous reconnecter.", "Two-factor authentication has been set up. Please log in again.": "L'authentification à deux facteurs a été configurée. Veuillez vous reconnecter.",
"Two-Factor authentication required": "Authentification à deux facteurs requise", "Two-Factor authentication required": "Authentification à deux facteurs requise",
"Your workspace requires two-factor authentication for all users": "Votre espace de travail nécessite l'authentification à deux facteurs pour tous les utilisateurs", "Your workspace requires two-factor authentication for all users": "Votre espace de travail exige lauthentification à deux facteurs pour tous les utilisateurs",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Pour continuer à accéder à votre espace de travail, vous devez configurer l'authentification à deux facteurs. Cela ajoute une couche de sécurité supplémentaire à votre compte.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Pour continuer à accéder à votre espace de travail, vous devez configurer l'authentification à deux facteurs. Cela ajoute une couche de sécurité supplémentaire à votre compte.",
"Set up two-factor authentication": "Configurer l'authentification à deux facteurs", "Set up two-factor authentication": "Configurer lauthentification à deux facteurs",
"Cancel and logout": "Annuler et se déconnecter", "Cancel and logout": "Annuler et se déconnecter",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Votre espace de travail nécessite l'authentification à deux facteurs. Veuillez le configurer pour continuer.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Votre espace de travail nécessite l'authentification à deux facteurs. Veuillez le configurer pour continuer.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Cela ajoute une couche de sécurité supplémentaire à votre compte en exigeant un code de vérification provenant de votre application d'authentification.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Cela ajoute une couche de sécurité supplémentaire à votre compte en exigeant un code de vérification provenant de votre application d'authentification.",
"Password is required": "Mot de passe requis", "Password is required": "Le mot de passe est requis",
"Password must be at least 8 characters": "Le mot de passe doit comporter au moins 8 caractères", "Password must be at least 8 characters": "Le mot de passe doit comporter au moins 8 caractères",
"Please enter a 6-digit code": "Veuillez entrer un code à 6 chiffres", "Please enter a 6-digit code": "Veuillez saisir un code à 6 chiffres",
"Code must be exactly 6 digits": "Le code doit être exactement de 6 chiffres", "Code must be exactly 6 digits": "Le code doit comporter exactement 6 chiffres",
"Enter the 6-digit code found in your authenticator app": "Entrez le code à 6 chiffres trouvé dans votre application d'authentification", "Enter the 6-digit code found in your authenticator app": "Saisissez le code à 6 chiffres indiqué dans votre application dauthentification",
"Need help authenticating?": "Besoin d'aide pour l'authentification ?", "Need help authenticating?": "Besoin d'aide pour l'authentification ?",
"MFA QR Code": "Code QR de l'A2F", "MFA QR Code": "Code QR dauthentification multifacteur",
"Account created successfully. Please log in to set up two-factor authentication.": "Compte créé avec succès. Veuillez vous connecter pour configurer l'authentification à deux facteurs.", "Account created successfully. Please log in to set up two-factor authentication.": "Compte créé avec succès. Veuillez vous connecter pour configurer l'authentification à deux facteurs.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Réinitialisation du mot de passe réussie. Veuillez vous connecter avec votre nouveau mot de passe et compléter l'authentification à deux facteurs.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "Réinitialisation du mot de passe réussie. Veuillez vous connecter avec votre nouveau mot de passe et compléter l'authentification à deux facteurs.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Réinitialisation du mot de passe réussie. Veuillez vous connecter avec votre nouveau mot de passe pour configurer l'authentification à deux facteurs.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Réinitialisation du mot de passe réussie. Veuillez vous connecter avec votre nouveau mot de passe pour configurer l'authentification à deux facteurs.",
"Password reset was successful. Please log in with your new password.": "La réinitialisation du mot de passe a réussi. Veuillez vous connecter avec votre nouveau mot de passe.", "Password reset was successful. Please log in with your new password.": "La réinitialisation du mot de passe a réussi. Veuillez vous connecter avec votre nouveau mot de passe.",
"Two-factor authentication": "Authentification à deux facteurs", "Two-factor authentication": "Authentification à deux facteurs",
"Use authenticator app instead": "Utilisez l'application d'authentification à la place", "Use authenticator app instead": "Utiliser lapplication dauthentification à la place",
"Verify backup code": "Vérifier le code de sauvegarde", "Verify backup code": "Vérifier le code de secours",
"Use backup code": "Utiliser le code de sauvegarde", "Use backup code": "Utiliser un code de secours",
"Enter one of your backup codes": "Entrez un de vos codes de sauvegarde", "Enter one of your backup codes": "Saisissez lun de vos codes de secours",
"Backup code": "Code de sauvegarde", "Backup code": "Code de secours",
"Enter one of your backup codes. Each backup code can only be used once.": "Entrez un de vos codes de sauvegarde. Chaque code de sauvegarde ne peut être utilisé qu'une seule fois.", "Enter one of your backup codes. Each backup code can only be used once.": "Entrez un de vos codes de sauvegarde. Chaque code de sauvegarde ne peut être utilisé qu'une seule fois.",
"Verify": "Vérifier", "Verify": "Vérifier",
"Trash": "Corbeille", "Trash": "Corbeille",
@@ -544,12 +568,12 @@
"Page moved to trash": "Page déplacée vers la corbeille", "Page moved to trash": "Page déplacée vers la corbeille",
"Page restored successfully": "Page restaurée avec succès", "Page restored successfully": "Page restaurée avec succès",
"Deleted by": "Supprimé par", "Deleted by": "Supprimé par",
"Deleted at": "Supprimé à", "Deleted at": "Supprimé le",
"Preview": "Aperçu", "Preview": "Aperçu",
"Subpages": "Sous-pages", "Subpages": "Sous-pages",
"Failed to load subpages": "Échec du chargement des sous-pages", "Failed to load subpages": "Échec du chargement des sous-pages",
"No subpages": "Pas de sous-pages", "No subpages": "Aucune sous-page",
"Subpages (Child pages)": "Sous-pages (Pages enfants)", "Subpages (Child pages)": "Sous-pages (pages enfants)",
"List all subpages of the current page": "Lister toutes les sous-pages de la page actuelle", "List all subpages of the current page": "Lister toutes les sous-pages de la page actuelle",
"Attachments": "Pièces jointes", "Attachments": "Pièces jointes",
"All spaces": "Tous les espaces", "All spaces": "Tous les espaces",
@@ -559,24 +583,24 @@
"Type": "Type", "Type": "Type",
"Enterprise": "Entreprise", "Enterprise": "Entreprise",
"Download attachment": "Télécharger la pièce jointe", "Download attachment": "Télécharger la pièce jointe",
"Allowed email domains": "Domaines de messagerie autorisés", "Allowed email domains": "Domaines e-mail autorisés",
"Only users with email addresses from these domains can signup via SSO.": "Seuls les utilisateurs possédant des adresses e-mail provenant de ces domaines peuvent s'inscrire via SSO.", "Only users with email addresses from these domains can signup via SSO.": "Seuls les utilisateurs disposant dadresses e-mail provenant de ces domaines peuvent sinscrire via lauthentification unique (SSO).",
"Enter valid domain names separated by comma or space": "Entrez des noms de domaine valides séparés par une virgule ou un espace", "Enter valid domain names separated by comma or space": "Saisissez des noms de domaine valides séparés par une virgule ou un espace",
"Enforce two-factor authentication": "Imposer l'authentification à deux facteurs", "Enforce two-factor authentication": "Imposer lauthentification à deux facteurs",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Une fois appliquée, tous les membres doivent activer l'authentification à deux facteurs pour accéder à l'espace de travail.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Une fois appliquée, tous les membres doivent activer l'authentification à deux facteurs pour accéder à l'espace de travail.",
"Toggle MFA enforcement": "Basculer l'application de l'AMF", "Toggle MFA enforcement": "Basculer lobligation dauthentification multifacteur",
"Display name": "Nom d'affichage", "Display name": "Nom daffichage",
"Allow signup": "Autoriser l'inscription", "Allow signup": "Autoriser linscription",
"Enabled": "Activé", "Enabled": "Activé",
"Advanced Settings": "Paramètres avancés", "Advanced Settings": "Paramètres avancés",
"Enable TLS/SSL": "Activer TLS/SSL", "Enable TLS/SSL": "Activer TLS/SSL",
"Use secure connection to LDAP server": "Utiliser une connexion sécurisée au serveur LDAP", "Use secure connection to LDAP server": "Utiliser une connexion sécurisée au serveur LDAP",
"Group sync": "Synchronisation de groupe", "Group sync": "Synchronisation des groupes",
"No SSO providers found.": "Aucun fournisseur SSO trouvé.", "No SSO providers found.": "Aucun fournisseur SSO trouvé.",
"Delete SSO provider": "Supprimer le fournisseur SSO", "Delete SSO provider": "Supprimer le fournisseur SSO",
"Are you sure you want to delete this SSO provider?": "Êtes-vous sûr de vouloir supprimer ce fournisseur SSO ?", "Are you sure you want to delete this SSO provider?": "Êtes-vous sûr de vouloir supprimer ce fournisseur SSO ?",
"Action": "Action", "Action": "Action",
"{{ssoProviderType}} configuration": "Configuration {{ssoProviderType}}", "{{ssoProviderType}} configuration": "Configuration de {{ssoProviderType}}",
"Icon": "Icône", "Icon": "Icône",
"Upload image": "Téléverser une image", "Upload image": "Téléverser une image",
"Remove image": "Supprimer l'image", "Remove image": "Supprimer l'image",
@@ -613,6 +637,7 @@
"AI Answer": "Réponse IA", "AI Answer": "Réponse IA",
"Ask AI": "Demander à l'IA", "Ask AI": "Demander à l'IA",
"AI is thinking...": "L'IA réfléchit...", "AI is thinking...": "L'IA réfléchit...",
"Thinking": "Réflexion en cours",
"Ask a question...": "Posez une question...", "Ask a question...": "Posez une question...",
"AI Answers": "Réponses IA", "AI Answers": "Réponses IA",
"AI-powered search (AI Answers)": "Recherche propulsée par IA (Réponses IA)", "AI-powered search (AI Answers)": "Recherche propulsée par IA (Réponses IA)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "IA générative (Demandez à l'IA)", "Generative AI (Ask AI)": "IA générative (Demandez à l'IA)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Activer la génération de contenu assistée par IA dans l'éditeur. Permet aux utilisateurs de générer, améliorer, traduire et transformer du texte.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Activer la génération de contenu assistée par IA dans l'éditeur. Permet aux utilisateurs de générer, améliorer, traduire et transformer du texte.",
"Toggle generative AI": "Activer/désactiver l'IA générative", "Toggle generative AI": "Activer/désactiver l'IA générative",
"Enterprise feature": "Fonctionnalité entreprise", "Upgrade your plan": "Mettez à niveau votre forfait",
"Available with a paid license": "Disponible avec une licence payante",
"Upgrade your license tier.": "Mettez à niveau votre niveau de licence.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "L'IA n'est disponible que dans l'édition Entreprise de Docmost. Contactez sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "L'IA n'est disponible que dans l'édition Entreprise de Docmost. Contactez sales@docmost.com.",
"AI & MCP": "IA & MCP", "AI & MCP": "IA & MCP",
"AI": "IA", "AI": "IA",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Protocole de contexte de modèle (MCP)", "Model Context Protocol (MCP)": "Protocole de contexte de modèle (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Activez le serveur MCP pour permettre aux assistants et outils IA d'interagir avec le contenu de votre espace de travail.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Activez le serveur MCP pour permettre aux assistants et outils IA d'interagir avec le contenu de votre espace de travail.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP n'est disponible que dans l'édition Entreprise de Docmost. Contactez sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP n'est disponible que dans l'édition Entreprise de Docmost. Contactez sales@docmost.com.",
"MCP documentation": "Documentation MCP",
"MCP Server URL": "URL du serveur MCP", "MCP Server URL": "URL du serveur MCP",
"Use your API key for authentication. You can manage API keys in your account settings.": "Utilisez votre clé API pour l'authentification. Vous pouvez gérer les clés API dans les paramètres de votre compte.", "Use your API key for authentication. You can manage API keys in your account settings.": "Utilisez votre clé API pour l'authentification. Vous pouvez gérer les clés API dans les paramètres de votre compte.",
"Supported tools": "Outils pris en charge", "Supported tools": "Outils pris en charge",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Votre espace de travail a MCP activé. Utilisez votre clé API pour connecter des assistants IA.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Votre espace de travail a MCP activé. Utilisez votre clé API pour connecter des assistants IA.",
"MCP server URL:": "URL du serveur MCP :", "MCP server URL:": "URL du serveur MCP :",
"Learn more": "En savoir plus", "Learn more": "En savoir plus",
"View the": "Voir la", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Gérez les clés API pour tous les utilisateurs de l'espace de travail. Consultez la <anchor>documentation API</anchor> pour plus de détails sur l'utilisation.",
"for usage details.": "pour les détails d'utilisation.", "View the <anchor>API documentation</anchor> for usage details.": "Consultez la <anchor>documentation API</anchor> pour plus de détails sur l'utilisation.",
"for setup instructions.": "pour les instructions de configuration.", "View the <anchor>MCP documentation</anchor>.": "Consultez la <anchor>documentation MCP</anchor>.",
"API documentation": "Documentation de l'API",
"Sources": "Sources", "Sources": "Sources",
"AI Answers not available for attachments": "Réponses IA non disponibles pour les pièces jointes", "AI Answers not available for attachments": "Réponses IA non disponibles pour les pièces jointes",
"No answer available": "Pas de réponse disponible", "No answer available": "Pas de réponse disponible",
@@ -654,12 +679,34 @@
"Mark all as read": "Tout marquer comme lu", "Mark all as read": "Tout marquer comme lu",
"Mark as read": "Marquer comme lu", "Mark as read": "Marquer comme lu",
"More options": "Plus d'options", "More options": "Plus d'options",
"mentioned you in a comment": "vous a mentionné dans un commentaire", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> vous a mentionné dans un commentaire",
"commented on a page": "a commenté une page", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> a commenté une page",
"resolved a comment": "a résolu un commentaire", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> a résolu un commentaire",
"mentioned you on a page": "vous a mentionné sur une page", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> vous a mentionné sur une page",
"gave you edit access to a page": "vous a donné l'accès pour modifier une page", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> vous a donné un accès de modification à une page",
"gave you view access to a page": "vous a donné l'accès pour consulter une page", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> vous a donné un accès en lecture à une page",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> a mis à jour une page",
"Watch page": "Suivre la page",
"Stop watching": "Arrêter de suivre",
"Watch space": "Suivre lespace",
"Stop watching space": "Arrêter de suivre lespace",
"Email notifications": "Notifications par e-mail",
"Page updates": "Mises à jour de la page",
"Get notified when pages you watch are updated.": "Recevez une notification lorsque les pages que vous surveillez sont mises à jour.",
"Page mentions": "Mentions sur la page",
"Get notified when someone mentions you on a page.": "Recevez une notification lorsqu'une personne vous mentionne sur une page.",
"Comment mentions": "Mentions dans les commentaires",
"Get notified when someone mentions you in a comment.": "Recevez une notification lorsqu'une personne vous mentionne dans un commentaire.",
"New comments": "Nouveaux commentaires",
"Get notified about new comments on threads you participate in.": "Recevez une notification concernant les nouveaux commentaires dans les fils auxquels vous participez.",
"Resolved comments": "Commentaires résolus",
"Get notified when your comment is resolved.": "Recevez une notification lorsque votre commentaire est résolu.",
"You are now watching this page": "Vous surveillez désormais cette page",
"You are no longer watching this page": "Vous ne surveillez plus cette page",
"You are now watching this space": "Vous suivez maintenant cet espace",
"You are no longer watching this space": "Vous ne suivez plus cet espace",
"Direct": "Direct",
"Updates": "Mises à jour",
"Today": "Aujourd'hui", "Today": "Aujourd'hui",
"Yesterday": "Hier", "Yesterday": "Hier",
"This week": "Cette semaine", "This week": "Cette semaine",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Échec de la mise à jour de la durée de conservation de la corbeille", "Failed to update trash retention": "Échec de la mise à jour de la durée de conservation de la corbeille",
"Removed page restriction": "Restriction de la page supprimée", "Removed page restriction": "Restriction de la page supprimée",
"Added page permission": "Autorisation de la page ajoutée", "Added page permission": "Autorisation de la page ajoutée",
"Removed page permission": "Autorisation de la page supprimée" "Removed page permission": "Autorisation de la page supprimée",
"day": "jour",
"days": "jours",
"week": "semaine",
"weeks": "semaines",
"month": "mois",
"months": "mois",
"year": "an",
"years": "ans",
"Period": "Période",
"Fixed date": "Date fixe",
"Indefinitely": "Indéfiniment",
"Days": "Jours",
"Weeks": "Semaines",
"Months": "Mois",
"Years": "Ans",
"Pick a date": "Choisir une date",
"Maximum is {{max}} {{unit}} for this unit": "Le maximum est de {{max}} {{unit}} pour cette unité",
"Never expires. Verifiers can re-verify at any time.": "Nexpire jamais. Les vérificateurs peuvent revérifier à tout moment.",
"Verified": "Vérifié",
"Review needed": "Révision nécessaire",
"Verification expired": "Vérification expirée",
"Draft": "Brouillon",
"In Approval": "En approbation",
"In approval": "En approbation",
"Approved": "Approuvé",
"Obsolete": "Obsolète",
"Expiring": "Expire bientôt",
"Set up verification": "Configurer la vérification",
"Verify page": "Vérifier la page",
"Page verification": "Vérification de la page",
"Add verification": "Ajouter une vérification",
"Edit verification": "Modifier la vérification",
"Search by title": "Rechercher par titre",
"Choose how this page should stay accurate.": "Choisissez comment cette page doit rester exacte.",
"Recurring verification": "Vérification récurrente",
"Verifiers re-confirm this page on a schedule.": "Les vérificateurs reconfirment cette page selon une fréquence définie.",
"Re-verify on a schedule (e.g every 30 days )": "Revérifier selon une fréquence définie (p. ex. tous les 30 jours)",
"Page stays editable at all times": "La page reste modifiable en permanence",
"Best for runbooks, FAQs, living documentation": "Idéal pour les runbooks, FAQ et la documentation évolutive",
"Approval workflow": "Flux dapprobation",
"Formal document lifecycle with named approvers.": "Cycle de vie formel du document avec des approbateurs désignés.",
"Draft → In approval → Approved → Obsolete": "Brouillon → En approbation → Approuvé → Obsolète",
"Locked once approved, with full history": "Verrouillé une fois approuvé, avec historique complet",
"Designed for ISO 9001, ISO 13485, and FDA": "Conçu pour lISO 9001, lISO 13485 et la FDA",
"Best for SOPs and controlled documents": "Idéal pour les SOP et les documents contrôlés",
"Back": "Retour",
"Quality management": "Gestion de la qualité",
"Recurring": "Récurrent",
"Pages move through draft, approval, and approved stages.": "Les pages passent par les étapes brouillon, approbation et approuvé.",
"Verifiers": "Vérificateurs",
"Add verifier": "Ajouter un vérificateur",
"I've reviewed this page for accuracy": "Jai vérifié lexactitude de cette page",
"Set up": "Configurer",
"Remove verification": "Supprimer la vérification",
"Are you sure you want to remove verification from this page?": "Voulez-vous vraiment supprimer la vérification de cette page ?",
"Assigned verifiers must periodically re-verify this page.": "Les vérificateurs assignés doivent revérifier périodiquement cette page.",
"Last verified by {{name}} {{time}} (expired)": "Dernière vérification par {{name}} {{time}} (expirée)",
"The fixed expiration date has passed.": "La date dexpiration fixe est passée.",
"Verified by {{name}} {{time}}": "Vérifié par {{name}} {{time}}",
"Expires {{date}}": "Expire le {{date}}",
"Expired {{date}}": "Expiré le {{date}}",
"Mark as obsolete": "Marquer comme obsolète",
"Mark obsolete": "Marquer comme obsolète",
"Returned by {{name}} {{time}}": "Renvoyé par {{name}} {{time}}",
"No approval has been requested yet.": "Aucune approbation na encore été demandée.",
"Submitted by {{name}} {{time}}": "Soumis par {{name}} {{time}}",
"Someone": "Quelquun",
"Approved by {{name}} {{time}}": "Approuvé par {{name}} {{time}}",
"This document has been marked as obsolete.": "Ce document a été marqué comme obsolète.",
"Rejection comment": "Commentaire de rejet",
"Reason for returning this document...": "Raison du renvoi de ce document...",
"Confirm rejection": "Confirmer le rejet",
"Submit for approval": "Soumettre pour approbation",
"Reject": "Rejeter",
"Approve": "Approuver",
"Re-submit for approval": "Soumettre à nouveau pour approbation",
"Verified until": "Vérifié jusquau",
"QMS": "SMQ",
"Verified pages": "Pages vérifiées",
"Search pages...": "Rechercher des pages...",
"Filter by space": "Filtrer par espace",
"Filter by type": "Filtrer par type",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> a vérifié une page",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> a soumis une page à votre approbation",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> a renvoyé une page pour révision",
"Page verification expires soon": "La vérification de la page expire bientôt",
"Page verification has expired": "La vérification de la page a expiré",
"Verifying your email": "Vérification de votre e-mail",
"Please wait...": "Veuillez patienter...",
"Verification failed. The link may have expired.": "Échec de la vérification. Le lien a peut-être expiré.",
"Check your email": "Vérifiez votre e-mail",
"We sent a verification link to {{email}}.": "Nous avons envoyé un lien de vérification à {{email}}.",
"We sent a verification link to your email.": "Nous avons envoyé un lien de vérification à votre adresse e-mail.",
"Click the link to verify your email and access your workspace.": "Cliquez sur le lien pour vérifier votre adresse et accéder à votre espace de travail.",
"Resend verification email": "Renvoyer le-mail de vérification",
"Verification email sent. Please check your inbox.": "E-mail de vérification envoyé. Veuillez vérifier votre boîte de réception.",
"Failed to resend verification email. Please try again.": "Échec de l'envoi du nouvel e-mail de vérification. Veuillez réessayer.",
"We've sent you an email with your associated workspaces.": "Nous vous avons envoyé un e-mail avec vos espaces de travail associés.",
"Load more": "Charger plus",
"Log out of all devices": "Se déconnecter de tous les appareils",
"Log out of all sessions except this device": "Se déconnecter de toutes les sessions sauf cet appareil",
"This Device": "Cet appareil",
"Unknown device": "Appareil inconnu",
"No active sessions": "Aucune session active",
"Session revoked": "Session révoquée",
"All other sessions revoked": "Toutes les autres sessions ont été révoquées",
"Last used": "Dernière utilisation",
"Created": "Créé",
"Rename": "Renommer",
"Publish": "Publier",
"Security": "Sécurité",
"Enforce SSO": "Imposer le SSO",
"Once enforced, members will not be able to login with email and password.": "Une fois activé, les membres ne pourront plus se connecter avec leur e-mail et leur mot de passe.",
"AI-generated content may not be accurate.": "Le contenu généré par lIA peut ne pas être exact.",
"AI Chat": "Chat IA",
"Analyze for insights": "Analyser pour obtenir des informations",
"Ask anything...": "Posez nimporte quelle question...",
"Chat history": "Historique des discussions",
"Chat name": "Nom de la discussion",
"Close": "Fermer",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Échec du chargement de la discussion. Une erreur sest produite.",
"Failed to render this message.": "Échec de laffichage de ce message.",
"How can I help you today?": "Comment puis-je vous aider aujourdhui ?",
"New chat": "Nouvelle discussion",
"No chat history": "Aucun historique de discussion",
"No chats found": "Aucune discussion trouvée",
"No conversations yet": "Aucune conversation pour le moment",
"Open full page": "Ouvrir la page complète",
"Previous 7 days": "7 derniers jours",
"Previous 30 days": "30 derniers jours",
"Search chats...": "Rechercher des discussions...",
"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",
"Translate this page": "Traduire cette page",
"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 ?"
} }
+272 -85
View File
@@ -7,6 +7,7 @@
"Add members": "Aggiungi membri", "Add members": "Aggiungi membri",
"Add to groups": "Aggiungi ai gruppi", "Add to groups": "Aggiungi ai gruppi",
"Add space members": "Aggiungi membri allo spazio", "Add space members": "Aggiungi membri allo spazio",
"Add to favorites": "Aggiungi ai preferiti",
"Admin": "Amministratore", "Admin": "Amministratore",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Sei sicuro di voler eliminare questo gruppo? I membri perderanno l'accesso alle risorse accessibili da questo gruppo.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Sei sicuro di voler eliminare questo gruppo? I membri perderanno l'accesso alle risorse accessibili da questo gruppo.",
"Are you sure you want to delete this page?": "Sei sicuro di voler eliminare questa pagina?", "Are you sure you want to delete this page?": "Sei sicuro di voler eliminare questa pagina?",
@@ -47,19 +48,19 @@
"e.g ACME": "es. ACME", "e.g ACME": "es. ACME",
"e.g ACME Inc": "es. ACME Inc", "e.g ACME Inc": "es. ACME Inc",
"e.g Developers": "es. Sviluppatori", "e.g Developers": "es. Sviluppatori",
"e.g Group for developers": "es. Gruppo per gli sviluppatori", "e.g Group for developers": "es. Gruppo per sviluppatori",
"e.g product": "es. prodotto", "e.g product": "es. prodotto",
"e.g Product Team": "es. Team di Prodotto", "e.g Product Team": "es. Team di prodotto",
"e.g Sales": "es. Vendite", "e.g Sales": "es. Vendite",
"e.g Space for product team": "es. Spazio per il team di prodotto", "e.g Space for product team": "es. Spazio per il team di prodotto",
"e.g Space for sales team to collaborate": "es. Spazio per la collaborazione del team di vendita", "e.g Space for sales team to collaborate": "es. Spazio per la collaborazione del team vendite",
"Edit": "Modifica", "Edit": "Modifica",
"Read": "Leggi", "Read": "Leggi",
"Edit group": "Modifica gruppo", "Edit group": "Modifica gruppo",
"Email": "Email", "Email": "Email",
"Enter a strong password": "Inserisci una password sicura", "Enter a strong password": "Inserisci una password sicura",
"Enter valid email addresses separated by comma or space max_50": "Inserisci degli indirizzi email validi separati da virgola o spazio [max: 50]", "Enter valid email addresses separated by comma or space max_50": "Inserisci degli indirizzi email validi separati da virgola o spazio [max: 50]",
"enter valid emails addresses": "inserisci degli indirizzi email validi", "enter valid emails addresses": "inserisci indirizzi email validi",
"Enter your current password": "Inserisci la tua password attuale", "Enter your current password": "Inserisci la tua password attuale",
"enter your full name": "inserisci il tuo nome completo", "enter your full name": "inserisci il tuo nome completo",
"Enter your new password": "Inserisci la tua nuova password", "Enter your new password": "Inserisci la tua nuova password",
@@ -74,6 +75,9 @@
"Failed to import pages": "Impossibile importare le pagine", "Failed to import pages": "Impossibile importare le pagine",
"Failed to load page. An error occurred.": "Il caricamento della pagina è fallito. Si è verificato un errore.", "Failed to load page. An error occurred.": "Il caricamento della pagina è fallito. Si è verificato un errore.",
"Failed to update data": "Impossibile aggiornare i dati", "Failed to update data": "Impossibile aggiornare i dati",
"Favorite spaces": "Spazi preferiti",
"Favorite spaces appear here": "Gli spazi preferiti appariranno qui",
"Favorites": "Preferiti",
"Full access": "Accesso completo", "Full access": "Accesso completo",
"Full page width": "Pagina a larghezza intera", "Full page width": "Pagina a larghezza intera",
"Full width": "Larghezza intera", "Full width": "Larghezza intera",
@@ -92,6 +96,7 @@
"Invite by email": "Invita tramite email", "Invite by email": "Invita tramite email",
"Invite members": "Invita membri", "Invite members": "Invita membri",
"Invite new members": "Invita nuovi membri", "Invite new members": "Invita nuovi membri",
"Invite People": "Invita persone",
"Invited members who are yet to accept their invitation will appear here.": "I membri invitati che non hanno ancora accettato il loro invito appariranno qui.", "Invited members who are yet to accept their invitation will appear here.": "I membri invitati che non hanno ancora accettato il loro invito appariranno qui.",
"Invited members will be granted access to spaces the groups can access": "I membri invitati avranno accesso agli spazi a cui i gruppi possono accedere", "Invited members will be granted access to spaces the groups can access": "I membri invitati avranno accesso agli spazi a cui i gruppi possono accedere",
"Join the workspace": "Unisciti all'area di lavoro", "Join the workspace": "Unisciti all'area di lavoro",
@@ -139,6 +144,7 @@
"Profile": "Profilo", "Profile": "Profilo",
"Recently updated": "Aggiornato di recente", "Recently updated": "Aggiornato di recente",
"Remove": "Rimuovi", "Remove": "Rimuovi",
"Remove from favorites": "Rimuovi dai preferiti",
"Remove group member": "Rimuovi membro dal gruppo", "Remove group member": "Rimuovi membro dal gruppo",
"Remove space member": "Rimuovi membro dallo spazio", "Remove space member": "Rimuovi membro dallo spazio",
"Restore": "Ripristina", "Restore": "Ripristina",
@@ -149,55 +155,56 @@
"Search for users": "Cerca un utente", "Search for users": "Cerca un utente",
"Search for users and groups": "Cerca un utente o un gruppo", "Search for users and groups": "Cerca un utente o un gruppo",
"Search...": "Cerca...", "Search...": "Cerca...",
"Select language": "Seleziona una lingua", "Select language": "Seleziona lingua",
"Select role": "Seleziona un ruolo", "Select role": "Seleziona ruolo",
"Select role to assign to all invited members": "Seleziona il ruolo da assegnare a tutti i membri invitati", "Select role to assign to all invited members": "Seleziona il ruolo da assegnare a tutti i membri invitati",
"Select theme": "Seleziona un tema", "Select theme": "Seleziona tema",
"Send invitation": "Invia invito", "Send invitation": "Invia invito",
"Invitation sent": "Invito inviato", "Invitation sent": "Invito inviato",
"Settings": "Impostazioni", "Settings": "Impostazioni",
"Setup workspace": "Configura l'area di lavoro", "Setup workspace": "Configura workspace",
"Sign In": "Accedi", "Sign In": "Accedi",
"Sign Up": "Registrati", "Sign Up": "Registrati",
"Slug": "Slug", "Slug": "Slug",
"Space": "Spazio", "Space": "Spazio",
"Space description": "Descrizione dello spazio", "Space description": "Descrizione dello spazio",
"Space menu": "Menu spazio", "Space menu": "Menu dello spazio",
"Space name": "Nome dello spazio", "Space name": "Nome dello spazio",
"Space settings": "Impostazioni dello spazio", "Space settings": "Impostazioni dello spazio",
"Space slug": "Slug dello spazio", "Space slug": "Slug dello spazio",
"Spaces": "Spazi", "Spaces": "Spazi",
"Spaces you belong to": "Spazi a cui appartieni", "Spaces you belong to": "Spazi di cui fai parte",
"No space found": "Nessuno spazio trovato", "No space found": "Nessuno spazio trovato",
"Search for spaces": "Cerca uno spazio", "Search for spaces": "Cerca spazi",
"Start typing to search...": "Inizia a digitare per cercare...", "Start typing to search...": "Inizia a digitare per cercare...",
"Status": "Stato", "Status": "Stato",
"Successfully imported": "Importato con successo", "Successfully imported": "Importato con successo",
"Successfully restored": "Ripristinato con successo", "Successfully restored": "Ripristinato con successo",
"System settings": "Impostazioni di sistema", "System settings": "Impostazioni di sistema",
"Templates": "Modelli",
"Theme": "Tema", "Theme": "Tema",
"To change your email, you have to enter your password and new email.": "Per cambiare la tua email, devi inserire la tua password e la nuova email.", "To change your email, you have to enter your password and new email.": "Per cambiare la tua email, devi inserire la tua password e la nuova email.",
"Toggle full page width": "Attiva/disattiva pagina a larghezza intera", "Toggle full page width": "Attiva/disattiva larghezza completa della pagina",
"Unable to import pages. Please try again.": "Impossibile importare le pagine. Riprova.", "Unable to import pages. Please try again.": "Impossibile importare le pagine. Riprova.",
"untitled": "senza titolo", "untitled": "senza titolo",
"Untitled": "Senza titolo", "Untitled": "Senza titolo",
"Updated successfully": "Aggiornato con successo", "Updated successfully": "Aggiornato con successo",
"User": "Utente", "User": "Utente",
"Workspace": "Area di lavoro", "Workspace": "Workspace",
"Workspace Name": "Nome dell'area di lavoro", "Workspace Name": "Nome del workspace",
"Workspace settings": "Impostazioni dell'area di lavoro", "Workspace settings": "Impostazioni del workspace",
"You can change your password here.": "Qui puoi cambiare la tua password.", "You can change your password here.": "Qui puoi cambiare la tua password.",
"Your Email": "La tua email", "Your Email": "La tua email",
"Your import is complete.": "La tua importazione è completata.", "Your import is complete.": "La tua importazione è completata.",
"Your name": "Il tuo nome", "Your name": "Il tuo nome",
"Your Name": "Il Tuo Nome", "Your Name": "Il tuo nome",
"Your password": "La tua password", "Your password": "La tua password",
"Your password must be a minimum of 8 characters.": "La tua password deve contenere almeno 8 caratteri.", "Your password must be a minimum of 8 characters.": "La tua password deve contenere almeno 8 caratteri.",
"Sidebar toggle": "Attiva/disattiva barra laterale", "Sidebar toggle": "Attiva/disattiva barra laterale",
"Comments": "Commenti", "Comments": "Commenti",
"404 page not found": "404 pagina non trovata", "404 page not found": "404 pagina non trovata",
"Sorry, we can't find the page you are looking for.": "Siamo spiacenti, non riusciamo a trovare la pagina che stai cercando.", "Sorry, we can't find the page you are looking for.": "Siamo spiacenti, non riusciamo a trovare la pagina che stai cercando.",
"Take me back to homepage": "Torna all'homepage", "Take me back to homepage": "Torna alla homepage",
"Forgot password": "Password dimenticata", "Forgot password": "Password dimenticata",
"Forgot your password?": "Hai dimenticato la password?", "Forgot your password?": "Hai dimenticato la password?",
"A password reset link has been sent to your email. Please check your inbox.": "Un link per il reset della password è stato inviato al tuo indirizzo email. Per favore, controlla la tua casella di posta.", "A password reset link has been sent to your email. Please check your inbox.": "Un link per il reset della password è stato inviato al tuo indirizzo email. Per favore, controlla la tua casella di posta.",
@@ -215,6 +222,8 @@
"Edit comment": "Modifica commento", "Edit comment": "Modifica commento",
"Delete comment": "Elimina commento", "Delete comment": "Elimina commento",
"Are you sure you want to delete this comment?": "Sei sicuro di voler eliminare questo commento?", "Are you sure you want to delete this comment?": "Sei sicuro di voler eliminare questo commento?",
"Delete chat": "Elimina chat",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Sei sicuro di voler eliminare '{{title}}'? Questa azione non può essere annullata.",
"Comment created successfully": "Commento creato con successo", "Comment created successfully": "Commento creato con successo",
"Error creating comment": "Si è verificato un errore durante la creazione del commento", "Error creating comment": "Si è verificato un errore durante la creazione del commento",
"Comment updated successfully": "Commento aggiornato con successo", "Comment updated successfully": "Commento aggiornato con successo",
@@ -223,12 +232,12 @@
"Failed to delete comment": "Impossibile eliminare il commento", "Failed to delete comment": "Impossibile eliminare il commento",
"Comment resolved successfully": "Commento risolto con successo", "Comment resolved successfully": "Commento risolto con successo",
"Comment re-opened successfully": "Commento riaperto con successo", "Comment re-opened successfully": "Commento riaperto con successo",
"Comment unresolved successfully": "Commento non risolto con successo", "Comment unresolved successfully": "Commento contrassegnato come non risolto con successo",
"Failed to resolve comment": "Impossibile risolvere il commento", "Failed to resolve comment": "Impossibile risolvere il commento",
"Resolve comment": "Risolvi commento", "Resolve comment": "Risolvi commento",
"Unresolve comment": "Annulla risoluzione commento", "Unresolve comment": "Segna commento come non risolto",
"Resolve Comment Thread": "Risolvi discussione commenti", "Resolve Comment Thread": "Risolvi discussione del commento",
"Unresolve Comment Thread": "Annulla risoluzione discussione commenti", "Unresolve Comment Thread": "Segna discussione del commento come non risolta",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Sei sicuro di voler risolvere questa discussione di commenti? Questo la contrassegnerà come completata.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Sei sicuro di voler risolvere questa discussione di commenti? Questo la contrassegnerà come completata.",
"Are you sure you want to unresolve this comment thread?": "Sei sicuro di voler annullare la risoluzione di questa discussione di commenti?", "Are you sure you want to unresolve this comment thread?": "Sei sicuro di voler annullare la risoluzione di questa discussione di commenti?",
"Resolved": "Risolto", "Resolved": "Risolto",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "Sei sicuro di voler eliminare questo spazio?", "Are you sure you want to delete this space?": "Sei sicuro di voler eliminare questo spazio?",
"Delete this space with all its pages and data.": "Elimina questo spazio con tutte le sue pagine e i suoi dati.", "Delete this space with all its pages and data.": "Elimina questo spazio con tutte le sue pagine e i suoi dati.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Tutte le pagine, i commenti, gli allegati e i permessi di questo spazio verranno eliminati irreversibilmente.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Tutte le pagine, i commenti, gli allegati e i permessi di questo spazio verranno eliminati irreversibilmente.",
"Confirm space name": "Conferma nome spazio", "Confirm space name": "Conferma nome dello spazio",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Digita il nome dello spazio <b>{{spaceName}}</b> per confermare la tua azione.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "Digita il nome dello spazio <b>{{spaceName}}</b> per confermare la tua azione.",
"Format": "Formato", "Format": "Formato",
"Include subpages": "Includi sottopagine", "Include subpages": "Includi sottopagine",
@@ -289,6 +298,11 @@
"Save & Exit": "Salva ed esci", "Save & Exit": "Salva ed esci",
"Double-click to edit Excalidraw diagram": "Fai doppio clic per modificare il diagramma di Excalidraw", "Double-click to edit Excalidraw diagram": "Fai doppio clic per modificare il diagramma di Excalidraw",
"Paste link": "Incolla link", "Paste link": "Incolla link",
"Paste link or search pages": "Incolla il link o cerca le pagine",
"Link to web page": "Collega a una pagina web",
"Recents": "Recenti",
"Page or URL": "Pagina o URL",
"Link title": "Titolo del link",
"Edit link": "Modifica link", "Edit link": "Modifica link",
"Remove link": "Rimuovi link", "Remove link": "Rimuovi link",
"Add link": "Aggiungi link", "Add link": "Aggiungi link",
@@ -307,7 +321,7 @@
"Pink": "Rosa", "Pink": "Rosa",
"Gray": "Grigio", "Gray": "Grigio",
"Embed link": "Incorpora collegamento", "Embed link": "Incorpora collegamento",
"Invalid {{provider}} embed link": "Link di incorporamento {{provider}} non valido", "Invalid {{provider}} embed link": "Link incorporato {{provider}} non valido",
"Embed {{provider}}": "Incorpora {{provider}}", "Embed {{provider}}": "Incorpora {{provider}}",
"Enter {{provider}} link to embed": "Inserisci il link {{provider}} per incorporare", "Enter {{provider}} link to embed": "Inserisci il link {{provider}} per incorporare",
"Bold": "Grassetto", "Bold": "Grassetto",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Inserisci divisore di regola orizzontale", "Insert horizontal rule divider": "Inserisci divisore di regola orizzontale",
"Upload any image from your device.": "Carica un'immagine dal tuo dispositivo.", "Upload any image from your device.": "Carica un'immagine dal tuo dispositivo.",
"Upload any video from your device.": "Carica qualsiasi video dal tuo dispositivo.", "Upload any video from your device.": "Carica qualsiasi video dal tuo dispositivo.",
"Upload any audio from your device.": "Carica qualsiasi audio dal tuo dispositivo.",
"Upload any file from your device.": "Carica qualsiasi file dal tuo dispositivo.", "Upload any file from your device.": "Carica qualsiasi file dal tuo dispositivo.",
"Uploading {{name}}": "Caricamento di {{name}}", "Uploading {{name}}": "Caricamento di {{name}}",
"Uploading file": "Caricamento file", "Uploading file": "Caricamento file",
@@ -343,22 +358,28 @@
"Insert a table.": "Inserisci una tabella.", "Insert a table.": "Inserisci una tabella.",
"Insert collapsible block.": "Inserisci blocco comprimibile.", "Insert collapsible block.": "Inserisci blocco comprimibile.",
"Video": "Video", "Video": "Video",
"Divider": "Divisore", "Divider": "Separatore",
"Quote": "Preventivo", "Quote": "Citazione",
"Image": "Immagine", "Image": "Immagine",
"Audio": "Audio",
"Embed PDF": "Incorpora PDF",
"Upload and embed a PDF file.": "Carica e incorpora un file PDF.",
"Embed as PDF": "Incorpora come PDF",
"Failed to load PDF": "Caricamento del PDF non riuscito",
"Convert to attachment": "Converti in allegato",
"File attachment": "Allegato file", "File attachment": "Allegato file",
"Toggle block": "Attiva blocco", "Toggle block": "Blocco a comparsa",
"Callout": "Avviso", "Callout": "Riquadro evidenziato",
"Insert callout notice.": "Inserisci avviso di richiamo.", "Insert callout notice.": "Inserisci avviso di richiamo.",
"Math inline": "Matematica in linea", "Math inline": "Formula matematica in linea",
"Insert inline math equation.": "Inserisci equazione matematica in linea.", "Insert inline math equation.": "Inserisci equazione matematica in linea.",
"Math block": "Blocco matematico", "Math block": "Blocco matematico",
"Insert math equation": "Inserisci equazione matematica", "Insert math equation": "Inserisci equazione matematica",
"Mermaid diagram": "Diagramma di Mermaid", "Mermaid diagram": "Diagramma Mermaid",
"Insert mermaid diagram": "Inserisci un diagramma di Mermaid", "Insert mermaid diagram": "Inserisci diagramma Mermaid",
"Insert and design Drawio diagrams": "Inserisci e progetta diagrammi Drawio", "Insert and design Drawio diagrams": "Inserisci e progetta diagrammi Drawio",
"Insert current date": "Inserisci la data corrente", "Insert current date": "Inserisci data corrente",
"Draw and sketch excalidraw diagrams": "Disegna e schizza diagrammi excalidraw", "Draw and sketch excalidraw diagrams": "Disegna e abbozza diagrammi Excalidraw",
"Multiple": "Multiplo", "Multiple": "Multiplo",
"Turn into": "Trasforma in", "Turn into": "Trasforma in",
"Text align": "Allinea testo", "Text align": "Allinea testo",
@@ -367,7 +388,7 @@
"Pages you create will show up here.": "Le pagine che crei appariranno qui.", "Pages you create will show up here.": "Le pagine che crei appariranno qui.",
"Heading {{level}}": "Intestazione {{level}}", "Heading {{level}}": "Intestazione {{level}}",
"Toggle title": "Attiva/disattiva titolo", "Toggle title": "Attiva/disattiva titolo",
"Write anything. Enter \"/\" for commands": "Scrivi qualcosa. Digita \"/\" per i comandi", "Write anything. Enter \"/\" for commands": "Scrivi qualsiasi cosa. Digita \"/\" per i comandi",
"Write...": "Scrivi...", "Write...": "Scrivi...",
"Column count": "Numero di colonne", "Column count": "Numero di colonne",
"{{count}} Columns": "{{count}} colonne", "{{count}} Columns": "{{count}} colonne",
@@ -388,12 +409,12 @@
"Member role updated successfully": "Ruolo del membro aggiornato con successo", "Member role updated successfully": "Ruolo del membro aggiornato con successo",
"Created by: <b>{{creatorName}}</b>": "Creato da: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "Creato da: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Creato il: {{time}}", "Created at: {{time}}": "Creato il: {{time}}",
"Edited by {{name}} {{time}}": "Modificato da {{name}} il {{time}}", "Edited by {{name}} {{time}}": "Modificato da {{name}} {{time}}",
"Word count: {{wordCount}}": "Conteggio parole: {{wordCount}}", "Word count: {{wordCount}}": "Conteggio parole: {{wordCount}}",
"Character count: {{characterCount}}": "Conteggio caratteri: {{characterCount}}", "Character count: {{characterCount}}": "Conteggio caratteri: {{characterCount}}",
"New update": "Nuovo aggiornamento", "New update": "Nuovo aggiornamento",
"{{latestVersion}} is available": "{{latestVersion}} è disponibile", "{{latestVersion}} is available": "{{latestVersion}} è disponibile",
"Default page edit mode": "Modalità di modifica pagina predefinita", "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 your preferred page edit mode. Avoid accidental edits.": "Scegli la tua modalità di modifica della pagina preferita. Evita modifiche accidentali.",
"Reading": "Lettura", "Reading": "Lettura",
"Delete member": "Elimina membro", "Delete member": "Elimina membro",
@@ -410,36 +431,38 @@
"Move page": "Sposta pagina", "Move page": "Sposta pagina",
"Move page to a different space.": "Sposta la pagina in un altro spazio.", "Move page to a different space.": "Sposta la pagina in un altro spazio.",
"Real-time editor connection lost. Retrying...": "Connessione all'editor in tempo reale persa. Riprovo...", "Real-time editor connection lost. Retrying...": "Connessione all'editor in tempo reale persa. Riprovo...",
"Table of contents": "Indice dei contenuti", "Table of contents": "Indice",
"Add headings (H1, H2, H3) to generate a table of contents.": "Aggiungi intestazioni (H1, H2, H3) per generare un sommario.", "Add headings (H1, H2, H3) to generate a table of contents.": "Aggiungi intestazioni (H1, H2, H3) per generare un sommario.",
"Share": "Condividi", "Share": "Condividi",
"Public sharing": "Condivisione pubblica", "Public sharing": "Condivisione pubblica",
"Shared by": "Condiviso da", "Shared by": "Condiviso da",
"Shared at": "Condiviso il", "Shared at": "Condiviso il",
"Inherits public sharing from": "Eredita la condivisione pubblica da", "Inherits public sharing from": "Eredita la condivisione pubblica da",
"Share to web": "Condividi su web", "Share to web": "Condividi sul web",
"Shared to web": "Condiviso su web", "Shared to web": "Condiviso sul web",
"Anyone with the link can view this page": "Chiunque abbia il link può visualizzare questa pagina", "Anyone with the link can view this page": "Chiunque abbia il link può visualizzare questa pagina",
"Make this page publicly accessible": "Rendi questa pagina accessibile pubblicamente", "Make this page publicly accessible": "Rendi questa pagina accessibile pubblicamente",
"Include sub-pages": "Includi sotto-pagine", "Include sub-pages": "Includi sottopagine",
"Make sub-pages public too": "Rendi pubbliche anche le sotto-pagine", "Make sub-pages public too": "Rendi pubbliche anche le sottopagine",
"Allow search engines to index page": "Permetti ai motori di ricerca di indicizzare la pagina", "Allow search engines to index page": "Consenti ai motori di ricerca di indicizzare la pagina",
"Open page": "Apri pagina", "Open page": "Apri pagina",
"Page": "Pagina", "Page": "Pagina",
"Delete public share link": "Elimina il link di condivisione pubblica", "Delete public share link": "Elimina link di condivisione pubblica",
"Delete share": "Elimina condivisione", "Delete share": "Elimina condivisione",
"Are you sure you want to delete this shared link?": "Sei sicuro di voler eliminare questo link condiviso?", "Are you sure you want to delete this shared link?": "Sei sicuro di voler eliminare questo link condiviso?",
"Publicly shared pages from spaces you are a member of will appear here": "Le pagine condivise pubblicamente dagli spazi di cui sei membro appariranno qui", "Publicly shared pages from spaces you are a member of will appear here": "Le pagine condivise pubblicamente degli spazi di cui fai parte appariranno qui",
"Share deleted successfully": "Condivisione eliminata con successo", "Share deleted successfully": "Condivisione eliminata con successo",
"Share not found": "Condivisione non trovata", "Share not found": "Condivisione non trovata",
"Failed to share page": "Condivisione della pagina fallita", "Failed to share page": "Condivisione della pagina non riuscita",
"Disable public sharing": "Disabilita la condivisione pubblica", "Disable public sharing": "Disabilita la condivisione pubblica",
"Prevent members from sharing pages publicly.": "Impedisci ai membri di condividere pubblicamente le pagine.", "Prevent members from sharing pages publicly.": "Impedisci ai membri di condividere pubblicamente le pagine.",
"Toggle public sharing": "Attiva/disattiva la condivisione pubblica", "Toggle public sharing": "Attiva/disattiva la condivisione pubblica",
"Toggle space public sharing": "Attiva/disattiva la condivisione pubblica nello spazio", "Toggle space public sharing": "Attiva/disattiva la condivisione pubblica nello spazio",
"Allow viewers to comment": "Consenti agli utenti di commentare",
"Allow viewers to add comments on pages in this space.": "Consenti agli utenti di aggiungere commenti alle pagine in questo spazio.",
"Toggle viewer comments": "Attiva/disattiva i commenti degli utenti",
"Public sharing is disabled at the workspace level": "La condivisione pubblica è disabilitata a livello di area di lavoro", "Public sharing is disabled at the workspace level": "La condivisione pubblica è disabilitata a livello di area di lavoro",
"Prevent pages in this space from being shared publicly.": "Impedisci che le pagine in questo spazio vengano condivise pubblicamente.", "Prevent pages in this space from being shared publicly.": "Impedisci che le pagine in questo spazio vengano condivise pubblicamente.",
"Requires an enterprise license": "Richiede una licenza enterprise",
"Page permissions": "Autorizzazioni della pagina.", "Page permissions": "Autorizzazioni della pagina.",
"Control who can view and edit individual pages. Available with an enterprise license.": "Controlla chi può visualizzare e modificare le singole pagine. Disponibile con una licenza Enterprise.", "Control who can view and edit individual pages. Available with an enterprise license.": "Controlla chi può visualizzare e modificare le singole pagine. Disponibile con una licenza Enterprise.",
"Enable public sharing": "Abilita la condivisione pubblica", "Enable public sharing": "Abilita la condivisione pubblica",
@@ -456,31 +479,32 @@
"Page duplicated successfully": "Pagina duplicata con successo", "Page duplicated successfully": "Pagina duplicata con successo",
"Find": "Trova", "Find": "Trova",
"Not found": "Non trovato", "Not found": "Non trovato",
"Previous Match (Shift+Enter)": "Corrispondenza precedente (Shift+Invio)", "Previous Match (Shift+Enter)": "Corrispondenza precedente (Maiusc+Invio)",
"Next match (Enter)": "Corrispondenza successiva (Invio)", "Next match (Enter)": "Corrispondenza successiva (Invio)",
"Match case (Alt+C)": "Maiuscole/minuscole (Alt+C)", "Match case (Alt+C)": "Distingui maiuscole/minuscole (Alt+C)",
"Replace": "Sostituisci", "Replace": "Sostituisci",
"Close (Escape)": "Chiudi (Esc)", "Close (Escape)": "Chiudi (Esc)",
"Replace (Enter)": "Sostituisci (Invio)", "Replace (Enter)": "Sostituisci (Invio)",
"Replace all (Ctrl+Alt+Enter)": "Sostituisci tutto (Ctrl+Alt+Invio)", "Replace all (Ctrl+Alt+Enter)": "Sostituisci tutto (Ctrl+Alt+Invio)",
"Replace all": "Sostituisci tutto", "Replace all": "Sostituisci tutto",
"View all": "Visualizza tutto",
"View all spaces": "Visualizza tutti gli spazi", "View all spaces": "Visualizza tutti gli spazi",
"Error": "Errore", "Error": "Errore",
"Failed to disable MFA": "Disabilitazione MFA non riuscita", "Failed to disable MFA": "Disattivazione MFA non riuscita",
"Disable two-factor authentication": "Disabilita autenticazione a due fattori", "Disable two-factor authentication": "Disattiva autenticazione a due fattori",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Disabilitare l'autenticazione a due fattori renderà il tuo account meno sicuro. Avrai bisogno solo della tua password per accedere.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Disabilitare l'autenticazione a due fattori renderà il tuo account meno sicuro. Avrai bisogno solo della tua password per accedere.",
"Please enter your password to disable two-factor authentication:": "Inserisci la tua password per disabilitare l'autenticazione a due fattori:", "Please enter your password to disable two-factor authentication:": "Inserisci la tua password per disabilitare l'autenticazione a due fattori:",
"Two-factor authentication has been enabled": "Autenticazione a due fattori abilitata", "Two-factor authentication has been enabled": "L'autenticazione a due fattori è stata abilitata",
"Two-factor authentication has been disabled": "Autenticazione a due fattori disabilitata", "Two-factor authentication has been disabled": "L'autenticazione a due fattori è stata disabilitata",
"2-step verification": "Verifica in 2 passaggi", "2-step verification": "Verifica in 2 passaggi",
"Protect your account with an additional verification layer when signing in.": "Proteggi il tuo account con un ulteriore livello di verifica durante l'accesso.", "Protect your account with an additional verification layer when signing in.": "Proteggi il tuo account con un ulteriore livello di verifica durante l'accesso.",
"Two-factor authentication is active on your account.": "L'autenticazione a due fattori è attiva sul tuo account.", "Two-factor authentication is active on your account.": "L'autenticazione a due fattori è attiva sul tuo account.",
"Add 2FA method": "Aggiungi metodo 2FA", "Add 2FA method": "Aggiungi metodo 2FA",
"Backup codes": "Codici di backup", "Backup codes": "Codici di backup",
"Disable": "Disabilita", "Disable": "Disattiva",
"Invalid verification code": "Codice di verifica non valido", "Invalid verification code": "Codice di verifica non valido",
"New backup codes have been generated": "Nuovi codici di backup generati", "New backup codes have been generated": "Sono stati generati nuovi codici di backup",
"Failed to regenerate backup codes": "Rigenerazione codici di backup non riuscita", "Failed to regenerate backup codes": "Rigenerazione dei codici di backup non riuscita",
"About backup codes": "Informazioni sui codici di backup", "About backup codes": "Informazioni sui codici di backup",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "I codici di backup possono essere utilizzati per accedere al tuo account se perdi l'accesso alla tua app di autenticazione. Ogni codice può essere usato solo una volta.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "I codici di backup possono essere utilizzati per accedere al tuo account se perdi l'accesso alla tua app di autenticazione. Ogni codice può essere usato solo una volta.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Puoi rigenerare nuovi codici di backup in qualsiasi momento. Questo invaliderà tutti i codici esistenti.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Puoi rigenerare nuovi codici di backup in qualsiasi momento. Questo invaliderà tutti i codici esistenti.",
@@ -490,9 +514,9 @@
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Assicurati di salvare questi codici in un luogo sicuro. I tuoi vecchi codici di backup non sono più validi.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Assicurati di salvare questi codici in un luogo sicuro. I tuoi vecchi codici di backup non sono più validi.",
"Your new backup codes": "I tuoi nuovi codici di backup", "Your new backup codes": "I tuoi nuovi codici di backup",
"I've saved my backup codes": "Ho salvato i miei codici di backup", "I've saved my backup codes": "Ho salvato i miei codici di backup",
"Failed to setup MFA": "Impostazione MFA non riuscita", "Failed to setup MFA": "Configurazione MFA non riuscita",
"Setup & Verify": "Imposta e Verifica", "Setup & Verify": "Configura e verifica",
"Add to authenticator": "Aggiungi ad authenticator", "Add to authenticator": "Aggiungi all'autenticatore",
"1. Scan this QR code with your authenticator app": "1. Scansiona questo codice QR con la tua app di autenticazione", "1. Scan this QR code with your authenticator app": "1. Scansiona questo codice QR con la tua app di autenticazione",
"Can't scan the code?": "Non riesci a scansionare il codice?", "Can't scan the code?": "Non riesci a scansionare il codice?",
"Enter this code manually in your authenticator app:": "Inserisci questo codice manualmente nella tua app di autenticazione:", "Enter this code manually in your authenticator app:": "Inserisci questo codice manualmente nella tua app di autenticazione:",
@@ -506,17 +530,17 @@
"Print": "Stampa", "Print": "Stampa",
"Two-factor authentication has been set up. Please log in again.": "L'autenticazione a due fattori è stata impostata. Effettua nuovamente l'accesso, per favore.", "Two-factor authentication has been set up. Please log in again.": "L'autenticazione a due fattori è stata impostata. Effettua nuovamente l'accesso, per favore.",
"Two-Factor authentication required": "Autenticazione a due fattori richiesta", "Two-Factor authentication required": "Autenticazione a due fattori richiesta",
"Your workspace requires two-factor authentication for all users": "Il tuo spazio di lavoro richiede l'autenticazione a due fattori per tutti gli utenti", "Your workspace requires two-factor authentication for all users": "Il tuo workspace richiede l'autenticazione a due fattori per tutti gli utenti",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Per continuare ad accedere al tuo spazio di lavoro, devi impostare l'autenticazione a due fattori. Questo aggiunge un ulteriore livello di sicurezza al tuo account.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Per continuare ad accedere al tuo spazio di lavoro, devi impostare l'autenticazione a due fattori. Questo aggiunge un ulteriore livello di sicurezza al tuo account.",
"Set up two-factor authentication": "Imposta l'autenticazione a due fattori", "Set up two-factor authentication": "Configura l'autenticazione a due fattori",
"Cancel and logout": "Annulla e disconnetti", "Cancel and logout": "Annulla e disconnettiti",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Il tuo spazio di lavoro richiede l'autenticazione a due fattori. Impostala per continuare.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Il tuo spazio di lavoro richiede l'autenticazione a due fattori. Impostala per continuare.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Questo aggiunge un ulteriore livello di sicurezza al tuo account richiedendo un codice di verifica dalla tua app di autenticazione.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Questo aggiunge un ulteriore livello di sicurezza al tuo account richiedendo un codice di verifica dalla tua app di autenticazione.",
"Password is required": "La password è richiesta", "Password is required": "La password è obbligatoria",
"Password must be at least 8 characters": "La password deve essere di almeno 8 caratteri", "Password must be at least 8 characters": "La password deve contenere almeno 8 caratteri",
"Please enter a 6-digit code": "Inserisci un codice a 6 cifre", "Please enter a 6-digit code": "Inserisci un codice di 6 cifre",
"Code must be exactly 6 digits": "Il codice deve essere esattamente di 6 cifre", "Code must be exactly 6 digits": "Il codice deve essere esattamente di 6 cifre",
"Enter the 6-digit code found in your authenticator app": "Inserisci il codice a 6 cifre trovato nella tua app di autenticazione", "Enter the 6-digit code found in your authenticator app": "Inserisci il codice di 6 cifre presente nella tua app di autenticazione",
"Need help authenticating?": "Hai bisogno di aiuto per autenticarti?", "Need help authenticating?": "Hai bisogno di aiuto per autenticarti?",
"MFA QR Code": "Codice QR MFA", "MFA QR Code": "Codice QR MFA",
"Account created successfully. Please log in to set up two-factor authentication.": "Account creato con successo. Effettua l'accesso per impostare l'autenticazione a due fattori.", "Account created successfully. Please log in to set up two-factor authentication.": "Account creato con successo. Effettua l'accesso per impostare l'autenticazione a due fattori.",
@@ -524,7 +548,7 @@
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Reimpostazione della password riuscita. Accedi con la tua nuova password per impostare l'autenticazione a due fattori.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Reimpostazione della password riuscita. Accedi con la tua nuova password per impostare l'autenticazione a due fattori.",
"Password reset was successful. Please log in with your new password.": "Reimpostazione della password riuscita. Accedi con la tua nuova password.", "Password reset was successful. Please log in with your new password.": "Reimpostazione della password riuscita. Accedi con la tua nuova password.",
"Two-factor authentication": "Autenticazione a due fattori", "Two-factor authentication": "Autenticazione a due fattori",
"Use authenticator app instead": "Usa l'app di autenticazione invece", "Use authenticator app instead": "Usa invece l'app di autenticazione",
"Verify backup code": "Verifica codice di backup", "Verify backup code": "Verifica codice di backup",
"Use backup code": "Usa codice di backup", "Use backup code": "Usa codice di backup",
"Enter one of your backup codes": "Inserisci uno dei tuoi codici di backup", "Enter one of your backup codes": "Inserisci uno dei tuoi codici di backup",
@@ -557,20 +581,20 @@
"Find a space": "Trova uno spazio", "Find a space": "Trova uno spazio",
"Search in all your spaces": "Cerca in tutti i tuoi spazi", "Search in all your spaces": "Cerca in tutti i tuoi spazi",
"Type": "Tipo", "Type": "Tipo",
"Enterprise": "Impresa", "Enterprise": "Enterprise",
"Download attachment": "Scarica allegato", "Download attachment": "Scarica allegato",
"Allowed email domains": "Domini email consentiti", "Allowed email domains": "Domini email consentiti",
"Only users with email addresses from these domains can signup via SSO.": "Solo gli utenti con indirizzi email provenienti da questi domini possono registrarsi tramite SSO.", "Only users with email addresses from these domains can signup via SSO.": "Solo gli utenti con indirizzi email di questi domini possono registrarsi tramite SSO.",
"Enter valid domain names separated by comma or space": "Inserisci nomi di dominio validi separati da virgole o spazi", "Enter valid domain names separated by comma or space": "Inserisci nomi di dominio validi separati da virgola o spazio",
"Enforce two-factor authentication": "Imponi l'autenticazione a due fattori", "Enforce two-factor authentication": "Rendi obbligatoria l'autenticazione a due fattori",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Una volta impostata, tutti i membri devono abilitare l'autenticazione a due fattori per accedere all'area di lavoro.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Una volta impostata, tutti i membri devono abilitare l'autenticazione a due fattori per accedere all'area di lavoro.",
"Toggle MFA enforcement": "Attiva disattiva l'applicazione MFA", "Toggle MFA enforcement": "Attiva/disattiva obbligatorietà MFA",
"Display name": "Nome visualizzato", "Display name": "Nome visualizzato",
"Allow signup": "Consenti iscrizione", "Allow signup": "Consenti registrazione",
"Enabled": "Abilitato", "Enabled": "Abilitato",
"Advanced Settings": "Impostazioni avanzate", "Advanced Settings": "Impostazioni avanzate",
"Enable TLS/SSL": "Abilita TLS/SSL", "Enable TLS/SSL": "Abilita TLS/SSL",
"Use secure connection to LDAP server": "Usa connessione sicura al server LDAP", "Use secure connection to LDAP server": "Usa una connessione sicura al server LDAP",
"Group sync": "Sincronizzazione gruppi", "Group sync": "Sincronizzazione gruppi",
"No SSO providers found.": "Nessun provider SSO trovato.", "No SSO providers found.": "Nessun provider SSO trovato.",
"Delete SSO provider": "Elimina provider SSO", "Delete SSO provider": "Elimina provider SSO",
@@ -613,6 +637,7 @@
"AI Answer": "Risposta AI", "AI Answer": "Risposta AI",
"Ask AI": "Chiedi all'AI", "Ask AI": "Chiedi all'AI",
"AI is thinking...": "L'AI sta pensando...", "AI is thinking...": "L'AI sta pensando...",
"Thinking": "Sto pensando",
"Ask a question...": "Fai una domanda...", "Ask a question...": "Fai una domanda...",
"AI Answers": "Risposte AI", "AI Answers": "Risposte AI",
"AI-powered search (AI Answers)": "Ricerca con AI (Risposte AI)", "AI-powered search (AI Answers)": "Ricerca con AI (Risposte AI)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "AI generativa (Chiedi AI)", "Generative AI (Ask AI)": "AI generativa (Chiedi AI)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Abilita la generazione di contenuti con AI nell'editor. Consente agli utenti di generare, migliorare, tradurre e trasformare il testo.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Abilita la generazione di contenuti con AI nell'editor. Consente agli utenti di generare, migliorare, tradurre e trasformare il testo.",
"Toggle generative AI": "Attiva/Disattiva AI generativa", "Toggle generative AI": "Attiva/Disattiva AI generativa",
"Enterprise feature": "Funzionalità Enterprise", "Upgrade your plan": "Aggiorna il tuo piano",
"Available with a paid license": "Disponibile con una licenza a pagamento",
"Upgrade your license tier.": "Aggiorna il livello della tua licenza.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "L'IA è disponibile solo nell'edizione Enterprise di Docmost. Contatta sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "L'IA è disponibile solo nell'edizione Enterprise di Docmost. Contatta sales@docmost.com.",
"AI & MCP": "IA e MCP", "AI & MCP": "IA e MCP",
"AI": "IA", "AI": "IA",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Model Context Protocol (MCP)", "Model Context Protocol (MCP)": "Model Context Protocol (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Abilita il server MCP per consentire ad assistenti e strumenti IA di interagire con i contenuti del tuo spazio di lavoro.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Abilita il server MCP per consentire ad assistenti e strumenti IA di interagire con i contenuti del tuo spazio di lavoro.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP è disponibile solo nell'edizione Enterprise di Docmost. Contatta sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP è disponibile solo nell'edizione Enterprise di Docmost. Contatta sales@docmost.com.",
"MCP documentation": "Documentazione MCP",
"MCP Server URL": "URL del server MCP", "MCP Server URL": "URL del server MCP",
"Use your API key for authentication. You can manage API keys in your account settings.": "Usa la tua chiave API per l'autenticazione. Puoi gestire le chiavi API nelle impostazioni del tuo account.", "Use your API key for authentication. You can manage API keys in your account settings.": "Usa la tua chiave API per l'autenticazione. Puoi gestire le chiavi API nelle impostazioni del tuo account.",
"Supported tools": "Strumenti supportati", "Supported tools": "Strumenti supportati",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Il tuo spazio di lavoro ha MCP abilitato. Usa la tua chiave API per collegare gli assistenti IA.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Il tuo spazio di lavoro ha MCP abilitato. Usa la tua chiave API per collegare gli assistenti IA.",
"MCP server URL:": "URL del server MCP:", "MCP server URL:": "URL del server MCP:",
"Learn more": "Scopri di più", "Learn more": "Scopri di più",
"View the": "Visualizza la", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Gestisci le API key per tutti gli utenti nello spazio di lavoro. Consulta la <anchor>documentazione API</anchor> per i dettagli sull'utilizzo.",
"for usage details.": "per i dettagli sull'utilizzo.", "View the <anchor>API documentation</anchor> for usage details.": "Consulta la <anchor>documentazione API</anchor> per i dettagli sull'utilizzo.",
"for setup instructions.": "per le istruzioni di configurazione.", "View the <anchor>MCP documentation</anchor>.": "Consulta la <anchor>documentazione MCP</anchor>.",
"API documentation": "Documentazione API",
"Sources": "Fonti", "Sources": "Fonti",
"AI Answers not available for attachments": "Risposte AI non disponibili per gli allegati", "AI Answers not available for attachments": "Risposte AI non disponibili per gli allegati",
"No answer available": "Nessuna risposta disponibile", "No answer available": "Nessuna risposta disponibile",
@@ -654,12 +679,34 @@
"Mark all as read": "Segna tutto come letto", "Mark all as read": "Segna tutto come letto",
"Mark as read": "Segna come letto", "Mark as read": "Segna come letto",
"More options": "Altre opzioni", "More options": "Altre opzioni",
"mentioned you in a comment": "ti ha menzionato in un commento", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> ti ha menzionato in un commento",
"commented on a page": "ha commentato una pagina", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> ha commentato una pagina",
"resolved a comment": "ha risolto un commento", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> ha risolto un commento",
"mentioned you on a page": "ti ha menzionato in una pagina", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> ti ha menzionato in una pagina",
"gave you edit access to a page": "ti ha concesso l'accesso per modificare una pagina", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> ti ha dato accesso in modifica a una pagina",
"gave you view access to a page": "ti ha concesso l'accesso per visualizzare una pagina", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> ti ha dato accesso in visualizzazione a una pagina",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> ha aggiornato una pagina",
"Watch page": "Segui pagina",
"Stop watching": "Smetti di seguire",
"Watch space": "Segui spazio",
"Stop watching space": "Smetti di seguire lo spazio",
"Email notifications": "Notifiche email",
"Page updates": "Aggiornamenti pagina",
"Get notified when pages you watch are updated.": "Ricevi una notifica quando le pagine che segui vengono aggiornate.",
"Page mentions": "Menzioni nella pagina",
"Get notified when someone mentions you on a page.": "Ricevi una notifica quando qualcuno ti menziona su una pagina.",
"Comment mentions": "Menzioni nei commenti",
"Get notified when someone mentions you in a comment.": "Ricevi una notifica quando qualcuno ti menziona in un commento.",
"New comments": "Nuovi commenti",
"Get notified about new comments on threads you participate in.": "Ricevi una notifica sui nuovi commenti nelle discussioni a cui partecipi.",
"Resolved comments": "Commenti risolti",
"Get notified when your comment is resolved.": "Ricevi una notifica quando il tuo commento viene risolto.",
"You are now watching this page": "Ora stai seguendo questa pagina",
"You are no longer watching this page": "Non stai più seguendo questa pagina",
"You are now watching this space": "Ora stai seguendo questo spazio",
"You are no longer watching this space": "Non stai più seguendo questo spazio",
"Direct": "Diretto",
"Updates": "Aggiornamenti",
"Today": "Oggi", "Today": "Oggi",
"Yesterday": "Ieri", "Yesterday": "Ieri",
"This week": "Questa settimana", "This week": "Questa settimana",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Impossibile aggiornare la conservazione del cestino", "Failed to update trash retention": "Impossibile aggiornare la conservazione del cestino",
"Removed page restriction": "Restrizione della pagina rimossa", "Removed page restriction": "Restrizione della pagina rimossa",
"Added page permission": "Permesso sulla pagina aggiunto", "Added page permission": "Permesso sulla pagina aggiunto",
"Removed page permission": "Permesso sulla pagina rimosso" "Removed page permission": "Permesso sulla pagina rimosso",
"day": "giorno",
"days": "giorni",
"week": "settimana",
"weeks": "settimane",
"month": "mese",
"months": "mesi",
"year": "anno",
"years": "anni",
"Period": "Periodo",
"Fixed date": "Data fissa",
"Indefinitely": "A tempo indeterminato",
"Days": "Giorni",
"Weeks": "Settimane",
"Months": "Mesi",
"Years": "Anni",
"Pick a date": "Scegli una data",
"Maximum is {{max}} {{unit}} for this unit": "Il massimo consentito è {{max}} {{unit}} per questa unità",
"Never expires. Verifiers can re-verify at any time.": "Non scade mai. I verificatori possono verificare nuovamente in qualsiasi momento.",
"Verified": "Verificato",
"Review needed": "Revisione necessaria",
"Verification expired": "Verifica scaduta",
"Draft": "Bozza",
"In Approval": "In approvazione",
"In approval": "In approvazione",
"Approved": "Approvato",
"Obsolete": "Obsoleto",
"Expiring": "In scadenza",
"Set up verification": "Configura la verifica",
"Verify page": "Verifica la pagina",
"Page verification": "Verifica della pagina",
"Add verification": "Aggiungi verifica",
"Edit verification": "Modifica verifica",
"Search by title": "Cerca per titolo",
"Choose how this page should stay accurate.": "Scegli come mantenere accurata questa pagina.",
"Recurring verification": "Verifica ricorrente",
"Verifiers re-confirm this page on a schedule.": "I verificatori riconfermano questa pagina secondo una pianificazione.",
"Re-verify on a schedule (e.g every 30 days )": "Verifica nuovamente secondo una pianificazione (ad es. ogni 30 giorni)",
"Page stays editable at all times": "La pagina resta sempre modificabile",
"Best for runbooks, FAQs, living documentation": "Ideale per runbook, FAQ e documentazione dinamica",
"Approval workflow": "Flusso di approvazione",
"Formal document lifecycle with named approvers.": "Ciclo di vita formale del documento con approvatori nominati.",
"Draft → In approval → Approved → Obsolete": "Bozza → In approvazione → Approvato → Obsoleto",
"Locked once approved, with full history": "Bloccato una volta approvato, con cronologia completa",
"Designed for ISO 9001, ISO 13485, and FDA": "Progettato per ISO 9001, ISO 13485 e FDA",
"Best for SOPs and controlled documents": "Ideale per SOP e documenti controllati",
"Back": "Indietro",
"Quality management": "Gestione della qualità",
"Recurring": "Ricorrente",
"Pages move through draft, approval, and approved stages.": "Le pagine passano attraverso le fasi di bozza, approvazione e approvato.",
"Verifiers": "Verificatori",
"Add verifier": "Aggiungi verificatore",
"I've reviewed this page for accuracy": "Ho controllato l'accuratezza di questa pagina",
"Set up": "Configura",
"Remove verification": "Rimuovi verifica",
"Are you sure you want to remove verification from this page?": "Sei sicuro di voler rimuovere la verifica da questa pagina?",
"Assigned verifiers must periodically re-verify this page.": "I verificatori assegnati devono verificare nuovamente questa pagina periodicamente.",
"Last verified by {{name}} {{time}} (expired)": "Ultima verifica effettuata da {{name}} {{time}} (scaduta)",
"The fixed expiration date has passed.": "La data di scadenza fissa è trascorsa.",
"Verified by {{name}} {{time}}": "Verificato da {{name}} {{time}}",
"Expires {{date}}": "Scade il {{date}}",
"Expired {{date}}": "Scaduto il {{date}}",
"Mark as obsolete": "Contrassegna come obsoleto",
"Mark obsolete": "Contrassegna come obsoleto",
"Returned by {{name}} {{time}}": "Restituito da {{name}} {{time}}",
"No approval has been requested yet.": "Non è stata ancora richiesta alcuna approvazione.",
"Submitted by {{name}} {{time}}": "Inviato da {{name}} {{time}}",
"Someone": "Qualcuno",
"Approved by {{name}} {{time}}": "Approvato da {{name}} {{time}}",
"This document has been marked as obsolete.": "Questo documento è stato contrassegnato come obsoleto.",
"Rejection comment": "Commento di rifiuto",
"Reason for returning this document...": "Motivo della restituzione di questo documento...",
"Confirm rejection": "Conferma rifiuto",
"Submit for approval": "Invia per approvazione",
"Reject": "Rifiuta",
"Approve": "Approva",
"Re-submit for approval": "Invia nuovamente per approvazione",
"Verified until": "Verificato fino al",
"QMS": "QMS",
"Verified pages": "Pagine verificate",
"Search pages...": "Cerca pagine...",
"Filter by space": "Filtra per spazio",
"Filter by type": "Filtra per tipo",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> ha verificato una pagina",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> ha inviato una pagina per la tua approvazione",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> ha restituito una pagina per la revisione",
"Page verification expires soon": "La verifica della pagina scadrà presto",
"Page verification has expired": "La verifica della pagina è scaduta",
"Verifying your email": "Verifica della tua email in corso",
"Please wait...": "Attendere...",
"Verification failed. The link may have expired.": "Verifica non riuscita. Il link potrebbe essere scaduto.",
"Check your email": "Controlla la tua email",
"We sent a verification link to {{email}}.": "Abbiamo inviato un link di verifica a {{email}}.",
"We sent a verification link to your email.": "Abbiamo inviato un link di verifica alla tua email.",
"Click the link to verify your email and access your workspace.": "Clicca sul link per verificare la tua email e accedere al tuo workspace.",
"Resend verification email": "Invia nuovamente email di verifica",
"Verification email sent. Please check your inbox.": "Email di verifica inviata. Controlla la tua casella di posta.",
"Failed to resend verification email. Please try again.": "Invio dell'email di verifica non riuscito. Si prega di riprovare.",
"We've sent you an email with your associated workspaces.": "Ti abbiamo inviato un'email con i workspace associati.",
"Load more": "Carica altro",
"Log out of all devices": "Disconnetti da tutti i dispositivi",
"Log out of all sessions except this device": "Disconnetti da tutte le sessioni tranne questo dispositivo",
"This Device": "Questo dispositivo",
"Unknown device": "Dispositivo sconosciuto",
"No active sessions": "Nessuna sessione attiva",
"Session revoked": "Sessione revocata",
"All other sessions revoked": "Tutte le altre sessioni sono state revocate",
"Last used": "Ultimo utilizzo",
"Created": "Creato",
"Rename": "Rinomina",
"Publish": "Pubblica",
"Security": "Sicurezza",
"Enforce SSO": "Rendi obbligatorio SSO",
"Once enforced, members will not be able to login with email and password.": "Una volta reso obbligatorio, i membri non potranno accedere con email e password.",
"AI-generated content may not be accurate.": "I contenuti generati dall'IA potrebbero non essere accurati.",
"AI Chat": "Chat IA",
"Analyze for insights": "Analizza per ottenere approfondimenti",
"Ask anything...": "Chiedi qualsiasi cosa...",
"Chat history": "Cronologia chat",
"Chat name": "Nome chat",
"Close": "Chiudi",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Caricamento della chat non riuscito. Si è verificato un errore.",
"Failed to render this message.": "Impossibile visualizzare questo messaggio.",
"How can I help you today?": "Come posso aiutarti oggi?",
"New chat": "Nuova chat",
"No chat history": "Nessuna cronologia chat",
"No chats found": "Nessuna chat trovata",
"No conversations yet": "Nessuna conversazione al momento",
"Open full page": "Apri pagina completa",
"Previous 7 days": "Ultimi 7 giorni",
"Previous 30 days": "Ultimi 30 giorni",
"Search chats...": "Cerca nelle chat...",
"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",
"Translate this page": "Traduci questa pagina",
"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?"
} }
+304 -117
View File
@@ -7,6 +7,7 @@
"Add members": "メンバーを追加", "Add members": "メンバーを追加",
"Add to groups": "グループに追加", "Add to groups": "グループに追加",
"Add space members": "スペースメンバーを追加", "Add space members": "スペースメンバーを追加",
"Add to favorites": "お気に入りに追加",
"Admin": "管理者", "Admin": "管理者",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "このグループを削除してもよろしいですか? メンバーはこのグループがアクセス権を持つリソースにアクセスできなくなります。", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "このグループを削除してもよろしいですか? メンバーはこのグループがアクセス権を持つリソースにアクセスできなくなります。",
"Are you sure you want to delete this page?": "このページを削除してもよろしいですか?", "Are you sure you want to delete this page?": "このページを削除してもよろしいですか?",
@@ -44,15 +45,15 @@
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "このページを削除してもよろしいですか?子ページとページ履歴も削除されます。この操作は取り消せません。", "Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "このページを削除してもよろしいですか?子ページとページ履歴も削除されます。この操作は取り消せません。",
"Description": "説明", "Description": "説明",
"Details": "詳細", "Details": "詳細",
"e.g ACME": "例: 山田太郎", "e.g ACME": "例: ACME",
"e.g ACME Inc": "例: 株式会社サンプル", "e.g ACME Inc": "例: ACME Inc",
"e.g Developers": "例: エンジニア", "e.g Developers": "例: 開発者",
"e.g Group for developers": "例: 開発チーム", "e.g Group for developers": "例: 開発者向けグループ",
"e.g product": "例: product", "e.g product": "例: product",
"e.g Product Team": "例: プロダクトチーム", "e.g Product Team": "例: プロダクトチーム",
"e.g Sales": "例: 営業", "e.g Sales": "例: 営業",
"e.g Space for product team": "例: プロダクトチーム用スペース", "e.g Space for product team": "例: プロダクトチーム用スペース",
"e.g Space for sales team to collaborate": "例: 営業チームスペース", "e.g Space for sales team to collaborate": "例: 営業チームがコラボレーションするためのスペース",
"Edit": "編集", "Edit": "編集",
"Read": "閲覧", "Read": "閲覧",
"Edit group": "グループを編集", "Edit group": "グループを編集",
@@ -74,6 +75,9 @@
"Failed to import pages": "ページのインポートに失敗しました", "Failed to import pages": "ページのインポートに失敗しました",
"Failed to load page. An error occurred.": "ページの読み込みに失敗しました。エラーが発生しました。", "Failed to load page. An error occurred.": "ページの読み込みに失敗しました。エラーが発生しました。",
"Failed to update data": "データの更新に失敗しました", "Failed to update data": "データの更新に失敗しました",
"Favorite spaces": "お気に入りのスペース",
"Favorite spaces appear here": "お気に入りのスペースがここに表示されます",
"Favorites": "お気に入り",
"Full access": "フルアクセス", "Full access": "フルアクセス",
"Full page width": "フルページ幅で表示", "Full page width": "フルページ幅で表示",
"Full width": "左右の余白を縮小", "Full width": "左右の余白を縮小",
@@ -87,11 +91,12 @@
"Import pages": "ページをインポート", "Import pages": "ページをインポート",
"Import pages & space settings": "ページとスペース設定をインポート", "Import pages & space settings": "ページとスペース設定をインポート",
"Importing pages": "ページをインポートしています", "Importing pages": "ページをインポートしています",
"invalid invitation link": "無効な招待リンクです", "invalid invitation link": "招待リンクが無効です",
"Invitation signup": "招待登録", "Invitation signup": "招待登録",
"Invite by email": "メールアドレスで招待する", "Invite by email": "メールアドレスで招待する",
"Invite members": "メンバーを招待する", "Invite members": "メンバーを招待する",
"Invite new members": "新しいメンバーを招待する", "Invite new members": "新しいメンバーを招待する",
"Invite People": "ユーザーを招待",
"Invited members who are yet to accept their invitation will appear here.": "招待を承諾していないメンバーがここに表示されます", "Invited members who are yet to accept their invitation will appear here.": "招待を承諾していないメンバーがここに表示されます",
"Invited members will be granted access to spaces the groups can access": "招待されたメンバーはグループがアクセスできるスペースにアクセスできます", "Invited members will be granted access to spaces the groups can access": "招待されたメンバーはグループがアクセスできるスペースにアクセスできます",
"Join the workspace": "ワークスペースに参加", "Join the workspace": "ワークスペースに参加",
@@ -139,6 +144,7 @@
"Profile": "プロフィール", "Profile": "プロフィール",
"Recently updated": "最近の更新", "Recently updated": "最近の更新",
"Remove": "削除", "Remove": "削除",
"Remove from favorites": "お気に入りから削除",
"Remove group member": "グループメンバーを削除", "Remove group member": "グループメンバーを削除",
"Remove space member": "スペースメンバーを削除", "Remove space member": "スペースメンバーを削除",
"Restore": "復元", "Restore": "復元",
@@ -151,37 +157,38 @@
"Search...": "検索", "Search...": "検索",
"Select language": "言語を選択", "Select language": "言語を選択",
"Select role": "ロールを選択", "Select role": "ロールを選択",
"Select role to assign to all invited members": "招待するメンバーに割り当てるロールを選択", "Select role to assign to all invited members": "招待したすべてのメンバーに割り当てるロールを選択",
"Select theme": "テーマを選択", "Select theme": "テーマを選択",
"Send invitation": "招待を送", "Send invitation": "招待を送",
"Invitation sent": "招待を送信しました", "Invitation sent": "招待を送信しました",
"Settings": "設定", "Settings": "設定",
"Setup workspace": "ワークスペースを設定する", "Setup workspace": "ワークスペースを設定",
"Sign In": "サインイン", "Sign In": "サインイン",
"Sign Up": "新規登録", "Sign Up": "サインアップ",
"Slug": "スラッグURL識別子)", "Slug": "スラッグ",
"Space": "スペース", "Space": "スペース",
"Space description": "スペース説明", "Space description": "スペース説明",
"Space menu": "スペースメニュー", "Space menu": "スペースメニュー",
"Space name": "スペース名", "Space name": "スペース名",
"Space settings": "スペース設定", "Space settings": "スペース設定",
"Space slug": "スペーススラッグURL識別子)", "Space slug": "スペーススラッグ",
"Spaces": "スペース", "Spaces": "スペース",
"Spaces you belong to": "所属しているスペース", "Spaces you belong to": "所属しているスペース",
"No space found": "スペースが見つかりません", "No space found": "スペースが見つかりません",
"Search for spaces": "スペースを検索", "Search for spaces": "スペースを検索",
"Start typing to search...": "入力して検索", "Start typing to search...": "入力して検索",
"Status": "ステータス", "Status": "ステータス",
"Successfully imported": "インポートました", "Successfully imported": "正常にインポートされました",
"Successfully restored": "復元しました", "Successfully restored": "正常に復元されました",
"System settings": "システム設定", "System settings": "システム設定",
"Templates": "テンプレート",
"Theme": "テーマ", "Theme": "テーマ",
"To change your email, you have to enter your password and new email.": "メールアドレスを変更するには、パスワードと新しいメールアドレスを入力してください", "To change your email, you have to enter your password and new email.": "メールアドレスを変更するには、パスワードと新しいメールアドレスを入力してください",
"Toggle full page width": "ページを切り替え", "Toggle full page width": "ページ全幅表示を切り替え",
"Unable to import pages. Please try again.": "ページをインポートできませんでした。もう一度お試しください", "Unable to import pages. Please try again.": "ページをインポートできませんでした。もう一度お試しください",
"untitled": "無題", "untitled": "無題",
"Untitled": "無題", "Untitled": "無題",
"Updated successfully": "更新しました", "Updated successfully": "正常に更新されました",
"User": "ユーザー", "User": "ユーザー",
"Workspace": "ワークスペース", "Workspace": "ワークスペース",
"Workspace Name": "ワークスペース名", "Workspace Name": "ワークスペース名",
@@ -189,16 +196,16 @@
"You can change your password here.": "パスワードを変更できます", "You can change your password here.": "パスワードを変更できます",
"Your Email": "メールアドレス", "Your Email": "メールアドレス",
"Your import is complete.": "インポートが完了しました", "Your import is complete.": "インポートが完了しました",
"Your name": "名前", "Your name": "あなたの名前",
"Your Name": "名前", "Your Name": "あなたの名前",
"Your password": "パスワード", "Your password": "パスワード",
"Your password must be a minimum of 8 characters.": "パスワードは8文字以上にしてください", "Your password must be a minimum of 8 characters.": "パスワードは8文字以上にしてください",
"Sidebar toggle": "サイドバー切り替え", "Sidebar toggle": "サイドバー切り替え",
"Comments": "コメント", "Comments": "コメント",
"404 page not found": "404 ページが見つかりません", "404 page not found": "404 ページが見つかりません",
"Sorry, we can't find the page you are looking for.": "お探しのページが見つかりません", "Sorry, we can't find the page you are looking for.": "お探しのページが見つかりません",
"Take me back to homepage": "ホームに戻る", "Take me back to homepage": "ホームページに戻る",
"Forgot password": "パスワードを忘れた", "Forgot password": "パスワードを忘れた場合",
"Forgot your password?": "パスワードを忘れましたか?", "Forgot your password?": "パスワードを忘れましたか?",
"A password reset link has been sent to your email. Please check your inbox.": "パスワードリセット用のリンクをメールに送信しました。受信トレイを確認してください", "A password reset link has been sent to your email. Please check your inbox.": "パスワードリセット用のリンクをメールに送信しました。受信トレイを確認してください",
"Send reset link": "リセットリンクを送信", "Send reset link": "リセットリンクを送信",
@@ -215,6 +222,8 @@
"Edit comment": "コメントを編集する", "Edit comment": "コメントを編集する",
"Delete comment": "コメントを削除する", "Delete comment": "コメントを削除する",
"Are you sure you want to delete this comment?": "このコメントを削除してもよろしいですか?", "Are you sure you want to delete this comment?": "このコメントを削除してもよろしいですか?",
"Delete chat": "チャットを削除",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "「{{title}}」を削除してもよろしいですか?この操作は元に戻せません。",
"Comment created successfully": "コメントを作成しました", "Comment created successfully": "コメントを作成しました",
"Error creating comment": "コメントの作成に失敗しました", "Error creating comment": "コメントの作成に失敗しました",
"Comment updated successfully": "コメントを更新しました", "Comment updated successfully": "コメントを更新しました",
@@ -222,16 +231,16 @@
"Comment deleted successfully": "コメントを削除しました", "Comment deleted successfully": "コメントを削除しました",
"Failed to delete comment": "コメントの削除に失敗しました", "Failed to delete comment": "コメントの削除に失敗しました",
"Comment resolved successfully": "コメントを解決しました", "Comment resolved successfully": "コメントを解決しました",
"Comment re-opened successfully": "コメントを再開しました", "Comment re-opened successfully": "コメントを正常に再オープンしました",
"Comment unresolved successfully": "コメントを未解決に戻しました", "Comment unresolved successfully": "コメントの解決を正常に取り消しました",
"Failed to resolve comment": "コメントの解決に失敗しました", "Failed to resolve comment": "コメントの解決に失敗しました",
"Resolve comment": "コメントを解決", "Resolve comment": "コメントを解決",
"Unresolve comment": "コメントを未解決に戻す", "Unresolve comment": "コメントの解決を取り消す",
"Resolve Comment Thread": "コメントスレッドを解決", "Resolve Comment Thread": "コメントスレッドを解決",
"Unresolve Comment Thread": "コメントスレッドを未解決に戻す", "Unresolve Comment Thread": "コメントスレッドの解決を取り消す",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "このコメントスレッドを解決しますか?完了としてマークされます", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "このコメントスレッドを解決しますか?完了としてマークされます",
"Are you sure you want to unresolve this comment thread?": "このコメントスレッドを未解決に戻しますか?", "Are you sure you want to unresolve this comment thread?": "このコメントスレッドを未解決に戻しますか?",
"Resolved": "解決済", "Resolved": "解決済",
"No active comments.": "アクティブなコメントはありません", "No active comments.": "アクティブなコメントはありません",
"Revoke invitation": "招待を取り消す", "Revoke invitation": "招待を取り消す",
"Revoke": "取り消す", "Revoke": "取り消す",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "このスペースを削除してもよろしいですか?", "Are you sure you want to delete this space?": "このスペースを削除してもよろしいですか?",
"Delete this space with all its pages and data.": "このスペースとすべてのページ、データを削除します", "Delete this space with all its pages and data.": "このスペースとすべてのページ、データを削除します",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "スペース内のすべてのページ、コメント、添付ファイル、権限が完全に削除されます", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "スペース内のすべてのページ、コメント、添付ファイル、権限が完全に削除されます",
"Confirm space name": "スペース名を確認する", "Confirm space name": "スペース名を確認",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "確認のためスペース名 <b>{{spaceName}}</b> を入力してください", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "確認のためスペース名 <b>{{spaceName}}</b> を入力してください",
"Format": "フォーマット", "Format": "フォーマット",
"Include subpages": "サブページを含める", "Include subpages": "サブページを含める",
@@ -289,6 +298,11 @@
"Save & Exit": "保存して終了", "Save & Exit": "保存して終了",
"Double-click to edit Excalidraw diagram": "ダブルクリックして Excalidraw 図を編集", "Double-click to edit Excalidraw diagram": "ダブルクリックして Excalidraw 図を編集",
"Paste link": "リンクを貼り付け", "Paste link": "リンクを貼り付け",
"Paste link or search pages": "リンクを貼り付けるかページを検索してください。 ",
"Link to web page": "ウェブページへのリンク",
"Recents": "最近使用したもの",
"Page or URL": "ページまたはURL",
"Link title": "リンクタイトル",
"Edit link": "リンクを編集", "Edit link": "リンクを編集",
"Remove link": "リンクを削除", "Remove link": "リンクを削除",
"Add link": "リンクを追加", "Add link": "リンクを追加",
@@ -307,7 +321,7 @@
"Pink": "ピンク色", "Pink": "ピンク色",
"Gray": "灰色", "Gray": "灰色",
"Embed link": "リンクを埋め込む", "Embed link": "リンクを埋め込む",
"Invalid {{provider}} embed link": "埋め込まれた {{provider}} のリンク無効です", "Invalid {{provider}} embed link": "{{provider}} の埋め込みリンク無効です",
"Embed {{provider}}": "埋め込まれた {{provider}}", "Embed {{provider}}": "埋め込まれた {{provider}}",
"Enter {{provider}} link to embed": "埋め込みたい {{provider}} のリンクを入力してください", "Enter {{provider}} link to embed": "埋め込みたい {{provider}} のリンクを入力してください",
"Bold": "太字", "Bold": "太字",
@@ -336,29 +350,36 @@
"Insert horizontal rule divider": "区切り線を挿入します", "Insert horizontal rule divider": "区切り線を挿入します",
"Upload any image from your device.": "デバイスから画像をアップロードします", "Upload any image from your device.": "デバイスから画像をアップロードします",
"Upload any video from your device.": "デバイスから動画をアップロードします", "Upload any video from your device.": "デバイスから動画をアップロードします",
"Upload any audio from your device.": "デバイスから音声ファイルをアップロードします。",
"Upload any file from your device.": "デバイスからファイルをアップロードします", "Upload any file from your device.": "デバイスからファイルをアップロードします",
"Uploading {{name}}": "{{name}} をアップロード中", "Uploading {{name}}": "{{name}} をアップロード中",
"Uploading file": "ファイルをアップロード中", "Uploading file": "ファイルをアップロード中",
"Table": "テーブル", "Table": "",
"Insert a table.": "テーブルを挿入します", "Insert a table.": "テーブルを挿入します",
"Insert collapsible block.": "折りたたみブロックを挿入します", "Insert collapsible block.": "折りたたみブロックを挿入します",
"Video": "動画", "Video": "動画",
"Divider": "区切り線", "Divider": "区切り線",
"Quote": "引用", "Quote": "引用",
"Image": "画像", "Image": "画像",
"Audio": "音声",
"Embed PDF": "PDFを埋め込む",
"Upload and embed a PDF file.": "PDFファイルをアップロードして埋め込みます。",
"Embed as PDF": "PDFとして埋め込む",
"Failed to load PDF": "PDFの読み込みに失敗しました",
"Convert to attachment": "添付ファイルに変換",
"File attachment": "ファイル添付", "File attachment": "ファイル添付",
"Toggle block": "ブロックを切り替える", "Toggle block": "トグルブロック",
"Callout": "コールアウト", "Callout": "コールアウト",
"Insert callout notice.": "コールアウトを挿入します", "Insert callout notice.": "コールアウトを挿入します",
"Math inline": "インライン数式", "Math inline": "インライン数式",
"Insert inline math equation.": "インライン数式を挿入します", "Insert inline math equation.": "インライン数式を挿入します",
"Math block": "数式ブロック", "Math block": "数式ブロック",
"Insert math equation": "数式を挿入します", "Insert math equation": "数式を挿入",
"Mermaid diagram": "Mermaid ダイアグラム", "Mermaid diagram": "Mermaid ダイアグラム",
"Insert mermaid diagram": "Mermaid ダイアグラムを挿入します", "Insert mermaid diagram": "Mermaid ダイアグラムを挿入",
"Insert and design Drawio diagrams": "Draw.io 図を挿入・編集します", "Insert and design Drawio diagrams": "Drawio ダイアグラムを挿入して作成",
"Insert current date": "現在の日付を挿入します", "Insert current date": "現在の日付を挿入",
"Draw and sketch excalidraw diagrams": "Excalidraw 図を挿入します", "Draw and sketch excalidraw diagrams": "Excalidraw ダイアグラムを描画・スケッチ",
"Multiple": "複数", "Multiple": "複数",
"Turn into": "変換する", "Turn into": "変換する",
"Text align": "テキストの配置", "Text align": "テキストの配置",
@@ -366,8 +387,8 @@
"Go to homepage": "ホームページへ移動", "Go to homepage": "ホームページへ移動",
"Pages you create will show up here.": "ここに作成したページが表示されます。", "Pages you create will show up here.": "ここに作成したページが表示されます。",
"Heading {{level}}": "見出し {{level}}", "Heading {{level}}": "見出し {{level}}",
"Toggle title": "タイトルの表示/非表示を切り替える", "Toggle title": "トグルタイトル",
"Write anything. Enter \"/\" for commands": "文字を入力するか、「/」でコマンドを呼び出します", "Write anything. Enter \"/\" for commands": "何でも入力してください。コマンドを使うには「/」を入力",
"Write...": "ここに入力...", "Write...": "ここに入力...",
"Column count": "列数", "Column count": "列数",
"{{count}} Columns": "{{count}}列", "{{count}} Columns": "{{count}}列",
@@ -378,26 +399,26 @@
"Left wide": "左ワイド", "Left wide": "左ワイド",
"Right wide": "右ワイド", "Right wide": "右ワイド",
"Names do not match": "名前が一致しません", "Names do not match": "名前が一致しません",
"Today, {{time}}": "今日{{time}}", "Today, {{time}}": "今日 {{time}}",
"Yesterday, {{time}}": "昨日{{time}}", "Yesterday, {{time}}": "昨日 {{time}}",
"Space created successfully": "スペースを作成しました", "Space created successfully": "スペースが正常に作成されました",
"Space updated successfully": "スペースを更新しました", "Space updated successfully": "スペースが正常に更新されました",
"Space deleted successfully": "スペースを削除しました", "Space deleted successfully": "スペースが正常に削除されました",
"Members added successfully": "メンバーを追加しました", "Members added successfully": "メンバーが正常に追加されました",
"Member removed successfully": "メンバーを削除しました", "Member removed successfully": "メンバーが正常に削除されました",
"Member role updated successfully": "メンバーのロールを更新しました", "Member role updated successfully": "メンバーのロールが正常に更新されました",
"Created by: <b>{{creatorName}}</b>": "作成者: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "作成者: <b>{{creatorName}}</b>",
"Created at: {{time}}": "作成日: {{time}}", "Created at: {{time}}": "作成日: {{time}}",
"Edited by {{name}} {{time}}": "最終編集: {{name}} {{time}}", "Edited by {{name}} {{time}}": "{{name}} {{time}} に編集",
"Word count: {{wordCount}}": "単語数: {{wordCount}}", "Word count: {{wordCount}}": "単語数: {{wordCount}}",
"Character count: {{characterCount}}": "文字数: {{characterCount}}", "Character count: {{characterCount}}": "文字数: {{characterCount}}",
"New update": "新規更新", "New update": "新しいアップデート",
"{{latestVersion}} is available": "{{latestVersion}} が利用可能です", "{{latestVersion}} is available": "{{latestVersion}} が利用可能です",
"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.": "お好みのページ編集モードを選択してください(誤編集を防止します)",
"Reading": "読み取り", "Reading": "閲覧",
"Delete member": "メンバーを削除する", "Delete member": "メンバーを削除",
"Member deleted successfully": "メンバーを削除しました", "Member deleted successfully": "メンバーが正常に削除されました",
"Are you sure you want to delete this workspace member? This action is irreversible.": "このメンバーを削除してもよろしいですか?この操作は取り消せません", "Are you sure you want to delete this workspace member? This action is irreversible.": "このメンバーを削除してもよろしいですか?この操作は取り消せません",
"Deactivate member": "メンバーを無効化", "Deactivate member": "メンバーを無効化",
"Activate member": "メンバーを有効化", "Activate member": "メンバーを有効化",
@@ -416,30 +437,32 @@
"Public sharing": "公開共有", "Public sharing": "公開共有",
"Shared by": "共有者", "Shared by": "共有者",
"Shared at": "共有日時", "Shared at": "共有日時",
"Inherits public sharing from": "から公開共有を継承する", "Inherits public sharing from": "公開共有を次から継承",
"Share to web": "ウェブで共有", "Share to web": "Web に公開",
"Shared to web": "ウェブに共有済み", "Shared to web": "Web に公開済み",
"Anyone with the link can view this page": "リンクをっている人はこのページを閲覧できます", "Anyone with the link can view this page": "リンクをっている人は誰でもこのページを閲覧できます",
"Make this page publicly accessible": "このページを公開します", "Make this page publicly accessible": "このページを公開アクセス可能にする",
"Include sub-pages": "サブページを含", "Include sub-pages": "サブページを含める",
"Make sub-pages public too": "サブページも公開する", "Make sub-pages public too": "サブページも公開する",
"Allow search engines to index page": "検索エンジンにページのインデックス作成を許可する", "Allow search engines to index page": "検索エンジンによるページのインデックスを許可",
"Open page": "ページを開く", "Open page": "ページを開く",
"Page": "ページ", "Page": "ページ",
"Delete public share link": "公開リンクを削除", "Delete public share link": "公開共有リンクを削除",
"Delete share": "共有を削除", "Delete share": "共有を削除",
"Are you sure you want to delete this shared link?": "この共有リンクを削除してもよろしいですか?", "Are you sure you want to delete this shared link?": "この共有リンクを削除してもよろしいですか?",
"Publicly shared pages from spaces you are a member of will appear here": "メンバーであるスペースからの公開ページがここに表示されます", "Publicly shared pages from spaces you are a member of will appear here": "あなたがメンバーであるスペースの公開共有ページがここに表示されます",
"Share deleted successfully": "共有を削除しました", "Share deleted successfully": "共有が正常に削除されました",
"Share not found": "共有が見つかりません", "Share not found": "共有が見つかりません",
"Failed to share page": "ページの共有に失敗しました", "Failed to share page": "ページの共有に失敗しました",
"Disable public sharing": "公開共有を無効にする", "Disable public sharing": "公開共有を無効にする",
"Prevent members from sharing pages publicly.": "メンバーがページを公開で共有するのを防ぐ。", "Prevent members from sharing pages publicly.": "メンバーがページを公開で共有するのを防ぐ。",
"Toggle public sharing": "公開共有を切り替える", "Toggle public sharing": "公開共有を切り替える",
"Toggle space public sharing": "スペースの公開共有を切り替える", "Toggle space public sharing": "スペースの公開共有を切り替える",
"Allow viewers to comment": "閲覧者によるコメントを許可",
"Allow viewers to add comments on pages in this space.": "このスペース内のページに閲覧者がコメントを追加できるようにします。",
"Toggle viewer comments": "閲覧者コメントの切り替え",
"Public sharing is disabled at the workspace level": "ワークスペースレベルで公開共有が無効になっています", "Public sharing is disabled at the workspace level": "ワークスペースレベルで公開共有が無効になっています",
"Prevent pages in this space from being shared publicly.": "このスペース内のページが公開で共有されるのを防ぐ。", "Prevent pages in this space from being shared publicly.": "このスペース内のページが公開で共有されるのを防ぐ。",
"Requires an enterprise license": "エンタープライズライセンスが必要です",
"Page permissions": "ページのアクセス権", "Page permissions": "ページのアクセス権",
"Control who can view and edit individual pages. Available with an enterprise license.": "個々のページを誰が表示・編集できるかを制御します。エンタープライズライセンスで利用可能です。", "Control who can view and edit individual pages. Available with an enterprise license.": "個々のページを誰が表示・編集できるかを制御します。エンタープライズライセンスで利用可能です。",
"Enable public sharing": "公開共有を有効にする", "Enable public sharing": "公開共有を有効にする",
@@ -452,56 +475,57 @@
"Public sharing has been disabled for this space.": "このスペースで公開共有が無効になりました。", "Public sharing has been disabled for this space.": "このスペースで公開共有が無効になりました。",
"Copy page": "ページをコピー", "Copy page": "ページをコピー",
"Copy page to a different space.": "ページを別のスペースにコピーします", "Copy page to a different space.": "ページを別のスペースにコピーします",
"Page copied successfully": "ページコピーました", "Page copied successfully": "ページが正常にコピーされました",
"Page duplicated successfully": "ページを複製しました", "Page duplicated successfully": "ページが正常に複製されました",
"Find": "検索", "Find": "検索",
"Not found": "見つかりません", "Not found": "見つかりません",
"Previous Match (Shift+Enter)": "前の一致 (Shift+Enter)", "Previous Match (Shift+Enter)": "前の一致 (Shift+Enter)",
"Next match (Enter)": "次の一致 (Enter)", "Next match (Enter)": "次の一致 (Enter)",
"Match case (Alt+C)": "大文字小文字を区別 (Alt+C)", "Match case (Alt+C)": "大文字小文字を区別 (Alt+C)",
"Replace": "置換", "Replace": "置換",
"Close (Escape)": "閉じる (Escape)", "Close (Escape)": "閉じる (Escape)",
"Replace (Enter)": "置換 (Enter)", "Replace (Enter)": "置換 (Enter)",
"Replace all (Ctrl+Alt+Enter)": "すべて置換 (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "すべて置換 (Ctrl+Alt+Enter)",
"Replace all": "すべて置換", "Replace all": "すべて置換",
"View all": "すべて表示",
"View all spaces": "すべてのスペースを表示", "View all spaces": "すべてのスペースを表示",
"Error": "エラー", "Error": "エラー",
"Failed to disable MFA": "MFA無効化に失敗しました", "Failed to disable MFA": "MFA無効化できませんでした",
"Disable two-factor authentication": "二要素認証を無効化", "Disable two-factor authentication": "二要素認証を無効化",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "二要素認証を無効にすると、アカウントのセキュリティが低下します。サインインにはパスワードのみが必要になります", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "二要素認証を無効にすると、アカウントのセキュリティが低下します。サインインにはパスワードのみが必要になります",
"Please enter your password to disable two-factor authentication:": "二要素認証を無効にするにはパスワードを入力してください", "Please enter your password to disable two-factor authentication:": "二要素認証を無効にするにはパスワードを入力してください",
"Two-factor authentication has been enabled": "二要素認証有効にました", "Two-factor authentication has been enabled": "二要素認証有効になりました",
"Two-factor authentication has been disabled": "二要素認証無効にました", "Two-factor authentication has been disabled": "二要素認証無効になりました",
"2-step verification": "2 段階認証", "2-step verification": "2 段階認証",
"Protect your account with an additional verification layer when signing in.": "サインイン時に追加の認証でアカウントを保護します", "Protect your account with an additional verification layer when signing in.": "サインイン時に追加の認証でアカウントを保護します",
"Two-factor authentication is active on your account.": "二要素認証が有効です", "Two-factor authentication is active on your account.": "二要素認証が有効です",
"Add 2FA method": "2FAメソッドを追加", "Add 2FA method": "2FA 方法を追加",
"Backup codes": "バックアップコード", "Backup codes": "バックアップコード",
"Disable": "無効にする", "Disable": "無効",
"Invalid verification code": "無効な認証コード", "Invalid verification code": "認証コードが無効です",
"New backup codes have been generated": "新しいバックアップコード生成ました", "New backup codes have been generated": "新しいバックアップコード生成されました",
"Failed to regenerate backup codes": "バックアップコードの再生成に失敗しました", "Failed to regenerate backup codes": "バックアップコードの再生成に失敗しました",
"About backup codes": "バックアップコードについて", "About backup codes": "バックアップコードについて",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "認証アプリにアクセスできない場合、バックアップコードでアカウントにアクセスできます。各コードは1回のみ使用可能です", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "認証アプリにアクセスできない場合、バックアップコードでアカウントにアクセスできます。各コードは1回のみ使用可能です",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "新しいバックアップコードはいつでも再生成できます。既存のコードはすべて無効になります", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "新しいバックアップコードはいつでも再生成できます。既存のコードはすべて無効になります",
"Confirm password": "パスワードを確認", "Confirm password": "パスワードを確認",
"Generate new backup codes": "新しいバックアップコードを生成", "Generate new backup codes": "新しいバックアップコードを生成",
"Save your new backup codes": "新しいバックアップコードを保存", "Save your new backup codes": "新しいバックアップコードを保存してください",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "これらのコードを安全な場所に保存してください。古いバックアップコードは無効になりました", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "これらのコードを安全な場所に保存してください。古いバックアップコードは無効になりました",
"Your new backup codes": "新しいバックアップコード", "Your new backup codes": "新しいバックアップコード",
"I've saved my backup codes": "バックアップコードを保存しました", "I've saved my backup codes": "バックアップコードを保存しました",
"Failed to setup MFA": "MFA の設定に失敗しました", "Failed to setup MFA": "MFA の設定に失敗しました",
"Setup & Verify": "設定と確認", "Setup & Verify": "設定して認証",
"Add to authenticator": "認証アプリに追加", "Add to authenticator": "認証アプリに追加",
"1. Scan this QR code with your authenticator app": "1. このQRコードを認証アプリでスキャンしてください", "1. Scan this QR code with your authenticator app": "1. 認証アプリでこの QR コードをスキャンしてください",
"Can't scan the code?": "コードをスキャンできませんか?", "Can't scan the code?": "コードをスキャンできませんか?",
"Enter this code manually in your authenticator app:": "このコードを認証アプリに手動で入力してください:", "Enter this code manually in your authenticator app:": "このコードを認証アプリに手動で入力してください:",
"2. Enter the 6-digit code from your authenticator": "2. 認証アプリからの6桁のコードを入力してください", "2. Enter the 6-digit code from your authenticator": "2. 認証アプリに表示された 6 桁のコードを入力してください",
"Verify and enable": "確認と有効化", "Verify and enable": "認証して有効化",
"Failed to generate QR code. Please try again.": "QRコードの生成に失敗しました。もう一度お試しください", "Failed to generate QR code. Please try again.": "QRコードの生成に失敗しました。もう一度お試しください",
"Backup": "バックアップ", "Backup": "バックアップ",
"Save codes": "コードを保存", "Save codes": "コードを保存",
"Save your backup codes": "バックアップコードを保存", "Save your backup codes": "バックアップコードを保存してください",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "認証アプリにアクセスできない場合、これらのコードでアカウントにアクセスできます。各コードは1回のみ使用可能です", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "認証アプリにアクセスできない場合、これらのコードでアカウントにアクセスできます。各コードは1回のみ使用可能です",
"Print": "印刷", "Print": "印刷",
"Two-factor authentication has been set up. Please log in again.": "二要素認証を設定しました。再度ログインしてください", "Two-factor authentication has been set up. Please log in again.": "二要素認証を設定しました。再度ログインしてください",
@@ -512,10 +536,10 @@
"Cancel and logout": "キャンセルしてログアウト", "Cancel and logout": "キャンセルしてログアウト",
"Your workspace requires two-factor authentication. Please set it up to continue.": "このワークスペースでは二要素認証が必要です。続行するには設定してください", "Your workspace requires two-factor authentication. Please set it up to continue.": "このワークスペースでは二要素認証が必要です。続行するには設定してください",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "認証アプリからの確認コードでアカウントのセキュリティが強化されます", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "認証アプリからの確認コードでアカウントのセキュリティが強化されます",
"Password is required": "パスワードが必要です", "Password is required": "パスワードは必須です",
"Password must be at least 8 characters": "パスワードは8文字以上必要です", "Password must be at least 8 characters": "パスワードは 8 文字以上である必要があります",
"Please enter a 6-digit code": "6 桁のコードを入力してください", "Please enter a 6-digit code": "6 桁のコードを入力してください",
"Code must be exactly 6 digits": "コードは6桁で入力してください", "Code must be exactly 6 digits": "コードはちょうど 6 桁である必要があります",
"Enter the 6-digit code found in your authenticator app": "認証アプリに表示された 6 桁のコードを入力してください", "Enter the 6-digit code found in your authenticator app": "認証アプリに表示された 6 桁のコードを入力してください",
"Need help authenticating?": "認証に関するヘルプが必要ですか?", "Need help authenticating?": "認証に関するヘルプが必要ですか?",
"MFA QR Code": "MFA QR コード", "MFA QR Code": "MFA QR コード",
@@ -525,58 +549,58 @@
"Password reset was successful. Please log in with your new password.": "パスワードをリセットしました。新しいパスワードでログインしてください", "Password reset was successful. Please log in with your new password.": "パスワードをリセットしました。新しいパスワードでログインしてください",
"Two-factor authentication": "二要素認証", "Two-factor authentication": "二要素認証",
"Use authenticator app instead": "代わりに認証アプリを使用", "Use authenticator app instead": "代わりに認証アプリを使用",
"Verify backup code": "バックアップコードを認", "Verify backup code": "バックアップコードを認",
"Use backup code": "バックアップコードを使用", "Use backup code": "バックアップコードを使用",
"Enter one of your backup codes": "バックアップコードのいずれかを入力してください", "Enter one of your backup codes": "バックアップコードのいずれか 1 つを入力してください",
"Backup code": "バックアップコード", "Backup code": "バックアップコード",
"Enter one of your backup codes. Each backup code can only be used once.": "バックアップコードを入力してください。各コードは1回のみ使用可能です", "Enter one of your backup codes. Each backup code can only be used once.": "バックアップコードを入力してください。各コードは1回のみ使用可能です",
"Verify": "認", "Verify": "認",
"Trash": "ごみ箱", "Trash": "ゴミ箱",
"Pages in trash will be permanently deleted after {{count}} days.": "{count, plural, other {ゴミ箱内のページは#日後に完全に削除されます。}}", "Pages in trash will be permanently deleted after {{count}} days.": "{count, plural, other {ゴミ箱内のページは#日後に完全に削除されます。}}",
"Deleted": "削除", "Deleted": "削除済み",
"No pages in trash": "ごみ箱にページありません", "No pages in trash": "ゴミ箱にページありません",
"Permanently delete page?": "ページを完全に削除しますか?", "Permanently delete page?": "ページを完全に削除しますか?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "「{{title}}」を完全に削除しますか?この操作は取り消せません", "Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "「{{title}}」を完全に削除しますか?この操作は取り消せません",
"Restore '{{title}}' and its sub-pages?": "「{{title}}」とそのサブページを復元しますか?", "Restore '{{title}}' and its sub-pages?": "「{{title}}」とそのサブページを復元しますか?",
"Move to trash": "ごみ箱に移動", "Move to trash": "ゴミ箱に移動",
"Move this page to trash?": "このページをごみ箱に移動しますか?", "Move this page to trash?": "このページをごみ箱に移動しますか?",
"Restore page": "ページを復元", "Restore page": "ページを復元",
"Page moved to trash": "ページをごみ箱に移動しました", "Page moved to trash": "ページをゴミ箱に移動しました",
"Page restored successfully": "ページを復元しました", "Page restored successfully": "ページが正常に復元されました",
"Deleted by": "削除者", "Deleted by": "削除者",
"Deleted at": "削除日時", "Deleted at": "削除日時",
"Preview": "プレビュー", "Preview": "プレビュー",
"Subpages": "サブページ", "Subpages": "サブページ",
"Failed to load subpages": "サブページの読み込みに失敗しました", "Failed to load subpages": "サブページの読み込みに失敗しました",
"No subpages": "サブページありません", "No subpages": "サブページありません",
"Subpages (Child pages)": "サブページ(子ページ)", "Subpages (Child pages)": "サブページ(子ページ)",
"List all subpages of the current page": "現在のページのすべてのサブページをリスト", "List all subpages of the current page": "現在のページのすべてのサブページを一覧表示",
"Attachments": "添付ファイル", "Attachments": "添付ファイル",
"All spaces": "すべてのスペース", "All spaces": "すべてのスペース",
"Unknown": "不明", "Unknown": "不明",
"Find a space": "スペースを探す", "Find a space": "スペースを探す",
"Search in all your spaces": "あなたのすべてのスペース検索", "Search in all your spaces": "すべてのスペース検索",
"Type": "タイプ", "Type": "タイプ",
"Enterprise": "エンタープライズ", "Enterprise": "エンタープライズ",
"Download attachment": "添付ファイルをダウンロード", "Download attachment": "添付ファイルをダウンロード",
"Allowed email domains": "許可されたメールドメイン", "Allowed email domains": "許可されたメールドメイン",
"Only users with email addresses from these domains can signup via SSO.": "これらのドメインのメールアドレスを持つユーザーのみSSO経由で登録できます", "Only users with email addresses from these domains can signup via SSO.": "これらのドメインのメールアドレスを持つユーザーのみSSO 経由でサインアップできます",
"Enter valid domain names separated by comma or space": "ンマまたはスペース区切って有効なドメイン名を入力してください", "Enter valid domain names separated by comma or space": "有効なドメイン名をカンマまたはスペース区切りで入力してください",
"Enforce two-factor authentication": "二要素認証を強制する", "Enforce two-factor authentication": "二要素認証を必須化",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "有効にすると、すべてのメンバーが二要素認証を設定しないとワークスペースにアクセスできなくなります", "Once enforced, all members must enable two-factor authentication to access the workspace.": "有効にすると、すべてのメンバーが二要素認証を設定しないとワークスペースにアクセスできなくなります",
"Toggle MFA enforcement": "MFAの強制を切り替え", "Toggle MFA enforcement": "MFA 必須化を切り替え",
"Display name": "表示名", "Display name": "表示名",
"Allow signup": "登録を許可する", "Allow signup": "サインアップを許可",
"Enabled": "有効", "Enabled": "有効",
"Advanced Settings": "詳細設定", "Advanced Settings": "詳細設定",
"Enable TLS/SSL": "TLS/SSLを有効にする", "Enable TLS/SSL": "TLS/SSL を有効",
"Use secure connection to LDAP server": "LDAPサーバーへの安全な接続を使用する", "Use secure connection to LDAP server": "LDAP サーバーへの安全な接続を使用",
"Group sync": "グループ同期", "Group sync": "グループ同期",
"No SSO providers found.": "SSOプロバイダーが見つかりませんでした。", "No SSO providers found.": "SSOプロバイダーが見つかりませんでした。",
"Delete SSO provider": "SSOプロバイダーを削除する", "Delete SSO provider": "SSO プロバイダーを削除",
"Are you sure you want to delete this SSO provider?": "このSSOプロバイダーを削除してもよろしいですか?", "Are you sure you want to delete this SSO provider?": "このSSOプロバイダーを削除してもよろしいですか?",
"Action": "アクション", "Action": "操作",
"{{ssoProviderType}} configuration": "{{ssoProviderType}}の構成", "{{ssoProviderType}} configuration": "{{ssoProviderType}} の設定",
"Icon": "アイコン", "Icon": "アイコン",
"Upload image": "画像をアップロード", "Upload image": "画像をアップロード",
"Remove image": "画像を削除", "Remove image": "画像を削除",
@@ -613,6 +637,7 @@
"AI Answer": "AI回答", "AI Answer": "AI回答",
"Ask AI": "AIに質問する", "Ask AI": "AIに質問する",
"AI is thinking...": "AIが考え中...", "AI is thinking...": "AIが考え中...",
"Thinking": "考えています",
"Ask a question...": "質問を入力...", "Ask a question...": "質問を入力...",
"AI Answers": "AI回答", "AI Answers": "AI回答",
"AI-powered search (AI Answers)": "AI搭載検索 (AI回答)", "AI-powered search (AI Answers)": "AI搭載検索 (AI回答)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "生成AI (Ask AI)", "Generative AI (Ask AI)": "生成AI (Ask AI)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "エディターでAIを活用したコンテンツ生成を有効にします。ユーザーがテキストの生成、改善、翻訳、および変換を行うことができます。", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "エディターでAIを活用したコンテンツ生成を有効にします。ユーザーがテキストの生成、改善、翻訳、および変換を行うことができます。",
"Toggle generative AI": "生成AIを切り替える", "Toggle generative AI": "生成AIを切り替える",
"Enterprise feature": "エンタープライズ機能", "Upgrade your plan": "プランをアップグレードする",
"Available with a paid license": "有料ライセンスで利用可能",
"Upgrade your license tier.": "ライセンスタイアをアップグレードしてください。",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI は Docmost のエンタープライズ版でのみ利用可能です。sales@docmost.com までお問い合わせください。", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI は Docmost のエンタープライズ版でのみ利用可能です。sales@docmost.com までお問い合わせください。",
"AI & MCP": "AI と MCP", "AI & MCP": "AI と MCP",
"AI": "AI", "AI": "AI",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "モデルコンテキストプロトコル(MCP)", "Model Context Protocol (MCP)": "モデルコンテキストプロトコル(MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "MCP サーバーを有効にして、AI アシスタントやツールがワークスペースのコンテンツとやり取りできるようにします。", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "MCP サーバーを有効にして、AI アシスタントやツールがワークスペースのコンテンツとやり取りできるようにします。",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP は Docmost のエンタープライズ版でのみ利用可能です。sales@docmost.com までお問い合わせください。", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP は Docmost のエンタープライズ版でのみ利用可能です。sales@docmost.com までお問い合わせください。",
"MCP documentation": "MCP ドキュメント",
"MCP Server URL": "MCP サーバーの URL", "MCP Server URL": "MCP サーバーの URL",
"Use your API key for authentication. You can manage API keys in your account settings.": "認証には API キーを使用してください。API キーはアカウント設定で管理できます。", "Use your API key for authentication. You can manage API keys in your account settings.": "認証には API キーを使用してください。API キーはアカウント設定で管理できます。",
"Supported tools": "サポートされているツール", "Supported tools": "サポートされているツール",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "このワークスペースでは MCP が有効になっています。AI アシスタントを接続するには API キーを使用してください。", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "このワークスペースでは MCP が有効になっています。AI アシスタントを接続するには API キーを使用してください。",
"MCP server URL:": "MCP サーバーの URL:", "MCP server URL:": "MCP サーバーの URL:",
"Learn more": "詳細を見る", "Learn more": "詳細を見る",
"View the": "表示", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "ワークスペース内のすべてのユーザーのAPIキーを管理します。利用方法の詳細は<anchor>APIドキュメント</anchor>をご覧ください。",
"for usage details.": "使用方法の詳細については。", "View the <anchor>API documentation</anchor> for usage details.": "用方法の詳細は<anchor>APIドキュメント</anchor>をご覧ください。",
"for setup instructions.": "設定手順については。", "View the <anchor>MCP documentation</anchor>.": "<anchor>MCPドキュメント</anchor>をご覧ください。",
"API documentation": "API ドキュメント",
"Sources": "ソース", "Sources": "ソース",
"AI Answers not available for attachments": "添付ファイルにはAI回答を利用できません", "AI Answers not available for attachments": "添付ファイルにはAI回答を利用できません",
"No answer available": "回答がありません", "No answer available": "回答がありません",
@@ -654,12 +679,34 @@
"Mark all as read": "すべてを既読にする", "Mark all as read": "すべてを既読にする",
"Mark as read": "既読にする", "Mark as read": "既読にする",
"More options": "その他のオプション", "More options": "その他のオプション",
"mentioned you in a comment": "コメントであなたに言及しました", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold>さんがコメントであなたに言及しました",
"commented on a page": "ページにコメントしました", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold>さんがページにコメントしました",
"resolved a comment": "コメントを解決しました", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> さんがコメントを解決しました",
"mentioned you on a page": "ページであなたに言及しました", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> さんがページであなたにメンションしました",
"gave you edit access to a page": "あなたにページの編集アクセス権を付与しました", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> さんがあなたにページの編集権を付与しました",
"gave you view access to a page": "あなたにページの閲覧アクセス権を付与しました", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> さんがあなたにページの閲覧権を付与しました",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> さんがページを更新しました",
"Watch page": "ページをウォッチ",
"Stop watching": "ウォッチを解除",
"Watch space": "スペースをウォッチ",
"Stop watching space": "スペースのウォッチを解除",
"Email notifications": "メール通知",
"Page updates": "ページの更新",
"Get notified when pages you watch are updated.": "ウォッチしているページが更新されたときに通知を受け取ります。",
"Page mentions": "ページでの言及",
"Get notified when someone mentions you on a page.": "誰かがページであなたに言及したとき通知を受け取ります。",
"Comment mentions": "コメントでの言及",
"Get notified when someone mentions you in a comment.": "誰かがコメントであなたに言及したとき通知を受け取ります。",
"New comments": "新しいコメント",
"Get notified about new comments on threads you participate in.": "参加しているスレッドに新しいコメントがあると通知されます。",
"Resolved comments": "解決済みコメント",
"Get notified when your comment is resolved.": "あなたのコメントが解決されたとき通知を受け取ります。",
"You are now watching this page": "このページをウォッチしています",
"You are no longer watching this page": "このページのウォッチを解除しました",
"You are now watching this space": "このスペースのウォッチを開始しました",
"You are no longer watching this space": "このスペースのウォッチを解除しました",
"Direct": "直接",
"Updates": "アップデート",
"Today": "今日", "Today": "今日",
"Yesterday": "昨日", "Yesterday": "昨日",
"This week": "今週", "This week": "今週",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "ゴミ箱保持期間の更新に失敗しました", "Failed to update trash retention": "ゴミ箱保持期間の更新に失敗しました",
"Removed page restriction": "ページの制限を解除しました", "Removed page restriction": "ページの制限を解除しました",
"Added page permission": "ページの権限を追加しました", "Added page permission": "ページの権限を追加しました",
"Removed page permission": "ページの権限を削除しました" "Removed page permission": "ページの権限を削除しました",
"day": "日",
"days": "日",
"week": "週",
"weeks": "週",
"month": "か月",
"months": "か月",
"year": "年",
"years": "年",
"Period": "期間",
"Fixed date": "指定日",
"Indefinitely": "無期限",
"Days": "日",
"Weeks": "週",
"Months": "か月",
"Years": "年",
"Pick a date": "日付を選択",
"Maximum is {{max}} {{unit}} for this unit": "この単位の最大値は{{max}}{{unit}}です",
"Never expires. Verifiers can re-verify at any time.": "有効期限はありません。検証者はいつでも再検証できます。",
"Verified": "検証済み",
"Review needed": "確認が必要",
"Verification expired": "検証期限切れ",
"Draft": "下書き",
"In Approval": "承認中",
"In approval": "承認中",
"Approved": "承認済み",
"Obsolete": "廃止",
"Expiring": "期限間近",
"Set up verification": "検証を設定",
"Verify page": "ページを検証",
"Page verification": "ページ検証",
"Add verification": "検証を追加",
"Edit verification": "検証を編集",
"Search by title": "タイトルで検索",
"Choose how this page should stay accurate.": "このページの正確性をどのように維持するか選択してください。",
"Recurring verification": "定期検証",
"Verifiers re-confirm this page on a schedule.": "検証者がこのページを定期的に再確認します。",
"Re-verify on a schedule (e.g every 30 days )": "スケジュールに従って再検証(例:30日ごと)",
"Page stays editable at all times": "ページは常に編集可能です",
"Best for runbooks, FAQs, living documentation": "運用手順書、FAQ、継続的に更新されるドキュメントに最適",
"Approval workflow": "承認ワークフロー",
"Formal document lifecycle with named approvers.": "指定された承認者による正式な文書ライフサイクルです。",
"Draft → In approval → Approved → Obsolete": "下書き → 承認中 → 承認済み → 廃止",
"Locked once approved, with full history": "承認後はロックされ、完全な履歴が残ります",
"Designed for ISO 9001, ISO 13485, and FDA": "ISO 9001、ISO 13485、FDA向けに設計",
"Best for SOPs and controlled documents": "SOPや管理文書に最適",
"Back": "戻る",
"Quality management": "品質管理",
"Recurring": "定期",
"Pages move through draft, approval, and approved stages.": "ページは下書き、承認中、承認済みの各段階を進みます。",
"Verifiers": "検証者",
"Add verifier": "検証者を追加",
"I've reviewed this page for accuracy": "このページの正確性を確認しました",
"Set up": "設定",
"Remove verification": "検証を削除",
"Are you sure you want to remove verification from this page?": "このページから検証を削除してもよろしいですか?",
"Assigned verifiers must periodically re-verify this page.": "割り当てられた検証者はこのページを定期的に再検証する必要があります。",
"Last verified by {{name}} {{time}} (expired)": "最終検証者:{{name}} {{time}}(期限切れ)",
"The fixed expiration date has passed.": "指定された有効期限を過ぎています。",
"Verified by {{name}} {{time}}": "{{name}}が{{time}}に検証",
"Expires {{date}}": "有効期限:{{date}}",
"Expired {{date}}": "{{date}}に期限切れ",
"Mark as obsolete": "廃止としてマーク",
"Mark obsolete": "廃止にする",
"Returned by {{name}} {{time}}": "{{name}}が{{time}}に差し戻し",
"No approval has been requested yet.": "まだ承認は依頼されていません。",
"Submitted by {{name}} {{time}}": "{{name}}が{{time}}に提出",
"Someone": "誰か",
"Approved by {{name}} {{time}}": "{{name}}が{{time}}に承認",
"This document has been marked as obsolete.": "この文書は廃止としてマークされています。",
"Rejection comment": "差し戻しコメント",
"Reason for returning this document...": "この文書を差し戻す理由...",
"Confirm rejection": "差し戻しを確定",
"Submit for approval": "承認を申請",
"Reject": "差し戻す",
"Approve": "承認",
"Re-submit for approval": "再度承認を申請",
"Verified until": "検証有効期限",
"QMS": "QMS",
"Verified pages": "検証済みページ",
"Search pages...": "ページを検索...",
"Filter by space": "スペースで絞り込み",
"Filter by type": "タイプで絞り込み",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold>がページを検証しました",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold>があなたの承認のためにページを提出しました",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold>がページを修正のため差し戻しました",
"Page verification expires soon": "ページ検証の期限が間もなく切れます",
"Page verification has expired": "ページ検証の期限が切れています",
"Verifying your email": "メールアドレスを確認しています",
"Please wait...": "お待ちください…",
"Verification failed. The link may have expired.": "認証に失敗しました。リンクの有効期限が切れている可能性があります。",
"Check your email": "メールを確認してください",
"We sent a verification link to {{email}}.": "確認用リンクを{{email}}に送信しました。",
"We sent a verification link to your email.": "確認用リンクをあなたのメールアドレスに送信しました。",
"Click the link to verify your email and access your workspace.": "リンクをクリックしてメールを認証し、ワークスペースにアクセスしてください。",
"Resend verification email": "確認メールを再送信",
"Verification email sent. Please check your inbox.": "確認メールを送信しました。受信箱をご確認ください。",
"Failed to resend verification email. Please try again.": "確認メールの再送信に失敗しました。もう一度お試しください。",
"We've sent you an email with your associated workspaces.": "紐づいているワークスペース情報をメールでお送りしました。",
"Load more": "もっと読み込む",
"Log out of all devices": "すべてのデバイスからログアウト",
"Log out of all sessions except this device": "このデバイス以外のすべてのセッションからログアウト",
"This Device": "このデバイス",
"Unknown device": "不明なデバイス",
"No active sessions": "アクティブなセッションはありません",
"Session revoked": "セッションを無効化しました",
"All other sessions revoked": "他のすべてのセッションを無効化しました",
"Last used": "最終使用",
"Created": "作成日",
"Rename": "名前を変更",
"Publish": "公開",
"Security": "セキュリティ",
"Enforce SSO": "SSO を必須化",
"Once enforced, members will not be able to login with email and password.": "必須化すると、メンバーはメールアドレスとパスワードでログインできなくなります。",
"AI-generated content may not be accurate.": "AI が生成したコンテンツは正確でない場合があります。",
"AI Chat": "AI チャット",
"Analyze for insights": "分析してインサイトを得る",
"Ask anything...": "何でも聞いてください...",
"Chat history": "チャット履歴",
"Chat name": "チャット名",
"Close": "閉じる",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "チャットの読み込みに失敗しました。エラーが発生しました。",
"Failed to render this message.": "このメッセージの表示に失敗しました。",
"How can I help you today?": "本日はどのようにお手伝いできますか?",
"New chat": "新しいチャット",
"No chat history": "チャット履歴はありません",
"No chats found": "チャットが見つかりません",
"No conversations yet": "会話はまだありません",
"Open full page": "全ページで開く",
"Previous 7 days": "過去 7 日間",
"Previous 30 days": "過去 30 日間",
"Search chats...": "チャットを検索...",
"Start a new chat to see it here.": "ここに表示するには新しいチャットを開始してください。",
"Summarize this page": "このページを要約",
"Toggle AI Chat": "AI チャットを切り替え",
"Translate this page": "このページを翻訳",
"Try a different search term.": "別の検索語を試してください。",
"Try again": "再試行",
"Untitled chat": "無題のチャット",
"What can I help you with?": "何をお手伝いしましょうか?"
} }
+316 -129
View File
@@ -7,6 +7,7 @@
"Add members": "사용자 추가", "Add members": "사용자 추가",
"Add to groups": "팀에 추가", "Add to groups": "팀에 추가",
"Add space members": "Space에 사용자 추가", "Add space members": "Space에 사용자 추가",
"Add to favorites": "즐겨찾기에 추가",
"Admin": "관리자", "Admin": "관리자",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "이 팀을 삭제하시겠습니까? 해당 팀에 속한 사용자들은 이 팀이 가진 모든 권한을 잃게 됩니다.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "이 팀을 삭제하시겠습니까? 해당 팀에 속한 사용자들은 이 팀이 가진 모든 권한을 잃게 됩니다.",
"Are you sure you want to delete this page?": "이 페이지를 삭제하시겠습니까?", "Are you sure you want to delete this page?": "이 페이지를 삭제하시겠습니까?",
@@ -47,12 +48,12 @@
"e.g ACME": "예: ACME", "e.g ACME": "예: ACME",
"e.g ACME Inc": "예: ACME Inc", "e.g ACME Inc": "예: ACME Inc",
"e.g Developers": "예: 개발자", "e.g Developers": "예: 개발자",
"e.g Group for developers": "예: 개발자를 위한 ", "e.g Group for developers": "예: 개발자를 위한 그룹",
"e.g product": "예: 제품", "e.g product": "예: 제품",
"e.g Product Team": "예: 제품 팀", "e.g Product Team": "예: 제품 팀",
"e.g Sales": "예: 영업", "e.g Sales": "예: 영업",
"e.g Space for product team": "예: 제품 팀을 위한 Space", "e.g Space for product team": "예: 제품 팀용 스페이스",
"e.g Space for sales team to collaborate": "예: 영업 팀의 Space", "e.g Space for sales team to collaborate": "예: 영업 팀이 협업하는 스페이스",
"Edit": "편집", "Edit": "편집",
"Read": "읽기", "Read": "읽기",
"Edit group": "팀 편집", "Edit group": "팀 편집",
@@ -61,7 +62,7 @@
"Enter valid email addresses separated by comma or space max_50": "유효한 이메일 주소를 쉼표나 공백으로 구분하여 입력하세요 [최대: 50]", "Enter valid email addresses separated by comma or space max_50": "유효한 이메일 주소를 쉼표나 공백으로 구분하여 입력하세요 [최대: 50]",
"enter valid emails addresses": "유효한 이메일 주소를 입력하세요", "enter valid emails addresses": "유효한 이메일 주소를 입력하세요",
"Enter your current password": "기존 비밀번호를 입력하세요", "Enter your current password": "기존 비밀번호를 입력하세요",
"enter your full name": "전체 이름을 입력하세요", "enter your full name": "성명을 입력하세요",
"Enter your new password": "새 비밀번호를 입력하세요", "Enter your new password": "새 비밀번호를 입력하세요",
"Enter your new preferred email": "새로운 이메일을 입력하세요", "Enter your new preferred email": "새로운 이메일을 입력하세요",
"Enter your password": "비밀번호를 입력하세요", "Enter your password": "비밀번호를 입력하세요",
@@ -74,6 +75,9 @@
"Failed to import pages": "페이지 가져오기 실패", "Failed to import pages": "페이지 가져오기 실패",
"Failed to load page. An error occurred.": "페이지 불러오기 실패. 오류가 발생했습니다.", "Failed to load page. An error occurred.": "페이지 불러오기 실패. 오류가 발생했습니다.",
"Failed to update data": "데이터 갱신 실패", "Failed to update data": "데이터 갱신 실패",
"Favorite spaces": "즐겨찾는 스페이스",
"Favorite spaces appear here": "즐겨찾는 스페이스가 여기에 표시됩니다",
"Favorites": "즐겨찾기",
"Full access": "전체 권한", "Full access": "전체 권한",
"Full page width": "전체 페이지 너비", "Full page width": "전체 페이지 너비",
"Full width": "전체 너비", "Full width": "전체 너비",
@@ -87,11 +91,12 @@
"Import pages": "페이지 가져오기", "Import pages": "페이지 가져오기",
"Import pages & space settings": "페이지 및 Space 설정 가져오기", "Import pages & space settings": "페이지 및 Space 설정 가져오기",
"Importing pages": "페이지 가져오는 중", "Importing pages": "페이지 가져오는 중",
"invalid invitation link": "유효하지 않은 초대 링크", "invalid invitation link": "유효하지 않은 초대 링크입니다",
"Invitation signup": "초대 가입", "Invitation signup": "초대 가입",
"Invite by email": "이메일로 초대", "Invite by email": "이메일로 초대",
"Invite members": "사용자 초대", "Invite members": "사용자 초대",
"Invite new members": "새 사용자 초대", "Invite new members": "새 사용자 초대",
"Invite People": "사용자 초대",
"Invited members who are yet to accept their invitation will appear here.": "초대를 아직 수락하지 않은 초대된 사용자가 여기에 표시됩니다.", "Invited members who are yet to accept their invitation will appear here.": "초대를 아직 수락하지 않은 초대된 사용자가 여기에 표시됩니다.",
"Invited members will be granted access to spaces the groups can access": "초대된 사용자는 팀이 접근할 수 있는 Space에 대한 접근 권한을 받게 됩니다", "Invited members will be granted access to spaces the groups can access": "초대된 사용자는 팀이 접근할 수 있는 Space에 대한 접근 권한을 받게 됩니다",
"Join the workspace": "Workspace 참여", "Join the workspace": "Workspace 참여",
@@ -113,7 +118,7 @@
"New email": "새 이메일", "New email": "새 이메일",
"New page": "새 페이지", "New page": "새 페이지",
"New password": "새 비밀번호", "New password": "새 비밀번호",
"No group found": "을 찾을 수 없", "No group found": "그룹을 찾을 수 없습니다",
"No page history saved yet.": "아직 저장된 페이지 기록이 없습니다.", "No page history saved yet.": "아직 저장된 페이지 기록이 없습니다.",
"No pages yet": "아직 페이지가 없습니다", "No pages yet": "아직 페이지가 없습니다",
"No shared pages": "공유된 페이지가 없습니다.", "No shared pages": "공유된 페이지가 없습니다.",
@@ -139,6 +144,7 @@
"Profile": "프로필", "Profile": "프로필",
"Recently updated": "최근 업데이트", "Recently updated": "최근 업데이트",
"Remove": "제거", "Remove": "제거",
"Remove from favorites": "즐겨찾기에서 제거",
"Remove group member": "팀에서 사용자 제거", "Remove group member": "팀에서 사용자 제거",
"Remove space member": "Space에서 사용자 제거", "Remove space member": "Space에서 사용자 제거",
"Restore": "복원", "Restore": "복원",
@@ -151,41 +157,42 @@
"Search...": "검색...", "Search...": "검색...",
"Select language": "언어 선택", "Select language": "언어 선택",
"Select role": "역할 선택", "Select role": "역할 선택",
"Select role to assign to all invited members": "초대된 모든 사용자에게 할당할 역할 선택", "Select role to assign to all invited members": "초대된 모든 멤버에게 할당할 역할 선택하세요",
"Select theme": "배경 선택", "Select theme": "테마 선택",
"Send invitation": "초대 보내기", "Send invitation": "초대 보내기",
"Invitation sent": "초대 발송 완료", "Invitation sent": "초대를 보냈습니다",
"Settings": "설정", "Settings": "설정",
"Setup workspace": "Workspace 설정", "Setup workspace": "워크스페이스 설정",
"Sign In": "로그인", "Sign In": "로그인",
"Sign Up": "회원가입", "Sign Up": "회원가입",
"Slug": "고유 경로", "Slug": "슬러그",
"Space": "Space", "Space": "스페이스",
"Space description": "Space 설명", "Space description": "스페이스 설명",
"Space menu": "Space 메뉴", "Space menu": "스페이스 메뉴",
"Space name": "Space 이름", "Space name": "스페이스 이름",
"Space settings": "Space 설정", "Space settings": "스페이스 설정",
"Space slug": "Space의 고유 경로", "Space slug": "스페이스 슬러그",
"Spaces": "Space", "Spaces": "스페이스",
"Spaces you belong to": "소속된 Space", "Spaces you belong to": "내가 속한 스페이스",
"No space found": "Space을 찾을 수 없", "No space found": "스페이스를 찾을 수 없습니다",
"Search for spaces": "Space 검색", "Search for spaces": "스페이스 검색",
"Start typing to search...": "검색하려면 입력을 시작하세요...", "Start typing to search...": "검색하려면 입력을 시작하세요...",
"Status": "상태", "Status": "상태",
"Successfully imported": "가져오기 완료", "Successfully imported": "가져오기에 성공했습니다",
"Successfully restored": "복원 완료", "Successfully restored": "복원에 성공했습니다",
"System settings": "시스템 설정", "System settings": "시스템 설정",
"Theme": "배경", "Templates": "템플릿",
"Theme": "테마",
"To change your email, you have to enter your password and new email.": "이메일을 변경하려면 기존 비밀번호와 새 이메일을 입력해야 합니다.", "To change your email, you have to enter your password and new email.": "이메일을 변경하려면 기존 비밀번호와 새 이메일을 입력해야 합니다.",
"Toggle full page width": "전체 페이지 너비 전환", "Toggle full page width": "전체 페이지 너비 전환",
"Unable to import pages. Please try again.": "페이지를 가져올 수 없습니다. 다시 시도해주세요.", "Unable to import pages. Please try again.": "페이지를 가져올 수 없습니다. 다시 시도해주세요.",
"untitled": "제목 없음", "untitled": "제목 없음",
"Untitled": "제목 없음", "Untitled": "제목 없음",
"Updated successfully": "업데이트 완료", "Updated successfully": "성공적으로 업데이트되었습니다",
"User": "사용자", "User": "사용자",
"Workspace": "Workspace", "Workspace": "워크스페이스",
"Workspace Name": "Workspce 이름", "Workspace Name": "워크스페이스 이름",
"Workspace settings": "Workspace 설정", "Workspace settings": "워크스페이스 설정",
"You can change your password here.": "여기서 비밀번호를 변경할 수 있습니다.", "You can change your password here.": "여기서 비밀번호를 변경할 수 있습니다.",
"Your Email": "이메일", "Your Email": "이메일",
"Your import is complete.": "가져오기가 완료되었습니다.", "Your import is complete.": "가져오기가 완료되었습니다.",
@@ -195,10 +202,10 @@
"Your password must be a minimum of 8 characters.": "비밀번호는 최소 8자 이상이어야 합니다.", "Your password must be a minimum of 8 characters.": "비밀번호는 최소 8자 이상이어야 합니다.",
"Sidebar toggle": "사이드바 전환", "Sidebar toggle": "사이드바 전환",
"Comments": "댓글", "Comments": "댓글",
"404 page not found": "404 페이지를 찾을 수 없", "404 page not found": "404 페이지를 찾을 수 없습니다",
"Sorry, we can't find the page you are looking for.": "죄송합니다. 페이지를 찾을 수 없습니다.", "Sorry, we can't find the page you are looking for.": "죄송합니다. 페이지를 찾을 수 없습니다.",
"Take me back to homepage": "홈페이지로 돌아가기", "Take me back to homepage": "홈페이지로 돌아가기",
"Forgot password": "비밀번호 찾기", "Forgot password": "비밀번호를 잊으셨나요",
"Forgot your password?": "비밀번호를 잊으셨나요?", "Forgot your password?": "비밀번호를 잊으셨나요?",
"A password reset link has been sent to your email. Please check your inbox.": "비밀번호 재설정 링크가 이메일로 전송되었습니다. 받은 편지함을 확인해주세요.", "A password reset link has been sent to your email. Please check your inbox.": "비밀번호 재설정 링크가 이메일로 전송되었습니다. 받은 편지함을 확인해주세요.",
"Send reset link": "재설정 링크 보내기", "Send reset link": "재설정 링크 보내기",
@@ -215,6 +222,8 @@
"Edit comment": "댓글 수정", "Edit comment": "댓글 수정",
"Delete comment": "댓글 삭제", "Delete comment": "댓글 삭제",
"Are you sure you want to delete this comment?": "이 댓글을 삭제하시겠습니까?", "Are you sure you want to delete this comment?": "이 댓글을 삭제하시겠습니까?",
"Delete chat": "채팅 삭제",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "'{{title}}'을(를) 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"Comment created successfully": "댓글 생성 완료", "Comment created successfully": "댓글 생성 완료",
"Error creating comment": "댓글 생성 오류", "Error creating comment": "댓글 생성 오류",
"Comment updated successfully": "댓글 업데이트 완료", "Comment updated successfully": "댓글 업데이트 완료",
@@ -223,12 +232,12 @@
"Failed to delete comment": "댓글 삭제 실패", "Failed to delete comment": "댓글 삭제 실패",
"Comment resolved successfully": "댓글 처리 완료", "Comment resolved successfully": "댓글 처리 완료",
"Comment re-opened successfully": "댓글이 성공적으로 다시 열렸습니다", "Comment re-opened successfully": "댓글이 성공적으로 다시 열렸습니다",
"Comment unresolved successfully": "댓글 해결로 변경 완료", "Comment unresolved successfully": "댓글 해결이 성공적으로 취소되었습니다",
"Failed to resolve comment": "댓글 처리 실패", "Failed to resolve comment": "댓글 처리 실패",
"Resolve comment": "댓글 해결하기", "Resolve comment": "댓글 해결",
"Unresolve comment": "댓글 해결로 변경하기", "Unresolve comment": "댓글 해결 취소",
"Resolve Comment Thread": "댓글 스레드 해결하기", "Resolve Comment Thread": "댓글 스레드 해결",
"Unresolve Comment Thread": "댓글 스레드 해결로 변경하기", "Unresolve Comment Thread": "댓글 스레드 해결 취소",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "이 댓글 스레드를 해결하시겠습니까? 완료로 표시됩니다.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "이 댓글 스레드를 해결하시겠습니까? 완료로 표시됩니다.",
"Are you sure you want to unresolve this comment thread?": "이 댓글 스레드를 미해결로 변경하시겠습니까?", "Are you sure you want to unresolve this comment thread?": "이 댓글 스레드를 미해결로 변경하시겠습니까?",
"Resolved": "해결됨", "Resolved": "해결됨",
@@ -241,9 +250,9 @@
"Anyone with this link can join this workspace.": "이 링크를 가진 모든 사용자가 이 Workspace에 참여할 수 있습니다.", "Anyone with this link can join this workspace.": "이 링크를 가진 모든 사용자가 이 Workspace에 참여할 수 있습니다.",
"Invite link": "초대 링크", "Invite link": "초대 링크",
"Copy": "복사", "Copy": "복사",
"Copy to space": "공간에 복사하기", "Copy to space": "스페이스로 복사",
"Copied": "복사됨", "Copied": "복사됨",
"Duplicate": "복", "Duplicate": "복",
"Select a user": "사용자 선택", "Select a user": "사용자 선택",
"Select a group": "팀 선택", "Select a group": "팀 선택",
"Export all pages and attachments in this space.": "이 Space의 모든 페이지와 첨부파일을 내보냅니다.", "Export all pages and attachments in this space.": "이 Space의 모든 페이지와 첨부파일을 내보냅니다.",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "이 Space을 삭제하시겠습니까?", "Are you sure you want to delete this space?": "이 Space을 삭제하시겠습니까?",
"Delete this space with all its pages and data.": "이 Space의 모든 페이지와 데이터를 삭제합니다.", "Delete this space with all its pages and data.": "이 Space의 모든 페이지와 데이터를 삭제합니다.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "이 Space의 모든 페이지, 댓글, 첨부파일 및 권한이 영구적으로 삭제됩니다.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "이 Space의 모든 페이지, 댓글, 첨부파일 및 권한이 영구적으로 삭제됩니다.",
"Confirm space name": "Space 이름 확인", "Confirm space name": "스페이스 이름 확인",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "작업을 진행하려면 Space 이름 <b>{{spaceName}}</b>을 입력하세요.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "작업을 진행하려면 Space 이름 <b>{{spaceName}}</b>을 입력하세요.",
"Format": "형식", "Format": "형식",
"Include subpages": "하위 페이지 포함", "Include subpages": "하위 페이지 포함",
@@ -267,7 +276,7 @@
"Align left": "왼쪽 정렬", "Align left": "왼쪽 정렬",
"Align right": "오른쪽 정렬", "Align right": "오른쪽 정렬",
"Align center": "가운데 정렬", "Align center": "가운데 정렬",
"Justify": "정렬", "Justify": "양쪽 정렬",
"Merge cells": "셀 병합", "Merge cells": "셀 병합",
"Split cell": "셀 분할", "Split cell": "셀 분할",
"Delete column": "열 삭제", "Delete column": "열 삭제",
@@ -289,6 +298,11 @@
"Save & Exit": "저장 후 나가기", "Save & Exit": "저장 후 나가기",
"Double-click to edit Excalidraw diagram": "Excalidraw diagram을 편집하려면 더블 클릭하세요", "Double-click to edit Excalidraw diagram": "Excalidraw diagram을 편집하려면 더블 클릭하세요",
"Paste link": "링크 붙여넣기", "Paste link": "링크 붙여넣기",
"Paste link or search pages": "링크를 붙여넣거나 페이지를 검색",
"Link to web page": "웹페이지에 링크하기",
"Recents": "최근 항목",
"Page or URL": "페이지 또는 URL",
"Link title": "링크 제목",
"Edit link": "링크 수정", "Edit link": "링크 수정",
"Remove link": "링크 제거", "Remove link": "링크 제거",
"Add link": "링크 추가", "Add link": "링크 추가",
@@ -307,7 +321,7 @@
"Pink": "분홍색", "Pink": "분홍색",
"Gray": "회색", "Gray": "회색",
"Embed link": "임베드 링크", "Embed link": "임베드 링크",
"Invalid {{provider}} embed link": "잘못된 {{provider}} 임베드 링크", "Invalid {{provider}} embed link": "유효하지 않은 {{provider}} 임베드 링크입니다",
"Embed {{provider}}": "{{provider}} 임베드", "Embed {{provider}}": "{{provider}} 임베드",
"Enter {{provider}} link to embed": "임베드를 할 {{provider}} 링크 입력", "Enter {{provider}} link to embed": "임베드를 할 {{provider}} 링크 입력",
"Bold": "굵게", "Bold": "굵게",
@@ -336,38 +350,45 @@
"Insert horizontal rule divider": "가로 구분선 삽입", "Insert horizontal rule divider": "가로 구분선 삽입",
"Upload any image from your device.": "기기에서 이미지를 업로드하세요.", "Upload any image from your device.": "기기에서 이미지를 업로드하세요.",
"Upload any video from your device.": "기기에서 비디오를 업로드하세요.", "Upload any video from your device.": "기기에서 비디오를 업로드하세요.",
"Upload any audio from your device.": "기기에서 오디오를 업로드하세요.",
"Upload any file from your device.": "기기에서 파일을 업로드하세요.", "Upload any file from your device.": "기기에서 파일을 업로드하세요.",
"Uploading {{name}}": "{{name}} 업로드 중", "Uploading {{name}}": "{{name}} 업로드 중",
"Uploading file": "파일 업로드 중", "Uploading file": "파일 업로드 중",
"Table": "테이블", "Table": "",
"Insert a table.": "테이블 삽입.", "Insert a table.": "테이블 삽입.",
"Insert collapsible block.": "접을 수 있는 블록 삽입.", "Insert collapsible block.": "접을 수 있는 블록 삽입.",
"Video": "비디오", "Video": "동영상",
"Divider": "구분선", "Divider": "구분선",
"Quote": "인용", "Quote": "인용",
"Image": "이미지", "Image": "이미지",
"Audio": "오디오",
"Embed PDF": "PDF 임베드",
"Upload and embed a PDF file.": "PDF 파일을 업로드하고 임베드하세요.",
"Embed as PDF": "PDF로 임베드",
"Failed to load PDF": "PDF 로드 실패",
"Convert to attachment": "첨부 파일로 변환",
"File attachment": "파일 첨부", "File attachment": "파일 첨부",
"Toggle block": "블록 토글", "Toggle block": "토글 블록",
"Callout": "경고 상자", "Callout": "콜아웃",
"Insert callout notice.": "돋보이는 글을 작성하기.", "Insert callout notice.": "돋보이는 글을 작성하기.",
"Math inline": "수식", "Math inline": "인라인 수식",
"Insert inline math equation.": "수식 삽입.", "Insert inline math equation.": "수식 삽입.",
"Math block": "수식 블록", "Math block": "수식 블록",
"Insert math equation": "수식 삽입", "Insert math equation": "수식 삽입",
"Mermaid diagram": "Mermaid diagram", "Mermaid diagram": "Mermaid 다이어그램",
"Insert mermaid diagram": "Mermaid diagram 삽입", "Insert mermaid diagram": "Mermaid 다이어그램 삽입",
"Insert and design Drawio diagrams": "Drawio diagram 삽입 및 디자인", "Insert and design Drawio diagrams": "Drawio 다이어그램 삽입 및 편집",
"Insert current date": "현재 날짜 삽입", "Insert current date": "현재 날짜 삽입",
"Draw and sketch excalidraw diagrams": "Excalidraw diagram 그리기 및 스케치", "Draw and sketch excalidraw diagrams": "Excalidraw 다이어그램 그리기 및 스케치",
"Multiple": "복제", "Multiple": "다중",
"Turn into": "변경하기", "Turn into": "변경하기",
"Text align": "텍스트 정렬", "Text align": "텍스트 정렬",
"This page may have been deleted, moved, or you may not have access.": "이 페이지는 삭제되었거나 이동되었거나 접근 권한이 없을 수 있습니다.", "This page may have been deleted, moved, or you may not have access.": "이 페이지는 삭제되었거나 이동되었거나 접근 권한이 없을 수 있습니다.",
"Go to homepage": "홈으로 이동", "Go to homepage": "홈으로 이동",
"Pages you create will show up here.": "여기에 생성한 페이지가 표시됩니다.", "Pages you create will show up here.": "여기에 생성한 페이지가 표시됩니다.",
"Heading {{level}}": "제목 {{level}}", "Heading {{level}}": "제목 {{level}}",
"Toggle title": "제목 토글", "Toggle title": "토글 제목",
"Write anything. Enter \"/\" for commands": "아무거나 입력하세요. 명령어를 사용하려면 \"/\"를 입력하세요", "Write anything. Enter \"/\" for commands": "무엇이든 입력하세요. 명령어를 사용하려면 \"/\"를 입력하세요",
"Write...": "작성...", "Write...": "작성...",
"Column count": "열 개수", "Column count": "열 개수",
"{{count}} Columns": "{{count}}열", "{{count}} Columns": "{{count}}열",
@@ -380,24 +401,24 @@
"Names do not match": "이름이 일치하지 않습니다", "Names do not match": "이름이 일치하지 않습니다",
"Today, {{time}}": "오늘, {{time}}", "Today, {{time}}": "오늘, {{time}}",
"Yesterday, {{time}}": "어제, {{time}}", "Yesterday, {{time}}": "어제, {{time}}",
"Space created successfully": "공간 생성 완료", "Space created successfully": "스페이스가 성공적으로 생성되었습니다",
"Space updated successfully": "공간이 성공적으로 업데이트되었습니다", "Space updated successfully": "스페이스가 성공적으로 업데이트되었습니다",
"Space deleted successfully": "스페이스 삭제 완료", "Space deleted successfully": "스페이스가 성공적으로 삭제되었습니다",
"Members added successfully": "회원 추가 완료", "Members added successfully": "멤버가 성공적으로 추가되었습니다",
"Member removed successfully": "멤버가 성공적으로 제거되었습니다", "Member removed successfully": "멤버가 성공적으로 제거되었습니다",
"Member role updated successfully": "회원 역할이 성공적으로 업데이트되었습니다", "Member role updated successfully": "멤버 역할이 성공적으로 업데이트되었습니다",
"Created by: <b>{{creatorName}}</b>": "작성자: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "작성자: <b>{{creatorName}}</b>",
"Created at: {{time}}": "날짜: {{time}}", "Created at: {{time}}": "시간: {{time}}",
"Edited by {{name}} {{time}}": "{{name}}님이 편집함 {{time}}", "Edited by {{name}} {{time}}": "{{name}}님이 {{time}}에 편집함",
"Word count: {{wordCount}}": "단어 수: {{wordCount}}", "Word count: {{wordCount}}": "단어 수: {{wordCount}}",
"Character count: {{characterCount}}": "문자 수: {{characterCount}}", "Character count: {{characterCount}}": "문자 수: {{characterCount}}",
"New update": "새로운 업데이트", "New update": "새 업데이트",
"{{latestVersion}} is available": "{{latestVersion}}이 사용 가능합니다", "{{latestVersion}} is available": "{{latestVersion}} 버전을 사용할 수 있습니다",
"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.": "선호하는 페이지 편집 모드를 선택하세요. 실수로 인한 편집을 방지하세요.",
"Reading": "읽기", "Reading": "읽기",
"Delete member": "회원 삭제", "Delete member": "멤버 삭제",
"Member deleted successfully": "멤버가 성공적으로 제되었습니다", "Member deleted successfully": "멤버가 성공적으로 제되었습니다",
"Are you sure you want to delete this workspace member? This action is irreversible.": "이 워크스페이스 멤버를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", "Are you sure you want to delete this workspace member? This action is irreversible.": "이 워크스페이스 멤버를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"Deactivate member": "멤버 비활성화", "Deactivate member": "멤버 비활성화",
"Activate member": "멤버 활성화", "Activate member": "멤버 활성화",
@@ -414,22 +435,22 @@
"Add headings (H1, H2, H3) to generate a table of contents.": "목차를 생성하려면 제목 (H1, H2, H3)을 추가하세요.", "Add headings (H1, H2, H3) to generate a table of contents.": "목차를 생성하려면 제목 (H1, H2, H3)을 추가하세요.",
"Share": "공유", "Share": "공유",
"Public sharing": "공개 공유", "Public sharing": "공개 공유",
"Shared by": "공유", "Shared by": "공유한 사람",
"Shared at": "공유 시간", "Shared at": "공유 시간",
"Inherits public sharing from": "로부터 공개 공유를 상속", "Inherits public sharing from": "다음으로부터 공개 공유를 상속받음",
"Share to web": "웹에 공유", "Share to web": "웹에 공유",
"Shared to web": "웹에 공유됨", "Shared to web": "웹에 공유됨",
"Anyone with the link can view this page": "링크가 있는 사람은 이 페이지를 볼 수 있습니다", "Anyone with the link can view this page": "링크가 있는 누구나 이 페이지를 볼 수 있습니다",
"Make this page publicly accessible": "이 페이지를 공개적으로 접근 가능하게 만들기", "Make this page publicly accessible": "이 페이지를 공개적으로 접근 가능하게 설정",
"Include sub-pages": "하위 페이지 포함", "Include sub-pages": "하위 페이지 포함",
"Make sub-pages public too": "하위 페이지도 공개로 설정", "Make sub-pages public too": "하위 페이지도 공개로 설정",
"Allow search engines to index page": "검색 엔진이 페이지를 색인할 수 있도록 허용", "Allow search engines to index page": "검색 엔진이 페이지를 색인도록 허용",
"Open page": "페이지 열기", "Open page": "페이지 열기",
"Page": "페이지", "Page": "페이지",
"Delete public share link": "공유 링크 삭제", "Delete public share link": "공개 공유 링크 삭제",
"Delete share": "공유 삭제", "Delete share": "공유 삭제",
"Are you sure you want to delete this shared link?": "이 공유 링크를 삭제하시겠습니까?", "Are you sure you want to delete this shared link?": "이 공유 링크를 삭제하시겠습니까?",
"Publicly shared pages from spaces you are a member of will appear here": "회원인 공간의 공개 공유 페이지가 여기에 표시됩니다", "Publicly shared pages from spaces you are a member of will appear here": "회원으로 속한 스페이스의 공개 공유 페이지가 여기에 표시됩니다",
"Share deleted successfully": "공유가 성공적으로 삭제되었습니다", "Share deleted successfully": "공유가 성공적으로 삭제되었습니다",
"Share not found": "공유를 찾을 수 없습니다", "Share not found": "공유를 찾을 수 없습니다",
"Failed to share page": "페이지 공유에 실패했습니다", "Failed to share page": "페이지 공유에 실패했습니다",
@@ -437,9 +458,11 @@
"Prevent members from sharing pages publicly.": "멤버들이 페이지를 공개적으로 공유하지 못하도록 방지하십시오.", "Prevent members from sharing pages publicly.": "멤버들이 페이지를 공개적으로 공유하지 못하도록 방지하십시오.",
"Toggle public sharing": "공유 전환", "Toggle public sharing": "공유 전환",
"Toggle space public sharing": "공간 공유 전환", "Toggle space public sharing": "공간 공유 전환",
"Allow viewers to comment": "뷰어가 댓글을 달 수 있도록 허용",
"Allow viewers to add comments on pages in this space.": "이 공간 내 페이지에 뷰어가 댓글을 추가할 수 있도록 허용합니다.",
"Toggle viewer comments": "뷰어 댓글 전환",
"Public sharing is disabled at the workspace level": "워크스페이스 수준에서 공유가 비활성화되었습니다.", "Public sharing is disabled at the workspace level": "워크스페이스 수준에서 공유가 비활성화되었습니다.",
"Prevent pages in this space from being shared publicly.": "이 공간의 페이지가 공개적으로 공유되지 않도록 방지하십시오.", "Prevent pages in this space from being shared publicly.": "이 공간의 페이지가 공개적으로 공유되지 않도록 방지하십시오.",
"Requires an enterprise license": "기업 라이센스가 필요합니다.",
"Page permissions": "페이지 권한},{", "Page permissions": "페이지 권한},{",
"Control who can view and edit individual pages. Available with an enterprise license.": "개별 페이지의 조회 및 편집 권한을 제어합니다. 엔터프라이즈 라이선스에서 이용 가능합니다.", "Control who can view and edit individual pages. Available with an enterprise license.": "개별 페이지의 조회 및 편집 권한을 제어합니다. 엔터프라이즈 라이선스에서 이용 가능합니다.",
"Enable public sharing": "공유 활성화", "Enable public sharing": "공유 활성화",
@@ -450,7 +473,7 @@
"Public sharing is disabled": "공유가 비활성화되었습니다.", "Public sharing is disabled": "공유가 비활성화되었습니다.",
"Public sharing has been disabled at the workspace level.": "워크스페이스 수준에서 공유가 비활성화되었습니다.", "Public sharing has been disabled at the workspace level.": "워크스페이스 수준에서 공유가 비활성화되었습니다.",
"Public sharing has been disabled for this space.": "이 공간의 공유가 비활성화되었습니다.", "Public sharing has been disabled for this space.": "이 공간의 공유가 비활성화되었습니다.",
"Copy page": "페이지 복사하기", "Copy page": "페이지 복사",
"Copy page to a different space.": "다른 공간으로 페이지 복사하기.", "Copy page to a different space.": "다른 공간으로 페이지 복사하기.",
"Page copied successfully": "페이지가 성공적으로 복사되었습니다", "Page copied successfully": "페이지가 성공적으로 복사되었습니다",
"Page duplicated successfully": "페이지가 성공적으로 복제되었습니다", "Page duplicated successfully": "페이지가 성공적으로 복제되었습니다",
@@ -459,71 +482,72 @@
"Previous Match (Shift+Enter)": "이전 일치 항목 (Shift+Enter)", "Previous Match (Shift+Enter)": "이전 일치 항목 (Shift+Enter)",
"Next match (Enter)": "다음 일치 항목 (Enter)", "Next match (Enter)": "다음 일치 항목 (Enter)",
"Match case (Alt+C)": "대소문자 구분 (Alt+C)", "Match case (Alt+C)": "대소문자 구분 (Alt+C)",
"Replace": "교체", "Replace": "바꾸기",
"Close (Escape)": "닫기 (Escape)", "Close (Escape)": "닫기 (Escape)",
"Replace (Enter)": "교체 (Enter)", "Replace (Enter)": "바꾸기 (Enter)",
"Replace all (Ctrl+Alt+Enter)": "모두 교체하기 (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "모두 바꾸기 (Ctrl+Alt+Enter)",
"Replace all": "모두 교체하기", "Replace all": "모두 바꾸기",
"View all spaces": "모든 공간 보기", "View all": "모 보기",
"View all spaces": "모든 스페이스 보기",
"Error": "오류", "Error": "오류",
"Failed to disable MFA": "MFA 비활성화 실패", "Failed to disable MFA": "MFA 비활성화 실패했습니다",
"Disable two-factor authentication": "이중 인증 비활성화", "Disable two-factor authentication": "2단계 인증 비활성화",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "이중 인증을 비활성화하면 계정의 보안이 낮아집니다. 로그인 시 비밀번호만 필요하게 됩니다.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "이중 인증을 비활성화하면 계정의 보안이 낮아집니다. 로그인 시 비밀번호만 필요하게 됩니다.",
"Please enter your password to disable two-factor authentication:": "이중 인증 비활성화를 위해 비밀번호를 입력하세요:", "Please enter your password to disable two-factor authentication:": "이중 인증 비활성화를 위해 비밀번호를 입력하세요:",
"Two-factor authentication has been enabled": "이중 인증이 활성화되었습니다", "Two-factor authentication has been enabled": "2단계 인증이 활성화되었습니다",
"Two-factor authentication has been disabled": "이중 인증이 비활성화되었습니다", "Two-factor authentication has been disabled": "2단계 인증이 비활성화되었습니다",
"2-step verification": "2단계 인증", "2-step verification": "2단계 인증",
"Protect your account with an additional verification layer when signing in.": "로그인 시 추가 인증 단계를 통해 계정을 보호하세요.", "Protect your account with an additional verification layer when signing in.": "로그인 시 추가 인증 단계를 통해 계정을 보호하세요.",
"Two-factor authentication is active on your account.": "이중 인증이 계정에 활성화되어 있습니다.", "Two-factor authentication is active on your account.": "이중 인증이 계정에 활성화되어 있습니다.",
"Add 2FA method": "2FA 방법 추가", "Add 2FA method": "2FA 방법 추가",
"Backup codes": "백업 코드", "Backup codes": "백업 코드",
"Disable": "비활성화", "Disable": "비활성화",
"Invalid verification code": "유효하지 않은 인증 코드", "Invalid verification code": "유효하지 않은 인증 코드입니다",
"New backup codes have been generated": "새 백업 코드가 생성되었습니다", "New backup codes have been generated": "새 백업 코드가 생성되었습니다",
"Failed to regenerate backup codes": "백업 코드 재생성 실패", "Failed to regenerate backup codes": "백업 코드 재생성 실패했습니다",
"About backup codes": "백업 코드에 대하여", "About backup codes": "백업 코드 정보",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "인증 앱에 접근할 수 없게 된 경우, 백업 코드를 사용하여 계정에 접근할 수 있습니다. 각 코드는 한 번만 사용할 수 있습니다.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "인증 앱에 접근할 수 없게 된 경우, 백업 코드를 사용하여 계정에 접근할 수 있습니다. 각 코드는 한 번만 사용할 수 있습니다.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "언제든지 새 백업 코드를 재생성할 수 있습니다. 이 작업은 기존 모든 코드를 무효화합니다.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "언제든지 새 백업 코드를 재생성할 수 있습니다. 이 작업은 기존 모든 코드를 무효화합니다.",
"Confirm password": "비밀번호 확인", "Confirm password": "비밀번호 확인",
"Generate new backup codes": "새 백업 코드 생성하기", "Generate new backup codes": "새 백업 코드 생성",
"Save your new backup codes": "새 백업 코드 저장하", "Save your new backup codes": "새 백업 코드 저장하세요",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "이 코드를 안전한 장소에 저장하세요. 이전 백업 코드는 더 이상 유효하지 않습니다.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "이 코드를 안전한 장소에 저장하세요. 이전 백업 코드는 더 이상 유효하지 않습니다.",
"Your new backup codes": "새 백업 코드", "Your new backup codes": "새 백업 코드",
"I've saved my backup codes": "백업 코드를 저장했습니다", "I've saved my backup codes": "백업 코드를 저장했습니다",
"Failed to setup MFA": "MFA 설정 실패", "Failed to setup MFA": "MFA 설정 실패했습니다",
"Setup & Verify": "설정 및 확인", "Setup & Verify": "설정 및 확인",
"Add to authenticator": "인증 앱에 추가", "Add to authenticator": "인증 앱에 추가",
"1. Scan this QR code with your authenticator app": "1. 인증앱으로 이 QR 코드를 스캔하십시오.", "1. Scan this QR code with your authenticator app": "1. 인증 앱으로 이 QR 코드를 스캔하세요",
"Can't scan the code?": "코드를 스캔할 수 없습니까?", "Can't scan the code?": "코드를 스캔할 수 없습니까?",
"Enter this code manually in your authenticator app:": "이 코드를 인증앱에 수동으로 입력해 주세요:", "Enter this code manually in your authenticator app:": "이 코드를 인증앱에 수동으로 입력해 주세요:",
"2. Enter the 6-digit code from your authenticator": "2. 인증앱에 6자리 코드를 입력하십시오", "2. Enter the 6-digit code from your authenticator": "2. 인증 앱에 표시된 6자리 코드를 입력하세요",
"Verify and enable": "확인 활성화", "Verify and enable": "확인 활성화",
"Failed to generate QR code. Please try again.": "QR 코드 생성 실패. 다시 시도해 주세요.", "Failed to generate QR code. Please try again.": "QR 코드 생성 실패. 다시 시도해 주세요.",
"Backup": "백업", "Backup": "백업",
"Save codes": "코드 저장", "Save codes": "코드 저장",
"Save your backup codes": "백업 코드 저장하", "Save your backup codes": "백업 코드 저장하세요",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "인증 앱에 대한 접근 권한을 잃은 경우, 이 코드를 사용하여 귀하의 계정에 접근할 수 있습니다. 각 코드는 한 번만 사용할 수 있습니다.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "인증 앱에 대한 접근 권한을 잃은 경우, 이 코드를 사용하여 귀하의 계정에 접근할 수 있습니다. 각 코드는 한 번만 사용할 수 있습니다.",
"Print": "인쇄", "Print": "인쇄",
"Two-factor authentication has been set up. Please log in again.": "이중 인증이 설정되었습니다. 다시 로그인해 주세요.", "Two-factor authentication has been set up. Please log in again.": "이중 인증이 설정되었습니다. 다시 로그인해 주세요.",
"Two-Factor authentication required": "이중 인증 필요", "Two-Factor authentication required": "2단계 인증 필요합니다",
"Your workspace requires two-factor authentication for all users": "워크스페이스에서는 모든 사용자에게 이중 인증이 필요합니다.", "Your workspace requires two-factor authentication for all users": "워크스페이스는 모든 사용자에게 2단계 인증을 요구합니다",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "워크스페이스 접근을 계속하려면 이중 인증을 설정해야 합니다. 이는 계정에 추가 보안 계층을 추가합니다.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "워크스페이스 접근을 계속하려면 이중 인증을 설정해야 합니다. 이는 계정에 추가 보안 계층을 추가합니다.",
"Set up two-factor authentication": "이중 인증 설정하기", "Set up two-factor authentication": "2단계 인증 설정",
"Cancel and logout": "취소 로그아웃", "Cancel and logout": "취소하고 로그아웃",
"Your workspace requires two-factor authentication. Please set it up to continue.": "워크스페이스에서는 이중 인증이 필요합니다. 계속하려면 설정해 주세요.", "Your workspace requires two-factor authentication. Please set it up to continue.": "워크스페이스에서는 이중 인증이 필요합니다. 계속하려면 설정해 주세요.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "인증앱에서 얻은 인증 코드를 요구하여 계정의 보안에 추가적인 계층을 추가합니다.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "인증앱에서 얻은 인증 코드를 요구하여 계정의 보안에 추가적인 계층을 추가합니다.",
"Password is required": "비밀번호요합니다", "Password is required": "비밀번호수입니다",
"Password must be at least 8 characters": "비밀번호는 최소 8자 이상이어야 합니다", "Password must be at least 8 characters": "비밀번호는 8자 이상이어야 합니다",
"Please enter a 6-digit code": "6자리 코드를 입력해 주세요", "Please enter a 6-digit code": "6자리 코드를 입력세요",
"Code must be exactly 6 digits": "코드는 정확히 6자리여야 합니다", "Code must be exactly 6 digits": "코드는 정확히 6자리여야 합니다",
"Enter the 6-digit code found in your authenticator app": "인증앱에서 찾은 6자리 코드를 입력하십시오", "Enter the 6-digit code found in your authenticator app": "인증 앱에 표시된 6자리 코드를 입력하세요",
"Need help authenticating?": "인증에 도움이 필요하십니까?", "Need help authenticating?": "인증에 도움이 필요하십니까?",
"MFA QR Code": "MFA QR 코드", "MFA QR Code": "MFA QR 코드",
"Account created successfully. Please log in to set up two-factor authentication.": "계정이 성공적으로 생성되었습니다. 이중 인증을 설정하려면 로그인해 주세요.", "Account created successfully. Please log in to set up two-factor authentication.": "계정이 성공적으로 생성되었습니다. 이중 인증을 설정하려면 로그인해 주세요.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "비밀번호 재설정 성공. 새 비밀번호로 로그인하여 이중 인증을 완료하세요.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "비밀번호 재설정 성공. 새 비밀번호로 로그인하여 이중 인증을 완료하세요.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "비밀번호 재설정 성공. 새 비밀번호로 로그인하여 이중 인증을 설정하세요.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "비밀번호 재설정 성공. 새 비밀번호로 로그인하여 이중 인증을 설정하세요.",
"Password reset was successful. Please log in with your new password.": "비밀번호 재설정이 성공적으로 완료되었습니다. 새 비밀번호로 로그인하세요.", "Password reset was successful. Please log in with your new password.": "비밀번호 재설정이 성공적으로 완료되었습니다. 새 비밀번호로 로그인하세요.",
"Two-factor authentication": "이중 인증", "Two-factor authentication": "2단계 인증",
"Use authenticator app instead": "대신 인증 앱 사용", "Use authenticator app instead": "대신 인증 앱 사용",
"Verify backup code": "백업 코드 확인", "Verify backup code": "백업 코드 확인",
"Use backup code": "백업 코드 사용", "Use backup code": "백업 코드 사용",
@@ -540,37 +564,37 @@
"Restore '{{title}}' and its sub-pages?": "'{{title}}' 및 하위 페이지를 복구하시겠습니까?", "Restore '{{title}}' and its sub-pages?": "'{{title}}' 및 하위 페이지를 복구하시겠습니까?",
"Move to trash": "휴지통으로 이동", "Move to trash": "휴지통으로 이동",
"Move this page to trash?": "이 페이지를 휴지통으로 이동하시겠습니까?", "Move this page to trash?": "이 페이지를 휴지통으로 이동하시겠습니까?",
"Restore page": "페이지 복", "Restore page": "페이지 복",
"Page moved to trash": "페이지가 휴지통으로 이동되었습니다", "Page moved to trash": "페이지가 휴지통으로 이동되었습니다",
"Page restored successfully": "페이지가 성공적으로 복되었습니다", "Page restored successfully": "페이지가 성공적으로 복되었습니다",
"Deleted by": "삭제", "Deleted by": "삭제한 사람",
"Deleted at": "삭제 시간", "Deleted at": "삭제 시간",
"Preview": "미리보기", "Preview": "미리보기",
"Subpages": "하위 페이지", "Subpages": "하위 페이지",
"Failed to load subpages": "하위 페이지 로드 실패", "Failed to load subpages": "하위 페이지를 불러오지 못했습니다",
"No subpages": "하위 페이지 없", "No subpages": "하위 페이지습니다",
"Subpages (Child pages)": "하위 페이지 (자식 페이지)", "Subpages (Child pages)": "하위 페이지 (자식 페이지)",
"List all subpages of the current page": "현재 페이지의 모든 하위 페이지 목록", "List all subpages of the current page": "현재 페이지의 모든 하위 페이지 나열",
"Attachments": "첨부파일", "Attachments": "첨부파일",
"All spaces": "전체 공간", "All spaces": "모든 스페이스",
"Unknown": "알 수 없음", "Unknown": "알 수 없음",
"Find a space": "공간 찾기", "Find a space": "스페이스 찾기",
"Search in all your spaces": "모든 공간에서 검색", "Search in all your spaces": "모든 스페이스에서 검색",
"Type": "유형", "Type": "유형",
"Enterprise": "기업", "Enterprise": "엔터프라이즈",
"Download attachment": "첨부파일 다운로드", "Download attachment": "첨부파일 다운로드",
"Allowed email domains": "허용된 이메일 도메인", "Allowed email domains": "허용된 이메일 도메인",
"Only users with email addresses from these domains can signup via SSO.": "이 도메인의 이메일 주소를 가진 사용자만 SSO를 통해 가입할 수 있습니다.", "Only users with email addresses from these domains can signup via SSO.": "이 도메인의 이메일 주소를 가진 사용자만 SSO를 통해 가입할 수 있습니다.",
"Enter valid domain names separated by comma or space": "콤마 또는 공백으로 구분하여 유효한 도메인 이름 입력", "Enter valid domain names separated by comma or space": "쉼표 또는 공백으로 구분 유효한 도메인 이름 입력하세요",
"Enforce two-factor authentication": "이중 인증 시행", "Enforce two-factor authentication": "2단계 인증 강제",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "시행되면 모든 멤버가 작업 공간에 액세스하기 위해 이중 인증을 활성화해야 합니다.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "시행되면 모든 멤버가 작업 공간에 액세스하기 위해 이중 인증을 활성화해야 합니다.",
"Toggle MFA enforcement": "MFA 시행 전환", "Toggle MFA enforcement": "MFA 강제 설정 전환",
"Display name": "표시 이름", "Display name": "표시 이름",
"Allow signup": "가입 허용", "Allow signup": "가입 허용",
"Enabled": "활성화됨", "Enabled": "활성화됨",
"Advanced Settings": "고급 설정", "Advanced Settings": "고급 설정",
"Enable TLS/SSL": "TLS\\/SSL 활성화", "Enable TLS/SSL": "TLS/SSL 활성화",
"Use secure connection to LDAP server": "LDAP 서버에 안전한 연결 사용", "Use secure connection to LDAP server": "LDAP 서버에 안 연결 사용",
"Group sync": "그룹 동기화", "Group sync": "그룹 동기화",
"No SSO providers found.": "SSO 제공자를 찾을 수 없습니다.", "No SSO providers found.": "SSO 제공자를 찾을 수 없습니다.",
"Delete SSO provider": "SSO 제공자 삭제", "Delete SSO provider": "SSO 제공자 삭제",
@@ -613,6 +637,7 @@
"AI Answer": "AI 답변", "AI Answer": "AI 답변",
"Ask AI": "AI에게 묻기", "Ask AI": "AI에게 묻기",
"AI is thinking...": "AI가 생각 중입니다...", "AI is thinking...": "AI가 생각 중입니다...",
"Thinking": "생각 중",
"Ask a question...": "질문하세요...", "Ask a question...": "질문하세요...",
"AI Answers": "AI 답변", "AI Answers": "AI 답변",
"AI-powered search (AI Answers)": "AI 구동 검색 (AI 답변)", "AI-powered search (AI Answers)": "AI 구동 검색 (AI 답변)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "생성 AI (Ask AI)", "Generative AI (Ask AI)": "생성 AI (Ask AI)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "편집기에서 AI 구동 콘텐츠 생성을 활성화합니다. 사용자가 텍스트를 생성, 개선, 번역 및 변환할 수 있습니다.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "편집기에서 AI 구동 콘텐츠 생성을 활성화합니다. 사용자가 텍스트를 생성, 개선, 번역 및 변환할 수 있습니다.",
"Toggle generative AI": "생성 AI 토글", "Toggle generative AI": "생성 AI 토글",
"Enterprise feature": "엔터프라이즈 기능", "Upgrade your plan": "요금제를 업그레이드하세요",
"Available with a paid license": "유료 라이선스에서만 사용 가능합니다",
"Upgrade your license tier.": "라이선스 등급을 업그레이드하세요.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI는 Docmost 엔터프라이즈 에디션에서만 제공됩니다. sales@docmost.com으로 문의하세요.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI는 Docmost 엔터프라이즈 에디션에서만 제공됩니다. sales@docmost.com으로 문의하세요.",
"AI & MCP": "AI 및 MCP", "AI & MCP": "AI 및 MCP",
"AI": "AI", "AI": "AI",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "모델 컨텍스트 프로토콜(MCP)", "Model Context Protocol (MCP)": "모델 컨텍스트 프로토콜(MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "AI 어시스턴트와 도구가 워크스페이스 콘텐츠와 상호작용할 수 있도록 MCP 서버를 활성화하세요.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "AI 어시스턴트와 도구가 워크스페이스 콘텐츠와 상호작용할 수 있도록 MCP 서버를 활성화하세요.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP는 Docmost 엔터프라이즈 에디션에서만 제공됩니다. sales@docmost.com으로 문의하세요.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP는 Docmost 엔터프라이즈 에디션에서만 제공됩니다. sales@docmost.com으로 문의하세요.",
"MCP documentation": "MCP 문서",
"MCP Server URL": "MCP 서버 URL", "MCP Server URL": "MCP 서버 URL",
"Use your API key for authentication. You can manage API keys in your account settings.": "인증을 위해 API 키를 사용하세요. API 키는 계정 설정에서 관리할 수 있습니다.", "Use your API key for authentication. You can manage API keys in your account settings.": "인증을 위해 API 키를 사용하세요. API 키는 계정 설정에서 관리할 수 있습니다.",
"Supported tools": "지원되는 도구", "Supported tools": "지원되는 도구",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "워크스페이스에 MCP가 활성화되어 있습니다. AI 어시스턴트를 연결하려면 API 키를 사용하세요.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "워크스페이스에 MCP가 활성화되어 있습니다. AI 어시스턴트를 연결하려면 API 키를 사용하세요.",
"MCP server URL:": "MCP 서버 URL:", "MCP server URL:": "MCP 서버 URL:",
"Learn more": "자세히 알아보기", "Learn more": "자세히 알아보기",
"View the": "다음을", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "워크스페이스의 모든 사용자를 위한 API 키를 관리하세요. 사용 방법은 <anchor>API 문서</anchor>를 참고하세요.",
"for usage details.": "에서 사용 방법을 확인하세요.", "View the <anchor>API documentation</anchor> for usage details.": "사용 방법은 <anchor>API 문서</anchor>를 참고하세요.",
"for setup instructions.": "에서 설정 지침을 확인하세요.", "View the <anchor>MCP documentation</anchor>.": "<anchor>MCP 문서</anchor>를 확인하세요.",
"API documentation": "API 문서",
"Sources": "출처", "Sources": "출처",
"AI Answers not available for attachments": "첨부 파일에 대해 AI 답변을 사용할 수 없습니다", "AI Answers not available for attachments": "첨부 파일에 대해 AI 답변을 사용할 수 없습니다",
"No answer available": "답변을 제공할 수 없습니다", "No answer available": "답변을 제공할 수 없습니다",
@@ -654,12 +679,34 @@
"Mark all as read": "모두 읽음으로 표시", "Mark all as read": "모두 읽음으로 표시",
"Mark as read": "읽음으로 표시", "Mark as read": "읽음으로 표시",
"More options": "추가 옵션", "More options": "추가 옵션",
"mentioned you in a comment": "댓글에서 당신을 언급했습니다", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold>님이 댓글에서 당신을 언급했습니다",
"commented on a page": "페이지에 댓글을 달았습니다", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold>님이 페이지에 댓글을 남겼습니다",
"resolved a comment": "댓글을 해결했습니다", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold>님이 댓글을 해결했습니다",
"mentioned you on a page": "페이지에서 당신을 언급했습니다", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold>님이 페이지에서 나를 멘션했습니다",
"gave you edit access to a page": "페이지 편집 권한을 부여했습니다", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold>님이 페이지 편집 권한을 부여했습니다",
"gave you view access to a page": "페이지 보기 권한을 부여했습니다", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold>님이 페이지 보기 권한을 부여했습니다",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold>님이 페이지를 업데이트했습니다",
"Watch page": "페이지 구독",
"Stop watching": "구독 중지",
"Watch space": "스페이스 구독",
"Stop watching space": "스페이스 구독 중지",
"Email notifications": "이메일 알림",
"Page updates": "페이지 업데이트",
"Get notified when pages you watch are updated.": "구독한 페이지가 업데이트될 때 알림을 받으세요.",
"Page mentions": "페이지 언급",
"Get notified when someone mentions you on a page.": "누군가가 페이지에서 당신을 언급하면 알림을 받으세요.",
"Comment mentions": "댓글 언급",
"Get notified when someone mentions you in a comment.": "누군가가 댓글에서 당신을 언급하면 알림을 받으세요.",
"New comments": "새 댓글",
"Get notified about new comments on threads you participate in.": "참여 중인 스레드에 새 댓글이 달리면 알림을 받으세요.",
"Resolved comments": "해결된 댓글",
"Get notified when your comment is resolved.": "내 댓글이 해결되었을 때 알림을 받으세요.",
"You are now watching this page": "이제 이 페이지를 주시합니다.",
"You are no longer watching this page": "더 이상 이 페이지를 주시하지 않습니다.",
"You are now watching this space": "이제 이 스페이스를 구독합니다",
"You are no longer watching this space": "더 이상 이 스페이스를 구독하지 않습니다",
"Direct": "직접",
"Updates": "업데이트",
"Today": "오늘", "Today": "오늘",
"Yesterday": "어제", "Yesterday": "어제",
"This week": "이번 주", "This week": "이번 주",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "휴지통 보관 기간 업데이트에 실패했습니다.", "Failed to update trash retention": "휴지통 보관 기간 업데이트에 실패했습니다.",
"Removed page restriction": "페이지 제한이 제거됨", "Removed page restriction": "페이지 제한이 제거됨",
"Added page permission": "페이지 권한이 추가됨", "Added page permission": "페이지 권한이 추가됨",
"Removed page permission": "페이지 권한이 제거됨" "Removed page permission": "페이지 권한이 제거됨",
"day": "일",
"days": "일",
"week": "주",
"weeks": "주",
"month": "개월",
"months": "개월",
"year": "년",
"years": "년",
"Period": "기간",
"Fixed date": "고정 날짜",
"Indefinitely": "무기한",
"Days": "일",
"Weeks": "주",
"Months": "개월",
"Years": "년",
"Pick a date": "날짜 선택",
"Maximum is {{max}} {{unit}} for this unit": "이 단위의 최대값은 {{max}} {{unit}}입니다",
"Never expires. Verifiers can re-verify at any time.": "만료되지 않습니다. 검증자는 언제든지 다시 검증할 수 있습니다.",
"Verified": "검증됨",
"Review needed": "검토 필요",
"Verification expired": "검증 만료됨",
"Draft": "초안",
"In Approval": "승인 진행 중",
"In approval": "승인 진행 중",
"Approved": "승인됨",
"Obsolete": "폐기됨",
"Expiring": "만료 예정",
"Set up verification": "검증 설정",
"Verify page": "페이지 검증",
"Page verification": "페이지 검증",
"Add verification": "검증 추가",
"Edit verification": "검증 편집",
"Search by title": "제목으로 검색",
"Choose how this page should stay accurate.": "이 페이지의 정확성을 유지할 방법을 선택하세요.",
"Recurring verification": "반복 검증",
"Verifiers re-confirm this page on a schedule.": "검증자가 일정에 따라 이 페이지를 다시 확인합니다.",
"Re-verify on a schedule (e.g every 30 days )": "일정에 따라 다시 검증(예: 30일마다)",
"Page stays editable at all times": "페이지는 항상 편집 가능합니다",
"Best for runbooks, FAQs, living documentation": "런북, FAQ, 살아 있는 문서에 적합",
"Approval workflow": "승인 워크플로",
"Formal document lifecycle with named approvers.": "지정된 승인자가 있는 공식 문서 수명 주기입니다.",
"Draft → In approval → Approved → Obsolete": "초안 → 승인 진행 중 → 승인됨 → 폐기됨",
"Locked once approved, with full history": "승인되면 잠기며 전체 이력이 유지됩니다",
"Designed for ISO 9001, ISO 13485, and FDA": "ISO 9001, ISO 13485 및 FDA용으로 설계됨",
"Best for SOPs and controlled documents": "SOP 및 관리 문서에 적합",
"Back": "뒤로",
"Quality management": "품질 관리",
"Recurring": "반복",
"Pages move through draft, approval, and approved stages.": "페이지는 초안, 승인, 승인됨 단계를 거칩니다.",
"Verifiers": "검증자",
"Add verifier": "검증자 추가",
"I've reviewed this page for accuracy": "이 페이지의 정확성을 검토했습니다",
"Set up": "설정",
"Remove verification": "검증 제거",
"Are you sure you want to remove verification from this page?": "이 페이지에서 검증을 제거하시겠습니까?",
"Assigned verifiers must periodically re-verify this page.": "지정된 검증자는 이 페이지를 주기적으로 다시 검증해야 합니다.",
"Last verified by {{name}} {{time}} (expired)": "마지막 검증자: {{name}} {{time}} (만료됨)",
"The fixed expiration date has passed.": "고정된 만료일이 지났습니다.",
"Verified by {{name}} {{time}}": "검증자: {{name}} {{time}}",
"Expires {{date}}": "{{date}}에 만료",
"Expired {{date}}": "{{date}}에 만료됨",
"Mark as obsolete": "폐기로 표시",
"Mark obsolete": "폐기 표시",
"Returned by {{name}} {{time}}": "반려자: {{name}} {{time}}",
"No approval has been requested yet.": "아직 승인이 요청되지 않았습니다.",
"Submitted by {{name}} {{time}}": "제출자: {{name}} {{time}}",
"Someone": "누군가",
"Approved by {{name}} {{time}}": "승인자: {{name}} {{time}}",
"This document has been marked as obsolete.": "이 문서는 폐기로 표시되었습니다.",
"Rejection comment": "반려 사유",
"Reason for returning this document...": "이 문서를 반려하는 이유...",
"Confirm rejection": "반려 확인",
"Submit for approval": "승인 요청",
"Reject": "반려",
"Approve": "승인",
"Re-submit for approval": "승인 재요청",
"Verified until": "다음까지 검증됨",
"QMS": "QMS",
"Verified pages": "검증된 페이지",
"Search pages...": "페이지 검색...",
"Filter by space": "스페이스별 필터",
"Filter by type": "유형별 필터",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold>님이 페이지를 검증했습니다",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold>님이 승인을 위해 페이지를 제출했습니다",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold>님이 수정을 위해 페이지를 반려했습니다",
"Page verification expires soon": "페이지 검토가 곧 만료됩니다",
"Page verification has expired": "페이지 검토가 만료되었습니다",
"Verifying your email": "이메일 확인 중",
"Please wait...": "잠시만 기다려 주세요...",
"Verification failed. The link may have expired.": "인증에 실패했습니다. 링크가 만료되었을 수 있습니다.",
"Check your email": "이메일을 확인하세요",
"We sent a verification link to {{email}}.": "{{email}} 주소로 인증 링크를 보냈습니다.",
"We sent a verification link to your email.": "이메일로 인증 링크를 보냈습니다.",
"Click the link to verify your email and access your workspace.": "이메일의 링크를 클릭하여 인증하고 워크스페이스에 접속하세요.",
"Resend verification email": "인증 이메일 다시 보내기",
"Verification email sent. Please check your inbox.": "인증 이메일이 전송되었습니다. 받은 편지함을 확인하세요.",
"Failed to resend verification email. Please try again.": "인증 이메일 재전송에 실패했습니다. 다시 시도해 주세요.",
"We've sent you an email with your associated workspaces.": "연결된 워크스페이스 목록이 포함된 이메일을 보내드렸습니다.",
"Load more": "더 보기",
"Log out of all devices": "모든 기기에서 로그아웃",
"Log out of all sessions except this device": "이 기기를 제외한 모든 세션에서 로그아웃",
"This Device": "이 기기",
"Unknown device": "알 수 없는 기기",
"No active sessions": "활성 세션이 없습니다",
"Session revoked": "세션이 해제되었습니다",
"All other sessions revoked": "다른 모든 세션이 해제되었습니다",
"Last used": "마지막 사용",
"Created": "생성됨",
"Rename": "이름 변경",
"Publish": "게시",
"Security": "보안",
"Enforce SSO": "SSO 강제",
"Once enforced, members will not be able to login with email and password.": "강제 적용되면 멤버는 이메일과 비밀번호로 로그인할 수 없습니다.",
"AI-generated content may not be accurate.": "AI가 생성한 콘텐츠는 정확하지 않을 수 있습니다.",
"AI Chat": "AI 채팅",
"Analyze for insights": "인사이트 분석",
"Ask anything...": "무엇이든 물어보세요...",
"Chat history": "채팅 기록",
"Chat name": "채팅 이름",
"Close": "닫기",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "채팅을 불러오지 못했습니다. 오류가 발생했습니다.",
"Failed to render this message.": "이 메시지를 렌더링하지 못했습니다.",
"How can I help you today?": "오늘 무엇을 도와드릴까요?",
"New chat": "새 채팅",
"No chat history": "채팅 기록이 없습니다",
"No chats found": "채팅을 찾을 수 없습니다",
"No conversations yet": "아직 대화가 없습니다",
"Open full page": "전체 페이지 열기",
"Previous 7 days": "지난 7일",
"Previous 30 days": "지난 30일",
"Search chats...": "채팅 검색...",
"Start a new chat to see it here.": "여기에 표시하려면 새 채팅을 시작하세요.",
"Summarize this page": "이 페이지 요약",
"Toggle AI Chat": "AI 채팅 전환",
"Translate this page": "이 페이지 번역",
"Try a different search term.": "다른 검색어를 사용해 보세요.",
"Try again": "다시 시도",
"Untitled chat": "제목 없는 채팅",
"What can I help you with?": "무엇을 도와드릴까요?"
} }
+298 -111
View File
@@ -7,6 +7,7 @@
"Add members": "Leden toevoegen", "Add members": "Leden toevoegen",
"Add to groups": "Toevoegen aan groepen", "Add to groups": "Toevoegen aan groepen",
"Add space members": "Voeg leden toe ruimte", "Add space members": "Voeg leden toe ruimte",
"Add to favorites": "Toevoegen aan favorieten",
"Admin": "Beheerder", "Admin": "Beheerder",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Weet je zeker dat je deze groep wilt verwijderen? Leden verliezen toegang tot documenten waar deze groep toegang toe heeft.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Weet je zeker dat je deze groep wilt verwijderen? Leden verliezen toegang tot documenten waar deze groep toegang toe heeft.",
"Are you sure you want to delete this page?": "Weet u zeker dat u deze pagina wil verwijderen?", "Are you sure you want to delete this page?": "Weet u zeker dat u deze pagina wil verwijderen?",
@@ -49,8 +50,8 @@
"e.g Developers": "bijv. Ontwikkelaars", "e.g Developers": "bijv. Ontwikkelaars",
"e.g Group for developers": "bijv. Groep voor ontwikkelaars", "e.g Group for developers": "bijv. Groep voor ontwikkelaars",
"e.g product": "bijv. product", "e.g product": "bijv. product",
"e.g Product Team": "bijv. Product Team", "e.g Product Team": "bijv. Productteam",
"e.g Sales": "bijv. Verkopen", "e.g Sales": "bijv. Verkoop",
"e.g Space for product team": "bijv. Ruimte voor productteam", "e.g Space for product team": "bijv. Ruimte voor productteam",
"e.g Space for sales team to collaborate": "bijv. Ruimte voor verkoopteam om samen te werken", "e.g Space for sales team to collaborate": "bijv. Ruimte voor verkoopteam om samen te werken",
"Edit": "Bewerken", "Edit": "Bewerken",
@@ -61,7 +62,7 @@
"Enter valid email addresses separated by comma or space max_50": "Voer geldige e-mailadressen in, gescheiden door komma of spatie [max: 50]", "Enter valid email addresses separated by comma or space max_50": "Voer geldige e-mailadressen in, gescheiden door komma of spatie [max: 50]",
"enter valid emails addresses": "voer geldige e-mailadressen in", "enter valid emails addresses": "voer geldige e-mailadressen in",
"Enter your current password": "Voer uw huidige wachtwoord in", "Enter your current password": "Voer uw huidige wachtwoord in",
"enter your full name": "voer uw volledige naam in", "enter your full name": "voer je volledige naam in",
"Enter your new password": "Voer uw nieuwe wachtwoord in", "Enter your new password": "Voer uw nieuwe wachtwoord in",
"Enter your new preferred email": "Voer uw nieuwe e-mailadres in", "Enter your new preferred email": "Voer uw nieuwe e-mailadres in",
"Enter your password": "Voer uw wachtwoord in", "Enter your password": "Voer uw wachtwoord in",
@@ -74,6 +75,9 @@
"Failed to import pages": "Pagina's importeren mislukt", "Failed to import pages": "Pagina's importeren mislukt",
"Failed to load page. An error occurred.": "Laden van pagina mislukt. Er is een fout opgetreden.", "Failed to load page. An error occurred.": "Laden van pagina mislukt. Er is een fout opgetreden.",
"Failed to update data": "Bijwerken van gegevens mislukt", "Failed to update data": "Bijwerken van gegevens mislukt",
"Favorite spaces": "Favoriete ruimtes",
"Favorite spaces appear here": "Favoriete ruimtes verschijnen hier",
"Favorites": "Favorieten",
"Full access": "Volledig toegang", "Full access": "Volledig toegang",
"Full page width": "Volledige pagina breedte", "Full page width": "Volledige pagina breedte",
"Full width": "Volledige breedte", "Full width": "Volledige breedte",
@@ -92,6 +96,7 @@
"Invite by email": "Uitnodigen via e-mail", "Invite by email": "Uitnodigen via e-mail",
"Invite members": "Leden uitnodigen", "Invite members": "Leden uitnodigen",
"Invite new members": "Nieuwe leden uitnodigen", "Invite new members": "Nieuwe leden uitnodigen",
"Invite People": "Mensen uitnodigen",
"Invited members who are yet to accept their invitation will appear here.": "Uitgenodigde leden die hun uitnodiging nog moeten accepteren zullen hier worden getoond.", "Invited members who are yet to accept their invitation will appear here.": "Uitgenodigde leden die hun uitnodiging nog moeten accepteren zullen hier worden getoond.",
"Invited members will be granted access to spaces the groups can access": "Uitgenodigde leden wordt toegang gegeven tot ruimtes de groepen toegang toe heeft", "Invited members will be granted access to spaces the groups can access": "Uitgenodigde leden wordt toegang gegeven tot ruimtes de groepen toegang toe heeft",
"Join the workspace": "Word lid van de werkruimte", "Join the workspace": "Word lid van de werkruimte",
@@ -139,6 +144,7 @@
"Profile": "Profiel", "Profile": "Profiel",
"Recently updated": "Recent bijgewerkt", "Recently updated": "Recent bijgewerkt",
"Remove": "Verwijderen", "Remove": "Verwijderen",
"Remove from favorites": "Verwijderen uit favorieten",
"Remove group member": "Lid uit groep verwijderd", "Remove group member": "Lid uit groep verwijderd",
"Remove space member": "Lid uit ruimte verwijderd", "Remove space member": "Lid uit ruimte verwijderd",
"Restore": "Herstellen", "Restore": "Herstellen",
@@ -151,23 +157,23 @@
"Search...": "Zoeken...", "Search...": "Zoeken...",
"Select language": "Selecteer taal", "Select language": "Selecteer taal",
"Select role": "Selecteer rol", "Select role": "Selecteer rol",
"Select role to assign to all invited members": "Selecteer rol en wijs toe aan alle uitgenodigde leden", "Select role to assign to all invited members": "Selecteer een rol om toe te wijzen aan alle uitgenodigde leden",
"Select theme": "Selecteer thema", "Select theme": "Selecteer thema",
"Send invitation": "Uitnodiging versturen", "Send invitation": "Uitnodiging verzenden",
"Invitation sent": "Uitnodiging verzonden", "Invitation sent": "Uitnodiging verzonden",
"Settings": "Instellingen", "Settings": "Instellingen",
"Setup workspace": "Werkruimte instellen", "Setup workspace": "Werkruimte instellen",
"Sign In": "Inloggen", "Sign In": "Inloggen",
"Sign Up": "Aanmelden", "Sign Up": "Registreren",
"Slug": "Afkorting", "Slug": "Slug",
"Space": "Ruimte", "Space": "Ruimte",
"Space description": "Omschrijving van de ruimte", "Space description": "Ruimtebeschrijving",
"Space menu": "Ruimtemenu", "Space menu": "Ruimtemenu",
"Space name": "Naam ruimte", "Space name": "Ruimtenaam",
"Space settings": "Ruimte instellingen", "Space settings": "Ruimte-instellingen",
"Space slug": "Ruimte afkorting", "Space slug": "Ruimte-slug",
"Spaces": "Ruimtes", "Spaces": "Ruimtes",
"Spaces you belong to": "Ruimtes waar je bij hoort", "Spaces you belong to": "Ruimtes waarvan je lid bent",
"No space found": "Geen ruimte gevonden", "No space found": "Geen ruimte gevonden",
"Search for spaces": "Zoek naar ruimtes", "Search for spaces": "Zoek naar ruimtes",
"Start typing to search...": "Begin met typen om te zoeken...", "Start typing to search...": "Begin met typen om te zoeken...",
@@ -175,29 +181,30 @@
"Successfully imported": "Succesvol geïmporteerd", "Successfully imported": "Succesvol geïmporteerd",
"Successfully restored": "Succesvol hersteld", "Successfully restored": "Succesvol hersteld",
"System settings": "Systeeminstellingen", "System settings": "Systeeminstellingen",
"Templates": "Sjablonen",
"Theme": "Thema", "Theme": "Thema",
"To change your email, you have to enter your password and new email.": "Om uw e-mailadres te wijzigen, moet u uw wachtwoord en nieuwe e-mail invullen.", "To change your email, you have to enter your password and new email.": "Om uw e-mailadres te wijzigen, moet u uw wachtwoord en nieuwe e-mail invullen.",
"Toggle full page width": "Schakel volledige pagina breedte in", "Toggle full page width": "Volledige paginabreedte in-/uitschakelen",
"Unable to import pages. Please try again.": "Pagina's importeren is niet gelukt. Probeer het opnieuw.", "Unable to import pages. Please try again.": "Pagina's importeren is niet gelukt. Probeer het opnieuw.",
"untitled": "naamloos", "untitled": "zonder titel",
"Untitled": "Naamloos", "Untitled": "Zonder titel",
"Updated successfully": "Succesvol bijgewerkt", "Updated successfully": "Succesvol bijgewerkt",
"User": "Gebruiker", "User": "Gebruiker",
"Workspace": "Werkruimte", "Workspace": "Werkruimte",
"Workspace Name": "Naam werkruimte", "Workspace Name": "Naam van werkruimte",
"Workspace settings": "Instellingen werkruimte", "Workspace settings": "Werkruimte-instellingen",
"You can change your password here.": "U kunt hier uw wachtwoord wijzigen.", "You can change your password here.": "U kunt hier uw wachtwoord wijzigen.",
"Your Email": "Uw e-mailadres", "Your Email": "Je e-mailadres",
"Your import is complete.": "Uw import is voltooid.", "Your import is complete.": "Uw import is voltooid.",
"Your name": "Uw naam", "Your name": "Je naam",
"Your Name": "Uw Naam", "Your Name": "Je naam",
"Your password": "Uw wachtwoord", "Your password": "Je wachtwoord",
"Your password must be a minimum of 8 characters.": "Uw wachtwoord moet minimaal 8 tekens bevatten.", "Your password must be a minimum of 8 characters.": "Uw wachtwoord moet minimaal 8 tekens bevatten.",
"Sidebar toggle": "Zijbalk toggelen", "Sidebar toggle": "Zijbalk in-/uitschakelen",
"Comments": "Opmerkingen", "Comments": "Opmerkingen",
"404 page not found": "404 pagina niet gevonden", "404 page not found": "404 pagina niet gevonden",
"Sorry, we can't find the page you are looking for.": "Sorry, we kunnen de pagina die u zoekt niet vinden.", "Sorry, we can't find the page you are looking for.": "Sorry, we kunnen de pagina die u zoekt niet vinden.",
"Take me back to homepage": "Ga terug naar de homepage", "Take me back to homepage": "Breng me terug naar de homepage",
"Forgot password": "Wachtwoord vergeten", "Forgot password": "Wachtwoord vergeten",
"Forgot your password?": "Wachtwoord vergeten?", "Forgot your password?": "Wachtwoord vergeten?",
"A password reset link has been sent to your email. Please check your inbox.": "Een link om uw wachtwoord te resetten is verstuurd naar uw e-mail. Controleer uw inbox.", "A password reset link has been sent to your email. Please check your inbox.": "Een link om uw wachtwoord te resetten is verstuurd naar uw e-mail. Controleer uw inbox.",
@@ -215,6 +222,8 @@
"Edit comment": "Bewerk reactie", "Edit comment": "Bewerk reactie",
"Delete comment": "Verwijder reactie", "Delete comment": "Verwijder reactie",
"Are you sure you want to delete this comment?": "Weet je zeker dat je deze reactie wilt verwijderen?", "Are you sure you want to delete this comment?": "Weet je zeker dat je deze reactie wilt verwijderen?",
"Delete chat": "Chat verwijderen",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Weet je zeker dat je '{{title}}' wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.",
"Comment created successfully": "Reactie succesvol aangemaakt", "Comment created successfully": "Reactie succesvol aangemaakt",
"Error creating comment": "Fout bij het aanmaken van reactie", "Error creating comment": "Fout bij het aanmaken van reactie",
"Comment updated successfully": "Opmerking succesvol bijgewerkt", "Comment updated successfully": "Opmerking succesvol bijgewerkt",
@@ -222,13 +231,13 @@
"Comment deleted successfully": "Reactie met succes verwijderd", "Comment deleted successfully": "Reactie met succes verwijderd",
"Failed to delete comment": "Verwijderen van reactie mislukt", "Failed to delete comment": "Verwijderen van reactie mislukt",
"Comment resolved successfully": "Reactie succesvol opgelost", "Comment resolved successfully": "Reactie succesvol opgelost",
"Comment re-opened successfully": "Reactie succesvol heropend", "Comment re-opened successfully": "Opmerking succesvol heropend",
"Comment unresolved successfully": "Reactie succesvol niet-opgelost gemaakt", "Comment unresolved successfully": "Opmerking succesvol als onopgelost gemarkeerd",
"Failed to resolve comment": "Reactie oplossen mislukt", "Failed to resolve comment": "Reactie oplossen mislukt",
"Resolve comment": "Reactie oplossen", "Resolve comment": "Opmerking oplossen",
"Unresolve comment": "Reactie niet oplossen", "Unresolve comment": "Markering opgelost ongedaan maken",
"Resolve Comment Thread": "Reactiedraad oplossen", "Resolve Comment Thread": "Opmerkingsthread oplossen",
"Unresolve Comment Thread": "Reactiedraad niet oplossen", "Unresolve Comment Thread": "Oplossen van opmerkingsthread ongedaan maken",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Weet u zeker dat u deze reactiedraad wilt oplossen? Dit zal het als voltooid markeren.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Weet u zeker dat u deze reactiedraad wilt oplossen? Dit zal het als voltooid markeren.",
"Are you sure you want to unresolve this comment thread?": "Weet u zeker dat u deze reactiedraad niet wilt oplossen?", "Are you sure you want to unresolve this comment thread?": "Weet u zeker dat u deze reactiedraad niet wilt oplossen?",
"Resolved": "Opgelost", "Resolved": "Opgelost",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "Weet u zeker dat u deze ruimte wil verwijderen?", "Are you sure you want to delete this space?": "Weet u zeker dat u deze ruimte wil verwijderen?",
"Delete this space with all its pages and data.": "Verwijder deze ruimte met alle pagina's en gegevens.", "Delete this space with all its pages and data.": "Verwijder deze ruimte met alle pagina's en gegevens.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Alle pagina's, opmerkingen, bijlagen en permissies in deze ruimte zullen onherroepelijk worden verwijderd.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Alle pagina's, opmerkingen, bijlagen en permissies in deze ruimte zullen onherroepelijk worden verwijderd.",
"Confirm space name": "Bevestig naam van ruimte", "Confirm space name": "Bevestig ruimtenaam",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Typ de ruimtenaam <b>{{spaceName}}</b> om uw actie te bevestigen.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "Typ de ruimtenaam <b>{{spaceName}}</b> om uw actie te bevestigen.",
"Format": "Formaat", "Format": "Formaat",
"Include subpages": "Inclusief onderliggend pagina's", "Include subpages": "Inclusief onderliggend pagina's",
@@ -289,6 +298,11 @@
"Save & Exit": "Opslaan & Afsluiten", "Save & Exit": "Opslaan & Afsluiten",
"Double-click to edit Excalidraw diagram": "Dubbelklik om Excalidraw diagram te bewerken", "Double-click to edit Excalidraw diagram": "Dubbelklik om Excalidraw diagram te bewerken",
"Paste link": "Link plakken", "Paste link": "Link plakken",
"Paste link or search pages": "Plak link of zoek pagina's",
"Link to web page": "Link naar webpagina",
"Recents": "Recent",
"Page or URL": "Pagina of URL",
"Link title": "Kop van de link",
"Edit link": "Link bewerken", "Edit link": "Link bewerken",
"Remove link": "Link verwijderen", "Remove link": "Link verwijderen",
"Add link": "Link toevoegen", "Add link": "Link toevoegen",
@@ -307,7 +321,7 @@
"Pink": "Roze", "Pink": "Roze",
"Gray": "Grijs", "Gray": "Grijs",
"Embed link": "Link insluiten", "Embed link": "Link insluiten",
"Invalid {{provider}} embed link": "Ongeldige {{provider}} insluitingslink", "Invalid {{provider}} embed link": "Ongeldige {{provider}}-insluitlink",
"Embed {{provider}}": "Insluiten {{provider}}", "Embed {{provider}}": "Insluiten {{provider}}",
"Enter {{provider}} link to embed": "Voer {{provider}} link in om in te voegen", "Enter {{provider}} link to embed": "Voer {{provider}} link in om in te voegen",
"Bold": "Dikgedrukt", "Bold": "Dikgedrukt",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Horizontale lijn invoegen", "Insert horizontal rule divider": "Horizontale lijn invoegen",
"Upload any image from your device.": "Upload een afbeelding vanaf uw apparaat.", "Upload any image from your device.": "Upload een afbeelding vanaf uw apparaat.",
"Upload any video from your device.": "Upload een video vanaf uw apparaat.", "Upload any video from your device.": "Upload een video vanaf uw apparaat.",
"Upload any audio from your device.": "Upload een audio vanaf uw apparaat.",
"Upload any file from your device.": "Upload een bestand vanaf uw apparaat.", "Upload any file from your device.": "Upload een bestand vanaf uw apparaat.",
"Uploading {{name}}": "Uploaden {{name}}", "Uploading {{name}}": "Uploaden {{name}}",
"Uploading file": "Bestand uploaden", "Uploading file": "Bestand uploaden",
@@ -344,21 +359,27 @@
"Insert collapsible block.": "Inklapbaar blok invoegen.", "Insert collapsible block.": "Inklapbaar blok invoegen.",
"Video": "Video", "Video": "Video",
"Divider": "Scheidingslijn", "Divider": "Scheidingslijn",
"Quote": "Quote", "Quote": "Citaat",
"Image": "Afbeelding", "Image": "Afbeelding",
"File attachment": "Bestand bijlage", "Audio": "Audio",
"Toggle block": "Schakel blok in/uit", "Embed PDF": "PDF insluiten",
"Callout": "Opmerking", "Upload and embed a PDF file.": "Upload en sluit een PDF-bestand in.",
"Embed as PDF": "Insluiten als PDF",
"Failed to load PDF": "Laden van PDF mislukt",
"Convert to attachment": "Converteren naar bijlage",
"File attachment": "Bestandsbijlage",
"Toggle block": "In-/uitklapbaar blok",
"Callout": "Uitgelicht blok",
"Insert callout notice.": "Invoegen opmerking.", "Insert callout notice.": "Invoegen opmerking.",
"Math inline": "Wiskundige inline", "Math inline": "Inline wiskunde",
"Insert inline math equation.": "Wiskundige inline vergelijking invoegen.", "Insert inline math equation.": "Wiskundige inline vergelijking invoegen.",
"Math block": "Wiskundeblok", "Math block": "Wiskundeblok",
"Insert math equation": "Wiskundige inline vergelijking invoegen", "Insert math equation": "Wiskundige vergelijking invoegen",
"Mermaid diagram": "Mermaid diagram", "Mermaid diagram": "Mermaid-diagram",
"Insert mermaid diagram": "Voeg mermaid diagram in", "Insert mermaid diagram": "Mermaid-diagram invoegen",
"Insert and design Drawio diagrams": "Drawio diagrammen invoegen en ontwerpen", "Insert and design Drawio diagrams": "Drawio-diagrammen invoegen en ontwerpen",
"Insert current date": "Huidige datum invoeren", "Insert current date": "Huidige datum invoegen",
"Draw and sketch excalidraw diagrams": "Teken en schets excalidraw diagrammen", "Draw and sketch excalidraw diagrams": "Excalidraw-diagrammen tekenen en schetsen",
"Multiple": "Meerdere", "Multiple": "Meerdere",
"Turn into": "Omzetten naar", "Turn into": "Omzetten naar",
"Text align": "Tekstuitlijning", "Text align": "Tekstuitlijning",
@@ -366,8 +387,8 @@
"Go to homepage": "Ga naar de startpagina", "Go to homepage": "Ga naar de startpagina",
"Pages you create will show up here.": "Pagina's die u aanmaakt, verschijnen hier.", "Pages you create will show up here.": "Pagina's die u aanmaakt, verschijnen hier.",
"Heading {{level}}": "Kop {{level}}", "Heading {{level}}": "Kop {{level}}",
"Toggle title": "Schakel titel in/uit", "Toggle title": "Titel in-/uitklappen",
"Write anything. Enter \"/\" for commands": "Schrijf iets. Voer \"/\" in voor commando's", "Write anything. Enter \"/\" for commands": "Schrijf iets. Typ \"/\" voor opdrachten",
"Write...": "Typ...", "Write...": "Typ...",
"Column count": "Aantal kolommen", "Column count": "Aantal kolommen",
"{{count}} Columns": "{{count}} kolommen", "{{count}} Columns": "{{count}} kolommen",
@@ -385,18 +406,18 @@
"Space deleted successfully": "Ruimte succesvol verwijderd", "Space deleted successfully": "Ruimte succesvol verwijderd",
"Members added successfully": "Leden succesvol toegevoegd", "Members added successfully": "Leden succesvol toegevoegd",
"Member removed successfully": "Lid succesvol verwijderd", "Member removed successfully": "Lid succesvol verwijderd",
"Member role updated successfully": "Lidrol succesvol bijgewerkt", "Member role updated successfully": "Rol van lid succesvol bijgewerkt",
"Created by: <b>{{creatorName}}</b>": "Gemaakt door: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "Aangemaakt door: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Aangemaakt op: {{time}}", "Created at: {{time}}": "Aangemaakt op: {{time}}",
"Edited by {{name}} {{time}}": "Bewerkt door {{name}} {{time}}", "Edited by {{name}} {{time}}": "Bewerkt door {{name}} {{time}}",
"Word count: {{wordCount}}": "Aantal woorden: {{wordCount}}", "Word count: {{wordCount}}": "Aantal woorden: {{wordCount}}",
"Character count: {{characterCount}}": "Aantal tekens: {{characterCount}}", "Character count: {{characterCount}}": "Aantal tekens: {{characterCount}}",
"New update": "Nieuwe update", "New update": "Nieuwe update",
"{{latestVersion}} is available": "{{latestVersion}} is beschikbaar", "{{latestVersion}} is available": "{{latestVersion}} is beschikbaar",
"Default page edit mode": "Standaard pagina bewerkmodus", "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 your preferred page edit mode. Avoid accidental edits.": "Kies uw voorkeurs bewerkmodus voor pagina's. Vermijd per ongeluk bewerken.",
"Reading": "Lezen", "Reading": "Lezen",
"Delete member": "Verwijder lid", "Delete member": "Lid verwijderen",
"Member deleted successfully": "Lid succesvol verwijderd", "Member deleted successfully": "Lid succesvol verwijderd",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Weet u zeker dat u dit lid van de werkruimte wilt verwijderen? Deze actie kan niet ongedaan gemaakt worden.", "Are you sure you want to delete this workspace member? This action is irreversible.": "Weet u zeker dat u dit lid van de werkruimte wilt verwijderen? Deze actie kan niet ongedaan gemaakt worden.",
"Deactivate member": "Lid deactiveren", "Deactivate member": "Lid deactiveren",
@@ -417,29 +438,31 @@
"Shared by": "Gedeeld door", "Shared by": "Gedeeld door",
"Shared at": "Gedeeld op", "Shared at": "Gedeeld op",
"Inherits public sharing from": "Erft openbaar delen van", "Inherits public sharing from": "Erft openbaar delen van",
"Share to web": "Delen naar web", "Share to web": "Delen op het web",
"Shared to web": "Gedeeld naar web", "Shared to web": "Gedeeld op het web",
"Anyone with the link can view this page": "Iedereen met de link kan deze pagina bekijken", "Anyone with the link can view this page": "Iedereen met de link kan deze pagina bekijken",
"Make this page publicly accessible": "Maak deze pagina openbaar toegankelijk", "Make this page publicly accessible": "Maak deze pagina openbaar toegankelijk",
"Include sub-pages": "Inclusief subpagina's", "Include sub-pages": "Subpagina's opnemen",
"Make sub-pages public too": "Maak subpagina's ook openbaar", "Make sub-pages public too": "Maak subpagina's ook openbaar",
"Allow search engines to index page": "Sta zoekmachines toe om pagina te indexeren", "Allow search engines to index page": "Sta zoekmachines toe de pagina te indexeren",
"Open page": "Pagina openen", "Open page": "Pagina openen",
"Page": "Pagina", "Page": "Pagina",
"Delete public share link": "Verwijder openbare deel-link", "Delete public share link": "Openbare deellink verwijderen",
"Delete share": "Verwijder deel", "Delete share": "Deel verwijderen",
"Are you sure you want to delete this shared link?": "Weet u zeker dat u deze gedeelde link wilt verwijderen?", "Are you sure you want to delete this shared link?": "Weet u zeker dat u deze gedeelde link wilt verwijderen?",
"Publicly shared pages from spaces you are a member of will appear here": "Openbaar gedeelde pagina's van ruimtes waarvan u lid bent, verschijnen hier", "Publicly shared pages from spaces you are a member of will appear here": "Openbaar gedeelde pagina's uit ruimtes waarvan je lid bent, verschijnen hier",
"Share deleted successfully": "Delen succesvol verwijderd", "Share deleted successfully": "Deel succesvol verwijderd",
"Share not found": "Delen niet gevonden", "Share not found": "Deel niet gevonden",
"Failed to share page": "Pagina delen mislukt", "Failed to share page": "Pagina delen mislukt",
"Disable public sharing": "Openbaar delen uitschakelen", "Disable public sharing": "Openbaar delen uitschakelen",
"Prevent members from sharing pages publicly.": "Voorkom dat leden pagina's openbaar delen.", "Prevent members from sharing pages publicly.": "Voorkom dat leden pagina's openbaar delen.",
"Toggle public sharing": "Wissel openbaar delen", "Toggle public sharing": "Wissel openbaar delen",
"Toggle space public sharing": "Wissel openbaar delen van ruimte", "Toggle space public sharing": "Wissel openbaar delen van ruimte",
"Allow viewers to comment": "Toestaan dat kijkers reageren",
"Allow viewers to add comments on pages in this space.": "Sta kijkers toe om reacties toe te voegen op pagina\u0019s in deze ruimte.",
"Toggle viewer comments": "Reacties van kijkers in- of uitschakelen",
"Public sharing is disabled at the workspace level": "Openbaar delen is uitgeschakeld op werkruimteniveau", "Public sharing is disabled at the workspace level": "Openbaar delen is uitgeschakeld op werkruimteniveau",
"Prevent pages in this space from being shared publicly.": "Voorkom dat pagina's in deze ruimte openbaar worden gedeeld.", "Prevent pages in this space from being shared publicly.": "Voorkom dat pagina's in deze ruimte openbaar worden gedeeld.",
"Requires an enterprise license": "Vereist een bedrijfslicentie",
"Page permissions": "Pagina rechten", "Page permissions": "Pagina rechten",
"Control who can view and edit individual pages. Available with an enterprise license.": "Beheer wie individuele pagina's kan bekijken en bewerken. Beschikbaar met een Enterprise-licentie.", "Control who can view and edit individual pages. Available with an enterprise license.": "Beheer wie individuele pagina's kan bekijken en bewerken. Beschikbaar met een Enterprise-licentie.",
"Enable public sharing": "Openbaar delen inschakelen", "Enable public sharing": "Openbaar delen inschakelen",
@@ -458,21 +481,22 @@
"Not found": "Niet gevonden", "Not found": "Niet gevonden",
"Previous Match (Shift+Enter)": "Vorige overeenkomst (Shift+Enter)", "Previous Match (Shift+Enter)": "Vorige overeenkomst (Shift+Enter)",
"Next match (Enter)": "Volgende overeenkomst (Enter)", "Next match (Enter)": "Volgende overeenkomst (Enter)",
"Match case (Alt+C)": "Hoofdlettergevoeligheid (Alt+C)", "Match case (Alt+C)": "Hoofdlettergevoelig (Alt+C)",
"Replace": "Vervangen", "Replace": "Vervangen",
"Close (Escape)": "Sluiten (Escape)", "Close (Escape)": "Sluiten (Escape)",
"Replace (Enter)": "Vervangen (Enter)", "Replace (Enter)": "Vervangen (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Alles vervangen (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Alles vervangen (Ctrl+Alt+Enter)",
"Replace all": "Alles vervangen", "Replace all": "Alles vervangen",
"View all spaces": "Bekijk alle ruimtes", "View all": "Alles bekijken",
"View all spaces": "Alle ruimtes bekijken",
"Error": "Fout", "Error": "Fout",
"Failed to disable MFA": "MFA uitschakelen mislukt", "Failed to disable MFA": "MFA uitschakelen mislukt",
"Disable two-factor authentication": "Twee-factor authenticatie uitschakelen", "Disable two-factor authentication": "Tweefactorauthenticatie uitschakelen",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Indien u twee-factor authenticatie uitschakelt, zal uw account minder veilig zijn. U heeft alleen uw wachtwoord nodig om in te loggen.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Indien u twee-factor authenticatie uitschakelt, zal uw account minder veilig zijn. U heeft alleen uw wachtwoord nodig om in te loggen.",
"Please enter your password to disable two-factor authentication:": "Voer uw wachtwoord in om twee-factor authenticatie uit te schakelen:", "Please enter your password to disable two-factor authentication:": "Voer uw wachtwoord in om twee-factor authenticatie uit te schakelen:",
"Two-factor authentication has been enabled": "Twee-factor authenticatie is ingeschakeld", "Two-factor authentication has been enabled": "Tweefactorauthenticatie is ingeschakeld",
"Two-factor authentication has been disabled": "Twee-factor authenticatie is uitgeschakeld", "Two-factor authentication has been disabled": "Tweefactorauthenticatie is uitgeschakeld",
"2-step verification": "2-staps verificatie", "2-step verification": "Verificatie in 2 stappen",
"Protect your account with an additional verification layer when signing in.": "Bescherm uw account met een extra verificatielaag tijdens het inloggen.", "Protect your account with an additional verification layer when signing in.": "Bescherm uw account met een extra verificatielaag tijdens het inloggen.",
"Two-factor authentication is active on your account.": "Twee-factor authenticatie is actief op uw account.", "Two-factor authentication is active on your account.": "Twee-factor authenticatie is actief op uw account.",
"Add 2FA method": "2FA-methode toevoegen", "Add 2FA method": "2FA-methode toevoegen",
@@ -485,49 +509,49 @@
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Back-up codes kunnen worden gebruikt om uw account te bereiken als u toegang tot uw authenticator-app verliest. Elke code kan slechts één keer worden gebruikt.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Back-up codes kunnen worden gebruikt om uw account te bereiken als u toegang tot uw authenticator-app verliest. Elke code kan slechts één keer worden gebruikt.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "U kunt te allen tijde nieuwe back-up codes genereren. Dit zal alle bestaande codes ongeldig maken.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "U kunt te allen tijde nieuwe back-up codes genereren. Dit zal alle bestaande codes ongeldig maken.",
"Confirm password": "Bevestig wachtwoord", "Confirm password": "Bevestig wachtwoord",
"Generate new backup codes": "Genereer nieuwe back-up codes", "Generate new backup codes": "Nieuwe back-upcodes genereren",
"Save your new backup codes": "Sla uw nieuwe back-up codes op", "Save your new backup codes": "Sla je nieuwe back-upcodes op",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Zorg ervoor dat u deze codes op een veilige plek opslaat. Uw oude back-up codes zijn niet langer geldig.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Zorg ervoor dat u deze codes op een veilige plek opslaat. Uw oude back-up codes zijn niet langer geldig.",
"Your new backup codes": "Uw nieuwe back-up codes", "Your new backup codes": "Je nieuwe back-upcodes",
"I've saved my backup codes": "Ik heb mijn back-upcodes opgeslagen", "I've saved my backup codes": "Ik heb mijn back-upcodes opgeslagen",
"Failed to setup MFA": "MFA instellen mislukt", "Failed to setup MFA": "MFA instellen mislukt",
"Setup & Verify": "Instellen & Verifiëren", "Setup & Verify": "Instellen en verifiëren",
"Add to authenticator": "Toevoegen aan de authenticator", "Add to authenticator": "Toevoegen aan authenticator",
"1. Scan this QR code with your authenticator app": "1. Scan deze QR-code met uw authenticator-app", "1. Scan this QR code with your authenticator app": "1. Scan deze QR-code met je authenticator-app",
"Can't scan the code?": "Kan de code niet scannen?", "Can't scan the code?": "Kan de code niet scannen?",
"Enter this code manually in your authenticator app:": "Voer deze code handmatig in uw authenticator-app in:", "Enter this code manually in your authenticator app:": "Voer deze code handmatig in uw authenticator-app in:",
"2. Enter the 6-digit code from your authenticator": "2. Voer de 6-cijferige code van uw authenticator in", "2. Enter the 6-digit code from your authenticator": "2. Voer de 6-cijferige code van je authenticator in",
"Verify and enable": "Verifiëren en inschakelen", "Verify and enable": "Verifiëren en inschakelen",
"Failed to generate QR code. Please try again.": "Het genereren van de QR-code is mislukt. Probeer het opnieuw.", "Failed to generate QR code. Please try again.": "Het genereren van de QR-code is mislukt. Probeer het opnieuw.",
"Backup": "Back-up", "Backup": "Back-up",
"Save codes": "Codes opslaan", "Save codes": "Codes opslaan",
"Save your backup codes": "Sla uw back-up codes op", "Save your backup codes": "Sla je back-upcodes op",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Deze codes kunnen worden gebruikt om toegang te krijgen tot uw account als u de toegang tot uw authenticator-app verliest. Elke code kan slechts één keer worden gebruikt.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Deze codes kunnen worden gebruikt om toegang te krijgen tot uw account als u de toegang tot uw authenticator-app verliest. Elke code kan slechts één keer worden gebruikt.",
"Print": "Afdrukken", "Print": "Afdrukken",
"Two-factor authentication has been set up. Please log in again.": "Twee-factor authenticatie is ingesteld. Log alstublieft opnieuw in.", "Two-factor authentication has been set up. Please log in again.": "Twee-factor authenticatie is ingesteld. Log alstublieft opnieuw in.",
"Two-Factor authentication required": "Twee-factor authenticatie vereist", "Two-Factor authentication required": "Tweefactorauthenticatie vereist",
"Your workspace requires two-factor authentication for all users": "Uw werkruimte vereist twee-factor authenticatie voor alle gebruikers", "Your workspace requires two-factor authentication for all users": "Je werkruimte vereist tweefactorauthenticatie voor alle gebruikers",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Om toegang te blijven krijgen tot uw werkruimte, moet u twee-factor authenticatie instellen. Dit voegt een extra beveiligingslaag toe aan uw account.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Om toegang te blijven krijgen tot uw werkruimte, moet u twee-factor authenticatie instellen. Dit voegt een extra beveiligingslaag toe aan uw account.",
"Set up two-factor authentication": "Stel twee-factor authenticatie in", "Set up two-factor authentication": "Tweefactorauthenticatie instellen",
"Cancel and logout": "Annuleren en uitloggen", "Cancel and logout": "Annuleren en uitloggen",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Uw werkruimte vereist twee-factor authenticatie. Stel het in om door te gaan.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Uw werkruimte vereist twee-factor authenticatie. Stel het in om door te gaan.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Dit voegt een extra beveiligingslaag toe aan uw account door een verificatiecode van uw authenticator-app te vereisen.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Dit voegt een extra beveiligingslaag toe aan uw account door een verificatiecode van uw authenticator-app te vereisen.",
"Password is required": "Wachtwoord is vereist", "Password is required": "Wachtwoord is verplicht",
"Password must be at least 8 characters": "Wachtwoord moet minimaal 8 tekens zijn", "Password must be at least 8 characters": "Wachtwoord moet minimaal 8 tekens bevatten",
"Please enter a 6-digit code": "Voer alstublieft een 6-cijferige code in", "Please enter a 6-digit code": "Voer een 6-cijferige code in",
"Code must be exactly 6 digits": "Code moet exact 6 cijfers zijn", "Code must be exactly 6 digits": "Code moet precies 6 cijfers bevatten",
"Enter the 6-digit code found in your authenticator app": "Voer de 6-cijferige code in die in uw authenticator-app staat", "Enter the 6-digit code found in your authenticator app": "Voer de 6-cijferige code uit je authenticator-app in",
"Need help authenticating?": "Hulp nodig bij het authenticeren?", "Need help authenticating?": "Hulp nodig bij het authenticeren?",
"MFA QR Code": "MFA QR-code", "MFA QR Code": "MFA QR-code",
"Account created successfully. Please log in to set up two-factor authentication.": "Account succesvol aangemaakt. Log alstublieft in om twee-factor authenticatie in te stellen.", "Account created successfully. Please log in to set up two-factor authentication.": "Account succesvol aangemaakt. Log alstublieft in om twee-factor authenticatie in te stellen.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Wachtwoord reset succesvol. Log in met uw nieuwe wachtwoord en voltooi twee-factor authenticatie.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "Wachtwoord reset succesvol. Log in met uw nieuwe wachtwoord en voltooi twee-factor authenticatie.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Wachtwoord reset succesvol. Log in met uw nieuwe wachtwoord om twee-factor authenticatie in te stellen.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Wachtwoord reset succesvol. Log in met uw nieuwe wachtwoord om twee-factor authenticatie in te stellen.",
"Password reset was successful. Please log in with your new password.": "De wachtwoord reset was succesvol. Log in met uw nieuwe wachtwoord.", "Password reset was successful. Please log in with your new password.": "De wachtwoord reset was succesvol. Log in met uw nieuwe wachtwoord.",
"Two-factor authentication": "Twee-factor authenticatie", "Two-factor authentication": "Tweefactorauthenticatie",
"Use authenticator app instead": "Gebruik in plaats daarvan de authenticator-app", "Use authenticator app instead": "Gebruik in plaats daarvan een authenticator-app",
"Verify backup code": "Back-upcode verifiëren", "Verify backup code": "Back-upcode verifiëren",
"Use backup code": "Gebruik back-up code", "Use backup code": "Back-upcode gebruiken",
"Enter one of your backup codes": "Voer een van uw back-up codes in", "Enter one of your backup codes": "Voer een van je back-upcodes in",
"Backup code": "Back-upcode", "Backup code": "Back-upcode",
"Enter one of your backup codes. Each backup code can only be used once.": "Voer een van uw back-up codes in. Elke back-up code kan slechts één keer worden gebruikt.", "Enter one of your backup codes. Each backup code can only be used once.": "Voer een van uw back-up codes in. Elke back-up code kan slechts één keer worden gebruikt.",
"Verify": "Verifiëren", "Verify": "Verifiëren",
@@ -538,46 +562,46 @@
"Permanently delete page?": "Pagina permanent verwijderen?", "Permanently delete page?": "Pagina permanent verwijderen?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Weet u zeker dat u '{{title}}' permanent wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.", "Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Weet u zeker dat u '{{title}}' permanent wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.",
"Restore '{{title}}' and its sub-pages?": "'{{title}}' en zijn subpagina's herstellen?", "Restore '{{title}}' and its sub-pages?": "'{{title}}' en zijn subpagina's herstellen?",
"Move to trash": "Naar de prullenbak verplaatsen", "Move to trash": "Verplaatsen naar prullenbak",
"Move this page to trash?": "Deze pagina naar de prullenbak verplaatsen?", "Move this page to trash?": "Deze pagina naar de prullenbak verplaatsen?",
"Restore page": "Pagina herstellen", "Restore page": "Pagina herstellen",
"Page moved to trash": "Pagina verplaatst naar de prullenbak", "Page moved to trash": "Pagina verplaatst naar prullenbak",
"Page restored successfully": "Pagina succesvol hersteld", "Page restored successfully": "Pagina succesvol hersteld",
"Deleted by": "Verwijderd door", "Deleted by": "Verwijderd door",
"Deleted at": "Verwijderd op", "Deleted at": "Verwijderd op",
"Preview": "Voorbeeld", "Preview": "Voorbeeld",
"Subpages": "Subpagina's", "Subpages": "Subpagina's",
"Failed to load subpages": "Laden van subpagina's mislukt", "Failed to load subpages": "Subpagina's laden mislukt",
"No subpages": "Geen subpagina's", "No subpages": "Geen subpagina's",
"Subpages (Child pages)": "Subpagina's (Kindpagina's)", "Subpages (Child pages)": "Subpagina's (onderliggende pagina's)",
"List all subpages of the current page": "Lijst van alle subpagina's van de huidige pagina", "List all subpages of the current page": "Toon alle subpagina's van de huidige pagina",
"Attachments": "Bijlagen", "Attachments": "Bijlagen",
"All spaces": "Alle ruimtes", "All spaces": "Alle ruimtes",
"Unknown": "Onbekend", "Unknown": "Onbekend",
"Find a space": "Vind een ruimte", "Find a space": "Zoek een ruimte",
"Search in all your spaces": "Zoek in al je ruimtes", "Search in all your spaces": "Zoek in al je ruimtes",
"Type": "Type", "Type": "Type",
"Enterprise": "Onderneming", "Enterprise": "Enterprise",
"Download attachment": "Bijlage downloaden", "Download attachment": "Bijlage downloaden",
"Allowed email domains": "Toegestane e-maildomeinen", "Allowed email domains": "Toegestane e-maildomeinen",
"Only users with email addresses from these domains can signup via SSO.": "Alleen gebruikers met e-mailadressen van deze domeinen kunnen zich aanmelden via SSO.", "Only users with email addresses from these domains can signup via SSO.": "Alleen gebruikers met e-mailadressen van deze domeinen kunnen zich via SSO registreren.",
"Enter valid domain names separated by comma or space": "Voer geldige domeinnamen in, gescheiden door komma of spatie", "Enter valid domain names separated by comma or space": "Voer geldige domeinnamen in, gescheiden door komma of spatie",
"Enforce two-factor authentication": "Handhaaf tweefactorauthenticatie", "Enforce two-factor authentication": "Tweefactorauthenticatie afdwingen",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Na handhaving moeten alle leden tweefactorauthenticatie inschakelen om toegang te krijgen tot de werkomgeving.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Na handhaving moeten alle leden tweefactorauthenticatie inschakelen om toegang te krijgen tot de werkomgeving.",
"Toggle MFA enforcement": "Schakel MFA-handhaving in of uit", "Toggle MFA enforcement": "MFA-afdwinging in-/uitschakelen",
"Display name": "Weergavenaam", "Display name": "Weergavenaam",
"Allow signup": "Aanmelden toestaan", "Allow signup": "Registratie toestaan",
"Enabled": "Ingeschakeld", "Enabled": "Ingeschakeld",
"Advanced Settings": "Geavanceerde instellingen", "Advanced Settings": "Geavanceerde instellingen",
"Enable TLS/SSL": "TLS/SSL inschakelen", "Enable TLS/SSL": "TLS/SSL inschakelen",
"Use secure connection to LDAP server": "Gebruik een beveiligde verbinding met de LDAP-server", "Use secure connection to LDAP server": "Gebruik een beveiligde verbinding met de LDAP-server",
"Group sync": "Groepssynchronisatie", "Group sync": "Groepssynchronisatie",
"No SSO providers found.": "Geen SSO-providers gevonden.", "No SSO providers found.": "Geen SSO-providers gevonden.",
"Delete SSO provider": "Verwijder SSO-provider", "Delete SSO provider": "SSO-provider verwijderen",
"Are you sure you want to delete this SSO provider?": "Weet u zeker dat u deze SSO-provider wilt verwijderen?", "Are you sure you want to delete this SSO provider?": "Weet u zeker dat u deze SSO-provider wilt verwijderen?",
"Action": "Actie", "Action": "Actie",
"{{ssoProviderType}} configuration": "{{ssoProviderType}} configuratie", "{{ssoProviderType}} configuration": "{{ssoProviderType}}-configuratie",
"Icon": "Icoon", "Icon": "Pictogram",
"Upload image": "Afbeelding uploaden", "Upload image": "Afbeelding uploaden",
"Remove image": "Afbeelding verwijderen", "Remove image": "Afbeelding verwijderen",
"Failed to remove image": "Afbeelding verwijderen mislukt", "Failed to remove image": "Afbeelding verwijderen mislukt",
@@ -613,6 +637,7 @@
"AI Answer": "AI Antwoord", "AI Answer": "AI Antwoord",
"Ask AI": "Vraag AI", "Ask AI": "Vraag AI",
"AI is thinking...": "AI is aan het nadenken...", "AI is thinking...": "AI is aan het nadenken...",
"Thinking": "Denken",
"Ask a question...": "Stel een vraag...", "Ask a question...": "Stel een vraag...",
"AI Answers": "AI Antwoorden", "AI Answers": "AI Antwoorden",
"AI-powered search (AI Answers)": "AI-gestuurde zoekopdracht (AI Antwoorden)", "AI-powered search (AI Answers)": "AI-gestuurde zoekopdracht (AI Antwoorden)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "Generatieve AI (Vraag het AI)", "Generative AI (Ask AI)": "Generatieve AI (Vraag het AI)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Schakel AI-gestuurde inhoudsgeneratie in de editor in. Hiermee kunnen gebruikers tekst genereren, verbeteren, vertalen en transformeren.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Schakel AI-gestuurde inhoudsgeneratie in de editor in. Hiermee kunnen gebruikers tekst genereren, verbeteren, vertalen en transformeren.",
"Toggle generative AI": "Generatieve AI schakelen", "Toggle generative AI": "Generatieve AI schakelen",
"Enterprise feature": "Enterprise-functie", "Upgrade your plan": "Upgrade je abonnement",
"Available with a paid license": "Beschikbaar met een betaalde licentie",
"Upgrade your license tier.": "Upgrade je licentieniveau.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI is alleen beschikbaar in de Docmost Enterprise-editie. Neem contact op met sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI is alleen beschikbaar in de Docmost Enterprise-editie. Neem contact op met sales@docmost.com.",
"AI & MCP": "AI & MCP", "AI & MCP": "AI & MCP",
"AI": "AI", "AI": "AI",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Model Context Protocol (MCP)", "Model Context Protocol (MCP)": "Model Context Protocol (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Schakel de MCP-server in zodat AI-assistenten en tools kunnen interageren met de inhoud van uw werkruimte.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Schakel de MCP-server in zodat AI-assistenten en tools kunnen interageren met de inhoud van uw werkruimte.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP is alleen beschikbaar in de Docmost Enterprise-editie. Neem contact op met sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP is alleen beschikbaar in de Docmost Enterprise-editie. Neem contact op met sales@docmost.com.",
"MCP documentation": "MCP-documentatie",
"MCP Server URL": "MCP-server-URL", "MCP Server URL": "MCP-server-URL",
"Use your API key for authentication. You can manage API keys in your account settings.": "Gebruik uw API-sleutel voor authenticatie. U kunt API-sleutels beheren in uw accountinstellingen.", "Use your API key for authentication. You can manage API keys in your account settings.": "Gebruik uw API-sleutel voor authenticatie. U kunt API-sleutels beheren in uw accountinstellingen.",
"Supported tools": "Ondersteunde tools", "Supported tools": "Ondersteunde tools",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "In uw werkruimte is MCP ingeschakeld. Gebruik uw API-sleutel om AI-assistenten te koppelen.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "In uw werkruimte is MCP ingeschakeld. Gebruik uw API-sleutel om AI-assistenten te koppelen.",
"MCP server URL:": "MCP-server-URL:", "MCP server URL:": "MCP-server-URL:",
"Learn more": "Meer informatie", "Learn more": "Meer informatie",
"View the": "Bekijk de", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Beheer API-sleutels voor alle gebruikers in de werkruimte. Bekijk de <anchor>API-documentatie</anchor> voor gebruiksdetails.",
"for usage details.": "voor details over het gebruik.", "View the <anchor>API documentation</anchor> for usage details.": "Bekijk de <anchor>API-documentatie</anchor> voor gebruiksdetails.",
"for setup instructions.": "voor installatie-instructies.", "View the <anchor>MCP documentation</anchor>.": "Bekijk de <anchor>MCP-documentatie</anchor>.",
"API documentation": "API-documentatie",
"Sources": "Bronnen", "Sources": "Bronnen",
"AI Answers not available for attachments": "AI Antwoorden niet beschikbaar voor bijlagen", "AI Answers not available for attachments": "AI Antwoorden niet beschikbaar voor bijlagen",
"No answer available": "Geen antwoord beschikbaar", "No answer available": "Geen antwoord beschikbaar",
@@ -654,12 +679,34 @@
"Mark all as read": "Markeer alles als gelezen", "Mark all as read": "Markeer alles als gelezen",
"Mark as read": "Markeer als gelezen", "Mark as read": "Markeer als gelezen",
"More options": "Meer opties", "More options": "Meer opties",
"mentioned you in a comment": "noemde je in een reactie", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> noemde je in een reactie",
"commented on a page": "reageerde op een pagina", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> heeft een reactie geplaatst op een pagina",
"resolved a comment": "heeft een opmerking opgelost", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> heeft een opmerking opgelost",
"mentioned you on a page": "noemde je op een pagina", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> heeft je genoemd op een pagina",
"gave you edit access to a page": "heeft je toegang gegeven om een pagina te bewerken", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> heeft je bewerkingsrechten gegeven voor een pagina",
"gave you view access to a page": "heeft je toegang gegeven om een pagina te bekijken", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> heeft je kijkrechten gegeven voor een pagina",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> heeft een pagina bijgewerkt",
"Watch page": "Pagina volgen",
"Stop watching": "Niet meer volgen",
"Watch space": "Ruimte volgen",
"Stop watching space": "Ruimte niet meer volgen",
"Email notifications": "E-mailmeldingen",
"Page updates": "Pagina-updates",
"Get notified when pages you watch are updated.": "Ontvang een melding wanneer pagina's die je volgt worden bijgewerkt.",
"Page mentions": "Pagina-vermeldingen",
"Get notified when someone mentions you on a page.": "Ontvang een melding wanneer iemand je noemt op een pagina.",
"Comment mentions": "Vermeldingen in opmerkingen",
"Get notified when someone mentions you in a comment.": "Ontvang een melding wanneer iemand je noemt in een opmerking.",
"New comments": "Nieuwe opmerkingen",
"Get notified about new comments on threads you participate in.": "Ontvang meldingen over nieuwe reacties in threads waaraan je deelneemt.",
"Resolved comments": "Opgeloste opmerkingen",
"Get notified when your comment is resolved.": "Ontvang een melding wanneer je reactie is opgelost.",
"You are now watching this page": "Je volgt nu deze pagina",
"You are no longer watching this page": "Je volgt deze pagina niet meer",
"You are now watching this space": "Je volgt deze ruimte nu",
"You are no longer watching this space": "Je volgt deze ruimte niet meer",
"Direct": "Direct",
"Updates": "Updates",
"Today": "Vandaag", "Today": "Vandaag",
"Yesterday": "Gisteren", "Yesterday": "Gisteren",
"This week": "Deze week", "This week": "Deze week",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Bijwerken van de bewaartermijn voor de prullenbak is mislukt.", "Failed to update trash retention": "Bijwerken van de bewaartermijn voor de prullenbak is mislukt.",
"Removed page restriction": "Pagina-restrictie verwijderd", "Removed page restriction": "Pagina-restrictie verwijderd",
"Added page permission": "Paginatoestemming toegevoegd", "Added page permission": "Paginatoestemming toegevoegd",
"Removed page permission": "Paginatoestemming verwijderd" "Removed page permission": "Paginatoestemming verwijderd",
"day": "dag",
"days": "dagen",
"week": "week",
"weeks": "weken",
"month": "maand",
"months": "maanden",
"year": "jaar",
"years": "jaren",
"Period": "Periode",
"Fixed date": "Vaste datum",
"Indefinitely": "Voor onbepaalde tijd",
"Days": "Dagen",
"Weeks": "Weken",
"Months": "Maanden",
"Years": "Jaren",
"Pick a date": "Kies een datum",
"Maximum is {{max}} {{unit}} for this unit": "Maximum is {{max}} {{unit}} voor deze eenheid",
"Never expires. Verifiers can re-verify at any time.": "Verloopt nooit. Verificateurs kunnen op elk moment opnieuw verifiëren.",
"Verified": "Geverifieerd",
"Review needed": "Beoordeling nodig",
"Verification expired": "Verificatie verlopen",
"Draft": "Concept",
"In Approval": "In goedkeuring",
"In approval": "In goedkeuring",
"Approved": "Goedgekeurd",
"Obsolete": "Verouderd",
"Expiring": "Verloopt binnenkort",
"Set up verification": "Verificatie instellen",
"Verify page": "Pagina verifiëren",
"Page verification": "Paginaverificatie",
"Add verification": "Verificatie toevoegen",
"Edit verification": "Verificatie bewerken",
"Search by title": "Zoeken op titel",
"Choose how this page should stay accurate.": "Kies hoe deze pagina accuraat moet blijven.",
"Recurring verification": "Terugkerende verificatie",
"Verifiers re-confirm this page on a schedule.": "Verificateurs bevestigen deze pagina opnieuw volgens een schema.",
"Re-verify on a schedule (e.g every 30 days )": "Opnieuw verifiëren volgens een schema (bijv. elke 30 dagen)",
"Page stays editable at all times": "Pagina blijft altijd bewerkbaar",
"Best for runbooks, FAQs, living documentation": "Het beste voor runbooks, veelgestelde vragen en levende documentatie",
"Approval workflow": "Goedkeuringsworkflow",
"Formal document lifecycle with named approvers.": "Formele documentlevenscyclus met benoemde goedkeurders.",
"Draft → In approval → Approved → Obsolete": "Concept → In goedkeuring → Goedgekeurd → Verouderd",
"Locked once approved, with full history": "Vergrendeld zodra goedgekeurd, met volledige geschiedenis",
"Designed for ISO 9001, ISO 13485, and FDA": "Ontworpen voor ISO 9001, ISO 13485 en FDA",
"Best for SOPs and controlled documents": "Het beste voor SOP's en beheerde documenten",
"Back": "Terug",
"Quality management": "Kwaliteitsmanagement",
"Recurring": "Terugkerend",
"Pages move through draft, approval, and approved stages.": "Pagina's doorlopen de fasen concept, goedkeuring en goedgekeurd.",
"Verifiers": "Verificateurs",
"Add verifier": "Verificateur toevoegen",
"I've reviewed this page for accuracy": "Ik heb deze pagina op nauwkeurigheid beoordeeld",
"Set up": "Instellen",
"Remove verification": "Verificatie verwijderen",
"Are you sure you want to remove verification from this page?": "Weet je zeker dat je verificatie van deze pagina wilt verwijderen?",
"Assigned verifiers must periodically re-verify this page.": "Toegewezen verificateurs moeten deze pagina periodiek opnieuw verifiëren.",
"Last verified by {{name}} {{time}} (expired)": "Laatst geverifieerd door {{name}} {{time}} (verlopen)",
"The fixed expiration date has passed.": "De vaste vervaldatum is verstreken.",
"Verified by {{name}} {{time}}": "Geverifieerd door {{name}} {{time}}",
"Expires {{date}}": "Verloopt op {{date}}",
"Expired {{date}}": "Verlopen op {{date}}",
"Mark as obsolete": "Markeren als verouderd",
"Mark obsolete": "Markeer als verouderd",
"Returned by {{name}} {{time}}": "Teruggestuurd door {{name}} {{time}}",
"No approval has been requested yet.": "Er is nog geen goedkeuring aangevraagd.",
"Submitted by {{name}} {{time}}": "Ingediend door {{name}} {{time}}",
"Someone": "Iemand",
"Approved by {{name}} {{time}}": "Goedgekeurd door {{name}} {{time}}",
"This document has been marked as obsolete.": "Dit document is als verouderd gemarkeerd.",
"Rejection comment": "Afwijzingsopmerking",
"Reason for returning this document...": "Reden om dit document terug te sturen...",
"Confirm rejection": "Afwijzing bevestigen",
"Submit for approval": "Indienen voor goedkeuring",
"Reject": "Afwijzen",
"Approve": "Goedkeuren",
"Re-submit for approval": "Opnieuw indienen voor goedkeuring",
"Verified until": "Geverifieerd tot",
"QMS": "QMS",
"Verified pages": "Geverifieerde pagina's",
"Search pages...": "Pagina's zoeken...",
"Filter by space": "Filteren op ruimte",
"Filter by type": "Filteren op type",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> heeft een pagina geverifieerd",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> heeft een pagina voor jouw goedkeuring ingediend",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> heeft een pagina teruggestuurd voor revisie",
"Page verification expires soon": "Paginaverificatie verloopt binnenkort",
"Page verification has expired": "Paginaverificatie is verlopen",
"Verifying your email": "Je e-mailadres wordt geverifieerd",
"Please wait...": "Even geduld...",
"Verification failed. The link may have expired.": "Verificatie mislukt. De link is mogelijk verlopen.",
"Check your email": "Controleer je e-mail",
"We sent a verification link to {{email}}.": "We hebben een verificatielink naar {{email}} gestuurd.",
"We sent a verification link to your email.": "We hebben een verificatielink naar je e-mailadres gestuurd.",
"Click the link to verify your email and access your workspace.": "Klik op de link om je e-mailadres te verifiëren en toegang te krijgen tot je werkruimte.",
"Resend verification email": "Verificatie-e-mail opnieuw verzenden",
"Verification email sent. Please check your inbox.": "Verificatie-e-mail verzonden. Controleer je inbox.",
"Failed to resend verification email. Please try again.": "Het verzenden van de verificatie-e-mail is mislukt. Probeer het opnieuw.",
"We've sent you an email with your associated workspaces.": "We hebben je een e-mail gestuurd met je gekoppelde werkruimtes.",
"Load more": "Meer laden",
"Log out of all devices": "Uitloggen op alle apparaten",
"Log out of all sessions except this device": "Uitloggen uit alle sessies behalve op dit apparaat",
"This Device": "Dit apparaat",
"Unknown device": "Onbekend apparaat",
"No active sessions": "Geen actieve sessies",
"Session revoked": "Sessie ingetrokken",
"All other sessions revoked": "Alle andere sessies ingetrokken",
"Last used": "Laatst gebruikt",
"Created": "Aangemaakt",
"Rename": "Hernoemen",
"Publish": "Publiceren",
"Security": "Beveiliging",
"Enforce SSO": "SSO afdwingen",
"Once enforced, members will not be able to login with email and password.": "Zodra dit is afgedwongen, kunnen leden niet meer inloggen met e-mail en wachtwoord.",
"AI-generated content may not be accurate.": "Door AI gegenereerde inhoud is mogelijk niet nauwkeurig.",
"AI Chat": "AI-chat",
"Analyze for insights": "Analyseren voor inzichten",
"Ask anything...": "Vraag iets...",
"Chat history": "Chatgeschiedenis",
"Chat name": "Chatnaam",
"Close": "Sluiten",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Chat laden mislukt. Er is een fout opgetreden.",
"Failed to render this message.": "Dit bericht kon niet worden weergegeven.",
"How can I help you today?": "Hoe kan ik je vandaag helpen?",
"New chat": "Nieuwe chat",
"No chat history": "Geen chatgeschiedenis",
"No chats found": "Geen chats gevonden",
"No conversations yet": "Nog geen gesprekken",
"Open full page": "Volledige pagina openen",
"Previous 7 days": "Afgelopen 7 dagen",
"Previous 30 days": "Afgelopen 30 dagen",
"Search chats...": "Chats zoeken...",
"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",
"Translate this page": "Vertaal deze pagina",
"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?"
} }
+278 -91
View File
@@ -7,6 +7,7 @@
"Add members": "Adicionar membros", "Add members": "Adicionar membros",
"Add to groups": "Adicionar aos grupos", "Add to groups": "Adicionar aos grupos",
"Add space members": "Adicionar membros do espaço", "Add space members": "Adicionar membros do espaço",
"Add to favorites": "Adicionar aos favoritos",
"Admin": "Administrador", "Admin": "Administrador",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Tem certeza de que deseja excluir este grupo? Os membros perderão acesso aos recursos que este grupo possui.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Tem certeza de que deseja excluir este grupo? Os membros perderão acesso aos recursos que este grupo possui.",
"Are you sure you want to delete this page?": "Tem certeza de que deseja excluir esta página?", "Are you sure you want to delete this page?": "Tem certeza de que deseja excluir esta página?",
@@ -59,7 +60,7 @@
"Email": "Email", "Email": "Email",
"Enter a strong password": "Insira uma senha forte", "Enter a strong password": "Insira uma senha forte",
"Enter valid email addresses separated by comma or space max_50": "Insira endereços de email válidos separados por vírgula ou espaço [máx: 50]", "Enter valid email addresses separated by comma or space max_50": "Insira endereços de email válidos separados por vírgula ou espaço [máx: 50]",
"enter valid emails addresses": "insira endereços de email válidos", "enter valid emails addresses": "insira endereços de e-mail válidos",
"Enter your current password": "Insira sua senha atual", "Enter your current password": "Insira sua senha atual",
"enter your full name": "insira seu nome completo", "enter your full name": "insira seu nome completo",
"Enter your new password": "Insira sua nova senha", "Enter your new password": "Insira sua nova senha",
@@ -74,6 +75,9 @@
"Failed to import pages": "Falha ao importar páginas", "Failed to import pages": "Falha ao importar páginas",
"Failed to load page. An error occurred.": "Falha ao carregar página. Ocorreu um erro.", "Failed to load page. An error occurred.": "Falha ao carregar página. Ocorreu um erro.",
"Failed to update data": "Falha ao atualizar dados", "Failed to update data": "Falha ao atualizar dados",
"Favorite spaces": "Espaços favoritos",
"Favorite spaces appear here": "Os espaços favoritos aparecem aqui",
"Favorites": "Favoritos",
"Full access": "Acesso total", "Full access": "Acesso total",
"Full page width": "Usar largura total da página", "Full page width": "Usar largura total da página",
"Full width": "Largura total", "Full width": "Largura total",
@@ -92,6 +96,7 @@
"Invite by email": "Convidar por email", "Invite by email": "Convidar por email",
"Invite members": "Convidar membros", "Invite members": "Convidar membros",
"Invite new members": "Convidar novos membros", "Invite new members": "Convidar novos membros",
"Invite People": "Convidar pessoas",
"Invited members who are yet to accept their invitation will appear here.": "Membros convidados que ainda não aceitaram o convite aparecerão aqui.", "Invited members who are yet to accept their invitation will appear here.": "Membros convidados que ainda não aceitaram o convite aparecerão aqui.",
"Invited members will be granted access to spaces the groups can access": "Os membros convidados terão acesso aos espaços que os grupos podem acessar", "Invited members will be granted access to spaces the groups can access": "Os membros convidados terão acesso aos espaços que os grupos podem acessar",
"Join the workspace": "Entrar no workspace", "Join the workspace": "Entrar no workspace",
@@ -139,6 +144,7 @@
"Profile": "Perfil", "Profile": "Perfil",
"Recently updated": "Atualizado recentemente", "Recently updated": "Atualizado recentemente",
"Remove": "Remover", "Remove": "Remover",
"Remove from favorites": "Remover dos favoritos",
"Remove group member": "Remover membro do grupo", "Remove group member": "Remover membro do grupo",
"Remove space member": "Remover membro do espaço", "Remove space member": "Remover membro do espaço",
"Restore": "Restaurar", "Restore": "Restaurar",
@@ -149,16 +155,16 @@
"Search for users": "Buscar usuários", "Search for users": "Buscar usuários",
"Search for users and groups": "Buscar usuários e grupos", "Search for users and groups": "Buscar usuários e grupos",
"Search...": "Buscar...", "Search...": "Buscar...",
"Select language": "Selecionar idioma", "Select language": "Selecione o idioma",
"Select role": "Selecionar função", "Select role": "Selecione a função",
"Select role to assign to all invited members": "Selecione a função para atribuir a todos os membros convidados", "Select role to assign to all invited members": "Selecione a função a ser atribuída a todos os membros convidados",
"Select theme": "Selecionar tema", "Select theme": "Selecione o tema",
"Send invitation": "Enviar convite", "Send invitation": "Enviar convite",
"Invitation sent": "Convite enviado", "Invitation sent": "Convite enviado",
"Settings": "Configurações", "Settings": "Configurações",
"Setup workspace": "Configurar workspace", "Setup workspace": "Configurar workspace",
"Sign In": "Entrar", "Sign In": "Entrar",
"Sign Up": "Registrar-se", "Sign Up": "Cadastrar-se",
"Slug": "Slug", "Slug": "Slug",
"Space": "Espaço", "Space": "Espaço",
"Space description": "Descrição do espaço", "Space description": "Descrição do espaço",
@@ -171,34 +177,35 @@
"No space found": "Nenhum espaço encontrado", "No space found": "Nenhum espaço encontrado",
"Search for spaces": "Pesquisar espaços", "Search for spaces": "Pesquisar espaços",
"Start typing to search...": "Comece a digitar para buscar...", "Start typing to search...": "Comece a digitar para buscar...",
"Status": "Estado", "Status": "Status",
"Successfully imported": "Importado com sucesso", "Successfully imported": "Importado com sucesso",
"Successfully restored": "Restaurado com sucesso", "Successfully restored": "Restaurado com sucesso",
"System settings": "Configurações do sistema", "System settings": "Configurações do sistema",
"Templates": "Modelos",
"Theme": "Tema", "Theme": "Tema",
"To change your email, you have to enter your password and new email.": "Para alterar seu email, você precisa inserir sua senha e o novo email.", "To change your email, you have to enter your password and new email.": "Para alterar seu email, você precisa inserir sua senha e o novo email.",
"Toggle full page width": "Alternar para largura total da página", "Toggle full page width": "Alternar largura total da página",
"Unable to import pages. Please try again.": "Não foi possível importar as páginas. Por favor, tente novamente.", "Unable to import pages. Please try again.": "Não foi possível importar as páginas. Por favor, tente novamente.",
"untitled": "sem título", "untitled": "sem título",
"Untitled": "Sem título", "Untitled": "Sem título",
"Updated successfully": "Atualizado com sucesso", "Updated successfully": "Atualizado com sucesso",
"User": "Usuário", "User": "Usuário",
"Workspace": "Espaço de Trabalho", "Workspace": "Workspace",
"Workspace Name": "Nome do Workspace", "Workspace Name": "Nome do workspace",
"Workspace settings": "Configurações do workspace", "Workspace settings": "Configurações do workspace",
"You can change your password here.": "Você pode alterar sua senha aqui.", "You can change your password here.": "Você pode alterar sua senha aqui.",
"Your Email": "Seu email", "Your Email": "Seu e-mail",
"Your import is complete.": "Sua importação está concluída.", "Your import is complete.": "Sua importação está concluída.",
"Your name": "Seu nome", "Your name": "Seu nome",
"Your Name": "Seu Nome", "Your Name": "Seu Nome",
"Your password": "Sua senha", "Your password": "Sua senha",
"Your password must be a minimum of 8 characters.": "Sua senha deve ter no mínimo 8 caracteres.", "Your password must be a minimum of 8 characters.": "Sua senha deve ter no mínimo 8 caracteres.",
"Sidebar toggle": "Interruptor do painel lateral", "Sidebar toggle": "Alternar barra lateral",
"Comments": "Comentários", "Comments": "Comentários",
"404 page not found": "Erro 404: Página não encontrada", "404 page not found": "404 página não encontrada",
"Sorry, we can't find the page you are looking for.": "Desculpe, não conseguimos encontrar a página que você está procurando.", "Sorry, we can't find the page you are looking for.": "Desculpe, não conseguimos encontrar a página que você está procurando.",
"Take me back to homepage": "Leve-me de volta para a página inicial", "Take me back to homepage": "Voltar para a página inicial",
"Forgot password": "Esqueci a senha", "Forgot password": "Esqueceu a senha",
"Forgot your password?": "Esqueceu sua senha?", "Forgot your password?": "Esqueceu sua senha?",
"A password reset link has been sent to your email. Please check your inbox.": "Um link de redefinição de senha foi enviado para o seu email. Por favor, verifique sua caixa de entrada.", "A password reset link has been sent to your email. Please check your inbox.": "Um link de redefinição de senha foi enviado para o seu email. Por favor, verifique sua caixa de entrada.",
"Send reset link": "Enviar link de recuperação", "Send reset link": "Enviar link de recuperação",
@@ -215,6 +222,8 @@
"Edit comment": "Editar comentário", "Edit comment": "Editar comentário",
"Delete comment": "Excluir comentário", "Delete comment": "Excluir comentário",
"Are you sure you want to delete this comment?": "Você tem certeza de que deseja excluir este comentário?", "Are you sure you want to delete this comment?": "Você tem certeza de que deseja excluir este comentário?",
"Delete chat": "Excluir chat",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Tem certeza de que deseja excluir '{{title}}'? Esta ação não pode ser desfeita.",
"Comment created successfully": "Comentário criado com sucesso", "Comment created successfully": "Comentário criado com sucesso",
"Error creating comment": "Erro ao criar comentário", "Error creating comment": "Erro ao criar comentário",
"Comment updated successfully": "Comentário atualizado com sucesso", "Comment updated successfully": "Comentário atualizado com sucesso",
@@ -223,12 +232,12 @@
"Failed to delete comment": "Falha ao excluir comentário", "Failed to delete comment": "Falha ao excluir comentário",
"Comment resolved successfully": "Comentário resolvido com sucesso", "Comment resolved successfully": "Comentário resolvido com sucesso",
"Comment re-opened successfully": "Comentário reaberto com sucesso", "Comment re-opened successfully": "Comentário reaberto com sucesso",
"Comment unresolved successfully": "Comentário não resolvido com sucesso", "Comment unresolved successfully": "Comentário marcado como não resolvido com sucesso",
"Failed to resolve comment": "Falha ao resolver comentário", "Failed to resolve comment": "Falha ao resolver comentário",
"Resolve comment": "Resolver comentário", "Resolve comment": "Resolver comentário",
"Unresolve comment": "Não resolver comentário", "Unresolve comment": "Marcar comentário como não resolvido",
"Resolve Comment Thread": "Resolver Fio de Comentários", "Resolve Comment Thread": "Resolver tópico de comentários",
"Unresolve Comment Thread": "Não resolver Fio de Comentários", "Unresolve Comment Thread": "Marcar tópico de comentários como não resolvido",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Tem certeza de que deseja resolver este fio de comentários? Isso o marcará como concluído.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Tem certeza de que deseja resolver este fio de comentários? Isso o marcará como concluído.",
"Are you sure you want to unresolve this comment thread?": "Tem certeza de que deseja não resolver este fio de comentários?", "Are you sure you want to unresolve this comment thread?": "Tem certeza de que deseja não resolver este fio de comentários?",
"Resolved": "Resolvido", "Resolved": "Resolvido",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "Tem certeza de que deseja excluir este espaço?", "Are you sure you want to delete this space?": "Tem certeza de que deseja excluir este espaço?",
"Delete this space with all its pages and data.": "Excluir este espaço com todas as suas páginas e dados.", "Delete this space with all its pages and data.": "Excluir este espaço com todas as suas páginas e dados.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Todas as páginas, comentários, anexos e permissões neste espaço serão excluídos de forma irreversível.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Todas as páginas, comentários, anexos e permissões neste espaço serão excluídos de forma irreversível.",
"Confirm space name": "Confirme o nome do espaço", "Confirm space name": "Confirmar nome do espaço",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Digite o nome do espaço <b>{{spaceName}}</b> para confirmar sua ação.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "Digite o nome do espaço <b>{{spaceName}}</b> para confirmar sua ação.",
"Format": "Formato", "Format": "Formato",
"Include subpages": "Incluir subpáginas", "Include subpages": "Incluir subpáginas",
@@ -289,6 +298,11 @@
"Save & Exit": "Salvar e Sair", "Save & Exit": "Salvar e Sair",
"Double-click to edit Excalidraw diagram": "Clique duas vezes para editar o diagrama Excalidraw", "Double-click to edit Excalidraw diagram": "Clique duas vezes para editar o diagrama Excalidraw",
"Paste link": "Colar link", "Paste link": "Colar link",
"Paste link or search pages": "Cole o link ou pesquise páginas",
"Link to web page": "Link para página da web",
"Recents": "Recentes",
"Page or URL": "Página ou URL",
"Link title": "Título do link",
"Edit link": "Editar link", "Edit link": "Editar link",
"Remove link": "Remover link", "Remove link": "Remover link",
"Add link": "Adicionar link", "Add link": "Adicionar link",
@@ -307,7 +321,7 @@
"Pink": "Rosa", "Pink": "Rosa",
"Gray": "Cinza", "Gray": "Cinza",
"Embed link": "Link embutido", "Embed link": "Link embutido",
"Invalid {{provider}} embed link": "Link de incorporação {{provider}} inválido", "Invalid {{provider}} embed link": "Link de incorporação do {{provider}} inválido",
"Embed {{provider}}": "Incorporar {{provider}}", "Embed {{provider}}": "Incorporar {{provider}}",
"Enter {{provider}} link to embed": "Digite o link do {{provider}} para incorporar", "Enter {{provider}} link to embed": "Digite o link do {{provider}} para incorporar",
"Bold": "Negrito", "Bold": "Negrito",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Insira um divisor horizontal", "Insert horizontal rule divider": "Insira um divisor horizontal",
"Upload any image from your device.": "Envie qualquer imagem do seu dispositivo.", "Upload any image from your device.": "Envie qualquer imagem do seu dispositivo.",
"Upload any video from your device.": "Envie qualquer vídeo do seu dispositivo.", "Upload any video from your device.": "Envie qualquer vídeo do seu dispositivo.",
"Upload any audio from your device.": "Envie qualquer áudio do seu dispositivo.",
"Upload any file from your device.": "Envie qualquer arquivo do seu dispositivo.", "Upload any file from your device.": "Envie qualquer arquivo do seu dispositivo.",
"Uploading {{name}}": "Enviando {{name}}", "Uploading {{name}}": "Enviando {{name}}",
"Uploading file": "Enviando arquivo", "Uploading file": "Enviando arquivo",
@@ -346,19 +361,25 @@
"Divider": "Divisor", "Divider": "Divisor",
"Quote": "Citação", "Quote": "Citação",
"Image": "Imagem", "Image": "Imagem",
"Audio": "Áudio",
"Embed PDF": "Incorporar PDF",
"Upload and embed a PDF file.": "Envie e incorpore um arquivo PDF.",
"Embed as PDF": "Incorporar como PDF",
"Failed to load PDF": "Falha ao carregar PDF",
"Convert to attachment": "Converter em anexo",
"File attachment": "Anexo de arquivo", "File attachment": "Anexo de arquivo",
"Toggle block": "Bloco colapsável", "Toggle block": "Bloco recolvel",
"Callout": "Aviso", "Callout": "Chamada",
"Insert callout notice.": "Insira um aviso.", "Insert callout notice.": "Insira um aviso.",
"Math inline": "Matemática inline", "Math inline": "Matemática em linha",
"Insert inline math equation.": "Insira uma equação matemática inline.", "Insert inline math equation.": "Insira uma equação matemática inline.",
"Math block": "Bloco de matemática", "Math block": "Bloco matemático",
"Insert math equation": "Insira uma equação matemática", "Insert math equation": "Inserir equação matemática",
"Mermaid diagram": "Diagrama Mermaid", "Mermaid diagram": "Diagrama Mermaid",
"Insert mermaid diagram": "Insira um diagrama Mermaid", "Insert mermaid diagram": "Inserir diagrama Mermaid",
"Insert and design Drawio diagrams": "Insira e projete diagramas Drawio", "Insert and design Drawio diagrams": "Inserir e criar diagramas Drawio",
"Insert current date": "Insira a data atual", "Insert current date": "Inserir data atual",
"Draw and sketch excalidraw diagrams": "Desenhe e esboce diagramas Excalidraw", "Draw and sketch excalidraw diagrams": "Desenhar e esboçar diagramas Excalidraw",
"Multiple": "Múltiplo", "Multiple": "Múltiplo",
"Turn into": "Transformar em", "Turn into": "Transformar em",
"Text align": "Alinhar texto", "Text align": "Alinhar texto",
@@ -366,8 +387,8 @@
"Go to homepage": "Ir para a página inicial", "Go to homepage": "Ir para a página inicial",
"Pages you create will show up here.": "As páginas que você criar aparecerão aqui.", "Pages you create will show up here.": "As páginas que você criar aparecerão aqui.",
"Heading {{level}}": "Título {{level}}", "Heading {{level}}": "Título {{level}}",
"Toggle title": "Alternar título", "Toggle title": "Título do bloco recolhível",
"Write anything. Enter \"/\" for commands": "Escreva qualquer coisa. Digite \"/\" para comandos", "Write anything. Enter \"/\" for commands": "Escreva qualquer coisa. Digite \"/\" para ver os comandos",
"Write...": "Escreva...", "Write...": "Escreva...",
"Column count": "Número de colunas", "Column count": "Número de colunas",
"{{count}} Columns": "{{count}} colunas", "{{count}} Columns": "{{count}} colunas",
@@ -377,7 +398,7 @@
"Wide center": "Centro largo", "Wide center": "Centro largo",
"Left wide": "Largo à esquerda", "Left wide": "Largo à esquerda",
"Right wide": "Largo à direita", "Right wide": "Largo à direita",
"Names do not match": "Os nomes não coincidem", "Names do not match": "Os nomes não correspondem",
"Today, {{time}}": "Hoje, {{time}}", "Today, {{time}}": "Hoje, {{time}}",
"Yesterday, {{time}}": "Ontem, {{time}}", "Yesterday, {{time}}": "Ontem, {{time}}",
"Space created successfully": "Espaço criado com sucesso", "Space created successfully": "Espaço criado com sucesso",
@@ -393,11 +414,11 @@
"Character count: {{characterCount}}": "Contagem de caracteres: {{characterCount}}", "Character count: {{characterCount}}": "Contagem de caracteres: {{characterCount}}",
"New update": "Nova atualização", "New update": "Nova atualização",
"{{latestVersion}} is available": "{{latestVersion}} está disponível", "{{latestVersion}} is available": "{{latestVersion}} está disponível",
"Default page edit mode": "Modo de edição de página padrão", "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 your preferred page edit mode. Avoid accidental edits.": "Escolha o modo de edição de página preferido. Evite edições acidentais.",
"Reading": "Leitura", "Reading": "Leitura",
"Delete member": "Excluir membro", "Delete member": "Excluir membro",
"Member deleted successfully": "Membro removido com sucesso", "Member deleted successfully": "Membro excluído com sucesso",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Você tem certeza que deseja deletar este membro do workspace? Esta ação é irreversível.", "Are you sure you want to delete this workspace member? This action is irreversible.": "Você tem certeza que deseja deletar este membro do workspace? Esta ação é irreversível.",
"Deactivate member": "Desativar membro", "Deactivate member": "Desativar membro",
"Activate member": "Ativar membro", "Activate member": "Ativar membro",
@@ -410,36 +431,38 @@
"Move page": "Mover página", "Move page": "Mover página",
"Move page to a different space.": "Mover página para um espaço diferente.", "Move page to a different space.": "Mover página para um espaço diferente.",
"Real-time editor connection lost. Retrying...": "Conexão do editor em tempo real perdida. Tentando novamente...", "Real-time editor connection lost. Retrying...": "Conexão do editor em tempo real perdida. Tentando novamente...",
"Table of contents": "Tabela de conteúdos", "Table of contents": "Sumário",
"Add headings (H1, H2, H3) to generate a table of contents.": "Adicionar títulos (H1, H2, H3) para gerar uma tabela de conteúdo.", "Add headings (H1, H2, H3) to generate a table of contents.": "Adicionar títulos (H1, H2, H3) para gerar uma tabela de conteúdo.",
"Share": "Compartilhar", "Share": "Compartilhar",
"Public sharing": "Compartilhamento público", "Public sharing": "Compartilhamento público",
"Shared by": "Compartilhado por", "Shared by": "Compartilhado por",
"Shared at": "Compartilhado em", "Shared at": "Compartilhado em",
"Inherits public sharing from": "Herdado do compartilhamento público de", "Inherits public sharing from": "Herda o compartilhamento público de",
"Share to web": "Compartilhar na web", "Share to web": "Compartilhar na web",
"Shared to web": "Compartilhado na web", "Shared to web": "Compartilhado na web",
"Anyone with the link can view this page": "Qualquer um com o link pode ver esta página", "Anyone with the link can view this page": "Qualquer pessoa com o link pode visualizar esta página",
"Make this page publicly accessible": "Tornar esta página publicamente acessível", "Make this page publicly accessible": "Tornar esta página acessível publicamente",
"Include sub-pages": "Incluir sub-páginas", "Include sub-pages": "Incluir subpáginas",
"Make sub-pages public too": "Tornar as sub-páginas públicas também", "Make sub-pages public too": "Tornar as subpáginas públicas também",
"Allow search engines to index page": "Permitir que mecanismos de busca indexem a página", "Allow search engines to index page": "Permitir que mecanismos de busca indexem a página",
"Open page": "Abrir página", "Open page": "Abrir página",
"Page": "Página", "Page": "Página",
"Delete public share link": "Excluir o link público compartilhado", "Delete public share link": "Excluir link de compartilhamento público",
"Delete share": "Excluir compartilhamento", "Delete share": "Excluir compartilhamento",
"Are you sure you want to delete this shared link?": "Tem certeza de que deseja excluir este link compartilhado?", "Are you sure you want to delete this shared link?": "Tem certeza de que deseja excluir este link compartilhado?",
"Publicly shared pages from spaces you are a member of will appear here": "Páginas compartilhadas publicamente de espaços que você é membro aparecerão aqui", "Publicly shared pages from spaces you are a member of will appear here": "Páginas compartilhadas publicamente dos espaços dos quais você é membro aparecerão aqui",
"Share deleted successfully": "Compartilhamento excluído com sucesso", "Share deleted successfully": "Compartilhamento excluído com sucesso",
"Share not found": "Compartilhamento não encontrado", "Share not found": "Compartilhamento não encontrado",
"Failed to share page": "Falha ao compartilhar página", "Failed to share page": "Falha ao compartilhar a página",
"Disable public sharing": "Desativar compartilhamento público", "Disable public sharing": "Desativar compartilhamento público",
"Prevent members from sharing pages publicly.": "Impedir que os membros compartilhem páginas publicamente.", "Prevent members from sharing pages publicly.": "Impedir que os membros compartilhem páginas publicamente.",
"Toggle public sharing": "Alternar compartilhamento público", "Toggle public sharing": "Alternar compartilhamento público",
"Toggle space public sharing": "Alternar compartilhamento público do espaço", "Toggle space public sharing": "Alternar compartilhamento público do espaço",
"Allow viewers to comment": "Permitir que os visualizadores comentem",
"Allow viewers to add comments on pages in this space.": "Permitir que os visualizadores adicionem comentários em páginas deste espaço.",
"Toggle viewer comments": "Ativar/desativar comentários de visualizadores",
"Public sharing is disabled at the workspace level": "O compartilhamento público está desativado no nível do espaço de trabalho", "Public sharing is disabled at the workspace level": "O compartilhamento público está desativado no nível do espaço de trabalho",
"Prevent pages in this space from being shared publicly.": "Impedir que as páginas neste espaço sejam compartilhadas publicamente.", "Prevent pages in this space from being shared publicly.": "Impedir que as páginas neste espaço sejam compartilhadas publicamente.",
"Requires an enterprise license": "Requer uma licença empresarial",
"Page permissions": "Permissões da página},{", "Page permissions": "Permissões da página},{",
"Control who can view and edit individual pages. Available with an enterprise license.": "Controle quem pode visualizar e editar páginas individuais. Disponível com licença empresarial.", "Control who can view and edit individual pages. Available with an enterprise license.": "Controle quem pode visualizar e editar páginas individuais. Disponível com licença empresarial.",
"Enable public sharing": "Ativar compartilhamento público", "Enable public sharing": "Ativar compartilhamento público",
@@ -454,7 +477,7 @@
"Copy page to a different space.": "Copiar página para um espaço diferente.", "Copy page to a different space.": "Copiar página para um espaço diferente.",
"Page copied successfully": "Página copiada com sucesso", "Page copied successfully": "Página copiada com sucesso",
"Page duplicated successfully": "Página duplicada com sucesso", "Page duplicated successfully": "Página duplicada com sucesso",
"Find": "Encontrar", "Find": "Localizar",
"Not found": "Não encontrado", "Not found": "Não encontrado",
"Previous Match (Shift+Enter)": "Correspondência anterior (Shift+Enter)", "Previous Match (Shift+Enter)": "Correspondência anterior (Shift+Enter)",
"Next match (Enter)": "Próxima correspondência (Enter)", "Next match (Enter)": "Próxima correspondência (Enter)",
@@ -464,15 +487,16 @@
"Replace (Enter)": "Substituir (Enter)", "Replace (Enter)": "Substituir (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Substituir tudo (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Substituir tudo (Ctrl+Alt+Enter)",
"Replace all": "Substituir tudo", "Replace all": "Substituir tudo",
"View all": "Ver tudo",
"View all spaces": "Ver todos os espaços", "View all spaces": "Ver todos os espaços",
"Error": "Erro", "Error": "Erro",
"Failed to disable MFA": "Falha ao desativar a MFA", "Failed to disable MFA": "Falha ao desativar a MFA",
"Disable two-factor authentication": "Desativar autenticação de dois fatores", "Disable two-factor authentication": "Desativar autenticação de dois fatores",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Desativar a autenticação de dois fatores tornará sua conta menos segura. Você só precisará de sua senha para entrar.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Desativar a autenticação de dois fatores tornará sua conta menos segura. Você só precisará de sua senha para entrar.",
"Please enter your password to disable two-factor authentication:": "Por favor, insira sua senha para desativar a autenticação de dois fatores:", "Please enter your password to disable two-factor authentication:": "Por favor, insira sua senha para desativar a autenticação de dois fatores:",
"Two-factor authentication has been enabled": "Autenticação de dois fatores foi ativada", "Two-factor authentication has been enabled": "A autenticação de dois fatores foi ativada",
"Two-factor authentication has been disabled": "Autenticação de dois fatores foi desativada", "Two-factor authentication has been disabled": "A autenticação de dois fatores foi desativada",
"2-step verification": "Verificação em duas etapas", "2-step verification": "Verificação em 2 etapas",
"Protect your account with an additional verification layer when signing in.": "Proteja sua conta com uma camada adicional de verificação ao entrar.", "Protect your account with an additional verification layer when signing in.": "Proteja sua conta com uma camada adicional de verificação ao entrar.",
"Two-factor authentication is active on your account.": "Autenticação de dois fatores está ativa na sua conta.", "Two-factor authentication is active on your account.": "Autenticação de dois fatores está ativa na sua conta.",
"Add 2FA method": "Adicionar método de 2FA", "Add 2FA method": "Adicionar método de 2FA",
@@ -480,43 +504,43 @@
"Disable": "Desativar", "Disable": "Desativar",
"Invalid verification code": "Código de verificação inválido", "Invalid verification code": "Código de verificação inválido",
"New backup codes have been generated": "Novos códigos de backup foram gerados", "New backup codes have been generated": "Novos códigos de backup foram gerados",
"Failed to regenerate backup codes": "Falha ao regenerar códigos de backup", "Failed to regenerate backup codes": "Falha ao regenerar os códigos de backup",
"About backup codes": "Sobre códigos de backup", "About backup codes": "Sobre os códigos de backup",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Códigos de backup podem ser usados para acessar sua conta se perder acesso ao aplicativo autenticador. Cada código só pode ser usado uma vez.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Códigos de backup podem ser usados para acessar sua conta se perder acesso ao aplicativo autenticador. Cada código só pode ser usado uma vez.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Você pode regenerar novos códigos de backup a qualquer momento. Isso invalidará todos os códigos existentes.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Você pode regenerar novos códigos de backup a qualquer momento. Isso invalidará todos os códigos existentes.",
"Confirm password": "Confirmar senha", "Confirm password": "Confirmar senha",
"Generate new backup codes": "Gerar novos códigos de backup", "Generate new backup codes": "Gerar novos códigos de backup",
"Save your new backup codes": "Salvar seus novos códigos de backup", "Save your new backup codes": "Salve seus novos códigos de backup",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Certifique-se de salvar esses códigos em um local seguro. Seus códigos de backup antigos não são mais válidos.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Certifique-se de salvar esses códigos em um local seguro. Seus códigos de backup antigos não são mais válidos.",
"Your new backup codes": "Seus novos códigos de backup", "Your new backup codes": "Seus novos códigos de backup",
"I've saved my backup codes": "Eu salvei meus códigos de backup", "I've saved my backup codes": "Salvei meus códigos de backup",
"Failed to setup MFA": "Falha ao configurar a MFA", "Failed to setup MFA": "Falha ao configurar a MFA",
"Setup & Verify": "Configurar & Verificar", "Setup & Verify": "Configurar e verificar",
"Add to authenticator": "Adicionar ao autenticador", "Add to authenticator": "Adicionar ao autenticador",
"1. Scan this QR code with your authenticator app": "1. Escaneie este código QR com seu aplicativo autenticador", "1. Scan this QR code with your authenticator app": "1. Escaneie este código QR com seu aplicativo autenticador",
"Can't scan the code?": "Não consegue escanear o código?", "Can't scan the code?": "Não consegue escanear o código?",
"Enter this code manually in your authenticator app:": "Digite este código manualmente em seu aplicativo autenticador:", "Enter this code manually in your authenticator app:": "Digite este código manualmente em seu aplicativo autenticador:",
"2. Enter the 6-digit code from your authenticator": "2. Digite o código de 6 dígitos do seu autenticador", "2. Enter the 6-digit code from your authenticator": "2. Insira o código de 6 dígitos do seu autenticador",
"Verify and enable": "Verificar e ativar", "Verify and enable": "Verificar e ativar",
"Failed to generate QR code. Please try again.": "Falha ao gerar código QR. Por favor, tente novamente.", "Failed to generate QR code. Please try again.": "Falha ao gerar código QR. Por favor, tente novamente.",
"Backup": "Backup", "Backup": "Backup",
"Save codes": "Salvar códigos", "Save codes": "Salvar códigos",
"Save your backup codes": "Salvar seus códigos de backup", "Save your backup codes": "Salve seus códigos de backup",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Esses códigos podem ser usados para acessar sua conta se você perder o acesso ao aplicativo autenticador. Cada código só pode ser usado uma vez.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Esses códigos podem ser usados para acessar sua conta se você perder o acesso ao aplicativo autenticador. Cada código só pode ser usado uma vez.",
"Print": "Imprimir", "Print": "Imprimir",
"Two-factor authentication has been set up. Please log in again.": "A autenticação de dois fatores foi configurada. Por favor, faça login novamente.", "Two-factor authentication has been set up. Please log in again.": "A autenticação de dois fatores foi configurada. Por favor, faça login novamente.",
"Two-Factor authentication required": "Autenticação de dois fatores necessária", "Two-Factor authentication required": "Autenticação de dois fatores obrigatória",
"Your workspace requires two-factor authentication for all users": "Seu espaço de trabalho requer autenticação de dois fatores para todos os usuários", "Your workspace requires two-factor authentication for all users": "Seu workspace exige autenticação de dois fatores para todos os usuários",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Para continuar acessando seu espaço de trabalho, você deve configurar a autenticação de dois fatores. Isso adiciona uma camada extra de segurança à sua conta.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Para continuar acessando seu espaço de trabalho, você deve configurar a autenticação de dois fatores. Isso adiciona uma camada extra de segurança à sua conta.",
"Set up two-factor authentication": "Configurar autenticação de dois fatores", "Set up two-factor authentication": "Configurar autenticação de dois fatores",
"Cancel and logout": "Cancelar e sair", "Cancel and logout": "Cancelar e sair",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Seu espaço de trabalho requer autenticação de dois fatores. Por favor, configure para continuar.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Seu espaço de trabalho requer autenticação de dois fatores. Por favor, configure para continuar.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Isso adiciona uma camada extra de segurança à sua conta, exigindo um código de verificação de seu aplicativo autenticador.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Isso adiciona uma camada extra de segurança à sua conta, exigindo um código de verificação de seu aplicativo autenticador.",
"Password is required": "Senha é necessária", "Password is required": "A senha é obrigatória",
"Password must be at least 8 characters": "A senha deve ter pelo menos 8 caracteres", "Password must be at least 8 characters": "A senha deve ter pelo menos 8 caracteres",
"Please enter a 6-digit code": "Por favor, insira um código de 6 dígitos", "Please enter a 6-digit code": "Insira um código de 6 dígitos",
"Code must be exactly 6 digits": "O código deve ter exatamente 6 dígitos", "Code must be exactly 6 digits": "O código deve ter exatamente 6 dígitos",
"Enter the 6-digit code found in your authenticator app": "Insira o código de 6 dígitos encontrado em seu aplicativo autenticador", "Enter the 6-digit code found in your authenticator app": "Insira o código de 6 dígitos encontrado no seu aplicativo autenticador",
"Need help authenticating?": "Precisa de ajuda para autenticar?", "Need help authenticating?": "Precisa de ajuda para autenticar?",
"MFA QR Code": "Código QR de MFA", "MFA QR Code": "Código QR de MFA",
"Account created successfully. Please log in to set up two-factor authentication.": "Conta criada com sucesso. Por favor, faça login para configurar a autenticação de dois fatores.", "Account created successfully. Please log in to set up two-factor authentication.": "Conta criada com sucesso. Por favor, faça login para configurar a autenticação de dois fatores.",
@@ -524,17 +548,17 @@
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Redefinição de senha bem-sucedida. Por favor, faça login com sua nova senha para configurar a autenticação de dois fatores.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Redefinição de senha bem-sucedida. Por favor, faça login com sua nova senha para configurar a autenticação de dois fatores.",
"Password reset was successful. Please log in with your new password.": "Redefinição de senha foi bem-sucedida. Por favor, faça login com sua nova senha.", "Password reset was successful. Please log in with your new password.": "Redefinição de senha foi bem-sucedida. Por favor, faça login com sua nova senha.",
"Two-factor authentication": "Autenticação de dois fatores", "Two-factor authentication": "Autenticação de dois fatores",
"Use authenticator app instead": "Use o aplicativo autenticador em vez disso", "Use authenticator app instead": "Usar aplicativo autenticador em vez disso",
"Verify backup code": "Verificar código de backup", "Verify backup code": "Verificar código de backup",
"Use backup code": "Usar código de backup", "Use backup code": "Usar código de backup",
"Enter one of your backup codes": "Digite um de seus códigos de backup", "Enter one of your backup codes": "Insira um dos seus códigos de backup",
"Backup code": "Código de backup", "Backup code": "Código de backup",
"Enter one of your backup codes. Each backup code can only be used once.": "Digite um de seus códigos de backup. Cada código de backup só pode ser usado uma vez.", "Enter one of your backup codes. Each backup code can only be used once.": "Digite um de seus códigos de backup. Cada código de backup só pode ser usado uma vez.",
"Verify": "Verificar", "Verify": "Verificar",
"Trash": "Lixeira", "Trash": "Lixeira",
"Pages in trash will be permanently deleted after {{count}} days.": "{count, plural, one {A página na lixeira será excluída permanentemente após # dia.} other {As páginas na lixeira serão excluídas permanentemente após # dias.}}", "Pages in trash will be permanently deleted after {{count}} days.": "{count, plural, one {A página na lixeira será excluída permanentemente após # dia.} other {As páginas na lixeira serão excluídas permanentemente após # dias.}}",
"Deleted": "Excluído", "Deleted": "Excluído",
"No pages in trash": "Sem páginas na lixeira", "No pages in trash": "Nenhuma página na lixeira",
"Permanently delete page?": "Excluir página permanentemente?", "Permanently delete page?": "Excluir página permanentemente?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Tem certeza de que deseja excluir permanentemente '{{title}}'? Esta ação não pode ser desfeita.", "Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Tem certeza de que deseja excluir permanentemente '{{title}}'? Esta ação não pode ser desfeita.",
"Restore '{{title}}' and its sub-pages?": "Restaurar '{{title}}' e suas subpáginas?", "Restore '{{title}}' and its sub-pages?": "Restaurar '{{title}}' e suas subpáginas?",
@@ -547,9 +571,9 @@
"Deleted at": "Excluído em", "Deleted at": "Excluído em",
"Preview": "Visualização", "Preview": "Visualização",
"Subpages": "Subpáginas", "Subpages": "Subpáginas",
"Failed to load subpages": "Falha ao carregar subpáginas", "Failed to load subpages": "Falha ao carregar as subpáginas",
"No subpages": "Sem subpáginas", "No subpages": "Nenhuma subpágina",
"Subpages (Child pages)": "Subpáginas (Páginas filhas)", "Subpages (Child pages)": "Subpáginas (páginas filhas)",
"List all subpages of the current page": "Listar todas as subpáginas da página atual", "List all subpages of the current page": "Listar todas as subpáginas da página atual",
"Attachments": "Anexos", "Attachments": "Anexos",
"All spaces": "Todos os espaços", "All spaces": "Todos os espaços",
@@ -557,28 +581,28 @@
"Find a space": "Encontrar um espaço", "Find a space": "Encontrar um espaço",
"Search in all your spaces": "Pesquisar em todos os seus espaços", "Search in all your spaces": "Pesquisar em todos os seus espaços",
"Type": "Tipo", "Type": "Tipo",
"Enterprise": "Empresa", "Enterprise": "Enterprise",
"Download attachment": "Baixar anexo", "Download attachment": "Baixar anexo",
"Allowed email domains": "Domínios de email permitidos", "Allowed email domains": "Domínios de e-mail permitidos",
"Only users with email addresses from these domains can signup via SSO.": "Apenas usuários com endereços de email desses domínios podem se inscrever via SSO.", "Only users with email addresses from these domains can signup via SSO.": "Somente usuários com endereços de e-mail desses domínios podem se cadastrar via SSO.",
"Enter valid domain names separated by comma or space": "Insira nomes de domínio válidos separados por vírgula ou espaço", "Enter valid domain names separated by comma or space": "Insira nomes de domínio válidos separados por vírgula ou espaço",
"Enforce two-factor authentication": "Impor autenticação de dois fatores", "Enforce two-factor authentication": "Exigir autenticação de dois fatores",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Uma vez imposto, todos os membros devem habilitar a autenticação de dois fatores para acessar o espaço de trabalho.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Uma vez imposto, todos os membros devem habilitar a autenticação de dois fatores para acessar o espaço de trabalho.",
"Toggle MFA enforcement": "Alternar imposição de MFA", "Toggle MFA enforcement": "Alternar exigência de MFA",
"Display name": "Nome de exibição", "Display name": "Nome de exibição",
"Allow signup": "Permitir inscrição", "Allow signup": "Permitir cadastro",
"Enabled": "Habilitado", "Enabled": "Ativado",
"Advanced Settings": "Configurações Avançadas", "Advanced Settings": "Configurações avançadas",
"Enable TLS/SSL": "Habilitar TLS/SSL", "Enable TLS/SSL": "Ativar TLS/SSL",
"Use secure connection to LDAP server": "Usar conexão segura com o servidor LDAP", "Use secure connection to LDAP server": "Usar conexão segura com o servidor LDAP",
"Group sync": "Sincronização de grupo", "Group sync": "Sincronização de grupos",
"No SSO providers found.": "Nenhum provedor de SSO encontrado.", "No SSO providers found.": "Nenhum provedor de SSO encontrado.",
"Delete SSO provider": "Excluir provedor de SSO", "Delete SSO provider": "Excluir provedor de SSO",
"Are you sure you want to delete this SSO provider?": "Tem certeza de que deseja excluir este provedor de SSO?", "Are you sure you want to delete this SSO provider?": "Tem certeza de que deseja excluir este provedor de SSO?",
"Action": "Ação", "Action": "Ação",
"{{ssoProviderType}} configuration": "Configuração de {{ssoProviderType}}", "{{ssoProviderType}} configuration": "Configuração de {{ssoProviderType}}",
"Icon": "Ícone", "Icon": "Ícone",
"Upload image": "Fazer upload da imagem", "Upload image": "Enviar imagem",
"Remove image": "Remover imagem", "Remove image": "Remover imagem",
"Failed to remove image": "Falha ao remover imagem", "Failed to remove image": "Falha ao remover imagem",
"Image exceeds 10MB limit.": "A imagem excede o limite de 10MB.", "Image exceeds 10MB limit.": "A imagem excede o limite de 10MB.",
@@ -613,6 +637,7 @@
"AI Answer": "Resposta de IA", "AI Answer": "Resposta de IA",
"Ask AI": "Pergunte à IA", "Ask AI": "Pergunte à IA",
"AI is thinking...": "IA está pensando...", "AI is thinking...": "IA está pensando...",
"Thinking": "Pensando",
"Ask a question...": "Faça uma pergunta...", "Ask a question...": "Faça uma pergunta...",
"AI Answers": "Respostas de IA", "AI Answers": "Respostas de IA",
"AI-powered search (AI Answers)": "Pesquisa com IA (Respostas de IA)", "AI-powered search (AI Answers)": "Pesquisa com IA (Respostas de IA)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "IA generativa (Perguntar à IA)", "Generative AI (Ask AI)": "IA generativa (Perguntar à IA)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Habilitar geração de conteúdo com IA no editor. Permite aos usuários gerar, melhorar, traduzir e transformar texto.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Habilitar geração de conteúdo com IA no editor. Permite aos usuários gerar, melhorar, traduzir e transformar texto.",
"Toggle generative AI": "Alternar IA generativa", "Toggle generative AI": "Alternar IA generativa",
"Enterprise feature": "Recurso empresarial", "Upgrade your plan": "Faça upgrade do seu plano",
"Available with a paid license": "Disponível com uma licença paga",
"Upgrade your license tier.": "Faça upgrade do seu nível de licença.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "A IA está disponível apenas na edição empresarial do Docmost. Contate sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "A IA está disponível apenas na edição empresarial do Docmost. Contate sales@docmost.com.",
"AI & MCP": "IA e MCP", "AI & MCP": "IA e MCP",
"AI": "IA", "AI": "IA",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Protocolo de Contexto de Modelo (MCP)", "Model Context Protocol (MCP)": "Protocolo de Contexto de Modelo (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Ative o servidor MCP para permitir que assistentes de IA e ferramentas interajam com o conteúdo do seu espaço de trabalho.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Ative o servidor MCP para permitir que assistentes de IA e ferramentas interajam com o conteúdo do seu espaço de trabalho.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "O MCP está disponível apenas na edição empresarial do Docmost. Contate sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "O MCP está disponível apenas na edição empresarial do Docmost. Contate sales@docmost.com.",
"MCP documentation": "Documentação do MCP",
"MCP Server URL": "URL do servidor MCP", "MCP Server URL": "URL do servidor MCP",
"Use your API key for authentication. You can manage API keys in your account settings.": "Use sua chave de API para autenticação. Você pode gerenciar chaves de API nas configurações da sua conta.", "Use your API key for authentication. You can manage API keys in your account settings.": "Use sua chave de API para autenticação. Você pode gerenciar chaves de API nas configurações da sua conta.",
"Supported tools": "Ferramentas compatíveis", "Supported tools": "Ferramentas compatíveis",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Seu espaço de trabalho tem MCP habilitado. Use sua chave de API para conectar assistentes de IA.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Seu espaço de trabalho tem MCP habilitado. Use sua chave de API para conectar assistentes de IA.",
"MCP server URL:": "URL do servidor MCP:", "MCP server URL:": "URL do servidor MCP:",
"Learn more": "Saiba mais", "Learn more": "Saiba mais",
"View the": "Veja o", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Gerencie as chaves de API de todos os usuários do workspace. Veja a <anchor>documentação da API</anchor> para detalhes de uso.",
"for usage details.": "para detalhes de uso.", "View the <anchor>API documentation</anchor> for usage details.": "Veja a <anchor>documentação da API</anchor> para detalhes de uso.",
"for setup instructions.": "para instruções de configuração.", "View the <anchor>MCP documentation</anchor>.": "Veja a <anchor>documentação MCP</anchor>.",
"API documentation": "Documentação da API",
"Sources": "Fontes", "Sources": "Fontes",
"AI Answers not available for attachments": "Respostas de IA não disponíveis para anexos", "AI Answers not available for attachments": "Respostas de IA não disponíveis para anexos",
"No answer available": "Nenhuma resposta disponível", "No answer available": "Nenhuma resposta disponível",
@@ -654,12 +679,34 @@
"Mark all as read": "Marcar todas como lidas", "Mark all as read": "Marcar todas como lidas",
"Mark as read": "Marcar como lida", "Mark as read": "Marcar como lida",
"More options": "Mais opções", "More options": "Mais opções",
"mentioned you in a comment": "mencionou você em um comentário", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> mencionou você em um comentário",
"commented on a page": "comentou em uma página", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> comentou em uma página",
"resolved a comment": "resolveu um comentário", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> resolveu um comentário",
"mentioned you on a page": "mencionou você em uma página", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> mencionou você em uma página",
"gave you edit access to a page": "concedeu a você acesso para editar a página", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> concedeu a você acesso de edição a uma página",
"gave you view access to a page": "concedeu a você acesso para visualizar a página", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> concedeu a você acesso de visualização a uma página",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> atualizou uma página",
"Watch page": "Acompanhar página",
"Stop watching": "Parar de acompanhar",
"Watch space": "Acompanhar espaço",
"Stop watching space": "Parar de acompanhar espaço",
"Email notifications": "Notificações por e-mail",
"Page updates": "Atualizações da página",
"Get notified when pages you watch are updated.": "Receba notificações quando as páginas que você observa forem atualizadas.",
"Page mentions": "Menções na página",
"Get notified when someone mentions you on a page.": "Receba notificações quando alguém mencionar você em uma página.",
"Comment mentions": "Menções em comentários",
"Get notified when someone mentions you in a comment.": "Receba notificações quando alguém mencionar você em um comentário.",
"New comments": "Novos comentários",
"Get notified about new comments on threads you participate in.": "Receba notificações sobre novos comentários nas discussões em que você participa.",
"Resolved comments": "Comentários resolvidos",
"Get notified when your comment is resolved.": "Receba notificações quando seu comentário for resolvido.",
"You are now watching this page": "Agora você está observando esta página",
"You are no longer watching this page": "Você não está mais observando esta página",
"You are now watching this space": "Agora você está acompanhando este espaço",
"You are no longer watching this space": "Você não está mais acompanhando este espaço",
"Direct": "Direto",
"Updates": "Atualizações",
"Today": "Hoje", "Today": "Hoje",
"Yesterday": "Ontem", "Yesterday": "Ontem",
"This week": "Esta semana", "This week": "Esta semana",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Falha ao atualizar a retenção da lixeira", "Failed to update trash retention": "Falha ao atualizar a retenção da lixeira",
"Removed page restriction": "Restrição de página removida", "Removed page restriction": "Restrição de página removida",
"Added page permission": "Permissão de página adicionada", "Added page permission": "Permissão de página adicionada",
"Removed page permission": "Permissão de página removida" "Removed page permission": "Permissão de página removida",
"day": "dia",
"days": "dias",
"week": "semana",
"weeks": "semanas",
"month": "mês",
"months": "meses",
"year": "ano",
"years": "anos",
"Period": "Período",
"Fixed date": "Data fixa",
"Indefinitely": "Indefinidamente",
"Days": "Dias",
"Weeks": "Semanas",
"Months": "Meses",
"Years": "Anos",
"Pick a date": "Escolha uma data",
"Maximum is {{max}} {{unit}} for this unit": "O máximo é {{max}} {{unit}} para esta unidade",
"Never expires. Verifiers can re-verify at any time.": "Nunca expira. Os verificadores podem verificar novamente a qualquer momento.",
"Verified": "Verificado",
"Review needed": "Revisão necessária",
"Verification expired": "A verificação expirou",
"Draft": "Rascunho",
"In Approval": "Em aprovação",
"In approval": "Em aprovação",
"Approved": "Aprovado",
"Obsolete": "Obsoleto",
"Expiring": "Expirando",
"Set up verification": "Configurar verificação",
"Verify page": "Verificar página",
"Page verification": "Verificação da página",
"Add verification": "Adicionar verificação",
"Edit verification": "Editar verificação",
"Search by title": "Pesquisar por título",
"Choose how this page should stay accurate.": "Escolha como esta página deve permanecer precisa.",
"Recurring verification": "Verificação recorrente",
"Verifiers re-confirm this page on a schedule.": "Os verificadores confirmam novamente esta página em uma programação definida.",
"Re-verify on a schedule (e.g every 30 days )": "Verificar novamente em uma programação definida (ex.: a cada 30 dias)",
"Page stays editable at all times": "A página permanece editável o tempo todo",
"Best for runbooks, FAQs, living documentation": "Ideal para runbooks, FAQs e documentação viva",
"Approval workflow": "Fluxo de aprovação",
"Formal document lifecycle with named approvers.": "Ciclo de vida formal do documento com aprovadores nomeados.",
"Draft → In approval → Approved → Obsolete": "Rascunho → Em aprovação → Aprovado → Obsoleto",
"Locked once approved, with full history": "Bloqueado após a aprovação, com histórico completo",
"Designed for ISO 9001, ISO 13485, and FDA": "Desenvolvido para ISO 9001, ISO 13485 e FDA",
"Best for SOPs and controlled documents": "Ideal para POPs e documentos controlados",
"Back": "Voltar",
"Quality management": "Gestão da qualidade",
"Recurring": "Recorrente",
"Pages move through draft, approval, and approved stages.": "As páginas passam pelos estágios de rascunho, aprovação e aprovado.",
"Verifiers": "Verificadores",
"Add verifier": "Adicionar verificador",
"I've reviewed this page for accuracy": "Revisei esta página quanto à precisão",
"Set up": "Configurar",
"Remove verification": "Remover verificação",
"Are you sure you want to remove verification from this page?": "Tem certeza de que deseja remover a verificação desta página?",
"Assigned verifiers must periodically re-verify this page.": "Os verificadores atribuídos devem verificar novamente esta página periodicamente.",
"Last verified by {{name}} {{time}} (expired)": "Verificado pela última vez por {{name}} {{time}} (expirado)",
"The fixed expiration date has passed.": "A data fixa de expiração já passou.",
"Verified by {{name}} {{time}}": "Verificado por {{name}} {{time}}",
"Expires {{date}}": "Expira em {{date}}",
"Expired {{date}}": "Expirou em {{date}}",
"Mark as obsolete": "Marcar como obsoleto",
"Mark obsolete": "Marcar como obsoleto",
"Returned by {{name}} {{time}}": "Devolvido por {{name}} {{time}}",
"No approval has been requested yet.": "Nenhuma aprovação foi solicitada ainda.",
"Submitted by {{name}} {{time}}": "Enviado por {{name}} {{time}}",
"Someone": "Alguém",
"Approved by {{name}} {{time}}": "Aprovado por {{name}} {{time}}",
"This document has been marked as obsolete.": "Este documento foi marcado como obsoleto.",
"Rejection comment": "Comentário de rejeição",
"Reason for returning this document...": "Motivo para devolver este documento...",
"Confirm rejection": "Confirmar rejeição",
"Submit for approval": "Enviar para aprovação",
"Reject": "Rejeitar",
"Approve": "Aprovar",
"Re-submit for approval": "Reenviar para aprovação",
"Verified until": "Verificado até",
"QMS": "SGQ",
"Verified pages": "Páginas verificadas",
"Search pages...": "Pesquisar páginas...",
"Filter by space": "Filtrar por espaço",
"Filter by type": "Filtrar por tipo",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> verificou uma página",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> enviou uma página para sua aprovação",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> devolveu uma página para revisão",
"Page verification expires soon": "A verificação da página expirará em breve",
"Page verification has expired": "A verificação da página expirou",
"Verifying your email": "Verificando seu e-mail",
"Please wait...": "Por favor, aguarde...",
"Verification failed. The link may have expired.": "Falha na verificação. O link pode ter expirado.",
"Check your email": "Verifique seu e-mail",
"We sent a verification link to {{email}}.": "Enviamos um link de verificação para {{email}}.",
"We sent a verification link to your email.": "Enviamos um link de verificação para seu e-mail.",
"Click the link to verify your email and access your workspace.": "Clique no link para verificar seu e-mail e acessar seu workspace.",
"Resend verification email": "Reenviar e-mail de verificação",
"Verification email sent. Please check your inbox.": "E-mail de verificação enviado. Por favor, verifique sua caixa de entrada.",
"Failed to resend verification email. Please try again.": "Falha ao reenviar o e-mail de verificação. Por favor, tente novamente.",
"We've sent you an email with your associated workspaces.": "Enviamos um e-mail para você com seus workspaces associados.",
"Load more": "Carregar mais",
"Log out of all devices": "Sair de todos os dispositivos",
"Log out of all sessions except this device": "Sair de todas as sessões, exceto deste dispositivo",
"This Device": "Este dispositivo",
"Unknown device": "Dispositivo desconhecido",
"No active sessions": "Nenhuma sessão ativa",
"Session revoked": "Sessão revogada",
"All other sessions revoked": "Todas as outras sessões foram revogadas",
"Last used": "Último uso",
"Created": "Criado",
"Rename": "Renomear",
"Publish": "Publicar",
"Security": "Segurança",
"Enforce SSO": "Exigir SSO",
"Once enforced, members will not be able to login with email and password.": "Depois de exigido, os membros não poderão fazer login com e-mail e senha.",
"AI-generated content may not be accurate.": "O conteúdo gerado por IA pode não ser preciso.",
"AI Chat": "Chat com IA",
"Analyze for insights": "Analisar para obter insights",
"Ask anything...": "Pergunte qualquer coisa...",
"Chat history": "Histórico de chats",
"Chat name": "Nome do chat",
"Close": "Fechar",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Falha ao carregar o chat. Ocorreu um erro.",
"Failed to render this message.": "Falha ao renderizar esta mensagem.",
"How can I help you today?": "Como posso ajudar você hoje?",
"New chat": "Novo chat",
"No chat history": "Nenhum histórico de chat",
"No chats found": "Nenhum chat encontrado",
"No conversations yet": "Ainda não há conversas",
"Open full page": "Abrir página inteira",
"Previous 7 days": "Últimos 7 dias",
"Previous 30 days": "Últimos 30 dias",
"Search chats...": "Pesquisar chats...",
"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",
"Translate this page": "Traduzir esta página",
"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ê?"
} }
+291 -104
View File
@@ -7,6 +7,7 @@
"Add members": "Добавить участников", "Add members": "Добавить участников",
"Add to groups": "Добавить в группы", "Add to groups": "Добавить в группы",
"Add space members": "Добавить участников пространства", "Add space members": "Добавить участников пространства",
"Add to favorites": "Добавить в избранное",
"Admin": "Администратор", "Admin": "Администратор",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Вы уверены, что хотите удалить эту группу? Участники потеряют доступ к материалам, к которым у этой группы есть доступ.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Вы уверены, что хотите удалить эту группу? Участники потеряют доступ к материалам, к которым у этой группы есть доступ.",
"Are you sure you want to delete this page?": "Вы уверены, что хотите удалить эту страницу?", "Are you sure you want to delete this page?": "Вы уверены, что хотите удалить эту страницу?",
@@ -46,20 +47,20 @@
"Details": "Подробности", "Details": "Подробности",
"e.g ACME": "например, ACME", "e.g ACME": "например, ACME",
"e.g ACME Inc": "например, ACME Inc", "e.g ACME Inc": "например, ACME Inc",
"e.g Developers": "например, Разработчики", "e.g Developers": "например, Developers",
"e.g Group for developers": "например, Группа для разработчиков", "e.g Group for developers": "например, Группа для разработчиков",
"e.g product": "например, продукт", "e.g product": "например, product",
"e.g Product Team": "например, Продуктовая команда", "e.g Product Team": "например, Команда продукта",
"e.g Sales": "например, Продажи", "e.g Sales": "например, Sales",
"e.g Space for product team": "например, Пространство для продуктовой команды", "e.g Space for product team": "например, Пространство для команды продукта",
"e.g Space for sales team to collaborate": "например, Пространство для совместной работы команды продаж", "e.g Space for sales team to collaborate": "например, Пространство для совместной работы команды продаж",
"Edit": "Редактировать", "Edit": "Редактировать",
"Read": итать", "Read": тение",
"Edit group": "Редактировать группу", "Edit group": "Редактировать группу",
"Email": "Электронная почта", "Email": "Электронная почта",
"Enter a strong password": "Введите надёжный пароль", "Enter a strong password": "Введите надёжный пароль",
"Enter valid email addresses separated by comma or space max_50": "Введите действительные адреса электронной почты, разделенные запятой или пробелом [макс: 50]", "Enter valid email addresses separated by comma or space max_50": "Введите действительные адреса электронной почты, разделенные запятой или пробелом [макс: 50]",
"enter valid emails addresses": "введите действительные адреса электронной почты", "enter valid emails addresses": "введите корректные адреса электронной почты",
"Enter your current password": "Введите ваш текущий пароль", "Enter your current password": "Введите ваш текущий пароль",
"enter your full name": "введите ваше полное имя", "enter your full name": "введите ваше полное имя",
"Enter your new password": "Введите ваш новый пароль", "Enter your new password": "Введите ваш новый пароль",
@@ -74,6 +75,9 @@
"Failed to import pages": "Не удалось импортировать страницы", "Failed to import pages": "Не удалось импортировать страницы",
"Failed to load page. An error occurred.": "Не удалось загрузить страницу. Произошла ошибка.", "Failed to load page. An error occurred.": "Не удалось загрузить страницу. Произошла ошибка.",
"Failed to update data": "Не удалось обновить данные", "Failed to update data": "Не удалось обновить данные",
"Favorite spaces": "Избранные пространства",
"Favorite spaces appear here": "Здесь отображаются избранные пространства",
"Favorites": "Избранное",
"Full access": "Полный доступ", "Full access": "Полный доступ",
"Full page width": "Ширина на всю страницу", "Full page width": "Ширина на всю страницу",
"Full width": "Во всю ширину", "Full width": "Во всю ширину",
@@ -87,11 +91,12 @@
"Import pages": "Импорт страниц", "Import pages": "Импорт страниц",
"Import pages & space settings": "Импорт страниц и настройки пространства", "Import pages & space settings": "Импорт страниц и настройки пространства",
"Importing pages": "Импортирование страниц", "Importing pages": "Импортирование страниц",
"invalid invitation link": "ссылка на приглашение недействительна", "invalid invitation link": "недействительная ссылка-приглашение",
"Invitation signup": "Регистрация по приглашению", "Invitation signup": "Регистрация по приглашению",
"Invite by email": "Пригласить по электронной почте", "Invite by email": "Пригласить по электронной почте",
"Invite members": "Пригласить участников", "Invite members": "Пригласить участников",
"Invite new members": "Пригласить новых участников", "Invite new members": "Пригласить новых участников",
"Invite People": "Пригласить людей",
"Invited members who are yet to accept their invitation will appear here.": "Приглашённые участники, которые ещё не приняли приглашение, появятся здесь.", "Invited members who are yet to accept their invitation will appear here.": "Приглашённые участники, которые ещё не приняли приглашение, появятся здесь.",
"Invited members will be granted access to spaces the groups can access": "Приглашённые участники получат доступ к пространствам, доступ к которым есть у группы", "Invited members will be granted access to spaces the groups can access": "Приглашённые участники получат доступ к пространствам, доступ к которым есть у группы",
"Join the workspace": "Присоединиться к рабочей области", "Join the workspace": "Присоединиться к рабочей области",
@@ -139,6 +144,7 @@
"Profile": "Профиль", "Profile": "Профиль",
"Recently updated": "Обновлено недавно", "Recently updated": "Обновлено недавно",
"Remove": "Удалить", "Remove": "Удалить",
"Remove from favorites": "Удалить из избранного",
"Remove group member": "Удалить участника группы", "Remove group member": "Удалить участника группы",
"Remove space member": "Удалить участника пространства", "Remove space member": "Удалить участника пространства",
"Restore": "Восстановить", "Restore": "Восстановить",
@@ -151,49 +157,50 @@
"Search...": "Поиск...", "Search...": "Поиск...",
"Select language": "Выберите язык", "Select language": "Выберите язык",
"Select role": "Выберите роль", "Select role": "Выберите роль",
"Select role to assign to all invited members": "Выберите роль для всех приглашённых участников", "Select role to assign to all invited members": "Выберите роль, которую нужно назначить всем приглашённым участникам",
"Select theme": "Выберите тему", "Select theme": "Выберите тему",
"Send invitation": "Отправить приглашение", "Send invitation": "Отправить приглашение",
"Invitation sent": "Приглашение отправлено", "Invitation sent": "Приглашение отправлено",
"Settings": "Настройки", "Settings": "Настройки",
"Setup workspace": "Настроить рабочую область", "Setup workspace": "Настроить рабочее пространство",
"Sign In": "Вход", "Sign In": "Войти",
"Sign Up": "Регистрация", "Sign Up": "Зарегистрироваться",
"Slug": "Slug", "Slug": "Слаг",
"Space": "Пространство", "Space": "Пространство",
"Space description": "Описание пространства", "Space description": "Описание пространства",
"Space menu": "Меню пространства", "Space menu": "Меню пространства",
"Space name": "Название пространства", "Space name": "Название пространства",
"Space settings": "Настройки пространства", "Space settings": "Настройки пространства",
"Space slug": "Slug пространства", "Space slug": "Слаг пространства",
"Spaces": "Пространства", "Spaces": "Пространства",
"Spaces you belong to": "Пространства, к которым вы принадлежите", "Spaces you belong to": "Пространства, в которых вы состоите",
"No space found": "Пространства не найдены", "No space found": "Пространство не найдено",
"Search for spaces": "Поиск пространств", "Search for spaces": "Поиск пространств",
"Start typing to search...": "Начните вводить для поиска...", "Start typing to search...": "Начните вводить для поиска...",
"Status": "Статус", "Status": "Статус",
"Successfully imported": "Успешно импортировано", "Successfully imported": "Успешно импортировано",
"Successfully restored": "Успешно восстановлено", "Successfully restored": "Успешно восстановлено",
"System settings": "Системные настройки", "System settings": "Системные настройки",
"Templates": "Шаблоны",
"Theme": "Тема", "Theme": "Тема",
"To change your email, you have to enter your password and new email.": "Чтобы изменить электронную почту, вам нужно ввести пароль и новый адрес.", "To change your email, you have to enter your password and new email.": "Чтобы изменить электронную почту, вам нужно ввести пароль и новый адрес.",
"Toggle full page width": "Переключить ширину на всю страницу", "Toggle full page width": "Переключить полную ширину страницы",
"Unable to import pages. Please try again.": "Не удалось импортировать страницы. Пожалуйста, попробуйте ещё раз.", "Unable to import pages. Please try again.": "Не удалось импортировать страницы. Пожалуйста, попробуйте ещё раз.",
"untitled": "без названия", "untitled": "без названия",
"Untitled": "Без названия", "Untitled": "Без названия",
"Updated successfully": "Обновлено успешно", "Updated successfully": "Успешно обновлено",
"User": "Пользователь", "User": "Пользователь",
"Workspace": "Рабочая область", "Workspace": "Рабочее пространство",
"Workspace Name": "Имя рабочей области", "Workspace Name": "Название рабочего пространства",
"Workspace settings": "Настройки рабочей области", "Workspace settings": "Настройки рабочего пространства",
"You can change your password here.": "Вы можете изменить свой пароль здесь.", "You can change your password here.": "Вы можете изменить свой пароль здесь.",
"Your Email": "Ваш адрес электронной почты", "Your Email": "Ваш адрес электронной почты",
"Your import is complete.": "Ваш импорт завершен.", "Your import is complete.": "Ваш импорт завершен.",
"Your name": "Ваше имя", "Your name": "Ваше имя",
"Your Name": "Ваше Имя", "Your Name": "Ваше имя",
"Your password": "Ваш пароль", "Your password": "Ваш пароль",
"Your password must be a minimum of 8 characters.": "Ваш пароль должен содержать минимум 8 символов.", "Your password must be a minimum of 8 characters.": "Ваш пароль должен содержать минимум 8 символов.",
"Sidebar toggle": "Переключить боковую панель", "Sidebar toggle": "Переключатель боковой панели",
"Comments": "Комментарии", "Comments": "Комментарии",
"404 page not found": "404 страница не найдена", "404 page not found": "404 страница не найдена",
"Sorry, we can't find the page you are looking for.": "К сожалению, мы не можем найти страницу, которую вы ищете.", "Sorry, we can't find the page you are looking for.": "К сожалению, мы не можем найти страницу, которую вы ищете.",
@@ -215,6 +222,8 @@
"Edit comment": "Редактировать комментарий", "Edit comment": "Редактировать комментарий",
"Delete comment": "Удалить комментарий", "Delete comment": "Удалить комментарий",
"Are you sure you want to delete this comment?": "Вы уверены, что хотите удалить этот комментарий?", "Are you sure you want to delete this comment?": "Вы уверены, что хотите удалить этот комментарий?",
"Delete chat": "Удалить чат",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Вы уверены, что хотите удалить '{{title}}'? Это действие нельзя отменить.",
"Comment created successfully": "Комментарий успешно создан", "Comment created successfully": "Комментарий успешно создан",
"Error creating comment": "Ошибка при создании комментария", "Error creating comment": "Ошибка при создании комментария",
"Comment updated successfully": "Комментарий успешно обновлён", "Comment updated successfully": "Комментарий успешно обновлён",
@@ -222,13 +231,13 @@
"Comment deleted successfully": "Комментарий успешно удалён", "Comment deleted successfully": "Комментарий успешно удалён",
"Failed to delete comment": "Не удалось удалить комментарий", "Failed to delete comment": "Не удалось удалить комментарий",
"Comment resolved successfully": "Комментарий успешно разрешён", "Comment resolved successfully": "Комментарий успешно разрешён",
"Comment re-opened successfully": "Комментарий успешно открыт заново", "Comment re-opened successfully": "Комментарий успешно открыт повторно",
"Comment unresolved successfully": "Комментарий успешно размечен как нерешённый", "Comment unresolved successfully": "Комментарий успешно переведён в нерешённые",
"Failed to resolve comment": "Не удалось разрешить комментарий", "Failed to resolve comment": "Не удалось разрешить комментарий",
"Resolve comment": "Разрешить комментарий", "Resolve comment": "Решить комментарий",
"Unresolve comment": "Отметить комментарий как нерешённый", "Unresolve comment": "Снять статус решённого с комментария",
"Resolve Comment Thread": "Закрыть цепочку комментариев", "Resolve Comment Thread": "Решить ветку комментариев",
"Unresolve Comment Thread": "Отметить цепочку комментариев как нерешённую", "Unresolve Comment Thread": "Снять статус решённой с ветки комментариев",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Вы уверены, что хотите закрыть эту цепочку комментариев? Это пометит её как завершённую.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Вы уверены, что хотите закрыть эту цепочку комментариев? Это пометит её как завершённую.",
"Are you sure you want to unresolve this comment thread?": "Вы уверены, что хотите отметить эту цепочку комментариев как нерешённую?", "Are you sure you want to unresolve this comment thread?": "Вы уверены, что хотите отметить эту цепочку комментариев как нерешённую?",
"Resolved": "Решено", "Resolved": "Решено",
@@ -289,6 +298,11 @@
"Save & Exit": "Сохранить и выйти", "Save & Exit": "Сохранить и выйти",
"Double-click to edit Excalidraw diagram": "Кликните дважды для редактирования диаграммы Excalidraw", "Double-click to edit Excalidraw diagram": "Кликните дважды для редактирования диаграммы Excalidraw",
"Paste link": "Вставить ссылку", "Paste link": "Вставить ссылку",
"Paste link or search pages": "Вставьте ссылку или найдите страницы",
"Link to web page": "Ссылка на веб-страницу",
"Recents": "Недавние",
"Page or URL": "Страница или URL",
"Link title": "Заголовок ссылки",
"Edit link": "Редактировать ссылку", "Edit link": "Редактировать ссылку",
"Remove link": "Удалить ссылку", "Remove link": "Удалить ссылку",
"Add link": "Добавить ссылку", "Add link": "Добавить ссылку",
@@ -307,7 +321,7 @@
"Pink": "Розовый", "Pink": "Розовый",
"Gray": "Серый", "Gray": "Серый",
"Embed link": "Встроенная ссылка", "Embed link": "Встроенная ссылка",
"Invalid {{provider}} embed link": "Неверная ссылка для встраивания {{provider}}", "Invalid {{provider}} embed link": "Недействительная ссылка для встраивания {{provider}}",
"Embed {{provider}}": "Встроить {{provider}}", "Embed {{provider}}": "Встроить {{provider}}",
"Enter {{provider}} link to embed": "Введите ссылку для встраивания {{provider}}", "Enter {{provider}} link to embed": "Введите ссылку для встраивания {{provider}}",
"Bold": "Жирный", "Bold": "Жирный",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Вставить горизонтальный разделитель", "Insert horizontal rule divider": "Вставить горизонтальный разделитель",
"Upload any image from your device.": "Загрузить любое изображение с вашего устройства.", "Upload any image from your device.": "Загрузить любое изображение с вашего устройства.",
"Upload any video from your device.": "Загрузить любое видео с вашего устройства.", "Upload any video from your device.": "Загрузить любое видео с вашего устройства.",
"Upload any audio from your device.": "Загрузите любой аудиофайл с вашего устройства.",
"Upload any file from your device.": "Загрузить любой файл с вашего устройства.", "Upload any file from your device.": "Загрузить любой файл с вашего устройства.",
"Uploading {{name}}": "Загрузка {{name}}", "Uploading {{name}}": "Загрузка {{name}}",
"Uploading file": "Загрузка файла", "Uploading file": "Загрузка файла",
@@ -346,19 +361,25 @@
"Divider": "Разделитель", "Divider": "Разделитель",
"Quote": "Цитата", "Quote": "Цитата",
"Image": "Изображение", "Image": "Изображение",
"File attachment": "Прикрепленный файл", "Audio": "Аудио",
"Embed PDF": "Встроить PDF",
"Upload and embed a PDF file.": "Загрузите и встроите PDF-файл.",
"Embed as PDF": "Встроить как PDF",
"Failed to load PDF": "Не удалось загрузить PDF",
"Convert to attachment": "Преобразовать в вложение",
"File attachment": "Вложение файла",
"Toggle block": "Сворачиваемый блок", "Toggle block": "Сворачиваемый блок",
"Callout": "Выноска", "Callout": "Выноска",
"Insert callout notice.": "Вставить выноску с сообщением.", "Insert callout notice.": "Вставить выноску с сообщением.",
"Math inline": "Формула", "Math inline": "Строчная формула",
"Insert inline math equation.": "Вставить математическое выражение в строку.", "Insert inline math equation.": "Вставить математическое выражение в строку.",
"Math block": "Блок формул", "Math block": "Блок формулы",
"Insert math equation": "Вставить математическое выражение", "Insert math equation": "Вставить математическую формулу",
"Mermaid diagram": "Диаграмма Mermaid", "Mermaid diagram": "Диаграмма Mermaid",
"Insert mermaid diagram": "Вставить диаграмму Mermaid", "Insert mermaid diagram": "Вставить диаграмму Mermaid",
"Insert and design Drawio diagrams": "Вставить и рисовать диаграммы Draw.io", "Insert and design Drawio diagrams": "Вставляйте и редактируйте диаграммы Drawio",
"Insert current date": "Вставить текущую дату", "Insert current date": "Вставить текущую дату",
"Draw and sketch excalidraw diagrams": "Вставить и рисовать диаграммы Excalidraw", "Draw and sketch excalidraw diagrams": "Рисуйте и создавайте диаграммы Excalidraw",
"Multiple": "Несколько", "Multiple": "Несколько",
"Turn into": "Преобразовать в", "Turn into": "Преобразовать в",
"Text align": "Выравнивание текста", "Text align": "Выравнивание текста",
@@ -366,8 +387,8 @@
"Go to homepage": "Вернуться на главную", "Go to homepage": "Вернуться на главную",
"Pages you create will show up here.": "Созданные вами страницы появятся здесь.", "Pages you create will show up here.": "Созданные вами страницы появятся здесь.",
"Heading {{level}}": "Заголовок {{level}}", "Heading {{level}}": "Заголовок {{level}}",
"Toggle title": "Переключить заголовок", "Toggle title": "Заголовок сворачиваемого блока",
"Write anything. Enter \"/\" for commands": "Начните писать. Введите \"/\" для списка команд", "Write anything. Enter \"/\" for commands": "Пишите что угодно. Введите \"/\" для команд",
"Write...": "Напишите...", "Write...": "Напишите...",
"Column count": "Количество столбцов", "Column count": "Количество столбцов",
"{{count}} Columns": "{count, plural, one{# столбец} few{# столбца} many{# столбцов} other{# столбца}}", "{{count}} Columns": "{count, plural, one{# столбец} few{# столбца} many{# столбцов} other{# столбца}}",
@@ -384,20 +405,20 @@
"Space updated successfully": "Пространство успешно обновлено", "Space updated successfully": "Пространство успешно обновлено",
"Space deleted successfully": "Пространство успешно удалено", "Space deleted successfully": "Пространство успешно удалено",
"Members added successfully": "Участники успешно добавлены", "Members added successfully": "Участники успешно добавлены",
"Member removed successfully": "Участник успешно удален", "Member removed successfully": "Участник успешно удалён",
"Member role updated successfully": "Роль участника успешно обновлена", "Member role updated successfully": "Роль участника успешно обновлена",
"Created by: <b>{{creatorName}}</b>": "Автор: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "Создано: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Дата создания: {{time}}", "Created at: {{time}}": "Создано: {{time}}",
"Edited by {{name}} {{time}}": "Изменено {{name}} {{time}}", "Edited by {{name}} {{time}}": "Изменено: {{name}} {{time}}",
"Word count: {{wordCount}}": "Количество слов: {{wordCount}}", "Word count: {{wordCount}}": "Количество слов: {{wordCount}}",
"Character count: {{characterCount}}": "Количество символов: {{characterCount}}", "Character count: {{characterCount}}": "Количество символов: {{characterCount}}",
"New update": "Новое обновление", "New update": "Новое обновление",
"{{latestVersion}} is available": "Доступна новая версия {{latestVersion}}", "{{latestVersion}} is available": "Доступна версия {{latestVersion}}",
"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.": "Выберите предпочитаемый режим редактирования страницы. Избегайте случайных изменений.",
"Reading": "Чтение", "Reading": "Чтение",
"Delete member": "Удалить участника", "Delete member": "Удалить участника",
"Member deleted successfully": "Участник успешно удален", "Member deleted successfully": "Участник успешно удалён",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Вы уверены, что хотите удалить этого участника рабочей области? Это действие необратимо.", "Are you sure you want to delete this workspace member? This action is irreversible.": "Вы уверены, что хотите удалить этого участника рабочей области? Это действие необратимо.",
"Deactivate member": "Деактивировать участника", "Deactivate member": "Деактивировать участника",
"Activate member": "Активировать участника", "Activate member": "Активировать участника",
@@ -410,36 +431,38 @@
"Move page": "Переместить страницу", "Move page": "Переместить страницу",
"Move page to a different space.": "Переместите страницу в другое пространство.", "Move page to a different space.": "Переместите страницу в другое пространство.",
"Real-time editor connection lost. Retrying...": "Соединение с редактором в реальном времени потеряно. Повторная попытка...", "Real-time editor connection lost. Retrying...": "Соединение с редактором в реальном времени потеряно. Повторная попытка...",
"Table of contents": "Содержание", "Table of contents": "Оглавление",
"Add headings (H1, H2, H3) to generate a table of contents.": "Добавьте заголовки (H1, H2, H3), чтобы создать оглавление.", "Add headings (H1, H2, H3) to generate a table of contents.": "Добавьте заголовки (H1, H2, H3), чтобы создать оглавление.",
"Share": "Поделиться", "Share": "Поделиться",
"Public sharing": "Общий доступ", "Public sharing": "Публичный доступ",
"Shared by": "Поделился", "Shared by": "Поделился",
"Shared at": "Поделился в", "Shared at": "Дата публикации",
"Inherits public sharing from": "Наследует общий доступ от", "Inherits public sharing from": "Наследует публичный доступ от",
"Share to web": "Поделиться в интернете", "Share to web": "Опубликовать в интернете",
"Shared to web": "Размещено в интернете", "Shared to web": "Опубликовано в интернете",
"Anyone with the link can view this page": "Любой, у кого есть ссылка, может просмотреть эту страницу", "Anyone with the link can view this page": "Любой, у кого есть ссылка, может просматривать эту страницу",
"Make this page publicly accessible": "Сделать эту страницу общедоступной", "Make this page publicly accessible": "Сделать эту страницу общедоступной",
"Include sub-pages": "Включить подстраницы", "Include sub-pages": "Включить подстраницы",
"Make sub-pages public too": "Сделать подстраницы также общедоступными", "Make sub-pages public too": "Сделать подстраницы тоже общедоступными",
"Allow search engines to index page": "Разрешить поисковым системам индексировать страницу", "Allow search engines to index page": "Разрешить поисковым системам индексировать страницу",
"Open page": "Открыть страницу", "Open page": "Открыть страницу",
"Page": "Страница", "Page": "Страница",
"Delete public share link": "Удалить ссылку на общий доступ", "Delete public share link": "Удалить публичную ссылку",
"Delete share": "Удалить общий доступ", "Delete share": "Удалить общий доступ",
"Are you sure you want to delete this shared link?": "Вы уверены, что хотите удалить эту ссылку общего доступа?", "Are you sure you want to delete this shared link?": "Вы уверены, что хотите удалить эту ссылку общего доступа?",
"Publicly shared pages from spaces you are a member of will appear here": "Общие страницы из пространств, участником которых вы являетесь, появятся здесь", "Publicly shared pages from spaces you are a member of will appear here": "Здесь будут отображаться публично опубликованные страницы из пространств, участником которых вы являетесь",
"Share deleted successfully": "Общий доступ успешно удален", "Share deleted successfully": "Общий доступ успешно удалён",
"Share not found": "Общий доступ не найден", "Share not found": "Общий доступ не найден",
"Failed to share page": "Не удалось поделиться страницей", "Failed to share page": "Не удалось предоставить доступ к странице",
"Disable public sharing": "Отключить общий доступ", "Disable public sharing": "Отключить общий доступ",
"Prevent members from sharing pages publicly.": "Запретить участникам делиться страницами публично.", "Prevent members from sharing pages publicly.": "Запретить участникам делиться страницами публично.",
"Toggle public sharing": "Переключить общий доступ", "Toggle public sharing": "Переключить общий доступ",
"Toggle space public sharing": "Переключить общий доступ для пространства", "Toggle space public sharing": "Переключить общий доступ для пространства",
"Allow viewers to comment": "Разрешить зрителям комментировать",
"Allow viewers to add comments on pages in this space.": "Разрешить зрителям добавлять комментарии на страницах в этом пространстве.",
"Toggle viewer comments": "Переключить комментарии зрителей",
"Public sharing is disabled at the workspace level": "Общий доступ отключен на уровне рабочего пространства", "Public sharing is disabled at the workspace level": "Общий доступ отключен на уровне рабочего пространства",
"Prevent pages in this space from being shared publicly.": "Запретить делиться страницами в этом пространстве публично.", "Prevent pages in this space from being shared publicly.": "Запретить делиться страницами в этом пространстве публично.",
"Requires an enterprise license": "Требуется корпоративная лицензия",
"Page permissions": "Права доступа к странице},{", "Page permissions": "Права доступа к странице},{",
"Control who can view and edit individual pages. Available with an enterprise license.": "Контролируйте, кто может просматривать и редактировать отдельные страницы. Доступно при наличии лицензии Enterprise.", "Control who can view and edit individual pages. Available with an enterprise license.": "Контролируйте, кто может просматривать и редактировать отдельные страницы. Доступно при наличии лицензии Enterprise.",
"Enable public sharing": "Включить общий доступ", "Enable public sharing": "Включить общий доступ",
@@ -464,9 +487,10 @@
"Replace (Enter)": "Заменить (Enter)", "Replace (Enter)": "Заменить (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Заменить все (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Заменить все (Ctrl+Alt+Enter)",
"Replace all": "Заменить все", "Replace all": "Заменить все",
"View all": "Просмотреть все",
"View all spaces": "Просмотреть все пространства", "View all spaces": "Просмотреть все пространства",
"Error": "Ошибка", "Error": "Ошибка",
"Failed to disable MFA": "Не удалось отключить двухфакторную аутентификацию", "Failed to disable MFA": "Не удалось отключить MFA",
"Disable two-factor authentication": "Отключить двухфакторную аутентификацию", "Disable two-factor authentication": "Отключить двухфакторную аутентификацию",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Отключение двухфакторной аутентификации сделает вашу учетную запись менее безопасной. Для входа потребуется только пароль.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Отключение двухфакторной аутентификации сделает вашу учетную запись менее безопасной. Для входа потребуется только пароль.",
"Please enter your password to disable two-factor authentication:": "Пожалуйста, введите ваш пароль, чтобы отключить двухфакторную аутентификацию:", "Please enter your password to disable two-factor authentication:": "Пожалуйста, введите ваш пароль, чтобы отключить двухфакторную аутентификацию:",
@@ -478,59 +502,59 @@
"Add 2FA method": "Добавить метод 2FA", "Add 2FA method": "Добавить метод 2FA",
"Backup codes": "Резервные коды", "Backup codes": "Резервные коды",
"Disable": "Отключить", "Disable": "Отключить",
"Invalid verification code": "Неверный код проверки", "Invalid verification code": "Недействительный код подтверждения",
"New backup codes have been generated": "Созданы новые резервные коды", "New backup codes have been generated": "Новые резервные коды сгенерированы",
"Failed to regenerate backup codes": "Не удалось создать новые резервные коды", "Failed to regenerate backup codes": "Не удалось заново сгенерировать резервные коды",
"About backup codes": "О резервных кодах", "About backup codes": "О резервных кодах",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Резервные коды можно использовать для доступа к вашей учетной записи, если вы потеряли доступ к приложению-аутентификатору. Каждый код можно использовать только один раз.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Резервные коды можно использовать для доступа к вашей учетной записи, если вы потеряли доступ к приложению-аутентификатору. Каждый код можно использовать только один раз.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Вы можете создать новые резервные коды в любое время. Это аннулирует все существующие коды.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Вы можете создать новые резервные коды в любое время. Это аннулирует все существующие коды.",
"Confirm password": "Подтвердите пароль", "Confirm password": "Подтвердите пароль",
"Generate new backup codes": "Создать новые резервные коды", "Generate new backup codes": "Сгенерировать новые резервные коды",
"Save your new backup codes": "Сохраните ваши новые резервные коды", "Save your new backup codes": "Сохраните ваши новые резервные коды",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Убедитесь, что сохранили эти коды в безопасном месте. Ваши старые резервные коды больше недействительны.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Убедитесь, что сохранили эти коды в безопасном месте. Ваши старые резервные коды больше недействительны.",
"Your new backup codes": "Ваши новые резервные коды", "Your new backup codes": "Ваши новые резервные коды",
"I've saved my backup codes": "Я сохранил(а) свои резервные коды", "I've saved my backup codes": "Я сохранил резервные коды",
"Failed to setup MFA": "Не удалось настроить многофакторную аутентификацию", "Failed to setup MFA": "Не удалось настроить MFA",
"Setup & Verify": "Настроить и проверить", "Setup & Verify": "Настроить и подтвердить",
"Add to authenticator": "Добавить в аутентификатор", "Add to authenticator": "Добавить в приложение-аутентификатор",
"1. Scan this QR code with your authenticator app": "1. Отсканируйте этот QR-код с помощью вашего приложения-аутентификатора", "1. Scan this QR code with your authenticator app": "1. Отсканируйте этот QR-код с помощью приложения-аутентификатора",
"Can't scan the code?": "Не удается сканировать код?", "Can't scan the code?": "Не удается сканировать код?",
"Enter this code manually in your authenticator app:": "Введите этот код вручную в приложении-аутентификаторе:", "Enter this code manually in your authenticator app:": "Введите этот код вручную в приложении-аутентификаторе:",
"2. Enter the 6-digit code from your authenticator": "2. Введите 6-значный код из вашего аутентификатора", "2. Enter the 6-digit code from your authenticator": "2. Введите 6-значный код из приложения-аутентификатора",
"Verify and enable": роверить и включить", "Verify and enable": "Подтвердить и включить",
"Failed to generate QR code. Please try again.": "Не удалось создать QR-код. Пожалуйста, попробуйте снова.", "Failed to generate QR code. Please try again.": "Не удалось создать QR-код. Пожалуйста, попробуйте снова.",
"Backup": "Резервное копирование", "Backup": "Резервный",
"Save codes": "Сохранить коды", "Save codes": "Сохранить коды",
"Save your backup codes": "Сохраните ваши резервные коды", "Save your backup codes": "Сохраните резервные коды",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Эти коды можно использовать для доступа к вашей учетной записи, если вы потеряли доступ к приложению-аутентификатору. Каждый код можно использовать только один раз.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Эти коды можно использовать для доступа к вашей учетной записи, если вы потеряли доступ к приложению-аутентификатору. Каждый код можно использовать только один раз.",
"Print": "Печать", "Print": "Печать",
"Two-factor authentication has been set up. Please log in again.": "Двухфакторная аутентификация настроена. Пожалуйста, войдите снова.", "Two-factor authentication has been set up. Please log in again.": "Двухфакторная аутентификация настроена. Пожалуйста, войдите снова.",
"Two-Factor authentication required": "Требуется двухфакторная аутентификация", "Two-Factor authentication required": "Требуется двухфакторная аутентификация",
"Your workspace requires two-factor authentication for all users": "Ваше рабочее пространство требует двухфакторной аутентификации для всех пользователей", "Your workspace requires two-factor authentication for all users": "Ваше рабочее пространство требует двухфакторную аутентификацию для всех пользователей",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Чтобы продолжать доступ к вашему рабочему пространству, вы должны настроить двухфакторную аутентификацию. Это добавляет дополнительный уровень безопасности к вашей учетной записи.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Чтобы продолжать доступ к вашему рабочему пространству, вы должны настроить двухфакторную аутентификацию. Это добавляет дополнительный уровень безопасности к вашей учетной записи.",
"Set up two-factor authentication": "Настройте двухфакторную аутентификацию", "Set up two-factor authentication": "Настроить двухфакторную аутентификацию",
"Cancel and logout": "Отменить и выйти", "Cancel and logout": "Отменить и выйти",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Ваше рабочее пространство требует двухфакторной аутентификации. Пожалуйста, настройте её, чтобы продолжить.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Ваше рабочее пространство требует двухфакторной аутентификации. Пожалуйста, настройте её, чтобы продолжить.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Это добавляет дополнительный уровень безопасности к вашей учетной записи, требуя код проверки из вашего приложения-аутентификатора.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Это добавляет дополнительный уровень безопасности к вашей учетной записи, требуя код проверки из вашего приложения-аутентификатора.",
"Password is required": "Требуется пароль", "Password is required": "Требуется пароль",
"Password must be at least 8 characters": "Пароль должен содержать как минимум 8 символов", "Password must be at least 8 characters": "Пароль должен содержать не менее 8 символов",
"Please enter a 6-digit code": "Пожалуйста, введите 6-значный код", "Please enter a 6-digit code": "Пожалуйста, введите 6-значный код",
"Code must be exactly 6 digits": "Код должен содержать ровно 6 цифр", "Code must be exactly 6 digits": "Код должен состоять ровно из 6 цифр",
"Enter the 6-digit code found in your authenticator app": "Введите 6-значный код из вашего приложения-аутентификатора", "Enter the 6-digit code found in your authenticator app": "Введите 6-значный код из вашего приложения-аутентификатора",
"Need help authenticating?": "Нужна помощь с аутентификацией?", "Need help authenticating?": "Нужна помощь с аутентификацией?",
"MFA QR Code": "QR-код двухфакторной аутентификации", "MFA QR Code": "QR-код MFA",
"Account created successfully. Please log in to set up two-factor authentication.": "Учетная запись успешно создана. Пожалуйста, войдите, чтобы настроить двухфакторную аутентификацию.", "Account created successfully. Please log in to set up two-factor authentication.": "Учетная запись успешно создана. Пожалуйста, войдите, чтобы настроить двухфакторную аутентификацию.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем и завершите настройку двухфакторной аутентификации.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем и завершите настройку двухфакторной аутентификации.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем, чтобы настроить двухфакторную аутентификацию.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем, чтобы настроить двухфакторную аутентификацию.",
"Password reset was successful. Please log in with your new password.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем.", "Password reset was successful. Please log in with your new password.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем.",
"Two-factor authentication": "Двухфакторная аутентификация", "Two-factor authentication": "Двухфакторная аутентификация",
"Use authenticator app instead": "Используйте приложение-аутентификатор вместо этого", "Use authenticator app instead": "Использовать приложение-аутентификатор вместо этого",
"Verify backup code": роверка резервного кода", "Verify backup code": одтвердить резервный код",
"Use backup code": "Использовать резервный код", "Use backup code": "Использовать резервный код",
"Enter one of your backup codes": "Введите один из ваших резервных кодов", "Enter one of your backup codes": "Введите один из ваших резервных кодов",
"Backup code": "Резервный код", "Backup code": "Резервный код",
"Enter one of your backup codes. Each backup code can only be used once.": "Введите один из ваших резервных кодов. Каждый резервный код можно использовать только один раз.", "Enter one of your backup codes. Each backup code can only be used once.": "Введите один из ваших резервных кодов. Каждый резервный код можно использовать только один раз.",
"Verify": роверить", "Verify": "Подтвердить",
"Trash": "Корзина", "Trash": "Корзина",
"Pages in trash will be permanently deleted after {{count}} days.": "{count, plural, one {Страница в корзине будет окончательно удалена через # день.} few {Страницы в корзине будут окончательно удалены через # дня.} many {Страницы в корзине будут окончательно удалены через # дней.} other {Страницы в корзине будут окончательно удалены через # дней.}}", "Pages in trash will be permanently deleted after {{count}} days.": "{count, plural, one {Страница в корзине будет окончательно удалена через # день.} few {Страницы в корзине будут окончательно удалены через # дня.} many {Страницы в корзине будут окончательно удалены через # дней.} other {Страницы в корзине будут окончательно удалены через # дней.}}",
"Deleted": "Удалено", "Deleted": "Удалено",
@@ -544,24 +568,24 @@
"Page moved to trash": "Страница перемещена в корзину", "Page moved to trash": "Страница перемещена в корзину",
"Page restored successfully": "Страница успешно восстановлена", "Page restored successfully": "Страница успешно восстановлена",
"Deleted by": "Удалено пользователем", "Deleted by": "Удалено пользователем",
"Deleted at": "Удалено в", "Deleted at": "Удалено",
"Preview": "Предпросмотр", "Preview": "Предпросмотр",
"Subpages": "Подстраницы", "Subpages": "Подстраницы",
"Failed to load subpages": "Не удалось загрузить подстраницы", "Failed to load subpages": "Не удалось загрузить подстраницы",
"No subpages": "Нет подстраниц", "No subpages": "Нет подстраниц",
"Subpages (Child pages)": "Подстраницы (вложенные страницы)", "Subpages (Child pages)": "Подстраницы (дочерние страницы)",
"List all subpages of the current page": "Показать все под страницы", "List all subpages of the current page": "Показать все подстраницы текущей страницы",
"Attachments": "Вложения", "Attachments": "Вложения",
"All spaces": "Все пространства", "All spaces": "Все пространства",
"Unknown": "Неизвестно", "Unknown": "Неизвестно",
"Find a space": "Найти пространство", "Find a space": "Найти пространство",
"Search in all your spaces": "Поиск во всех ваших пространствах", "Search in all your spaces": "Искать во всех ваших пространствах",
"Type": "Тип", "Type": "Тип",
"Enterprise": "Предприятие", "Enterprise": "Корпоративный",
"Download attachment": "Скачать вложение", "Download attachment": "Скачать вложение",
"Allowed email domains": "Разрешенные домены электронной почты", "Allowed email domains": "Разрешённые домены электронной почты",
"Only users with email addresses from these domains can signup via SSO.": "Только пользователи с электронными адресами из этих доменов могут зарегистрироваться через SSO.", "Only users with email addresses from these domains can signup via SSO.": "Только пользователи с адресами электронной почты из этих доменов могут зарегистрироваться через SSO.",
"Enter valid domain names separated by comma or space": "Введите допустимые доменные имена, разделённые запятыми или пробелами", "Enter valid domain names separated by comma or space": "Введите корректные доменные имена, разделённые запятой или пробелом",
"Enforce two-factor authentication": "Обязательная двухфакторная аутентификация", "Enforce two-factor authentication": "Обязательная двухфакторная аутентификация",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "После введения обязательности все участники должны будут включить двухфакторную аутентификацию для доступа к рабочему пространству.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "После введения обязательности все участники должны будут включить двухфакторную аутентификацию для доступа к рабочему пространству.",
"Toggle MFA enforcement": "Переключить обязательность MFA", "Toggle MFA enforcement": "Переключить обязательность MFA",
@@ -570,13 +594,13 @@
"Enabled": "Включено", "Enabled": "Включено",
"Advanced Settings": "Расширенные настройки", "Advanced Settings": "Расширенные настройки",
"Enable TLS/SSL": "Включить TLS/SSL", "Enable TLS/SSL": "Включить TLS/SSL",
"Use secure connection to LDAP server": "Использовать защищённое соединение с сервером LDAP", "Use secure connection to LDAP server": "Использовать защищённое подключение к серверу LDAP",
"Group sync": "Синхронизация группы", "Group sync": "Синхронизация групп",
"No SSO providers found.": "Поставщики SSO не найдены.", "No SSO providers found.": "Поставщики SSO не найдены.",
"Delete SSO provider": "Удалить поставщика SSO", "Delete SSO provider": "Удалить провайдера SSO",
"Are you sure you want to delete this SSO provider?": "Вы уверены, что хотите удалить этого поставщика SSO?", "Are you sure you want to delete this SSO provider?": "Вы уверены, что хотите удалить этого поставщика SSO?",
"Action": "Действие", "Action": "Действие",
"{{ssoProviderType}} configuration": "Настройка {{ssoProviderType}}", "{{ssoProviderType}} configuration": "Конфигурация {{ssoProviderType}}",
"Icon": "Иконка", "Icon": "Иконка",
"Upload image": "Загрузить изображение", "Upload image": "Загрузить изображение",
"Remove image": "Удалить изображение", "Remove image": "Удалить изображение",
@@ -613,6 +637,7 @@
"AI Answer": "Ответ ИИ", "AI Answer": "Ответ ИИ",
"Ask AI": "Спросить ИИ", "Ask AI": "Спросить ИИ",
"AI is thinking...": "ИИ обрабатывает запрос...", "AI is thinking...": "ИИ обрабатывает запрос...",
"Thinking": "Думаю",
"Ask a question...": "Задайте вопрос...", "Ask a question...": "Задайте вопрос...",
"AI Answers": "Ответы ИИ", "AI Answers": "Ответы ИИ",
"AI-powered search (AI Answers)": "Поиск на базе ИИ (Ответы ИИ)", "AI-powered search (AI Answers)": "Поиск на базе ИИ (Ответы ИИ)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "Генеративный ИИ (Спросить ИИ)", "Generative AI (Ask AI)": "Генеративный ИИ (Спросить ИИ)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Включите создание контента на базе ИИ в редакторе. Позволяет пользователям генерировать, улучшать, переводить и преобразовывать текст.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Включите создание контента на базе ИИ в редакторе. Позволяет пользователям генерировать, улучшать, переводить и преобразовывать текст.",
"Toggle generative AI": "Переключить генеративный ИИ", "Toggle generative AI": "Переключить генеративный ИИ",
"Enterprise feature": "Корпоративная функция", "Upgrade your plan": "Обновите свой тарифный план",
"Available with a paid license": "Доступно с платной лицензией",
"Upgrade your license tier.": "Обновите уровень вашей лицензии.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "ИИ доступен только в корпоративной версии Docmost. Свяжитесь по адресу sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "ИИ доступен только в корпоративной версии Docmost. Свяжитесь по адресу sales@docmost.com.",
"AI & MCP": "ИИ и MCP", "AI & MCP": "ИИ и MCP",
"AI": "ИИ", "AI": "ИИ",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Протокол контекста модели (MCP)", "Model Context Protocol (MCP)": "Протокол контекста модели (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Включите сервер MCP, чтобы ИИ-ассистенты и инструменты могли взаимодействовать с содержимым вашего рабочего пространства.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Включите сервер MCP, чтобы ИИ-ассистенты и инструменты могли взаимодействовать с содержимым вашего рабочего пространства.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP доступен только в корпоративной версии Docmost. Свяжитесь по адресу sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP доступен только в корпоративной версии Docmost. Свяжитесь по адресу sales@docmost.com.",
"MCP documentation": "Документация MCP",
"MCP Server URL": "URL сервера MCP", "MCP Server URL": "URL сервера MCP",
"Use your API key for authentication. You can manage API keys in your account settings.": "Используйте ваш API-ключ для аутентификации. Управлять API-ключами можно в настройках аккаунта.", "Use your API key for authentication. You can manage API keys in your account settings.": "Используйте ваш API-ключ для аутентификации. Управлять API-ключами можно в настройках аккаунта.",
"Supported tools": "Поддерживаемые инструменты", "Supported tools": "Поддерживаемые инструменты",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "В вашем рабочем пространстве включён MCP. Используйте свой API-ключ для подключения ИИ-ассистентов.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "В вашем рабочем пространстве включён MCP. Используйте свой API-ключ для подключения ИИ-ассистентов.",
"MCP server URL:": "URL сервера MCP:", "MCP server URL:": "URL сервера MCP:",
"Learn more": "Подробнее", "Learn more": "Подробнее",
"View the": "Просмотреть", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Управляйте API-ключами для всех пользователей в рабочем пространстве. Смотрите <anchor>документацию по API</anchor> для получения информации об использовании.",
"for usage details.": "для подробностей использования.", "View the <anchor>API documentation</anchor> for usage details.": "Смотрите <anchor>документацию по API</anchor> для получения информации об использовании.",
"for setup instructions.": "для инструкций по настройке.", "View the <anchor>MCP documentation</anchor>.": "Смотрите <anchor>документацию по MCP</anchor>.",
"API documentation": "Документация API",
"Sources": "Источники", "Sources": "Источники",
"AI Answers not available for attachments": "Ответы ИИ недоступны для вложений", "AI Answers not available for attachments": "Ответы ИИ недоступны для вложений",
"No answer available": "Ответ недоступен", "No answer available": "Ответ недоступен",
@@ -654,12 +679,34 @@
"Mark all as read": "Отметить все как прочитанные", "Mark all as read": "Отметить все как прочитанные",
"Mark as read": "Отметить как прочитанное", "Mark as read": "Отметить как прочитанное",
"More options": "Больше возможностей", "More options": "Больше возможностей",
"mentioned you in a comment": "упомянул вас в комментарии", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> упомянул вас в комментарии",
"commented on a page": "прокомментировал на странице", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> оставил комментарий на странице",
"resolved a comment": "разрешил комментарий", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> отметил(а) комментарий как решённый",
"mentioned you on a page": "упомянул вас на странице", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> упомянул(а) вас на странице",
"gave you edit access to a page": "предоставил вам доступ на редактирование страницы", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> предоставил(а) вам доступ на редактирование страницы",
"gave you view access to a page": "предоставил вам доступ для просмотра страницы", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> предоставил(а) вам доступ на просмотр страницы",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> обновил(а) страницу",
"Watch page": "Следить за страницей",
"Stop watching": "Перестать следить",
"Watch space": "Следить за пространством",
"Stop watching space": "Перестать следить за пространством",
"Email notifications": "Уведомления на email",
"Page updates": "Обновления страницы",
"Get notified when pages you watch are updated.": "Получайте уведомления, когда отслеживаемые вами страницы обновляются.",
"Page mentions": "Упоминания на странице",
"Get notified when someone mentions you on a page.": "Получайте уведомления, когда кто-то упоминает вас на странице.",
"Comment mentions": "Упоминания в комментариях",
"Get notified when someone mentions you in a comment.": "Получайте уведомления, когда кто-то упоминает вас в комментарии.",
"New comments": "Новые комментарии",
"Get notified about new comments on threads you participate in.": "Получайте уведомления о новых комментариях в цепочках, в которых вы участвуете.",
"Resolved comments": "Разрешённые комментарии",
"Get notified when your comment is resolved.": "Получайте уведомление, когда ваш комментарий разрешён.",
"You are now watching this page": "Вы теперь следите за этой страницей",
"You are no longer watching this page": "Вы больше не следите за этой страницей",
"You are now watching this space": "Теперь вы следите за этим пространством",
"You are no longer watching this space": "Вы больше не следите за этим пространством",
"Direct": "Прямые",
"Updates": "Обновления",
"Today": "Сегодня", "Today": "Сегодня",
"Yesterday": "Вчера", "Yesterday": "Вчера",
"This week": "На этой неделе", "This week": "На этой неделе",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Не удалось обновить срок хранения корзины", "Failed to update trash retention": "Не удалось обновить срок хранения корзины",
"Removed page restriction": "Ограничение доступа к странице удалено", "Removed page restriction": "Ограничение доступа к странице удалено",
"Added page permission": "Добавлено разрешение доступа к странице", "Added page permission": "Добавлено разрешение доступа к странице",
"Removed page permission": "Удалено разрешение доступа к странице" "Removed page permission": "Удалено разрешение доступа к странице",
"day": "день",
"days": "дни",
"week": "неделя",
"weeks": "недели",
"month": "месяц",
"months": "месяцы",
"year": "год",
"years": "годы",
"Period": "Период",
"Fixed date": "Фиксированная дата",
"Indefinitely": "Бессрочно",
"Days": "Дни",
"Weeks": "Недели",
"Months": "Месяцы",
"Years": "Годы",
"Pick a date": "Выберите дату",
"Maximum is {{max}} {{unit}} for this unit": "Максимум для этой единицы измерения — {{max}} {{unit}}",
"Never expires. Verifiers can re-verify at any time.": "Срок действия не истекает. Проверяющие могут повторно подтверждать в любое время.",
"Verified": "Проверено",
"Review needed": "Требуется проверка",
"Verification expired": "Срок проверки истёк",
"Draft": "Черновик",
"In Approval": "На утверждении",
"In approval": "На утверждении",
"Approved": "Утверждено",
"Obsolete": "Устарело",
"Expiring": "Истекает",
"Set up verification": "Настроить проверку",
"Verify page": "Проверить страницу",
"Page verification": "Проверка страницы",
"Add verification": "Добавить проверку",
"Edit verification": "Изменить проверку",
"Search by title": "Поиск по заголовку",
"Choose how this page should stay accurate.": "Выберите, как поддерживать актуальность этой страницы.",
"Recurring verification": "Регулярная проверка",
"Verifiers re-confirm this page on a schedule.": "Проверяющие повторно подтверждают эту страницу по расписанию.",
"Re-verify on a schedule (e.g every 30 days )": "Повторно проверять по расписанию (например, каждые 30 дней)",
"Page stays editable at all times": "Страница остаётся редактируемой в любое время",
"Best for runbooks, FAQs, living documentation": "Лучше всего подходит для инструкций, FAQ и живой документации",
"Approval workflow": "Процесс утверждения",
"Formal document lifecycle with named approvers.": "Формальный жизненный цикл документа с назначенными утверждающими.",
"Draft → In approval → Approved → Obsolete": "Черновик → На утверждении → Утверждено → Устарело",
"Locked once approved, with full history": "После утверждения блокируется, с полной историей",
"Designed for ISO 9001, ISO 13485, and FDA": "Разработано для ISO 9001, ISO 13485 и FDA",
"Best for SOPs and controlled documents": "Лучше всего подходит для СОП и контролируемых документов",
"Back": "Назад",
"Quality management": "Управление качеством",
"Recurring": "Регулярно",
"Pages move through draft, approval, and approved stages.": "Страницы проходят стадии черновика, утверждения и утверждённого состояния.",
"Verifiers": "Проверяющие",
"Add verifier": "Добавить проверяющего",
"I've reviewed this page for accuracy": "Я проверил(а) эту страницу на точность",
"Set up": "Настроить",
"Remove verification": "Удалить проверку",
"Are you sure you want to remove verification from this page?": "Вы уверены, что хотите удалить проверку с этой страницы?",
"Assigned verifiers must periodically re-verify this page.": "Назначенные проверяющие должны периодически повторно проверять эту страницу.",
"Last verified by {{name}} {{time}} (expired)": "Последняя проверка: {{name}}, {{time}} (срок истёк)",
"The fixed expiration date has passed.": "Фиксированная дата истечения срока уже прошла.",
"Verified by {{name}} {{time}}": "Проверено: {{name}}, {{time}}",
"Expires {{date}}": "Истекает {{date}}",
"Expired {{date}}": "Срок истёк {{date}}",
"Mark as obsolete": "Отметить как устаревшее",
"Mark obsolete": "Отметить как устаревшее",
"Returned by {{name}} {{time}}": "Возвращено: {{name}}, {{time}}",
"No approval has been requested yet.": "Запрос на утверждение ещё не отправлен.",
"Submitted by {{name}} {{time}}": "Отправлено: {{name}}, {{time}}",
"Someone": "Кто-то",
"Approved by {{name}} {{time}}": "Утверждено: {{name}}, {{time}}",
"This document has been marked as obsolete.": "Этот документ был отмечен как устаревший.",
"Rejection comment": "Комментарий к отклонению",
"Reason for returning this document...": "Причина возврата этого документа...",
"Confirm rejection": "Подтвердить отклонение",
"Submit for approval": "Отправить на утверждение",
"Reject": "Отклонить",
"Approve": "Утвердить",
"Re-submit for approval": "Повторно отправить на утверждение",
"Verified until": "Проверено до",
"QMS": "QMS",
"Verified pages": "Проверенные страницы",
"Search pages...": "Поиск страниц...",
"Filter by space": "Фильтр по пространству",
"Filter by type": "Фильтр по типу",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> проверил(а) страницу",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> отправил(а) страницу вам на утверждение",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> вернул(а) страницу на доработку",
"Page verification expires soon": "Срок проверки страницы скоро истекает",
"Page verification has expired": "Срок проверки страницы истёк",
"Verifying your email": "Подтверждение вашего адреса электронной почты",
"Please wait...": "Пожалуйста, подождите...",
"Verification failed. The link may have expired.": "Ошибка проверки. Ссылка могла устареть.",
"Check your email": "Проверьте вашу электронную почту",
"We sent a verification link to {{email}}.": "Мы отправили ссылку для подтверждения на {{email}}.",
"We sent a verification link to your email.": "Мы отправили ссылку для подтверждения на вашу электронную почту.",
"Click the link to verify your email and access your workspace.": "Перейдите по ссылке, чтобы подтвердить электронную почту и получить доступ к рабочему пространству.",
"Resend verification email": "Отправить письмо для подтверждения повторно",
"Verification email sent. Please check your inbox.": "Письмо для подтверждения отправлено. Пожалуйста, проверьте ваш почтовый ящик.",
"Failed to resend verification email. Please try again.": "Не удалось отправить письмо для подтверждения. Пожалуйста, попробуйте снова.",
"We've sent you an email with your associated workspaces.": "Мы отправили вам электронное письмо с привязанными рабочими пространствами.",
"Load more": "Загрузить ещё",
"Log out of all devices": "Выйти на всех устройствах",
"Log out of all sessions except this device": "Выйти из всех сеансов, кроме этого устройства",
"This Device": "Это устройство",
"Unknown device": "Неизвестное устройство",
"No active sessions": "Нет активных сеансов",
"Session revoked": "Сеанс отозван",
"All other sessions revoked": "Все остальные сеансы отозваны",
"Last used": "Последнее использование",
"Created": "Создано",
"Rename": "Переименовать",
"Publish": "Опубликовать",
"Security": "Безопасность",
"Enforce SSO": "Сделать SSO обязательным",
"Once enforced, members will not be able to login with email and password.": "После включения участники не смогут входить с помощью электронной почты и пароля.",
"AI-generated content may not be accurate.": "Контент, созданный ИИ, может быть неточным.",
"AI Chat": "Чат с ИИ",
"Analyze for insights": "Проанализировать и получить выводы",
"Ask anything...": "Спросите что угодно...",
"Chat history": "История чатов",
"Chat name": "Название чата",
"Close": "Закрыть",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Не удалось загрузить чат. Произошла ошибка.",
"Failed to render this message.": "Не удалось отобразить это сообщение.",
"How can I help you today?": "Чем я могу помочь вам сегодня?",
"New chat": "Новый чат",
"No chat history": "Нет истории чатов",
"No chats found": "Чаты не найдены",
"No conversations yet": "Пока нет разговоров",
"Open full page": "Открыть полную страницу",
"Previous 7 days": "Предыдущие 7 дней",
"Previous 30 days": "Предыдущие 30 дней",
"Search chats...": "Поиск чатов...",
"Start a new chat to see it here.": "Начните новый чат, чтобы увидеть его здесь.",
"Summarize this page": "Суммировать эту страницу",
"Toggle AI Chat": "Переключить чат с ИИ",
"Translate this page": "Перевести эту страницу",
"Try a different search term.": "Попробуйте другой поисковый запрос.",
"Try again": "Попробовать снова",
"Untitled chat": "Чат без названия",
"What can I help you with?": "Чем я могу вам помочь?"
} }
+309 -122
View File
@@ -7,6 +7,7 @@
"Add members": "Додати учасників", "Add members": "Додати учасників",
"Add to groups": "Додати до груп", "Add to groups": "Додати до груп",
"Add space members": "Додати учасників простору", "Add space members": "Додати учасників простору",
"Add to favorites": "Додати до обраного",
"Admin": "Адміністратор", "Admin": "Адміністратор",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Ви впевнені, що хочете видалити цю групу? Учасники втратять доступ до матеріалів, до яких ця група має доступ.", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "Ви впевнені, що хочете видалити цю групу? Учасники втратять доступ до матеріалів, до яких ця група має доступ.",
"Are you sure you want to delete this page?": "Ви впевнені, що хочете видалити цю сторінку?", "Are you sure you want to delete this page?": "Ви впевнені, що хочете видалити цю сторінку?",
@@ -44,15 +45,15 @@
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Ви впевнені, що хочете видалити цю сторінку? Це видалить її дочірні сторінки, а також історію сторінки. Ця дія необоротна.", "Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Ви впевнені, що хочете видалити цю сторінку? Це видалить її дочірні сторінки, а також історію сторінки. Ця дія необоротна.",
"Description": "Опис", "Description": "Опис",
"Details": "Деталі", "Details": "Деталі",
"e.g ACME": "наприклад, ACME", "e.g ACME": "напр., ACME",
"e.g ACME Inc": "наприклад, ACME Inc", "e.g ACME Inc": "напр., ACME Inc",
"e.g Developers": "наприклад, Розробники", "e.g Developers": "напр., Розробники",
"e.g Group for developers": "наприклад, Група для розробників", "e.g Group for developers": "напр., Група для розробників",
"e.g product": "наприклад, продукт", "e.g product": "напр., продукт",
"e.g Product Team": "наприклад, Продуктова команда", "e.g Product Team": "напр., Команда продукту",
"e.g Sales": "наприклад, Продажі", "e.g Sales": "напр., Продажі",
"e.g Space for product team": "наприклад, Простір для продуктової команди", "e.g Space for product team": "напр., Простір для команди продукту",
"e.g Space for sales team to collaborate": "наприклад, Простір для спільної роботи команди продажів", "e.g Space for sales team to collaborate": "напр., Простір для співпраці команди продажів",
"Edit": "Редагувати", "Edit": "Редагувати",
"Read": "Читати", "Read": "Читати",
"Edit group": "Редагувати групу", "Edit group": "Редагувати групу",
@@ -61,7 +62,7 @@
"Enter valid email addresses separated by comma or space max_50": "Введіть дійсні адреси електронної пошти, розділені комою або пробілом [макс: 50]", "Enter valid email addresses separated by comma or space max_50": "Введіть дійсні адреси електронної пошти, розділені комою або пробілом [макс: 50]",
"enter valid emails addresses": "введіть дійсні адреси електронної пошти", "enter valid emails addresses": "введіть дійсні адреси електронної пошти",
"Enter your current password": "Введіть ваш поточний пароль", "Enter your current password": "Введіть ваш поточний пароль",
"enter your full name": "введіть ваше повне ім'я", "enter your full name": "введіть своє повне імя",
"Enter your new password": "Введіть ваш новий пароль", "Enter your new password": "Введіть ваш новий пароль",
"Enter your new preferred email": "Введіть вашу нову бажану електронну пошту", "Enter your new preferred email": "Введіть вашу нову бажану електронну пошту",
"Enter your password": "Введіть ваш пароль", "Enter your password": "Введіть ваш пароль",
@@ -74,6 +75,9 @@
"Failed to import pages": "Не вдалося імпортувати сторінки", "Failed to import pages": "Не вдалося імпортувати сторінки",
"Failed to load page. An error occurred.": "Не вдалося завантажити сторінку. Сталася помилка.", "Failed to load page. An error occurred.": "Не вдалося завантажити сторінку. Сталася помилка.",
"Failed to update data": "Не вдалося оновити дані", "Failed to update data": "Не вдалося оновити дані",
"Favorite spaces": "Обрані простори",
"Favorite spaces appear here": "Тут відображаються обрані простори",
"Favorites": "Обране",
"Full access": "Повний доступ", "Full access": "Повний доступ",
"Full page width": "Ширина на всю сторінку", "Full page width": "Ширина на всю сторінку",
"Full width": "На всю ширину", "Full width": "На всю ширину",
@@ -87,11 +91,12 @@
"Import pages": "Імпорт сторінок", "Import pages": "Імпорт сторінок",
"Import pages & space settings": "Імпорт сторінок і налаштування простору", "Import pages & space settings": "Імпорт сторінок і налаштування простору",
"Importing pages": "Імпортування сторінок", "Importing pages": "Імпортування сторінок",
"invalid invitation link": "посилання на запрошення недійсне", "invalid invitation link": "недійсне посилання запрошення",
"Invitation signup": "Реєстрація за запрошенням", "Invitation signup": "Реєстрація за запрошенням",
"Invite by email": "Запросити електронною поштою", "Invite by email": "Запросити електронною поштою",
"Invite members": "Запросити учасників", "Invite members": "Запросити учасників",
"Invite new members": "Запросити нових учасників", "Invite new members": "Запросити нових учасників",
"Invite People": "Запросити людей",
"Invited members who are yet to accept their invitation will appear here.": "Запрошені учасники, які ще не прийняли запрошення, з'являться тут.", "Invited members who are yet to accept their invitation will appear here.": "Запрошені учасники, які ще не прийняли запрошення, з'являться тут.",
"Invited members will be granted access to spaces the groups can access": "Запрошені учасники отримають доступ до просторів, доступ до яких має група", "Invited members will be granted access to spaces the groups can access": "Запрошені учасники отримають доступ до просторів, доступ до яких має група",
"Join the workspace": "Приєднатися до робочої області", "Join the workspace": "Приєднатися до робочої області",
@@ -139,6 +144,7 @@
"Profile": "Профіль", "Profile": "Профіль",
"Recently updated": "Нещодавно оновлено", "Recently updated": "Нещодавно оновлено",
"Remove": "Видалити", "Remove": "Видалити",
"Remove from favorites": "Видалити з обраного",
"Remove group member": "Видалити учасника групи", "Remove group member": "Видалити учасника групи",
"Remove space member": "Видалити учасника простору", "Remove space member": "Видалити учасника простору",
"Restore": "Відновити", "Restore": "Відновити",
@@ -149,16 +155,16 @@
"Search for users": "Пошук користувачів", "Search for users": "Пошук користувачів",
"Search for users and groups": "Пошук користувачів та груп", "Search for users and groups": "Пошук користувачів та груп",
"Search...": "Пошук...", "Search...": "Пошук...",
"Select language": "Оберіть мову", "Select language": "Виберіть мову",
"Select role": "Оберіть роль", "Select role": "Виберіть роль",
"Select role to assign to all invited members": "Оберіть роль для всіх запрошених учасників", "Select role to assign to all invited members": "Виберіть роль, яку буде призначено всім запрошеним учасникам",
"Select theme": "Оберіть тему", "Select theme": "Виберіть тему",
"Send invitation": "Надіслати запрошення", "Send invitation": "Надіслати запрошення",
"Invitation sent": "Запрошення надіслано", "Invitation sent": "Запрошення надіслано",
"Settings": "Налаштування", "Settings": "Налаштування",
"Setup workspace": "Налаштувати робочу область", "Setup workspace": "Налаштувати робочий простір",
"Sign In": "Вхід", "Sign In": "Увійти",
"Sign Up": "Реєстрація", "Sign Up": "Зареєструватися",
"Slug": "Slug", "Slug": "Slug",
"Space": "Простір", "Space": "Простір",
"Space description": "Опис простору", "Space description": "Опис простору",
@@ -168,36 +174,37 @@
"Space slug": "Slug простору", "Space slug": "Slug простору",
"Spaces": "Простори", "Spaces": "Простори",
"Spaces you belong to": "Простори, до яких ви належите", "Spaces you belong to": "Простори, до яких ви належите",
"No space found": "Простори не знайдено", "No space found": "Простір не знайдено",
"Search for spaces": "Пошук просторів", "Search for spaces": "Пошук просторів",
"Start typing to search...": "Почніть вводити для пошуку...", "Start typing to search...": "Почніть вводити для пошуку...",
"Status": "Статус", "Status": "Статус",
"Successfully imported": "Успішно імпортовано", "Successfully imported": "Успішно імпортовано",
"Successfully restored": "Успішно відновлено", "Successfully restored": "Успішно відновлено",
"System settings": "Системні налаштування", "System settings": "Системні налаштування",
"Templates": "Шаблони",
"Theme": "Тема", "Theme": "Тема",
"To change your email, you have to enter your password and new email.": "Щоб змінити електронну пошту, вам потрібно ввести пароль і нову адресу.", "To change your email, you have to enter your password and new email.": "Щоб змінити електронну пошту, вам потрібно ввести пароль і нову адресу.",
"Toggle full page width": "Перемкнути ширину на всю сторінку", "Toggle full page width": "Перемкнути повну ширину сторінки",
"Unable to import pages. Please try again.": "Не вдалося імпортувати сторінки. Будь ласка, спробуйте ще раз.", "Unable to import pages. Please try again.": "Не вдалося імпортувати сторінки. Будь ласка, спробуйте ще раз.",
"untitled": "без назви", "untitled": "без назви",
"Untitled": "Без назви", "Untitled": "Без назви",
"Updated successfully": "Оновлено успішно", "Updated successfully": "Успішно оновлено",
"User": "Користувач", "User": "Користувач",
"Workspace": "Робоча область", "Workspace": "Робочий простір",
"Workspace Name": "Ім'я робочої області", "Workspace Name": "Назва робочого простору",
"Workspace settings": "Налаштування робочої області", "Workspace settings": "Налаштування робочого простору",
"You can change your password here.": "Ви можете змінити свій пароль тут.", "You can change your password here.": "Ви можете змінити свій пароль тут.",
"Your Email": "Ваша електронна пошта", "Your Email": "Ваша електронна пошта",
"Your import is complete.": "Ваш імпорт завершено.", "Your import is complete.": "Ваш імпорт завершено.",
"Your name": "Ваше ім'я", "Your name": "Ваше імя",
"Your Name": "Ваше ім'я", "Your Name": "Ваше імя",
"Your password": "Ваш пароль", "Your password": "Ваш пароль",
"Your password must be a minimum of 8 characters.": "Ваш пароль повинен містити мінімум 8 символів.", "Your password must be a minimum of 8 characters.": "Ваш пароль повинен містити мінімум 8 символів.",
"Sidebar toggle": "Перемкнути бічну панель", "Sidebar toggle": "Перемикач бічної панелі",
"Comments": "Коментарі", "Comments": "Коментарі",
"404 page not found": "404 сторінку не знайдено", "404 page not found": "404 сторінку не знайдено",
"Sorry, we can't find the page you are looking for.": "На жаль, ми не можемо знайти сторінку, яку ви шукаєте.", "Sorry, we can't find the page you are looking for.": "На жаль, ми не можемо знайти сторінку, яку ви шукаєте.",
"Take me back to homepage": "Повернутися на головну сторінку", "Take me back to homepage": "Повернути мене на головну сторінку",
"Forgot password": "Забули пароль", "Forgot password": "Забули пароль",
"Forgot your password?": "Забули пароль?", "Forgot your password?": "Забули пароль?",
"A password reset link has been sent to your email. Please check your inbox.": "Посилання для скидання пароля було надіслано на вашу електронну адресу. Будь ласка, перевірте вхідні повідомлення.", "A password reset link has been sent to your email. Please check your inbox.": "Посилання для скидання пароля було надіслано на вашу електронну адресу. Будь ласка, перевірте вхідні повідомлення.",
@@ -215,6 +222,8 @@
"Edit comment": "Редагувати коментар", "Edit comment": "Редагувати коментар",
"Delete comment": "Видалити коментар", "Delete comment": "Видалити коментар",
"Are you sure you want to delete this comment?": "Ви впевнені, що хочете видалити цей коментар?", "Are you sure you want to delete this comment?": "Ви впевнені, що хочете видалити цей коментар?",
"Delete chat": "Видалити чат",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "Ви впевнені, що хочете видалити '{{title}}'? Цю дію неможливо скасувати.",
"Comment created successfully": "Коментар успішно створено", "Comment created successfully": "Коментар успішно створено",
"Error creating comment": "Помилка при створенні коментаря", "Error creating comment": "Помилка при створенні коментаря",
"Comment updated successfully": "Коментар успішно оновлено", "Comment updated successfully": "Коментар успішно оновлено",
@@ -222,13 +231,13 @@
"Comment deleted successfully": "Коментар успішно видалено", "Comment deleted successfully": "Коментар успішно видалено",
"Failed to delete comment": "Не вдалося видалити коментар", "Failed to delete comment": "Не вдалося видалити коментар",
"Comment resolved successfully": "Коментар успішно вирішено", "Comment resolved successfully": "Коментар успішно вирішено",
"Comment re-opened successfully": "Коментар успішно відкрито повторно", "Comment re-opened successfully": "Коментар успішно знову відкрито",
"Comment unresolved successfully": "Коментар успішно розв'язано", "Comment unresolved successfully": "Позначку вирішення коментаря успішно знято",
"Failed to resolve comment": "Не вдалося вирішити коментар", "Failed to resolve comment": "Не вдалося вирішити коментар",
"Resolve comment": "Вирішити коментар", "Resolve comment": "Позначити коментар як вирішений",
"Unresolve comment": "Розв'язати коментар", "Unresolve comment": "Зняти позначку вирішення з коментаря",
"Resolve Comment Thread": "Вирішити ланцюжок коментарів", "Resolve Comment Thread": "Позначити гілку коментарів як вирішену",
"Unresolve Comment Thread": "Розв'язати ланцюжок коментарів", "Unresolve Comment Thread": "Зняти позначку вирішення з гілки коментарів",
"Are you sure you want to resolve this comment thread? This will mark it as completed.": "Ви впевнені, що хочете вирішити цей ланцюжок коментарів? Це позначить його як завершений.", "Are you sure you want to resolve this comment thread? This will mark it as completed.": "Ви впевнені, що хочете вирішити цей ланцюжок коментарів? Це позначить його як завершений.",
"Are you sure you want to unresolve this comment thread?": "Ви впевнені, що хочете розв'язати цей ланцюжок коментарів?", "Are you sure you want to unresolve this comment thread?": "Ви впевнені, що хочете розв'язати цей ланцюжок коментарів?",
"Resolved": "Вирішено", "Resolved": "Вирішено",
@@ -241,7 +250,7 @@
"Anyone with this link can join this workspace.": "Будь-хто, хто має це посилання, може приєднатися до цієї робочої області.", "Anyone with this link can join this workspace.": "Будь-хто, хто має це посилання, може приєднатися до цієї робочої області.",
"Invite link": "Посилання для запрошення", "Invite link": "Посилання для запрошення",
"Copy": "Копіювати", "Copy": "Копіювати",
"Copy to space": "Скопіювати в простір", "Copy to space": "Копіювати до простору",
"Copied": "Скопійовано", "Copied": "Скопійовано",
"Duplicate": "Дублювати", "Duplicate": "Дублювати",
"Select a user": "Оберіть користувача", "Select a user": "Оберіть користувача",
@@ -251,7 +260,7 @@
"Are you sure you want to delete this space?": "Ви впевнені, що хочете видалити цей простір?", "Are you sure you want to delete this space?": "Ви впевнені, що хочете видалити цей простір?",
"Delete this space with all its pages and data.": "Видалити цей простір з усіма його сторінками та даними.", "Delete this space with all its pages and data.": "Видалити цей простір з усіма його сторінками та даними.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Усі сторінки, коментарі, вкладення та дозволи в цьому просторі будуть видалені безповоротно.", "All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Усі сторінки, коментарі, вкладення та дозволи в цьому просторі будуть видалені безповоротно.",
"Confirm space name": "Підтвердіть назву простору", "Confirm space name": "Підтвердьте назву простору",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Введіть назву простору <b>{{spaceName}}</b>, щоб підтвердити вашу дію.", "Type the space name <b>{{spaceName}}</b> to confirm your action.": "Введіть назву простору <b>{{spaceName}}</b>, щоб підтвердити вашу дію.",
"Format": "Формат", "Format": "Формат",
"Include subpages": "Включити вкладені сторінки", "Include subpages": "Включити вкладені сторінки",
@@ -289,6 +298,11 @@
"Save & Exit": "Зберегти та вийти", "Save & Exit": "Зберегти та вийти",
"Double-click to edit Excalidraw diagram": "Клацніть двічі для редагування діаграми Excalidraw", "Double-click to edit Excalidraw diagram": "Клацніть двічі для редагування діаграми Excalidraw",
"Paste link": "Вставити посилання", "Paste link": "Вставити посилання",
"Paste link or search pages": "Вставте посилання або знайдіть сторінки",
"Link to web page": "Посилання на веб-сторінку",
"Recents": "Нещодавні",
"Page or URL": "Сторінка або URL",
"Link title": "Назва посилання",
"Edit link": "Редагувати посилання", "Edit link": "Редагувати посилання",
"Remove link": "Видалити посилання", "Remove link": "Видалити посилання",
"Add link": "Додати посилання", "Add link": "Додати посилання",
@@ -307,7 +321,7 @@
"Pink": "Рожевий", "Pink": "Рожевий",
"Gray": "Сірий", "Gray": "Сірий",
"Embed link": "Вбудоване посилання", "Embed link": "Вбудоване посилання",
"Invalid {{provider}} embed link": "Невірне посилання для вбудовування {{provider}}", "Invalid {{provider}} embed link": "Недійсне посилання для вбудовування {{provider}}",
"Embed {{provider}}": "Вбудувати {{provider}}", "Embed {{provider}}": "Вбудувати {{provider}}",
"Enter {{provider}} link to embed": "Введіть посилання для вбудовування {{provider}}", "Enter {{provider}} link to embed": "Введіть посилання для вбудовування {{provider}}",
"Bold": "Жирний", "Bold": "Жирний",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "Вставити горизонтальний роздільник", "Insert horizontal rule divider": "Вставити горизонтальний роздільник",
"Upload any image from your device.": "Завантажити будь-яке зображення з вашого пристрою.", "Upload any image from your device.": "Завантажити будь-яке зображення з вашого пристрою.",
"Upload any video from your device.": "Завантажити будь-яке відео з вашого пристрою.", "Upload any video from your device.": "Завантажити будь-яке відео з вашого пристрою.",
"Upload any audio from your device.": "Завантажте будь-який аудіофайл зі свого пристрою.",
"Upload any file from your device.": "Завантажити будь-який файл з вашого пристрою.", "Upload any file from your device.": "Завантажити будь-який файл з вашого пристрою.",
"Uploading {{name}}": "Завантаження {{name}}", "Uploading {{name}}": "Завантаження {{name}}",
"Uploading file": "Завантаження файлу", "Uploading file": "Завантаження файлу",
@@ -346,28 +361,34 @@
"Divider": "Роздільник", "Divider": "Роздільник",
"Quote": "Цитата", "Quote": "Цитата",
"Image": "Зображення", "Image": "Зображення",
"File attachment": "Прикріплений файл", "Audio": "Аудіо",
"Toggle block": "Блок, що згортається", "Embed PDF": "Вбудувати PDF",
"Upload and embed a PDF file.": "Завантажте та вбудуйте файл PDF.",
"Embed as PDF": "Вбудувати як PDF",
"Failed to load PDF": "Не вдалося завантажити PDF",
"Convert to attachment": "Перетворити на вкладення",
"File attachment": "Вкладення файлу",
"Toggle block": "Розкривний блок",
"Callout": "Виноска", "Callout": "Виноска",
"Insert callout notice.": "Вставити виноску з повідомленням.", "Insert callout notice.": "Вставити виноску з повідомленням.",
"Math inline": "Формула", "Math inline": "Вбудована формула",
"Insert inline math equation.": "Вставити математичне рівняння в рядок.", "Insert inline math equation.": "Вставити математичне рівняння в рядок.",
"Math block": "Блок формул", "Math block": "Блок формули",
"Insert math equation": "Вставити математичне рівняння", "Insert math equation": "Вставити математичну формулу",
"Mermaid diagram": "Діаграма Mermaid", "Mermaid diagram": "Діаграма Mermaid",
"Insert mermaid diagram": "Вставити діаграму Mermaid", "Insert mermaid diagram": "Вставити діаграму Mermaid",
"Insert and design Drawio diagrams": "Вставити та розробити діаграми Draw.io", "Insert and design Drawio diagrams": "Вставляйте та створюйте діаграми Drawio",
"Insert current date": "Вставити поточну дату", "Insert current date": "Вставити поточну дату",
"Draw and sketch excalidraw diagrams": "Вставити та малювати діаграми Excalidraw", "Draw and sketch excalidraw diagrams": "Створюйте та кресліть діаграми Excalidraw",
"Multiple": "Декілька", "Multiple": "Кілька",
"Turn into": "Перетворити", "Turn into": "Перетворити",
"Text align": "Вирівнювання тексту", "Text align": "Вирівнювання тексту",
"This page may have been deleted, moved, or you may not have access.": "Цю сторінку могли видалити, перемістити або у вас може не бути до неї доступу.", "This page may have been deleted, moved, or you may not have access.": "Цю сторінку могли видалити, перемістити або у вас може не бути до неї доступу.",
"Go to homepage": "Перейти на головну", "Go to homepage": "Перейти на головну",
"Pages you create will show up here.": "Сторінки, які ви створите, з'являться тут.", "Pages you create will show up here.": "Сторінки, які ви створите, з'являться тут.",
"Heading {{level}}": "Заголовок {{level}}", "Heading {{level}}": "Заголовок {{level}}",
"Toggle title": "Перемкнути заголовок", "Toggle title": "Назва розкривного блоку",
"Write anything. Enter \"/\" for commands": очніть писати. Введіть \"/\" для списку команд", "Write anything. Enter \"/\" for commands": ишіть що завгодно. Введіть \"/\" для команд",
"Write...": "Напишіть...", "Write...": "Напишіть...",
"Column count": "Кількість колонок", "Column count": "Кількість колонок",
"{{count}} Columns": "{count, plural, one{# колонка} few{# колонки} many{# колонок} other{# колонки}}", "{{count}} Columns": "{count, plural, one{# колонка} few{# колонки} many{# колонок} other{# колонки}}",
@@ -377,7 +398,7 @@
"Wide center": "Широка центральна колонка", "Wide center": "Широка центральна колонка",
"Left wide": "Широка ліва колонка", "Left wide": "Широка ліва колонка",
"Right wide": "Широка права колонка", "Right wide": "Широка права колонка",
"Names do not match": "Назви не співпадають", "Names do not match": "Назви не збігаються",
"Today, {{time}}": "Сьогодні, {{time}}", "Today, {{time}}": "Сьогодні, {{time}}",
"Yesterday, {{time}}": "Вчора, {{time}}", "Yesterday, {{time}}": "Вчора, {{time}}",
"Space created successfully": "Простір успішно створено", "Space created successfully": "Простір успішно створено",
@@ -386,13 +407,13 @@
"Members added successfully": "Учасників успішно додано", "Members added successfully": "Учасників успішно додано",
"Member removed successfully": "Учасника успішно видалено", "Member removed successfully": "Учасника успішно видалено",
"Member role updated successfully": "Роль учасника успішно оновлено", "Member role updated successfully": "Роль учасника успішно оновлено",
"Created by: <b>{{creatorName}}</b>": "Автор: <b>{{creatorName}}</b>", "Created by: <b>{{creatorName}}</b>": "Створено: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Дата створення: {{time}}", "Created at: {{time}}": "Створено: {{time}}",
"Edited by {{name}} {{time}}": "Змінено {{name}} {{time}}", "Edited by {{name}} {{time}}": "Змінено {{name}} {{time}}",
"Word count: {{wordCount}}": "Кількість слів: {{wordCount}}", "Word count: {{wordCount}}": "Кількість слів: {{wordCount}}",
"Character count: {{characterCount}}": "Кількість символів: {{characterCount}}", "Character count: {{characterCount}}": "Кількість символів: {{characterCount}}",
"New update": "Нове оновлення", "New update": "Нове оновлення",
"{{latestVersion}} is available": "Доступна нова версія {{latestVersion}}", "{{latestVersion}} is available": "Доступна версія {{latestVersion}}",
"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.": "Виберіть бажаний режим редагування сторінки. Уникайте випадкових редагувань.",
"Reading": "Читання", "Reading": "Читання",
@@ -415,31 +436,33 @@
"Share": "Поділитися", "Share": "Поділитися",
"Public sharing": "Публічний доступ", "Public sharing": "Публічний доступ",
"Shared by": "Поділився", "Shared by": "Поділився",
"Shared at": "Поділився в", "Shared at": "Поділено",
"Inherits public sharing from": "Успадковує публічний доступ від", "Inherits public sharing from": "Успадковує публічний доступ від",
"Share to web": "Поділитися в інтернеті", "Share to web": "Опублікувати в інтернеті",
"Shared to web": "Розміщено в інтернеті", "Shared to web": "Опубліковано в інтернеті",
"Anyone with the link can view this page": "Будь-хто, хто має посилання, може переглянути цю сторінку", "Anyone with the link can view this page": "Будь-хто, хто має посилання, може переглядати цю сторінку",
"Make this page publicly accessible": "Зробити цю сторінку загальнодоступною", "Make this page publicly accessible": "Зробити цю сторінку публічно доступною",
"Include sub-pages": "Включити підсторінки", "Include sub-pages": "Включити підсторінки",
"Make sub-pages public too": "Зробити підсторінки також загальнодоступними", "Make sub-pages public too": "Зробити підсторінки також публічними",
"Allow search engines to index page": "Дозволити пошуковим системам індексувати сторінку", "Allow search engines to index page": "Дозволити пошуковим системам індексувати сторінку",
"Open page": "Відкрити сторінку", "Open page": "Відкрити сторінку",
"Page": "Сторінка", "Page": "Сторінка",
"Delete public share link": "Видалити посилання на публічний доступ", "Delete public share link": "Видалити публічне посилання",
"Delete share": "Видалити спільний доступ", "Delete share": "Видалити спільний доступ",
"Are you sure you want to delete this shared link?": "Ви впевнені, що хочете видалити це посилання спільного доступу?", "Are you sure you want to delete this shared link?": "Ви впевнені, що хочете видалити це посилання спільного доступу?",
"Publicly shared pages from spaces you are a member of will appear here": "Публічні сторінки з просторів, учасником яких ви є, з'являться тут", "Publicly shared pages from spaces you are a member of will appear here": "Тут з’являться публічно поширені сторінки з просторів, учасником яких ви є",
"Share deleted successfully": "Спільний доступ успішно видалено", "Share deleted successfully": "Спільний доступ успішно видалено",
"Share not found": "Спільний доступ не знайдено", "Share not found": "Спільний доступ не знайдено",
"Failed to share page": "Не вдалося поділитися сторінкою", "Failed to share page": "Не вдалося надати спільний доступ до сторінки",
"Disable public sharing": "Вимкнути публічний доступ", "Disable public sharing": "Вимкнути публічний доступ",
"Prevent members from sharing pages publicly.": "Перешкодити учасникам публічно ділитися сторінками.", "Prevent members from sharing pages publicly.": "Перешкодити учасникам публічно ділитися сторінками.",
"Toggle public sharing": "Перемикання публічного доступу", "Toggle public sharing": "Перемикання публічного доступу",
"Toggle space public sharing": "Перемикання публічного доступу до просторів", "Toggle space public sharing": "Перемикання публічного доступу до просторів",
"Allow viewers to comment": "Дозволити глядачам коментувати",
"Allow viewers to add comments on pages in this space.": "Дозволити глядачам додавати коментарі на сторінках у цьому просторі.",
"Toggle viewer comments": "Увімкнути або вимкнути коментарі глядачів",
"Public sharing is disabled at the workspace level": "Публічний доступ вимкнуто на рівні робочого простору", "Public sharing is disabled at the workspace level": "Публічний доступ вимкнуто на рівні робочого простору",
"Prevent pages in this space from being shared publicly.": "Перешкодити публічному поширенню сторінок у цьому просторі.", "Prevent pages in this space from being shared publicly.": "Перешкодити публічному поширенню сторінок у цьому просторі.",
"Requires an enterprise license": "Потребує корпоративної ліцензії",
"Page permissions": "Права доступу до сторінки.", "Page permissions": "Права доступу до сторінки.",
"Control who can view and edit individual pages. Available with an enterprise license.": "Керуйте тим, хто може переглядати та редагувати окремі сторінки. Доступно з корпоративною ліцензією.", "Control who can view and edit individual pages. Available with an enterprise license.": "Керуйте тим, хто може переглядати та редагувати окремі сторінки. Доступно з корпоративною ліцензією.",
"Enable public sharing": "Увімкнути публічний доступ", "Enable public sharing": "Увімкнути публічний доступ",
@@ -450,7 +473,7 @@
"Public sharing is disabled": "Публічний доступ вимкнуто", "Public sharing is disabled": "Публічний доступ вимкнуто",
"Public sharing has been disabled at the workspace level.": "Публічний доступ було вимкнено на рівні робочого простору.", "Public sharing has been disabled at the workspace level.": "Публічний доступ було вимкнено на рівні робочого простору.",
"Public sharing has been disabled for this space.": "Публічний доступ було вимкнено для цього простору.", "Public sharing has been disabled for this space.": "Публічний доступ було вимкнено для цього простору.",
"Copy page": "Копіювати сторінки", "Copy page": "Копіювати сторінку",
"Copy page to a different space.": "Скопіювати сторінку в інший простір.", "Copy page to a different space.": "Скопіювати сторінку в інший простір.",
"Page copied successfully": "Сторінку успішно скопійовано", "Page copied successfully": "Сторінку успішно скопійовано",
"Page duplicated successfully": "Сторінку успішно дубльовано", "Page duplicated successfully": "Сторінку успішно дубльовано",
@@ -464,120 +487,121 @@
"Replace (Enter)": "Замінити (Enter)", "Replace (Enter)": "Замінити (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Замінити все (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "Замінити все (Ctrl+Alt+Enter)",
"Replace all": "Замінити все", "Replace all": "Замінити все",
"View all": "Переглянути все",
"View all spaces": "Переглянути всі простори", "View all spaces": "Переглянути всі простори",
"Error": "Помилка", "Error": "Помилка",
"Failed to disable MFA": "Не вдалося вимкнути MFA", "Failed to disable MFA": "Не вдалося вимкнути MFA",
"Disable two-factor authentication": "Вимкнути двоетапну аутентифікацію", "Disable two-factor authentication": "Вимкнути двофакторну автентифікацію",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Вимкнення двоетапної аутентифікації зробить ваш обліковий запис менш захищеним. Для входу потрібен лише пароль.", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "Вимкнення двоетапної аутентифікації зробить ваш обліковий запис менш захищеним. Для входу потрібен лише пароль.",
"Please enter your password to disable two-factor authentication:": "Будь ласка, введіть свій пароль, щоб вимкнути двоетапну аутентифікацію:", "Please enter your password to disable two-factor authentication:": "Будь ласка, введіть свій пароль, щоб вимкнути двоетапну аутентифікацію:",
"Two-factor authentication has been enabled": "Двоетапну аутентифікацію включено", "Two-factor authentication has been enabled": "Двофакторну автентифікацію ввімкнено",
"Two-factor authentication has been disabled": "Двоетапну аутентифікацію вимкнено", "Two-factor authentication has been disabled": "Двофакторну автентифікацію вимкнено",
"2-step verification": "Двоетапна перевірка", "2-step verification": "Двоетапна перевірка",
"Protect your account with an additional verification layer when signing in.": "Захистіть свій обліковий запис за допомогою додаткового шару перевірки при вході.", "Protect your account with an additional verification layer when signing in.": "Захистіть свій обліковий запис за допомогою додаткового шару перевірки при вході.",
"Two-factor authentication is active on your account.": "Двоетапну аутентифікацію активовано у вашому обліковому записі.", "Two-factor authentication is active on your account.": "Двоетапну аутентифікацію активовано у вашому обліковому записі.",
"Add 2FA method": "Додати метод 2FA", "Add 2FA method": "Додати метод 2FA",
"Backup codes": "Резервні коди", "Backup codes": "Резервні коди",
"Disable": "Вимкнути", "Disable": "Вимкнути",
"Invalid verification code": "Невірний код перевірки", "Invalid verification code": "Недійсний код перевірки",
"New backup codes have been generated": "Нові резервні коди створено", "New backup codes have been generated": "Нові резервні коди згенеровано",
"Failed to regenerate backup codes": "Не вдалося повторно створити резервні коди", "Failed to regenerate backup codes": "Не вдалося повторно згенерувати резервні коди",
"About backup codes": "Про резервні коди", "About backup codes": "Про резервні коди",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Резервні коди можуть бути використані для доступу до вашого облікового запису, якщо ви втратите доступ до додатку аутентифікатора. Кожен код можна використовувати лише один раз.", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Резервні коди можуть бути використані для доступу до вашого облікового запису, якщо ви втратите доступ до додатку аутентифікатора. Кожен код можна використовувати лише один раз.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Ви можете повторно створити нові резервні коди в будь-який час. Це зробить усі існуючі коди недійсними.", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Ви можете повторно створити нові резервні коди в будь-який час. Це зробить усі існуючі коди недійсними.",
"Confirm password": "Підтвердити пароль", "Confirm password": "Підтвердьте пароль",
"Generate new backup codes": "Створити нові резервні коди", "Generate new backup codes": "Згенерувати нові резервні коди",
"Save your new backup codes": "Збережіть нові резервні коди", "Save your new backup codes": "Збережіть нові резервні коди",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Обов'язково збережіть ці коди у безпечному місці. Ваші старі резервні коди більше не дійсні.", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "Обов'язково збережіть ці коди у безпечному місці. Ваші старі резервні коди більше не дійсні.",
"Your new backup codes": "Ваші нові резервні коди", "Your new backup codes": "Ваші нові резервні коди",
"I've saved my backup codes": "Я зберіг резервні коди", "I've saved my backup codes": "Я зберіг(-ла) свої резервні коди",
"Failed to setup MFA": "Не вдалося налаштувати MFA", "Failed to setup MFA": "Не вдалося налаштувати MFA",
"Setup & Verify": "Налаштувати та перевірити", "Setup & Verify": "Налаштувати й підтвердити",
"Add to authenticator": "Додати до аутентифікатора", "Add to authenticator": "Додати до застосунку автентифікації",
"1. Scan this QR code with your authenticator app": "1. Скануйте цей QR-код за допомогою додатку аутентифікатора", "1. Scan this QR code with your authenticator app": "1. Відскануйте цей QR-код за допомогою застосунку автентифікації",
"Can't scan the code?": "Не можете відсканувати код?", "Can't scan the code?": "Не можете відсканувати код?",
"Enter this code manually in your authenticator app:": "Введіть цей код вручну у додатку аутентифікатора:", "Enter this code manually in your authenticator app:": "Введіть цей код вручну у додатку аутентифікатора:",
"2. Enter the 6-digit code from your authenticator": "2. Введіть 6-значний код із аутентифікатора", "2. Enter the 6-digit code from your authenticator": "2. Введіть 6-значний код із застосунку автентифікації",
"Verify and enable": еревірити та увімкнути", "Verify and enable": ідтвердити й увімкнути",
"Failed to generate QR code. Please try again.": "Не вдалося створити QR-код. Будь ласка, спробуйте ще раз.", "Failed to generate QR code. Please try again.": "Не вдалося створити QR-код. Будь ласка, спробуйте ще раз.",
"Backup": "Резервне копіювання", "Backup": "Резервний",
"Save codes": "Зберегти коди", "Save codes": "Зберегти коди",
"Save your backup codes": "Зберегти резервні коди", "Save your backup codes": "Збережіть свої резервні коди",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Ці коди можуть бути використані для доступу до вашого облікового запису, якщо ви втратите доступ до додатку аутентифікатора. Кожен код можна використовувати лише один раз.", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "Ці коди можуть бути використані для доступу до вашого облікового запису, якщо ви втратите доступ до додатку аутентифікатора. Кожен код можна використовувати лише один раз.",
"Print": "Друкувати", "Print": "Друк",
"Two-factor authentication has been set up. Please log in again.": "Двоетапну аутентифікацію налаштовано. Будь ласка, увійдіть знову.", "Two-factor authentication has been set up. Please log in again.": "Двоетапну аутентифікацію налаштовано. Будь ласка, увійдіть знову.",
"Two-Factor authentication required": "Потрібна двоетапна аутентифікація", "Two-Factor authentication required": "Потрібна двофакторна автентифікація",
"Your workspace requires two-factor authentication for all users": "Ваш робочий простір вимагає двоетапної аутентифікації для всіх користувачів", "Your workspace requires two-factor authentication for all users": "Ваш робочий простір вимагає двофакторну автентифікацію для всіх користувачів",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Щоб продовжити доступ до робочого простору, вам потрібно налаштувати двоетапну аутентифікацію. Це додає додатковий шар захисту до вашого облікового запису.", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "Щоб продовжити доступ до робочого простору, вам потрібно налаштувати двоетапну аутентифікацію. Це додає додатковий шар захисту до вашого облікового запису.",
"Set up two-factor authentication": "Налаштувати двоетапну аутентифікацію", "Set up two-factor authentication": "Налаштувати двофакторну автентифікацію",
"Cancel and logout": "Скасувати та вийти", "Cancel and logout": "Скасувати й вийти",
"Your workspace requires two-factor authentication. Please set it up to continue.": "Ваш робочий простір вимагає двоетапної аутентифікації. Будь ласка, налаштуйте це щоб продовжити.", "Your workspace requires two-factor authentication. Please set it up to continue.": "Ваш робочий простір вимагає двоетапної аутентифікації. Будь ласка, налаштуйте це щоб продовжити.",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Це додає додатковий шар захисту до вашого облікового запису, вимагаючи код підтвердження з вашого додатку аутентифікатора.", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "Це додає додатковий шар захисту до вашого облікового запису, вимагаючи код підтвердження з вашого додатку аутентифікатора.",
"Password is required": "Вимагається пароль", "Password is required": "Пароль обов’язковий",
"Password must be at least 8 characters": "Пароль повинен містити щонайменше 8 символів", "Password must be at least 8 characters": "Пароль має містити щонайменше 8 символів",
"Please enter a 6-digit code": "Будь ласка, введіть 6-значний код", "Please enter a 6-digit code": "Будь ласка, введіть 6-значний код",
"Code must be exactly 6 digits": "Код повинен мати точно 6 цифр", "Code must be exactly 6 digits": "Код має містити рівно 6 цифр",
"Enter the 6-digit code found in your authenticator app": "Введіть 6-значний код з вашого додатку аутентифікатора", "Enter the 6-digit code found in your authenticator app": "Введіть 6-значний код із застосунку автентифікації",
"Need help authenticating?": "Потрібна допомога з аутентифікацією?", "Need help authenticating?": "Потрібна допомога з аутентифікацією?",
"MFA QR Code": "MFA QR-код", "MFA QR Code": "QR-код MFA",
"Account created successfully. Please log in to set up two-factor authentication.": "Обліковий запис успішно створено. Будь ласка, увійдіть, щоб налаштувати двоетапну аутентифікацію.", "Account created successfully. Please log in to set up two-factor authentication.": "Обліковий запис успішно створено. Будь ласка, увійдіть, щоб налаштувати двоетапну аутентифікацію.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю та завершіть двоетапну аутентифікацію.", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю та завершіть двоетапну аутентифікацію.",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю, щоб налаштувати двоетапну аутентифікацію.", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю, щоб налаштувати двоетапну аутентифікацію.",
"Password reset was successful. Please log in with your new password.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю.", "Password reset was successful. Please log in with your new password.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю.",
"Two-factor authentication": "Двоетапна аутентифікація", "Two-factor authentication": "Двофакторна автентифікація",
"Use authenticator app instead": "Використовуйте додаток аутентифікатора замість цього", "Use authenticator app instead": "Натомість використати застосунок автентифікації",
"Verify backup code": еревірити резервний код", "Verify backup code": ідтвердити резервний код",
"Use backup code": "Використовуйте резервний код", "Use backup code": "Використати резервний код",
"Enter one of your backup codes": "Введіть один з ваших резервних кодів", "Enter one of your backup codes": "Введіть один зі своїх резервних кодів",
"Backup code": "Резервний код", "Backup code": "Резервний код",
"Enter one of your backup codes. Each backup code can only be used once.": "Введіть один з ваших резервних кодів. Кожен резервний код можна використовувати лише один раз.", "Enter one of your backup codes. Each backup code can only be used once.": "Введіть один з ваших резервних кодів. Кожен резервний код можна використовувати лише один раз.",
"Verify": еревірити", "Verify": ідтвердити",
"Trash": "Кошик", "Trash": "Кошик",
"Pages in trash will be permanently deleted after {{count}} days.": "Сторінки в кошику будуть остаточно видалені через {count, plural, one{# день} few{# дні} many{# днів} other{# дня}}.", "Pages in trash will be permanently deleted after {{count}} days.": "Сторінки в кошику будуть остаточно видалені через {count, plural, one{# день} few{# дні} many{# днів} other{# дня}}.",
"Deleted": "Видалено", "Deleted": "Видалено",
"No pages in trash": "Немає сторінок у кошику", "No pages in trash": "У кошику немає сторінок",
"Permanently delete page?": "Остаточно видалити сторінку?", "Permanently delete page?": "Остаточно видалити сторінку?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Ви впевнені, що хочете остаточно видалити '{{title}}'? Цю дію не можна скасувати.", "Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Ви впевнені, що хочете остаточно видалити '{{title}}'? Цю дію не можна скасувати.",
"Restore '{{title}}' and its sub-pages?": "Відновити '{{title}}' та її підсторінки?", "Restore '{{title}}' and its sub-pages?": "Відновити '{{title}}' та її підсторінки?",
"Move to trash": "Перемістити до кошика", "Move to trash": "Перемістити в кошик",
"Move this page to trash?": "Перемістити цю сторінку до кошика?", "Move this page to trash?": "Перемістити цю сторінку до кошика?",
"Restore page": "Відновити сторінку", "Restore page": "Відновити сторінку",
"Page moved to trash": "Сторінка переміщена до кошика", "Page moved to trash": "Сторінку переміщено в кошик",
"Page restored successfully": "Сторінку успішно відновлено", "Page restored successfully": "Сторінку успішно відновлено",
"Deleted by": "Видалено", "Deleted by": "Видалив",
"Deleted at": "Видалено о", "Deleted at": "Видалено",
"Preview": "Попередній перегляд", "Preview": "Попередній перегляд",
"Subpages": "Підсторінки", "Subpages": "Підсторінки",
"Failed to load subpages": "Не вдалося завантажити підсторінки", "Failed to load subpages": "Не вдалося завантажити підсторінки",
"No subpages": "Немає підсторінок", "No subpages": "Немає підсторінок",
"Subpages (Child pages)": "Підсторінки (дочірні сторінки)", "Subpages (Child pages)": "Підсторінки (дочірні сторінки)",
"List all subpages of the current page": ерелік всіх підсторінок поточної сторінки", "List all subpages of the current page": оказати всі підсторінки поточної сторінки",
"Attachments": "Вкладення", "Attachments": "Вкладення",
"All spaces": "Усі простори", "All spaces": "Усі простори",
"Unknown": "Невідомо", "Unknown": "Невідомо",
"Find a space": "Знайти простір", "Find a space": "Знайти простір",
"Search in all your spaces": "Шукати у всіх ваших просторах", "Search in all your spaces": "Шукати в усіх ваших просторах",
"Type": "Тип", "Type": "Тип",
"Enterprise": "Підприємство", "Enterprise": "Enterprise",
"Download attachment": "Завантажити вкладення", "Download attachment": "Завантажити вкладення",
"Allowed email domains": "Дозволені домени електронної пошти", "Allowed email domains": "Дозволені домени електронної пошти",
"Only users with email addresses from these domains can signup via SSO.": "Лише користувачі з адресами електронної пошти з цих доменів можуть реєструватися через SSO.", "Only users with email addresses from these domains can signup via SSO.": "Лише користувачі з адресами електронної пошти з цих доменів можуть зареєструватися через SSO.",
"Enter valid domain names separated by comma or space": "Введіть дійсні доменні імена, розділені комою або пробілом", "Enter valid domain names separated by comma or space": "Введіть дійсні доменні імена, розділені комою або пробілом",
"Enforce two-factor authentication": "Вимагати двофакторну автентифікацію", "Enforce two-factor authentication": "Зробити двофакторну автентифікацію обов’язковою",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Після увімкнення всі учасники повинні ввімкнути двофакторну автентифікацію для доступу до робочого простору.", "Once enforced, all members must enable two-factor authentication to access the workspace.": "Після увімкнення всі учасники повинні ввімкнути двофакторну автентифікацію для доступу до робочого простору.",
"Toggle MFA enforcement": "Перемикання вимоги MFA", "Toggle MFA enforcement": "Перемкнути обов’язковість MFA",
"Display name": "Відображуване ім'я", "Display name": "Ім’я для відображення",
"Allow signup": "Дозволити реєстрацію", "Allow signup": "Дозволити реєстрацію",
"Enabled": "Увімкнено", "Enabled": "Увімкнено",
"Advanced Settings": "Розширені налаштування", "Advanced Settings": "Розширені налаштування",
"Enable TLS/SSL": "Увімкнути TLS/SSL", "Enable TLS/SSL": "Увімкнути TLS/SSL",
"Use secure connection to LDAP server": "Використовувати захищене з'єднання з сервером LDAP", "Use secure connection to LDAP server": "Використовувати захищене зєднання з сервером LDAP",
"Group sync": "Синхронізація групи", "Group sync": "Синхронізація груп",
"No SSO providers found.": "Постачальників SSO не знайдено.", "No SSO providers found.": "Постачальників SSO не знайдено.",
"Delete SSO provider": "Видалити постачальника SSO", "Delete SSO provider": "Видалити постачальника SSO",
"Are you sure you want to delete this SSO provider?": "Ви впевнені, що хочете видалити цього постачальника SSO?", "Are you sure you want to delete this SSO provider?": "Ви впевнені, що хочете видалити цього постачальника SSO?",
"Action": "Дія", "Action": "Дія",
"{{ssoProviderType}} configuration": "Конфігурація {{ssoProviderType}}", "{{ssoProviderType}} configuration": "Конфігурація {{ssoProviderType}}",
"Icon": "Іконка", "Icon": "Значок",
"Upload image": "Завантажити зображення", "Upload image": "Завантажити зображення",
"Remove image": "Видалити зображення", "Remove image": "Видалити зображення",
"Failed to remove image": "Не вдалося видалити зображення", "Failed to remove image": "Не вдалося видалити зображення",
@@ -613,6 +637,7 @@
"AI Answer": "Відповідь ШІ", "AI Answer": "Відповідь ШІ",
"Ask AI": "Запитати ШІ", "Ask AI": "Запитати ШІ",
"AI is thinking...": "ШІ думає...", "AI is thinking...": "ШІ думає...",
"Thinking": "Думаю",
"Ask a question...": "Задайте питання...", "Ask a question...": "Задайте питання...",
"AI Answers": "Відповіді ШІ", "AI Answers": "Відповіді ШІ",
"AI-powered search (AI Answers)": "Пошук на базі ШІ (Відповіді ШІ)", "AI-powered search (AI Answers)": "Пошук на базі ШІ (Відповіді ШІ)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "Генеративний ШІ (Запитати ШІ)", "Generative AI (Ask AI)": "Генеративний ШІ (Запитати ШІ)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Увімкнути генерацію контенту за допомогою ШІ в редакторі. Дозволяє користувачам генерувати, покращувати, перекладати та трансформувати текст.", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Увімкнути генерацію контенту за допомогою ШІ в редакторі. Дозволяє користувачам генерувати, покращувати, перекладати та трансформувати текст.",
"Toggle generative AI": "Переключити генеративний ШІ", "Toggle generative AI": "Переключити генеративний ШІ",
"Enterprise feature": "Функція корпоративної версії", "Upgrade your plan": "Оновіть свій тарифний план",
"Available with a paid license": "Доступно за платною ліцензією",
"Upgrade your license tier.": "Оновіть рівень своєї ліцензії.",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "ШІ доступний лише в корпоративній редакції Docmost. Зверніться до sales@docmost.com.", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "ШІ доступний лише в корпоративній редакції Docmost. Зверніться до sales@docmost.com.",
"AI & MCP": "ШІ та MCP", "AI & MCP": "ШІ та MCP",
"AI": "ШІ", "AI": "ШІ",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "Протокол контексту моделі (MCP)", "Model Context Protocol (MCP)": "Протокол контексту моделі (MCP)",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Увімкніть MCP‑сервер, щоб дозволити ШІ‑помічникам та інструментам взаємодіяти з вмістом вашого робочого простору.", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Увімкніть MCP‑сервер, щоб дозволити ШІ‑помічникам та інструментам взаємодіяти з вмістом вашого робочого простору.",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP доступний лише в корпоративній редакції Docmost. Зверніться до sales@docmost.com.", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP доступний лише в корпоративній редакції Docmost. Зверніться до sales@docmost.com.",
"MCP documentation": "Документація MCP",
"MCP Server URL": "URL сервера MCP", "MCP Server URL": "URL сервера MCP",
"Use your API key for authentication. You can manage API keys in your account settings.": "Використовуйте свій API‑ключ для аутентифікації. Ви можете керувати API‑ключами в налаштуваннях облікового запису.", "Use your API key for authentication. You can manage API keys in your account settings.": "Використовуйте свій API‑ключ для аутентифікації. Ви можете керувати API‑ключами в налаштуваннях облікового запису.",
"Supported tools": "Підтримувані інструменти", "Supported tools": "Підтримувані інструменти",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "У вашому робочому просторі MCP увімкнено. Використайте свій API‑ключ, щоб підключити ШІ‑помічників.", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "У вашому робочому просторі MCP увімкнено. Використайте свій API‑ключ, щоб підключити ШІ‑помічників.",
"MCP server URL:": "URL сервера MCP:", "MCP server URL:": "URL сервера MCP:",
"Learn more": "Дізнатися більше", "Learn more": "Дізнатися більше",
"View the": "Переглянути", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Керуйте ключами API для всіх користувачів у робочому просторі. Перегляньте <anchor>документацію API</anchor> для деталей використання.",
"for usage details.": "для відомостей про використання.", "View the <anchor>API documentation</anchor> for usage details.": "Перегляньте <anchor>документацію API</anchor> для деталей використання.",
"for setup instructions.": "для інструкцій з налаштування.", "View the <anchor>MCP documentation</anchor>.": "Перегляньте <anchor>документацію MCP</anchor>.",
"API documentation": "Документація API",
"Sources": "Джерела", "Sources": "Джерела",
"AI Answers not available for attachments": "Відповіді ШІ недоступні для вкладень", "AI Answers not available for attachments": "Відповіді ШІ недоступні для вкладень",
"No answer available": "Відповідь недоступна", "No answer available": "Відповідь недоступна",
@@ -654,12 +679,34 @@
"Mark all as read": "Позначити все як прочитане", "Mark all as read": "Позначити все як прочитане",
"Mark as read": "Позначити як прочитане", "Mark as read": "Позначити як прочитане",
"More options": "Більше опцій", "More options": "Більше опцій",
"mentioned you in a comment": "згадали вас у коментарі", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> згадав вас у коментарі",
"commented on a page": "прокоментували на сторінці", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> залишив коментар на сторінці",
"resolved a comment": "вирішили коментар", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> позначив(-ла) коментар як вирішений",
"mentioned you on a page": "згадали вас на сторінці", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> згадав(-ла) вас на сторінці",
"gave you edit access to a page": "надав вам доступ для редагування сторінки", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> надав(-ла) вам доступ до редагування сторінки",
"gave you view access to a page": "надав вам доступ для перегляду сторінки", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> надав(-ла) вам доступ до перегляду сторінки",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> оновив(-ла) сторінку",
"Watch page": "Стежити за сторінкою",
"Stop watching": "Припинити стежити",
"Watch space": "Стежити за простором",
"Stop watching space": "Припинити стежити за простором",
"Email notifications": "Сповіщення електронною поштою",
"Page updates": "Оновлення сторінки",
"Get notified when pages you watch are updated.": "Отримуйте сповіщення, коли сторінки, за якими ви стежите, оновлюються.",
"Page mentions": "Згадки на сторінці",
"Get notified when someone mentions you on a page.": "Отримуйте сповіщення, коли хтось згадує вас на сторінці.",
"Comment mentions": "Згадки у коментарях",
"Get notified when someone mentions you in a comment.": "Отримуйте сповіщення, коли хтось згадує вас у коментарі.",
"New comments": "Нові коментарі",
"Get notified about new comments on threads you participate in.": "Отримуйте сповіщення про нові коментарі у темах, у яких ви берете участь.",
"Resolved comments": "Вирішені коментарі",
"Get notified when your comment is resolved.": "Отримайте сповіщення, коли ваш коментар вирішено.",
"You are now watching this page": "Ви зараз стежите за цією сторінкою",
"You are no longer watching this page": "Ви більше не стежите за цією сторінкою",
"You are now watching this space": "Тепер ви стежите за цим простором",
"You are no longer watching this space": "Ви більше не стежите за цим простором",
"Direct": "Прямі",
"Updates": "Оновлення",
"Today": "Сьогодні", "Today": "Сьогодні",
"Yesterday": "Вчора", "Yesterday": "Вчора",
"This week": "Цього тижня", "This week": "Цього тижня",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "Не вдалося оновити термін зберігання у кошику", "Failed to update trash retention": "Не вдалося оновити термін зберігання у кошику",
"Removed page restriction": "Обмеження сторінки видалено", "Removed page restriction": "Обмеження сторінки видалено",
"Added page permission": "Додано дозвіл на сторінку", "Added page permission": "Додано дозвіл на сторінку",
"Removed page permission": "Дозвіл на сторінку видалено" "Removed page permission": "Дозвіл на сторінку видалено",
"day": "день",
"days": "дні",
"week": "тиждень",
"weeks": "тижні",
"month": "місяць",
"months": "місяці",
"year": "рік",
"years": "роки",
"Period": "Період",
"Fixed date": "Фіксована дата",
"Indefinitely": "Безстроково",
"Days": "Дні",
"Weeks": "Тижні",
"Months": "Місяці",
"Years": "Роки",
"Pick a date": "Виберіть дату",
"Maximum is {{max}} {{unit}} for this unit": "Максимум для цієї одиниці — {{max}} {{unit}}",
"Never expires. Verifiers can re-verify at any time.": "Термін дії не спливає. Верифікатори можуть повторно перевірити будь-коли.",
"Verified": "Перевірено",
"Review needed": "Потрібен перегляд",
"Verification expired": "Термін перевірки сплив",
"Draft": "Чернетка",
"In Approval": "На погодженні",
"In approval": "На погодженні",
"Approved": "Погоджено",
"Obsolete": "Застаріло",
"Expiring": "Термін дії спливає",
"Set up verification": "Налаштувати перевірку",
"Verify page": "Перевірити сторінку",
"Page verification": "Перевірка сторінки",
"Add verification": "Додати перевірку",
"Edit verification": "Редагувати перевірку",
"Search by title": "Пошук за назвою",
"Choose how this page should stay accurate.": "Виберіть, як підтримувати актуальність цієї сторінки.",
"Recurring verification": "Регулярна перевірка",
"Verifiers re-confirm this page on a schedule.": "Верифікатори повторно підтверджують цю сторінку за розкладом.",
"Re-verify on a schedule (e.g every 30 days )": "Повторно перевіряти за розкладом (наприклад, кожні 30 днів)",
"Page stays editable at all times": "Сторінка залишається доступною для редагування в будь-який час",
"Best for runbooks, FAQs, living documentation": "Найкраще підходить для runbook-ів, FAQ і живої документації",
"Approval workflow": "Процес погодження",
"Formal document lifecycle with named approvers.": "Формальний життєвий цикл документа з призначеними погоджувачами.",
"Draft → In approval → Approved → Obsolete": "Чернетка → На погодженні → Погоджено → Застаріло",
"Locked once approved, with full history": "Після погодження блокується, із повною історією",
"Designed for ISO 9001, ISO 13485, and FDA": "Призначено для ISO 9001, ISO 13485 та FDA",
"Best for SOPs and controlled documents": "Найкраще підходить для SOP і контрольованих документів",
"Back": "Назад",
"Quality management": "Управління якістю",
"Recurring": "Регулярна",
"Pages move through draft, approval, and approved stages.": "Сторінки проходять стадії чернетки, погодження та погодженого документа.",
"Verifiers": "Верифікатори",
"Add verifier": "Додати верифікатора",
"I've reviewed this page for accuracy": "Я перевірив(ла) цю сторінку на точність",
"Set up": "Налаштувати",
"Remove verification": "Видалити перевірку",
"Are you sure you want to remove verification from this page?": "Ви впевнені, що хочете видалити перевірку з цієї сторінки?",
"Assigned verifiers must periodically re-verify this page.": "Призначені верифікатори мають періодично повторно перевіряти цю сторінку.",
"Last verified by {{name}} {{time}} (expired)": "Востаннє перевірив(-ла) {{name}} {{time}} (термін дії сплив)",
"The fixed expiration date has passed.": "Фіксована дата завершення вже минула.",
"Verified by {{name}} {{time}}": "Перевірено: {{name}} {{time}}",
"Expires {{date}}": "Термін дії спливає {{date}}",
"Expired {{date}}": "Термін дії сплив {{date}}",
"Mark as obsolete": "Позначити як застаріле",
"Mark obsolete": "Позначити як застаріле",
"Returned by {{name}} {{time}}": "Повернуто: {{name}} {{time}}",
"No approval has been requested yet.": "Запит на погодження ще не було надіслано.",
"Submitted by {{name}} {{time}}": "Надіслано: {{name}} {{time}}",
"Someone": "Хтось",
"Approved by {{name}} {{time}}": "Погоджено: {{name}} {{time}}",
"This document has been marked as obsolete.": "Цей документ позначено як застарілий.",
"Rejection comment": "Коментар щодо відхилення",
"Reason for returning this document...": "Причина повернення цього документа...",
"Confirm rejection": "Підтвердити відхилення",
"Submit for approval": "Надіслати на погодження",
"Reject": "Відхилити",
"Approve": "Погодити",
"Re-submit for approval": "Повторно надіслати на погодження",
"Verified until": "Перевірено до",
"QMS": "QMS",
"Verified pages": "Перевірені сторінки",
"Search pages...": "Шукати сторінки...",
"Filter by space": "Фільтрувати за простором",
"Filter by type": "Фільтрувати за типом",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> перевірив(-ла) сторінку",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> надіслав(-ла) сторінку вам на погодження",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> повернув(-ла) сторінку на доопрацювання",
"Page verification expires soon": "Термін перевірки сторінки скоро спливає",
"Page verification has expired": "Термін перевірки сторінки сплив",
"Verifying your email": "Перевірка вашої електронної пошти",
"Please wait...": "Будь ласка, зачекайте...",
"Verification failed. The link may have expired.": "Підтвердження не вдалося. Посилання могло втратити чинність.",
"Check your email": "Перевірте свою електронну пошту",
"We sent a verification link to {{email}}.": "Ми надіслали посилання для підтвердження на {{email}}.",
"We sent a verification link to your email.": "Ми надіслали посилання для підтвердження на вашу електронну пошту.",
"Click the link to verify your email and access your workspace.": "Клікніть на посилання, щоб підтвердити електронну пошту та отримати доступ до робочого простору.",
"Resend verification email": "Повторно надіслати лист для підтвердження",
"Verification email sent. Please check your inbox.": "Лист для підтвердження надіслано. Будь ласка, перевірте свою скриньку.",
"Failed to resend verification email. Please try again.": "Не вдалося повторно надіслати лист для підтвердження. Будь ласка, спробуйте ще раз.",
"We've sent you an email with your associated workspaces.": "Ми надіслали вам лист із переліком пов’язаних робочих просторів.",
"Load more": "Завантажити більше",
"Log out of all devices": "Вийти на всіх пристроях",
"Log out of all sessions except this device": "Вийти з усіх сеансів, крім цього пристрою",
"This Device": "Цей пристрій",
"Unknown device": "Невідомий пристрій",
"No active sessions": "Немає активних сеансів",
"Session revoked": "Сеанс відкликано",
"All other sessions revoked": "Усі інші сеанси відкликано",
"Last used": "Останнє використання",
"Created": "Створено",
"Rename": "Перейменувати",
"Publish": "Опублікувати",
"Security": "Безпека",
"Enforce SSO": "Зробити SSO обов’язковим",
"Once enforced, members will not be able to login with email and password.": "Після ввімкнення учасники не зможуть входити за допомогою електронної пошти та пароля.",
"AI-generated content may not be accurate.": "Вміст, згенерований ШІ, може бути неточним.",
"AI Chat": "AI-чат",
"Analyze for insights": "Проаналізувати для отримання висновків",
"Ask anything...": "Запитайте що завгодно...",
"Chat history": "Історія чатів",
"Chat name": "Назва чату",
"Close": "Закрити",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "Не вдалося завантажити чат. Сталася помилка.",
"Failed to render this message.": "Не вдалося відобразити це повідомлення.",
"How can I help you today?": "Чим я можу допомогти вам сьогодні?",
"New chat": "Новий чат",
"No chat history": "Немає історії чатів",
"No chats found": "Чатів не знайдено",
"No conversations yet": "Розмов поки немає",
"Open full page": "Відкрити повну сторінку",
"Previous 7 days": "Попередні 7 днів",
"Previous 30 days": "Попередні 30 днів",
"Search chats...": "Шукати чати...",
"Start a new chat to see it here.": "Почніть новий чат, щоб побачити його тут.",
"Summarize this page": "Підсумувати цю сторінку",
"Toggle AI Chat": "Перемкнути AI-чат",
"Translate this page": "Перекласти цю сторінку",
"Try a different search term.": "Спробуйте інший пошуковий запит.",
"Try again": "Спробувати ще раз",
"Untitled chat": "Чат без назви",
"What can I help you with?": "Чим я можу вам допомогти?"
} }
+299 -112
View File
@@ -7,6 +7,7 @@
"Add members": "添加成员", "Add members": "添加成员",
"Add to groups": "添加到群组", "Add to groups": "添加到群组",
"Add space members": "添加空间成员", "Add space members": "添加空间成员",
"Add to favorites": "添加到收藏",
"Admin": "管理员", "Admin": "管理员",
"Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "您确定要删除这个群组吗?成员将失去对该群组可访问资源的访问权限。", "Are you sure you want to delete this group? Members will lose access to resources this group has access to.": "您确定要删除这个群组吗?成员将失去对该群组可访问资源的访问权限。",
"Are you sure you want to delete this page?": "您确定要删除这个页面吗?", "Are you sure you want to delete this page?": "您确定要删除这个页面吗?",
@@ -44,24 +45,24 @@
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "您确定要删除这个页面吗?这将删除其子页面和页面历史记录。此操作不可逆。", "Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "您确定要删除这个页面吗?这将删除其子页面和页面历史记录。此操作不可逆。",
"Description": "描述", "Description": "描述",
"Details": "详情", "Details": "详情",
"e.g ACME": "例如ACME", "e.g ACME": "例如 ACME",
"e.g ACME Inc": "例如ACME Inc", "e.g ACME Inc": "例如 ACME Inc",
"e.g Developers": "例如:开发人员", "e.g Developers": "例如 Developers",
"e.g Group for developers": "例如开发人员群组", "e.g Group for developers": "例如 开发者小组",
"e.g product": "例如product", "e.g product": "例如 product",
"e.g Product Team": "例如产品团队", "e.g Product Team": "例如 产品团队",
"e.g Sales": "例如销售", "e.g Sales": "例如 销售",
"e.g Space for product team": "例如产品团队空间", "e.g Space for product team": "例如 产品团队空间",
"e.g Space for sales team to collaborate": "例如销售团队协作的空间", "e.g Space for sales team to collaborate": "例如销售团队协作的空间",
"Edit": "编辑", "Edit": "编辑",
"Read": "读", "Read": "读",
"Edit group": "编辑群组", "Edit group": "编辑群组",
"Email": "电子邮箱", "Email": "电子邮箱",
"Enter a strong password": "输入一个强密码", "Enter a strong password": "输入一个强密码",
"Enter valid email addresses separated by comma or space max_50": "输入有效的电子邮箱地址,用逗号或空格分隔 [最多:50个]", "Enter valid email addresses separated by comma or space max_50": "输入有效的电子邮箱地址,用逗号或空格分隔 [最多:50个]",
"enter valid emails addresses": "输入有效的电子邮箱地址", "enter valid emails addresses": "输入有效的电子邮箱地址",
"Enter your current password": "输入您的当前密码", "Enter your current password": "输入您的当前密码",
"enter your full name": "输入您的全名", "enter your full name": "输入您的全名",
"Enter your new password": "输入您的新密码", "Enter your new password": "输入您的新密码",
"Enter your new preferred email": "输入您新的首选电子邮箱", "Enter your new preferred email": "输入您新的首选电子邮箱",
"Enter your password": "输入您的密码", "Enter your password": "输入您的密码",
@@ -74,6 +75,9 @@
"Failed to import pages": "导入页面失败", "Failed to import pages": "导入页面失败",
"Failed to load page. An error occurred.": "页面加载失败。发生了一个错误。", "Failed to load page. An error occurred.": "页面加载失败。发生了一个错误。",
"Failed to update data": "数据更新失败", "Failed to update data": "数据更新失败",
"Favorite spaces": "收藏的空间",
"Favorite spaces appear here": "收藏的空间会显示在这里",
"Favorites": "收藏",
"Full access": "完全访问", "Full access": "完全访问",
"Full page width": "全页宽度", "Full page width": "全页宽度",
"Full width": "全宽", "Full width": "全宽",
@@ -92,6 +96,7 @@
"Invite by email": "通过电子邮箱邀请", "Invite by email": "通过电子邮箱邀请",
"Invite members": "邀请成员", "Invite members": "邀请成员",
"Invite new members": "邀请新成员", "Invite new members": "邀请新成员",
"Invite People": "邀请成员",
"Invited members who are yet to accept their invitation will appear here.": "尚未接受邀请的成员将显示在这里。", "Invited members who are yet to accept their invitation will appear here.": "尚未接受邀请的成员将显示在这里。",
"Invited members will be granted access to spaces the groups can access": "被邀请的成员将被授予访问群组可以访问的空间的权限", "Invited members will be granted access to spaces the groups can access": "被邀请的成员将被授予访问群组可以访问的空间的权限",
"Join the workspace": "加入工作空间", "Join the workspace": "加入工作空间",
@@ -139,6 +144,7 @@
"Profile": "个人资料", "Profile": "个人资料",
"Recently updated": "最近更新", "Recently updated": "最近更新",
"Remove": "移除", "Remove": "移除",
"Remove from favorites": "从收藏中移除",
"Remove group member": "移除群组成员", "Remove group member": "移除群组成员",
"Remove space member": "移除空间成员", "Remove space member": "移除空间成员",
"Restore": "恢复", "Restore": "恢复",
@@ -151,53 +157,54 @@
"Search...": "搜索...", "Search...": "搜索...",
"Select language": "选择语言", "Select language": "选择语言",
"Select role": "选择角色", "Select role": "选择角色",
"Select role to assign to all invited members": "选择要分配给所有被邀请成员的角色", "Select role to assign to all invited members": "选择要分配给所有受邀成员的角色",
"Select theme": "选择主题", "Select theme": "选择主题",
"Send invitation": "发送邀请", "Send invitation": "发送邀请",
"Invitation sent": "邀请邮件已发送", "Invitation sent": "邀请已发送",
"Settings": "设置", "Settings": "设置",
"Setup workspace": "设置工作空间", "Setup workspace": "设置工作",
"Sign In": "登录", "Sign In": "登录",
"Sign Up": "注册", "Sign Up": "注册",
"Slug": "短链接", "Slug": "标识符",
"Space": "空间", "Space": "空间",
"Space description": "空间描述", "Space description": "空间描述",
"Space menu": "空间菜单", "Space menu": "空间菜单",
"Space name": "空间名称", "Space name": "空间名称",
"Space settings": "空间设置", "Space settings": "空间设置",
"Space slug": "空间短链接", "Space slug": "空间标识符",
"Spaces": "空间", "Spaces": "空间",
"Spaces you belong to": "您所属的空间", "Spaces you belong to": "您所属的空间",
"No space found": "未找到空间", "No space found": "未找到空间",
"Search for spaces": "搜索空间", "Search for spaces": "搜索空间",
"Start typing to search...": "开始输入以搜索...", "Start typing to search...": "开始输入以搜索...",
"Status": "状态", "Status": "状态",
"Successfully imported": "成功导入", "Successfully imported": "导入成功",
"Successfully restored": "恢复成功", "Successfully restored": "恢复成功",
"System settings": "系统设置", "System settings": "系统设置",
"Templates": "模板",
"Theme": "主题", "Theme": "主题",
"To change your email, you have to enter your password and new email.": "要更改您的电子邮箱,您需要输入密码和新的电子邮箱地址。", "To change your email, you have to enter your password and new email.": "要更改您的电子邮箱,您需要输入密码和新的电子邮箱地址。",
"Toggle full page width": "切换页宽度", "Toggle full page width": "切换页宽度",
"Unable to import pages. Please try again.": "无法导入页面。请重试。", "Unable to import pages. Please try again.": "无法导入页面。请重试。",
"untitled": "无标题", "untitled": "未命名",
"Untitled": "无标题", "Untitled": "未命名",
"Updated successfully": "更新成功", "Updated successfully": "更新成功",
"User": "用户", "User": "用户",
"Workspace": "工作区", "Workspace": "工作区",
"Workspace Name": "工作空间名称", "Workspace Name": "工作名称",
"Workspace settings": "工作区设置", "Workspace settings": "工作区设置",
"You can change your password here.": "您可以在这里更改密码。", "You can change your password here.": "您可以在这里更改密码。",
"Your Email": "您的电子邮箱", "Your Email": "您的邮箱",
"Your import is complete.": "导入已完成。", "Your import is complete.": "导入已完成。",
"Your name": "您的姓名", "Your name": "您的姓名",
"Your Name": "您的姓名", "Your Name": "您的姓名",
"Your password": "您的密码", "Your password": "您的密码",
"Your password must be a minimum of 8 characters.": "您的密码必须至少包含8个字符。", "Your password must be a minimum of 8 characters.": "您的密码必须至少包含8个字符。",
"Sidebar toggle": "切换侧边栏", "Sidebar toggle": "侧边栏切换",
"Comments": "评论", "Comments": "评论",
"404 page not found": "404 页面未找到", "404 page not found": "404 页面未找到",
"Sorry, we can't find the page you are looking for.": "抱歉,我们无法找到你所需要的页面", "Sorry, we can't find the page you are looking for.": "抱歉,我们无法找到你所需要的页面",
"Take me back to homepage": "回到主页", "Take me back to homepage": "返回首页",
"Forgot password": "忘记密码", "Forgot password": "忘记密码",
"Forgot your password?": "忘记密码了吗?", "Forgot your password?": "忘记密码了吗?",
"A password reset link has been sent to your email. Please check your inbox.": "密码重置链接已经发送到您的邮箱,请检查收件箱", "A password reset link has been sent to your email. Please check your inbox.": "密码重置链接已经发送到您的邮箱,请检查收件箱",
@@ -215,6 +222,8 @@
"Edit comment": "编辑评论", "Edit comment": "编辑评论",
"Delete comment": "删除评论", "Delete comment": "删除评论",
"Are you sure you want to delete this comment?": "你确定要删除这条评论吗?", "Are you sure you want to delete this comment?": "你确定要删除这条评论吗?",
"Delete chat": "删除聊天",
"Are you sure you want to delete '{{title}}'? This action cannot be undone.": "您确定要删除「{{title}}」吗?此操作无法撤销。",
"Comment created successfully": "成功创建评论", "Comment created successfully": "成功创建评论",
"Error creating comment": "创建评论时出错", "Error creating comment": "创建评论时出错",
"Comment updated successfully": "评论更新成功", "Comment updated successfully": "评论更新成功",
@@ -222,8 +231,8 @@
"Comment deleted successfully": "成功删除评论", "Comment deleted successfully": "成功删除评论",
"Failed to delete comment": "删除评论失败", "Failed to delete comment": "删除评论失败",
"Comment resolved successfully": "成功标记评论为解决", "Comment resolved successfully": "成功标记评论为解决",
"Comment re-opened successfully": "成功重新打开评论", "Comment re-opened successfully": "评论重新打开成功",
"Comment unresolved successfully": "成功标记评论为未解决", "Comment unresolved successfully": "评论已成功取消解决",
"Failed to resolve comment": "标记评论为解决失败", "Failed to resolve comment": "标记评论为解决失败",
"Resolve comment": "解决评论", "Resolve comment": "解决评论",
"Unresolve comment": "取消解决评论", "Unresolve comment": "取消解决评论",
@@ -243,7 +252,7 @@
"Copy": "复制", "Copy": "复制",
"Copy to space": "复制到空间", "Copy to space": "复制到空间",
"Copied": "已复制", "Copied": "已复制",
"Duplicate": "复", "Duplicate": "复",
"Select a user": "选择一个用户", "Select a user": "选择一个用户",
"Select a group": "选择一个组", "Select a group": "选择一个组",
"Export all pages and attachments in this space.": "导出当前空间的所有页面和附件", "Export all pages and attachments in this space.": "导出当前空间的所有页面和附件",
@@ -289,6 +298,11 @@
"Save & Exit": "保存并退出", "Save & Exit": "保存并退出",
"Double-click to edit Excalidraw diagram": "双击以编辑 Excalidraw 图表", "Double-click to edit Excalidraw diagram": "双击以编辑 Excalidraw 图表",
"Paste link": "粘贴链接", "Paste link": "粘贴链接",
"Paste link or search pages": "粘贴链接或搜索页面",
"Link to web page": "链接到网页",
"Recents": "最近使用",
"Page or URL": "页面或网址",
"Link title": "链接标题",
"Edit link": "编辑链接", "Edit link": "编辑链接",
"Remove link": "移除链接", "Remove link": "移除链接",
"Add link": "添加链接", "Add link": "添加链接",
@@ -336,6 +350,7 @@
"Insert horizontal rule divider": "插入水平分割线", "Insert horizontal rule divider": "插入水平分割线",
"Upload any image from your device.": "从设备上传任何图像", "Upload any image from your device.": "从设备上传任何图像",
"Upload any video from your device.": "从设备上传任何视频", "Upload any video from your device.": "从设备上传任何视频",
"Upload any audio from your device.": "从您的设备上传任意音频文件。",
"Upload any file from your device.": "从设备上传任何文件", "Upload any file from your device.": "从设备上传任何文件",
"Uploading {{name}}": "正在上传{{name}}", "Uploading {{name}}": "正在上传{{name}}",
"Uploading file": "正在上传文件", "Uploading file": "正在上传文件",
@@ -345,10 +360,16 @@
"Video": "视频", "Video": "视频",
"Divider": "分割线", "Divider": "分割线",
"Quote": "引用", "Quote": "引用",
"Image": "图", "Image": "图",
"Audio": "音频",
"Embed PDF": "嵌入 PDF",
"Upload and embed a PDF file.": "上传并嵌入 PDF 文件。",
"Embed as PDF": "作为 PDF 嵌入",
"Failed to load PDF": "加载 PDF 失败",
"Convert to attachment": "转换为附件",
"File attachment": "文件附件", "File attachment": "文件附件",
"Toggle block": "切换块", "Toggle block": "折叠块",
"Callout": "标注块", "Callout": "提示块",
"Insert callout notice.": "插入标注提示块", "Insert callout notice.": "插入标注提示块",
"Math inline": "行内公式", "Math inline": "行内公式",
"Insert inline math equation.": "插入行内公式", "Insert inline math equation.": "插入行内公式",
@@ -356,18 +377,18 @@
"Insert math equation": "插入数学公式", "Insert math equation": "插入数学公式",
"Mermaid diagram": "Mermaid 图表", "Mermaid diagram": "Mermaid 图表",
"Insert mermaid diagram": "插入 Mermaid 图表", "Insert mermaid diagram": "插入 Mermaid 图表",
"Insert and design Drawio diagrams": "插入并设计 Draw.io 图表", "Insert and design Drawio diagrams": "插入并设计 Drawio 图表",
"Insert current date": "插入当前日期", "Insert current date": "插入当前日期",
"Draw and sketch excalidraw diagrams": "绘制 Excalidraw 图表", "Draw and sketch excalidraw diagrams": "绘制和草绘 Excalidraw 图表",
"Multiple": "多个", "Multiple": "多个",
"Turn into": "变成", "Turn into": "变成",
"Text align": "文本对齐", "Text align": "文本对齐",
"This page may have been deleted, moved, or you may not have access.": "此页面可能已被删除、移动,或者您可能无权访问。{", "This page may have been deleted, moved, or you may not have access.": "此页面可能已被删除、移动,或者您可能无权访问。{",
"Go to homepage": "前往首页", "Go to homepage": "前往首页",
"Pages you create will show up here.": "您创建的页面将显示在此处。", "Pages you create will show up here.": "您创建的页面将显示在此处。",
"Heading {{level}}": "{{level}} 级标题", "Heading {{level}}": "标题 {{level}}",
"Toggle title": "切换标题", "Toggle title": "折叠标题",
"Write anything. Enter \"/\" for commands": "开始编写内容输入 \"/\" 以使用指令", "Write anything. Enter \"/\" for commands": "输入任意内容输入“/”查看命令",
"Write...": "写点内容...", "Write...": "写点内容...",
"Column count": "列数", "Column count": "列数",
"{{count}} Columns": "{{count}} 列", "{{count}} Columns": "{{count}} 列",
@@ -382,7 +403,7 @@
"Yesterday, {{time}}": "昨天,{{time}}", "Yesterday, {{time}}": "昨天,{{time}}",
"Space created successfully": "空间创建成功", "Space created successfully": "空间创建成功",
"Space updated successfully": "空间更新成功", "Space updated successfully": "空间更新成功",
"Space deleted successfully": "空间已成功删除", "Space deleted successfully": "空间删除成功",
"Members added successfully": "成员添加成功", "Members added successfully": "成员添加成功",
"Member removed successfully": "成员移除成功", "Member removed successfully": "成员移除成功",
"Member role updated successfully": "成员角色更新成功", "Member role updated successfully": "成员角色更新成功",
@@ -392,7 +413,7 @@
"Word count: {{wordCount}}": "字数:{{wordCount}}", "Word count: {{wordCount}}": "字数:{{wordCount}}",
"Character count: {{characterCount}}": "字符数:{{characterCount}}", "Character count: {{characterCount}}": "字符数:{{characterCount}}",
"New update": "新更新", "New update": "新更新",
"{{latestVersion}} is available": "{{latestVersion}} 已经可以使用", "{{latestVersion}} is available": "{{latestVersion}} 用",
"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.": "选择您偏好的页面编辑模式。避免意外编辑。",
"Reading": "阅读", "Reading": "阅读",
@@ -415,31 +436,33 @@
"Share": "分享", "Share": "分享",
"Public sharing": "公开分享", "Public sharing": "公开分享",
"Shared by": "分享者", "Shared by": "分享者",
"Shared at": "分享时间", "Shared at": "分享",
"Inherits public sharing from": "继承自的公开分享", "Inherits public sharing from": "继承公开分享",
"Share to web": "分享到网页", "Share to web": "分享到网页",
"Shared to web": "已分享到网页", "Shared to web": "已分享到网页",
"Anyone with the link can view this page": "任何有链接的人都可以查看此页面", "Anyone with the link can view this page": "任何有链接的人都可以查看此页面",
"Make this page publicly accessible": "使此页面公开访问", "Make this page publicly accessible": "此页面设为公开访问",
"Include sub-pages": "包子页面", "Include sub-pages": "包子页面",
"Make sub-pages public too": "将子页面设为公开", "Make sub-pages public too": "同时将子页面设为公开",
"Allow search engines to index page": "允许搜索引擎索引页面", "Allow search engines to index page": "允许搜索引擎索引页面",
"Open page": "打开页面", "Open page": "打开页面",
"Page": "页面", "Page": "页面",
"Delete public share link": "删除公开分享链接", "Delete public share link": "删除公开分享链接",
"Delete share": "删除分享", "Delete share": "删除分享",
"Are you sure you want to delete this shared link?": "您确定要删除此分享链接吗?", "Are you sure you want to delete this shared link?": "您确定要删除此分享链接吗?",
"Publicly shared pages from spaces you are a member of will appear here": "您所空间公开共享页面显示在此处", "Publicly shared pages from spaces you are a member of will appear here": "您所空间公开分享的页面显示在这里",
"Share deleted successfully": "分享已成功删除", "Share deleted successfully": "分享删除成功",
"Share not found": "未找到分享", "Share not found": "未找到分享",
"Failed to share page": "页面分享失败", "Failed to share page": "页面分享失败",
"Disable public sharing": "禁用公开分享", "Disable public sharing": "禁用公开分享",
"Prevent members from sharing pages publicly.": "阻止成员公开分享页面。", "Prevent members from sharing pages publicly.": "阻止成员公开分享页面。",
"Toggle public sharing": "切换公开分享", "Toggle public sharing": "切换公开分享",
"Toggle space public sharing": "切换空间公开分享", "Toggle space public sharing": "切换空间公开分享",
"Allow viewers to comment": "允许观众评论",
"Allow viewers to add comments on pages in this space.": "允许观众在此空间的页面上添加评论。",
"Toggle viewer comments": "切换观众评论",
"Public sharing is disabled at the workspace level": "公开分享在工作区级别被禁用", "Public sharing is disabled at the workspace level": "公开分享在工作区级别被禁用",
"Prevent pages in this space from being shared publicly.": "阻止此空间中的页面被公开分享。", "Prevent pages in this space from being shared publicly.": "阻止此空间中的页面被公开分享。",
"Requires an enterprise license": "需要企业许可证",
"Page permissions": "页面权限},{", "Page permissions": "页面权限},{",
"Control who can view and edit individual pages. Available with an enterprise license.": "控制谁可以查看和编辑单个页面。此功能在企业版许可下可用。", "Control who can view and edit individual pages. Available with an enterprise license.": "控制谁可以查看和编辑单个页面。此功能在企业版许可下可用。",
"Enable public sharing": "启用公开分享", "Enable public sharing": "启用公开分享",
@@ -453,103 +476,104 @@
"Copy page": "复制页面", "Copy page": "复制页面",
"Copy page to a different space.": "将页面复制到不同的空间。", "Copy page to a different space.": "将页面复制到不同的空间。",
"Page copied successfully": "页面复制成功", "Page copied successfully": "页面复制成功",
"Page duplicated successfully": "页面复制成功", "Page duplicated successfully": "页面副本创建成功",
"Find": "查找", "Find": "查找",
"Not found": "未找到", "Not found": "未找到",
"Previous Match (Shift+Enter)": "上一个匹配 (Shift+Enter)", "Previous Match (Shift+Enter)": "上一个匹配项(Shift+Enter",
"Next match (Enter)": "下一个匹配 (Enter)", "Next match (Enter)": "下一个匹配项(Enter",
"Match case (Alt+C)": "区分大小写 (Alt+C)", "Match case (Alt+C)": "区分大小写Alt+C",
"Replace": "替换", "Replace": "替换",
"Close (Escape)": "关闭 (Escape)", "Close (Escape)": "关闭Escape",
"Replace (Enter)": "替换 (Enter)", "Replace (Enter)": "替换Enter",
"Replace all (Ctrl+Alt+Enter)": "全部替换 (Ctrl+Alt+Enter)", "Replace all (Ctrl+Alt+Enter)": "全部替换Ctrl+Alt+Enter",
"Replace all": "全部替换", "Replace all": "全部替换",
"View all": "查看全部",
"View all spaces": "查看所有空间", "View all spaces": "查看所有空间",
"Error": "错误", "Error": "错误",
"Failed to disable MFA": "用 MFA 失败", "Failed to disable MFA": "用 MFA 失败",
"Disable two-factor authentication": "用双因素认证", "Disable two-factor authentication": "用双重身份验证",
"Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "停用双因素认证会降低账户安全性。您只需密码即可登录。", "Disabling two-factor authentication will make your account less secure. You'll only need your password to sign in.": "停用双因素认证会降低账户安全性。您只需密码即可登录。",
"Please enter your password to disable two-factor authentication:": "请输入您的密码以停用双因素认证:", "Please enter your password to disable two-factor authentication:": "请输入您的密码以停用双因素认证:",
"Two-factor authentication has been enabled": "双因素认证已启用", "Two-factor authentication has been enabled": "双重身份验证已启用",
"Two-factor authentication has been disabled": "双因素认证已用", "Two-factor authentication has been disabled": "双重身份验证已用",
"2-step verification": "两步验证", "2-step verification": "两步验证",
"Protect your account with an additional verification layer when signing in.": "通过额外的验证层保护您的账户安全。", "Protect your account with an additional verification layer when signing in.": "通过额外的验证层保护您的账户安全。",
"Two-factor authentication is active on your account.": "您的账户已激活双因素认证。", "Two-factor authentication is active on your account.": "您的账户已激活双因素认证。",
"Add 2FA method": "添加 2FA 方", "Add 2FA method": "添加 2FA 方",
"Backup codes": "备代码", "Backup codes": "备代码",
"Disable": "用", "Disable": "用",
"Invalid verification code": "无效的验证码", "Invalid verification code": "无效的验证码",
"New backup codes have been generated": "已生成新的备代码", "New backup codes have been generated": "新的备代码已生成",
"Failed to regenerate backup codes": "重新生成备代码失败", "Failed to regenerate backup codes": "重新生成备代码失败",
"About backup codes": "关于备代码", "About backup codes": "关于备代码",
"Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "如果您无法访问身份验证器应用,可使用备份代码访问账户。每个代码仅可使用一次。", "Backup codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "如果您无法访问身份验证器应用,可使用备份代码访问账户。每个代码仅可使用一次。",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "您可以随时重新生成新的备份代码。这将使所有现有代码失效。", "You can regenerate new backup codes at any time. This will invalidate all existing codes.": "您可以随时重新生成新的备份代码。这将使所有现有代码失效。",
"Confirm password": "确认密码", "Confirm password": "确认密码",
"Generate new backup codes": "生成新的备代码", "Generate new backup codes": "生成新的备代码",
"Save your new backup codes": "保存您的新备代码", "Save your new backup codes": "保存您的新备代码",
"Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "请确保将这些代码保存在安全的地方。您的旧备份代码不再有效。", "Make sure to save these codes in a secure place. Your old backup codes are no longer valid.": "请确保将这些代码保存在安全的地方。您的旧备份代码不再有效。",
"Your new backup codes": "您的新备代码", "Your new backup codes": "您的新备代码",
"I've saved my backup codes": "我已保存了我的备份代码", "I've saved my backup codes": "我已保存备用代码",
"Failed to setup MFA": "设置 MFA 失败", "Failed to setup MFA": "设置 MFA 失败",
"Setup & Verify": "设置并验证", "Setup & Verify": "设置并验证",
"Add to authenticator": "添加到身份验证器", "Add to authenticator": "添加到身份验证器",
"1. Scan this QR code with your authenticator app": "1. 身份验证器应用扫描此二维码", "1. Scan this QR code with your authenticator app": "1. 使用您的身份验证器应用扫描此二维码",
"Can't scan the code?": "无法扫描代码?", "Can't scan the code?": "无法扫描代码?",
"Enter this code manually in your authenticator app:": "在您的身份验证器应用中手动输入此代码:", "Enter this code manually in your authenticator app:": "在您的身份验证器应用中手动输入此代码:",
"2. Enter the 6-digit code from your authenticator": "2. 输入来自身份验证器的6位代码", "2. Enter the 6-digit code from your authenticator": "2. 输入您的身份验证器中的 6 位代码",
"Verify and enable": "验证并启用", "Verify and enable": "验证并启用",
"Failed to generate QR code. Please try again.": "生成二维码失败。请重试。", "Failed to generate QR code. Please try again.": "生成二维码失败。请重试。",
"Backup": "备", "Backup": "备",
"Save codes": "保存代码", "Save codes": "保存代码",
"Save your backup codes": "保存您的备代码", "Save your backup codes": "保存您的备代码",
"These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "如果无法访问身份验证器应用,可以使用这些代码访问账户。每个代码仅可使用一次。", "These codes can be used to access your account if you lose access to your authenticator app. Each code can only be used once.": "如果无法访问身份验证器应用,可以使用这些代码访问账户。每个代码仅可使用一次。",
"Print": "打印", "Print": "打印",
"Two-factor authentication has been set up. Please log in again.": "双因素认证已设置。请重新登录。", "Two-factor authentication has been set up. Please log in again.": "双因素认证已设置。请重新登录。",
"Two-Factor authentication required": "需要双因素认证", "Two-Factor authentication required": "需要双重身份验证",
"Your workspace requires two-factor authentication for all users": "您的工作区要求所有用户启用双因素认证", "Your workspace requires two-factor authentication for all users": "您的工作区要求所有用户启用双重身份验证",
"To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "要继续访问工作区,必须设置双因素认证。此操作为您的账户添加一层额外的安全保障。", "To continue accessing your workspace, you must set up two-factor authentication. This adds an extra layer of security to your account.": "要继续访问工作区,必须设置双因素认证。此操作为您的账户添加一层额外的安全保障。",
"Set up two-factor authentication": "设置双因素认证", "Set up two-factor authentication": "设置双重身份验证",
"Cancel and logout": "取消并退出登录", "Cancel and logout": "取消并退出登录",
"Your workspace requires two-factor authentication. Please set it up to continue.": "您的工作区需要双因素认证。请设置以继续。", "Your workspace requires two-factor authentication. Please set it up to continue.": "您的工作区需要双因素认证。请设置以继续。",
"This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "通过要求您的身份验证器应用提供验证码,此操作为您的账户增加了一层额外的安全保障。", "This adds an extra layer of security to your account by requiring a verification code from your authenticator app.": "通过要求您的身份验证器应用提供验证码,此操作为您的账户增加了一层额外的安全保障。",
"Password is required": "需要密码", "Password is required": "密码为必填项",
"Password must be at least 8 characters": "密码必须至少包含8个字符", "Password must be at least 8 characters": "密码长度至少为 8 个字符",
"Please enter a 6-digit code": "请输入 6 位代码", "Please enter a 6-digit code": "请输入 6 位代码",
"Code must be exactly 6 digits": "代码必须正好是6位", "Code must be exactly 6 digits": "代码必须正好为 6 位",
"Enter the 6-digit code found in your authenticator app": "输入在您的身份验证器应用中找到的6位代码", "Enter the 6-digit code found in your authenticator app": "输入身份验证器应用中的 6 位代码",
"Need help authenticating?": "需要帮助进行身份验证吗?", "Need help authenticating?": "需要帮助进行身份验证吗?",
"MFA QR Code": "MFA 二维码", "MFA QR Code": "MFA 二维码",
"Account created successfully. Please log in to set up two-factor authentication.": "账户创建成功。请登录以设置双因素认证。", "Account created successfully. Please log in to set up two-factor authentication.": "账户创建成功。请登录以设置双因素认证。",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "密码重置成功。请使用新密码登录并完成双因素认证。", "Password reset successful. Please log in with your new password and complete two-factor authentication.": "密码重置成功。请使用新密码登录并完成双因素认证。",
"Password reset successful. Please log in with your new password to set up two-factor authentication.": "密码重置成功。请使用新密码登录以设置双因素认证。", "Password reset successful. Please log in with your new password to set up two-factor authentication.": "密码重置成功。请使用新密码登录以设置双因素认证。",
"Password reset was successful. Please log in with your new password.": "密码重置成功。请使用新密码登录。", "Password reset was successful. Please log in with your new password.": "密码重置成功。请使用新密码登录。",
"Two-factor authentication": "双因素认证", "Two-factor authentication": "双重身份验证",
"Use authenticator app instead": "改用身份验证器应用", "Use authenticator app instead": "改用身份验证器应用",
"Verify backup code": "验证备代码", "Verify backup code": "验证备代码",
"Use backup code": "使用备代码", "Use backup code": "使用备代码",
"Enter one of your backup codes": "输入您的一个备代码", "Enter one of your backup codes": "输入您的一个备代码",
"Backup code": "备代码", "Backup code": "备代码",
"Enter one of your backup codes. Each backup code can only be used once.": "输入您的一个备份代码。每个备份代码只能使用一次。", "Enter one of your backup codes. Each backup code can only be used once.": "输入您的一个备份代码。每个备份代码只能使用一次。",
"Verify": "验证", "Verify": "验证",
"Trash": "垃圾箱", "Trash": "回收站",
"Pages in trash will be permanently deleted after {{count}} days.": "垃圾箱中的页面将在{{count}}天后被永久删除。", "Pages in trash will be permanently deleted after {{count}} days.": "垃圾箱中的页面将在{{count}}天后被永久删除。",
"Deleted": "已删除", "Deleted": "已删除",
"No pages in trash": "垃圾箱中没有页面", "No pages in trash": "回收站中没有页面",
"Permanently delete page?": "永久删除页面?", "Permanently delete page?": "永久删除页面?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "确定要永久删除“{{title}}”吗?此操作无法撤销。", "Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "确定要永久删除“{{title}}”吗?此操作无法撤销。",
"Restore '{{title}}' and its sub-pages?": "恢复“{{title}}”及其子页面?", "Restore '{{title}}' and its sub-pages?": "恢复“{{title}}”及其子页面?",
"Move to trash": "移至垃圾箱", "Move to trash": "移至回收站",
"Move this page to trash?": "将此页面移至垃圾箱?", "Move this page to trash?": "将此页面移至垃圾箱?",
"Restore page": "恢复页面", "Restore page": "恢复页面",
"Page moved to trash": "页面已移至垃圾箱", "Page moved to trash": "页面已移至回收站",
"Page restored successfully": "页面恢复成功", "Page restored successfully": "页面恢复成功",
"Deleted by": "删除", "Deleted by": "删除",
"Deleted at": "删除时间", "Deleted at": "删除",
"Preview": "预览", "Preview": "预览",
"Subpages": "子页面", "Subpages": "子页面",
"Failed to load subpages": "加载子页面失败", "Failed to load subpages": "加载子页面失败",
"No subpages": "没有子页面", "No subpages": "没有子页面",
"Subpages (Child pages)": "子页面(页面)", "Subpages (Child pages)": "子页面(下级页面)",
"List all subpages of the current page": "列出当前页面的所有子页面", "List all subpages of the current page": "列出当前页面的所有子页面",
"Attachments": "附件", "Attachments": "附件",
"All spaces": "所有空间", "All spaces": "所有空间",
@@ -557,21 +581,21 @@
"Find a space": "查找空间", "Find a space": "查找空间",
"Search in all your spaces": "在您的所有空间中搜索", "Search in all your spaces": "在您的所有空间中搜索",
"Type": "类型", "Type": "类型",
"Enterprise": "企业", "Enterprise": "企业",
"Download attachment": "下载附件", "Download attachment": "下载附件",
"Allowed email domains": "允许的电子邮件域", "Allowed email domains": "允许的邮箱域名",
"Only users with email addresses from these domains can signup via SSO.": "只有来自这些域的电子邮件地址的用户才能通过SSO注册。", "Only users with email addresses from these domains can signup via SSO.": "只有使用这些域名邮箱地址的用户才能通过 SSO 注册。",
"Enter valid domain names separated by comma or space": "输入用逗号或空格分隔的有效域名", "Enter valid domain names separated by comma or space": "输入有效的域名,并用逗号或空格分隔",
"Enforce two-factor authentication": "强制实施双因素认证", "Enforce two-factor authentication": "强制启用双重身份验证",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "一旦实施,所有成员必须启用双因素认证才能访问工作区。", "Once enforced, all members must enable two-factor authentication to access the workspace.": "一旦实施,所有成员必须启用双因素认证才能访问工作区。",
"Toggle MFA enforcement": "切换多因素认证实施", "Toggle MFA enforcement": "切换 MFA 强制执行",
"Display name": "显示名称", "Display name": "显示名称",
"Allow signup": "允许注册", "Allow signup": "允许注册",
"Enabled": "已启用", "Enabled": "已启用",
"Advanced Settings": "高级设置", "Advanced Settings": "高级设置",
"Enable TLS/SSL": "启用 TLS/SSL", "Enable TLS/SSL": "启用 TLS/SSL",
"Use secure connection to LDAP server": "使用安全连接LDAP服务器", "Use secure connection to LDAP server": "使用安全连接访问 LDAP 服务器",
"Group sync": "组同步", "Group sync": "组同步",
"No SSO providers found.": "未找到SSO提供商。", "No SSO providers found.": "未找到SSO提供商。",
"Delete SSO provider": "删除 SSO 提供商", "Delete SSO provider": "删除 SSO 提供商",
"Are you sure you want to delete this SSO provider?": "您确定要删除此SSO提供商吗?", "Are you sure you want to delete this SSO provider?": "您确定要删除此SSO提供商吗?",
@@ -613,6 +637,7 @@
"AI Answer": "AI回答", "AI Answer": "AI回答",
"Ask AI": "询问AI", "Ask AI": "询问AI",
"AI is thinking...": "AI正在思考...", "AI is thinking...": "AI正在思考...",
"Thinking": "思考中",
"Ask a question...": "提问...", "Ask a question...": "提问...",
"AI Answers": "AI答案", "AI Answers": "AI答案",
"AI-powered search (AI Answers)": "AI驱动的搜索 (AI答案)", "AI-powered search (AI Answers)": "AI驱动的搜索 (AI答案)",
@@ -621,7 +646,9 @@
"Generative AI (Ask AI)": "生成型AI (询问AI)", "Generative AI (Ask AI)": "生成型AI (询问AI)",
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "在编辑器中启用AI驱动的内容生成。允许用户生成、改进、翻译和转换文本。", "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "在编辑器中启用AI驱动的内容生成。允许用户生成、改进、翻译和转换文本。",
"Toggle generative AI": "切换生成型AI", "Toggle generative AI": "切换生成型AI",
"Enterprise feature": "企业版功能", "Upgrade your plan": "升级您的方案",
"Available with a paid license": "需付费许可才可用",
"Upgrade your license tier.": "升级您的许可等级。",
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI 仅在 Docmost 企业版中提供。请联系 sales@docmost.com。", "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI 仅在 Docmost 企业版中提供。请联系 sales@docmost.com。",
"AI & MCP": "AI 与 MCP", "AI & MCP": "AI 与 MCP",
"AI": "AI", "AI": "AI",
@@ -629,17 +656,15 @@
"Model Context Protocol (MCP)": "模型上下文协议(MCP", "Model Context Protocol (MCP)": "模型上下文协议(MCP",
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "启用 MCP 服务器以允许 AI 助手和工具与您的工作区内容交互。", "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "启用 MCP 服务器以允许 AI 助手和工具与您的工作区内容交互。",
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP 仅在 Docmost 企业版中提供。请联系 sales@docmost.com。", "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP 仅在 Docmost 企业版中提供。请联系 sales@docmost.com。",
"MCP documentation": "MCP 文档",
"MCP Server URL": "MCP 服务器 URL", "MCP Server URL": "MCP 服务器 URL",
"Use your API key for authentication. You can manage API keys in your account settings.": "使用您的 API 密钥进行身份验证。您可以在账户设置中管理 API 密钥。", "Use your API key for authentication. You can manage API keys in your account settings.": "使用您的 API 密钥进行身份验证。您可以在账户设置中管理 API 密钥。",
"Supported tools": "支持的工具", "Supported tools": "支持的工具",
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "您的工作区已启用 MCP。使用您的 API 密钥连接 AI 助手。", "Your workspace has MCP enabled. Use your API key to connect AI assistants.": "您的工作区已启用 MCP。使用您的 API 密钥连接 AI 助手。",
"MCP server URL:": "MCP 服务器 URL", "MCP server URL:": "MCP 服务器 URL",
"Learn more": "了解更多", "Learn more": "了解更多",
"View the": "查看", "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "为工作区内所有用户管理 API 密钥。有关使用详情,请查阅<anchor>API 文档</anchor>。",
"for usage details.": "以获取使用详情。", "View the <anchor>API documentation</anchor> for usage details.": "有关使用详情,请查阅<anchor>API 文档</anchor>。",
"for setup instructions.": "以获取设置说明。", "View the <anchor>MCP documentation</anchor>.": "查看<anchor>MCP 文档</anchor>。",
"API documentation": "API 文档",
"Sources": "来源", "Sources": "来源",
"AI Answers not available for attachments": "AI答案不适用于附件", "AI Answers not available for attachments": "AI答案不适用于附件",
"No answer available": "无可用答案", "No answer available": "无可用答案",
@@ -654,12 +679,34 @@
"Mark all as read": "标记所有为已读", "Mark all as read": "标记所有为已读",
"Mark as read": "标记为已读", "Mark as read": "标记为已读",
"More options": "更多选项", "More options": "更多选项",
"mentioned you in a comment": "在评论中提到你", "<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold>在评论中提到你",
"commented on a page": "在页面上评论", "<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold>在页面上评论",
"resolved a comment": "解决了一评论", "<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> 解决了一评论",
"mentioned you on a page": "页面提到", "<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> 在某个页面提到了您",
"gave you edit access to a page": "已授予你编辑该页面的权限", "<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> 授予您某个页面的编辑权限",
"gave you view access to a page": "已授予你查看该页面的权限", "<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> 授予您某个页面的查看权限",
"<bold>{{name}}</bold> updated a page": "<bold>{{name}}</bold> 更新了某个页面",
"Watch page": "关注页面",
"Stop watching": "取消关注",
"Watch space": "关注空间",
"Stop watching space": "取消关注空间",
"Email notifications": "邮件通知",
"Page updates": "页面更新",
"Get notified when pages you watch are updated.": "当你关注的页面有更新时收到通知。",
"Page mentions": "页面提及",
"Get notified when someone mentions you on a page.": "当有人在页面上提到你时收到通知。",
"Comment mentions": "评论提及",
"Get notified when someone mentions you in a comment.": "当有人在评论中提到你时收到通知。",
"New comments": "新评论",
"Get notified about new comments on threads you participate in.": "当你参与的讨论有新评论时收到通知。",
"Resolved comments": "已解决的评论",
"Get notified when your comment is resolved.": "当你的评论被解决时收到通知。",
"You are now watching this page": "你现在正在关注此页面",
"You are no longer watching this page": "你已取消关注此页面",
"You are now watching this space": "您现在正在关注此空间",
"You are no longer watching this space": "您已不再关注此空间",
"Direct": "直接",
"Updates": "更新",
"Today": "今天", "Today": "今天",
"Yesterday": "昨天", "Yesterday": "昨天",
"This week": "本周", "This week": "本周",
@@ -693,5 +740,145 @@
"Failed to update trash retention": "更新垃圾箱保留期失败", "Failed to update trash retention": "更新垃圾箱保留期失败",
"Removed page restriction": "已移除页面限制", "Removed page restriction": "已移除页面限制",
"Added page permission": "已添加页面权限", "Added page permission": "已添加页面权限",
"Removed page permission": "已移除页面权限" "Removed page permission": "已移除页面权限",
"day": "天",
"days": "天",
"week": "周",
"weeks": "周",
"month": "个月",
"months": "个月",
"year": "年",
"years": "年",
"Period": "周期",
"Fixed date": "固定日期",
"Indefinitely": "无限期",
"Days": "天",
"Weeks": "周",
"Months": "个月",
"Years": "年",
"Pick a date": "选择日期",
"Maximum is {{max}} {{unit}} for this unit": "此单位的最大值为 {{max}} {{unit}}",
"Never expires. Verifiers can re-verify at any time.": "永不过期。验证者可随时重新验证。",
"Verified": "已验证",
"Review needed": "需要审核",
"Verification expired": "验证已过期",
"Draft": "草稿",
"In Approval": "审批中",
"In approval": "审批中",
"Approved": "已批准",
"Obsolete": "已作废",
"Expiring": "即将过期",
"Set up verification": "设置验证",
"Verify page": "验证页面",
"Page verification": "页面验证",
"Add verification": "添加验证",
"Edit verification": "编辑验证",
"Search by title": "按标题搜索",
"Choose how this page should stay accurate.": "选择此页面保持准确的方式。",
"Recurring verification": "定期验证",
"Verifiers re-confirm this page on a schedule.": "验证者按计划重新确认此页面。",
"Re-verify on a schedule (e.g every 30 days )": "按计划重新验证(例如每 30 天一次)",
"Page stays editable at all times": "页面始终可编辑",
"Best for runbooks, FAQs, living documentation": "最适合运行手册、常见问题和动态文档",
"Approval workflow": "审批工作流",
"Formal document lifecycle with named approvers.": "具有指定审批人的正式文档生命周期。",
"Draft → In approval → Approved → Obsolete": "草稿 → 审批中 → 已批准 → 已作废",
"Locked once approved, with full history": "批准后锁定,并保留完整历史记录",
"Designed for ISO 9001, ISO 13485, and FDA": "专为 ISO 9001、ISO 13485 和 FDA 设计",
"Best for SOPs and controlled documents": "最适合 SOP 和受控文档",
"Back": "返回",
"Quality management": "质量管理",
"Recurring": "定期",
"Pages move through draft, approval, and approved stages.": "页面会经历草稿、审批中和已批准阶段。",
"Verifiers": "验证者",
"Add verifier": "添加验证者",
"I've reviewed this page for accuracy": "我已审核此页面的准确性",
"Set up": "设置",
"Remove verification": "移除验证",
"Are you sure you want to remove verification from this page?": "确定要移除此页面的验证吗?",
"Assigned verifiers must periodically re-verify this page.": "指定的验证者必须定期重新验证此页面。",
"Last verified by {{name}} {{time}} (expired)": "最后由 {{name}} 于 {{time}} 验证(已过期)",
"The fixed expiration date has passed.": "固定到期日已过。",
"Verified by {{name}} {{time}}": "由 {{name}} 于 {{time}} 验证",
"Expires {{date}}": "于 {{date}} 到期",
"Expired {{date}}": "已于 {{date}} 过期",
"Mark as obsolete": "标记为作废",
"Mark obsolete": "标记作废",
"Returned by {{name}} {{time}}": "由 {{name}} 于 {{time}} 退回",
"No approval has been requested yet.": "尚未请求审批。",
"Submitted by {{name}} {{time}}": "由 {{name}} 于 {{time}} 提交",
"Someone": "某人",
"Approved by {{name}} {{time}}": "由 {{name}} 于 {{time}} 批准",
"This document has been marked as obsolete.": "此文档已被标记为作废。",
"Rejection comment": "退回意见",
"Reason for returning this document...": "退回此文档的原因...",
"Confirm rejection": "确认退回",
"Submit for approval": "提交审批",
"Reject": "退回",
"Approve": "批准",
"Re-submit for approval": "重新提交审批",
"Verified until": "验证有效期至",
"QMS": "QMS",
"Verified pages": "已验证页面",
"Search pages...": "搜索页面...",
"Filter by space": "按空间筛选",
"Filter by type": "按类型筛选",
"<bold>{{name}}</bold> verified a page": "<bold>{{name}}</bold> 验证了一个页面",
"<bold>{{name}}</bold> submitted a page for your approval": "<bold>{{name}}</bold> 提交了一个页面供您审批",
"<bold>{{name}}</bold> returned a page for revision": "<bold>{{name}}</bold> 退回了一个页面以供修改",
"Page verification expires soon": "页面验证即将过期",
"Page verification has expired": "页面验证已过期",
"Verifying your email": "正在验证您的邮箱",
"Please wait...": "请稍候……",
"Verification failed. The link may have expired.": "验证失败。该链接可能已过期。",
"Check your email": "检查您的邮箱",
"We sent a verification link to {{email}}.": "我们已向{{email}}发送了一封验证邮件。",
"We sent a verification link to your email.": "我们已向您的邮箱发送了一封验证邮件。",
"Click the link to verify your email and access your workspace.": "请点击链接以验证邮箱并访问您的工作区。",
"Resend verification email": "重新发送验证邮件",
"Verification email sent. Please check your inbox.": "验证邮件已发送。请检查您的收件箱。",
"Failed to resend verification email. Please try again.": "重新发送验证邮件失败。请重试。",
"We've sent you an email with your associated workspaces.": "我们已向您发送包含关联工作区的邮件。",
"Load more": "加载更多",
"Log out of all devices": "退出所有设备登录",
"Log out of all sessions except this device": "退出除当前设备外的所有会话",
"This Device": "此设备",
"Unknown device": "未知设备",
"No active sessions": "没有活动会话",
"Session revoked": "会话已撤销",
"All other sessions revoked": "所有其他会话已撤销",
"Last used": "上次使用",
"Created": "创建时间",
"Rename": "重命名",
"Publish": "发布",
"Security": "安全",
"Enforce SSO": "强制使用 SSO",
"Once enforced, members will not be able to login with email and password.": "启用后,成员将无法使用邮箱和密码登录。",
"AI-generated content may not be accurate.": "AI 生成的内容可能并不准确。",
"AI Chat": "AI 聊天",
"Analyze for insights": "分析并获取洞察",
"Ask anything...": "随便问点什么...",
"Chat history": "聊天记录",
"Chat name": "聊天名称",
"Close": "关闭",
"Docmost AI": "Docmost AI",
"Failed to load chat. An error occurred.": "加载聊天失败。发生错误。",
"Failed to render this message.": "渲染此消息失败。",
"How can I help you today?": "今天我可以如何帮助您?",
"New chat": "新聊天",
"No chat history": "没有聊天记录",
"No chats found": "未找到聊天",
"No conversations yet": "暂无对话",
"Open full page": "打开完整页面",
"Previous 7 days": "前 7 天",
"Previous 30 days": "前 30 天",
"Search chats...": "搜索聊天...",
"Start a new chat to see it here.": "开始新的聊天后会显示在这里。",
"Summarize this page": "总结此页面",
"Toggle AI Chat": "切换 AI 聊天",
"Translate this page": "翻译此页面",
"Try a different search term.": "请尝试其他搜索词。",
"Try again": "重试",
"Untitled chat": "未命名聊天",
"What can I help you with?": "我能帮您做什么?"
} }
+16
View File
@@ -26,6 +26,7 @@ import Security from "@/ee/security/pages/security.tsx";
import License from "@/ee/licence/pages/license.tsx"; import License from "@/ee/licence/pages/license.tsx";
import { useRedirectToCloudSelect } from "@/ee/hooks/use-redirect-to-cloud-select.tsx"; import { useRedirectToCloudSelect } from "@/ee/hooks/use-redirect-to-cloud-select.tsx";
import SharedPage from "@/pages/share/shared-page.tsx"; import SharedPage from "@/pages/share/shared-page.tsx";
import PdfRenderPage from "@/ee/pdf-export/pdf-render-page.tsx";
import Shares from "@/pages/settings/shares/shares.tsx"; import Shares from "@/pages/settings/shares/shares.tsx";
import ShareLayout from "@/features/share/components/share-layout.tsx"; import ShareLayout from "@/features/share/components/share-layout.tsx";
import ShareRedirect from "@/pages/share/share-redirect.tsx"; import ShareRedirect from "@/pages/share/share-redirect.tsx";
@@ -38,6 +39,11 @@ import UserApiKeys from "@/ee/api-key/pages/user-api-keys";
import WorkspaceApiKeys from "@/ee/api-key/pages/workspace-api-keys"; import WorkspaceApiKeys from "@/ee/api-key/pages/workspace-api-keys";
import AiSettings from "@/ee/ai/pages/ai-settings.tsx"; import AiSettings from "@/ee/ai/pages/ai-settings.tsx";
import AuditLogs from "@/ee/audit/pages/audit-logs.tsx"; import AuditLogs from "@/ee/audit/pages/audit-logs.tsx";
import VerifiedPages from "@/ee/page-verification/pages/verified-pages.tsx";
import TemplateList from "@/ee/template/pages/template-list";
import TemplateEditor from "@/ee/template/pages/template-editor";
import FavoritesPage from "@/pages/favorites/favorites-page";
import AiChat from "@/ee/ai-chat/pages/ai-chat.tsx";
import VerifyEmail from "@/ee/pages/verify-email.tsx"; import VerifyEmail from "@/ee/pages/verify-email.tsx";
export default function App() { export default function App() {
@@ -76,12 +82,21 @@ export default function App() {
<Route path={"/share/p/:pageSlug"} element={<SharedPage />} /> <Route path={"/share/p/:pageSlug"} element={<SharedPage />} />
</Route> </Route>
<Route path={"/pdf-render/:pageId"} element={<PdfRenderPage />} />
<Route path={"/share/:shareId"} element={<ShareRedirect />} /> <Route path={"/share/:shareId"} element={<ShareRedirect />} />
<Route path={"/p/:pageSlug"} element={<PageRedirect />} /> <Route path={"/p/:pageSlug"} element={<PageRedirect />} />
<Route element={<Layout />}> <Route element={<Layout />}>
<Route path={"/home"} element={<Home />} /> <Route path={"/home"} element={<Home />} />
<Route path={"/ai"} element={<AiChat />} />
<Route path={"/ai/chat/:chatId"} element={<AiChat />} />
<Route path={"/spaces"} element={<SpacesPage />} /> <Route path={"/spaces"} element={<SpacesPage />} />
<Route path={"/favorites"} element={<FavoritesPage />} />
<Route path={"/templates"} element={<TemplateList />} />
<Route
path={"/templates/:templateId"}
element={<TemplateEditor />}
/>
<Route path={"/s/:spaceSlug"} element={<SpaceHome />} /> <Route path={"/s/:spaceSlug"} element={<SpaceHome />} />
<Route path={"/s/:spaceSlug/trash"} element={<SpaceTrash />} /> <Route path={"/s/:spaceSlug/trash"} element={<SpaceTrash />} />
<Route <Route
@@ -107,6 +122,7 @@ export default function App() {
<Route path={"ai"} element={<AiSettings />} /> <Route path={"ai"} element={<AiSettings />} />
<Route path={"ai/mcp"} element={<AiSettings />} /> <Route path={"ai/mcp"} element={<AiSettings />} />
<Route path={"audit"} element={<AuditLogs />} /> <Route path={"audit"} element={<AuditLogs />} />
<Route path={"verifications"} element={<VerifiedPages />} />
{!isCloud() && <Route path={"license"} element={<License />} />} {!isCloud() && <Route path={"license"} element={<License />} />}
{isCloud() && <Route path={"billing"} element={<Billing />} />} {isCloud() && <Route path={"billing"} element={<Billing />} />}
</Route> </Route>
@@ -80,6 +80,12 @@ export default function AvatarUploader({
} }
}; };
const ariaLabel = {
[AvatarIconType.AVATAR]: t("Change avatar"),
[AvatarIconType.SPACE_ICON]: t("Change space icon"),
[AvatarIconType.WORKSPACE_ICON]: t("Change workspace icon"),
}[type];
const handleRemove = async () => { const handleRemove = async () => {
if (disabled) return; if (disabled) return;
@@ -104,6 +110,8 @@ export default function AvatarUploader({
ref={fileInputRef} ref={fileInputRef}
onChange={handleFileInputChange} onChange={handleFileInputChange}
accept="image/png,image/jpeg,image/jpg" accept="image/png,image/jpeg,image/jpg"
aria-label={ariaLabel}
tabIndex={-1}
style={{ display: "none" }} style={{ display: "none" }}
/> />
@@ -115,6 +123,8 @@ export default function AvatarUploader({
size={size} size={size}
avatarUrl={currentImageUrl} avatarUrl={currentImageUrl}
name={fallbackName} name={fallbackName}
aria-label={ariaLabel}
aria-haspopup="menu"
style={{ style={{
cursor: disabled || isLoading ? "default" : "pointer", cursor: disabled || isLoading ? "default" : "pointer",
opacity: isLoading ? 0.6 : 1, opacity: isLoading ? 0.6 : 1,
+6 -2
View File
@@ -1,4 +1,4 @@
import { ActionIcon, Tooltip } from "@mantine/core"; import { ActionIcon, MantineColor, MantineSize, Tooltip } from "@mantine/core";
import { CopyButton } from "@/components/common/copy-button"; import { CopyButton } from "@/components/common/copy-button";
import { IconCheck, IconCopy } from "@tabler/icons-react"; import { IconCheck, IconCopy } from "@tabler/icons-react";
import React from "react"; import React from "react";
@@ -6,8 +6,10 @@ import { useTranslation } from "react-i18next";
interface CopyProps { interface CopyProps {
text: string; text: string;
size?: MantineSize;
color?: MantineColor;
} }
export default function CopyTextButton({ text }: CopyProps) { export default function CopyTextButton({ text, size }: CopyProps) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@@ -22,6 +24,8 @@ export default function CopyTextButton({ text }: CopyProps) {
color={copied ? "teal" : "gray"} color={copied ? "teal" : "gray"}
variant="subtle" variant="subtle"
onClick={copy} onClick={copy}
size={size}
aria-label={copied ? t("Copied") : t("Copy")}
> >
{copied ? <IconCheck size={16} /> : <IconCopy size={16} />} {copied ? <IconCheck size={16} /> : <IconCopy size={16} />}
</ActionIcon> </ActionIcon>
@@ -4,7 +4,8 @@ import {
UnstyledButton, UnstyledButton,
Badge, Badge,
Table, Table,
ActionIcon, ThemeIcon,
Button,
} from "@mantine/core"; } from "@mantine/core";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import PageListSkeleton from "@/components/ui/page-list-skeleton.tsx"; import PageListSkeleton from "@/components/ui/page-list-skeleton.tsx";
@@ -23,7 +24,8 @@ interface Props {
export default function RecentChanges({ spaceId }: Props) { export default function RecentChanges({ spaceId }: Props) {
const { t } = useTranslation(); const { t } = useTranslation();
const { data: pages, isLoading, isError } = useRecentChangesQuery(spaceId); const { data, isLoading, isError, hasNextPage, fetchNextPage, isFetchingNextPage } = useRecentChangesQuery(spaceId);
const pages = data?.pages.flatMap((p) => p.items) ?? [];
if (isLoading) { if (isLoading) {
return <PageListSkeleton />; return <PageListSkeleton />;
@@ -33,11 +35,12 @@ export default function RecentChanges({ spaceId }: Props) {
return <Text>{t("Failed to fetch recent pages")}</Text>; return <Text>{t("Failed to fetch recent pages")}</Text>;
} }
return pages && pages.items.length > 0 ? ( return pages.length > 0 ? (
<>
<Table.ScrollContainer minWidth={500}> <Table.ScrollContainer minWidth={500}>
<Table highlightOnHover verticalSpacing="sm"> <Table highlightOnHover verticalSpacing="sm">
<Table.Tbody> <Table.Tbody>
{pages.items.map((page) => ( {pages.map((page) => (
<Table.Tr key={page.id}> <Table.Tr key={page.id}>
<Table.Td> <Table.Td>
<UnstyledButton <UnstyledButton
@@ -46,9 +49,9 @@ export default function RecentChanges({ spaceId }: Props) {
> >
<Group wrap="nowrap"> <Group wrap="nowrap">
{page.icon || ( {page.icon || (
<ActionIcon variant="transparent" color="gray" size={18}> <ThemeIcon variant="transparent" color="gray" size={18}>
<IconFileDescription size={18} /> <IconFileDescription size={18} />
</ActionIcon> </ThemeIcon>
)} )}
<Text fw={500} size="md" lineClamp={1}> <Text fw={500} size="md" lineClamp={1}>
@@ -85,6 +88,19 @@ export default function RecentChanges({ spaceId }: Props) {
</Table.Tbody> </Table.Tbody>
</Table> </Table>
</Table.ScrollContainer> </Table.ScrollContainer>
{hasNextPage && (
<Button
variant="subtle"
fullWidth
mt="sm"
mb="xl"
onClick={() => fetchNextPage()}
loading={isFetchingNextPage}
>
{t("Load more")}
</Button>
)}
</>
) : ( ) : (
<EmptyState <EmptyState
icon={IconFiles} icon={IconFiles}
@@ -6,12 +6,14 @@ import { useTranslation } from "react-i18next";
export interface SearchInputProps { export interface SearchInputProps {
placeholder?: string; placeholder?: string;
ariaLabel?: string;
debounceDelay?: number; debounceDelay?: number;
onSearch: (value: string) => void; onSearch: (value: string) => void;
} }
export function SearchInput({ export function SearchInput({
placeholder, placeholder,
ariaLabel,
debounceDelay = 500, debounceDelay = 500,
onSearch, onSearch,
}: SearchInputProps) { }: SearchInputProps) {
@@ -28,6 +30,7 @@ export function SearchInput({
<TextInput <TextInput
size="sm" size="sm"
placeholder={placeholder || t("Search...")} placeholder={placeholder || t("Search...")}
aria-label={ariaLabel || placeholder || t("Search")}
leftSection={<IconSearch size={16} />} leftSection={<IconSearch size={16} />}
value={value} value={value}
onChange={(e) => setValue(e.currentTarget.value)} onChange={(e) => setValue(e.currentTarget.value)}
@@ -1,11 +1,11 @@
import { ActionIcon, rem } from "@mantine/core"; import { ThemeIcon } from "@mantine/core";
import React from "react"; import React from "react";
import { IconUsersGroup } from "@tabler/icons-react"; import { IconUsersGroup } from "@tabler/icons-react";
export function IconGroupCircle() { export function IconGroupCircle() {
return ( return (
<ActionIcon variant="light" size="lg" color="gray" radius="xl"> <ThemeIcon variant="light" size="lg" color="gray" radius="xl">
<IconUsersGroup stroke={1.5} /> <IconUsersGroup stroke={1.5} />
</ActionIcon> </ThemeIcon>
); );
} }
@@ -7,6 +7,19 @@
padding-right: var(--mantine-spacing-md); padding-right: var(--mantine-spacing-md);
} }
.brand {
display: flex;
align-items: center;
text-decoration: none;
color: inherit;
cursor: pointer;
}
.brandIcon {
display: flex;
align-items: center;
}
.link { .link {
display: block; display: block;
line-height: 1; line-height: 1;
@@ -16,6 +29,9 @@
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
font-size: var(--mantine-font-size-sm); font-size: var(--mantine-font-size-sm);
font-weight: 500; font-weight: 500;
user-select: none;
white-space: nowrap;
flex-shrink: 0;
@mixin hover { @mixin hover {
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
@@ -1,8 +1,18 @@
import { Badge, Group, Text, Tooltip } from "@mantine/core"; import {
ActionIcon,
Badge,
Box,
Group,
Text,
Tooltip,
UnstyledButton,
} from "@mantine/core";
import classes from "./app-header.module.css"; import classes from "./app-header.module.css";
import React from "react"; import React from "react";
import TopMenu from "@/components/layouts/global/top-menu.tsx"; import TopMenu from "@/components/layouts/global/top-menu.tsx";
import { Link } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import { IconSparkles } from "@tabler/icons-react";
import useToggleAside from "@/hooks/use-toggle-aside.tsx";
import APP_ROUTE from "@/lib/app-route.ts"; import APP_ROUTE from "@/lib/app-route.ts";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { import {
@@ -23,8 +33,11 @@ import {
shareSearchSpotlight, shareSearchSpotlight,
} from "@/features/search/constants.ts"; } from "@/features/search/constants.ts";
import { NotificationPopover } from "@/features/notification/components/notification-popover.tsx"; import { NotificationPopover } from "@/features/notification/components/notification-popover.tsx";
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
const links = [{ link: APP_ROUTE.HOME, label: "Home" }]; const links = [
{ link: APP_ROUTE.HOME, label: "Home" },
];
export function AppHeader() { export function AppHeader() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -34,10 +47,12 @@ export function AppHeader() {
const [desktopOpened] = useAtom(desktopSidebarAtom); const [desktopOpened] = useAtom(desktopSidebarAtom);
const toggleDesktop = useToggleSidebar(desktopSidebarAtom); const toggleDesktop = useToggleSidebar(desktopSidebarAtom);
const { isTrial, trialDaysLeft } = useTrial(); const { isTrial, trialDaysLeft } = useTrial();
const location = useLocation();
const toggleAside = useToggleAside();
const [workspace] = useAtom(workspaceAtom);
const aiChatEnabled = workspace?.settings?.ai?.chat === true;
const isHomeRoute = location.pathname.startsWith("/home"); const isPageRoute = location.pathname.includes("/p/");
const isSpacesRoute = location.pathname === "/spaces";
const hideSidebar = isHomeRoute || isSpacesRoute;
const items = links.map((link) => ( const items = links.map((link) => (
<Link key={link.label} to={link.link} className={classes.link}> <Link key={link.label} to={link.link} className={classes.link}>
@@ -49,8 +64,6 @@ export function AppHeader() {
<> <>
<Group h="100%" px="md" justify="space-between" wrap={"nowrap"}> <Group h="100%" px="md" justify="space-between" wrap={"nowrap"}>
<Group wrap="nowrap"> <Group wrap="nowrap">
{!hideSidebar && (
<>
<Tooltip label={t("Sidebar toggle")}> <Tooltip label={t("Sidebar toggle")}>
<SidebarToggle <SidebarToggle
aria-label={t("Sidebar toggle")} aria-label={t("Sidebar toggle")}
@@ -70,18 +83,25 @@ export function AppHeader() {
size="sm" size="sm"
/> />
</Tooltip> </Tooltip>
</>
)}
<Link to="/home" className={classes.brand} aria-label="Docmost">
<Box hiddenFrom="sm" className={classes.brandIcon}>
<img
src="/icons/favicon-32x32.png"
alt="Docmost"
width={22}
height={22}
/>
</Box>
<Text <Text
size="lg" size="lg"
fw={600} fw={600}
style={{ cursor: "pointer", userSelect: "none" }} style={{ userSelect: "none" }}
component={Link} visibleFrom="sm"
to="/home"
> >
Docmost Docmost
</Text> </Text>
</Link>
<Group ml={50} gap={5} className={classes.links} visibleFrom="sm"> <Group ml={50} gap={5} className={classes.links} visibleFrom="sm">
{items} {items}
@@ -98,6 +118,49 @@ export function AppHeader() {
</div> </div>
<Group px={"xl"} wrap="nowrap"> <Group px={"xl"} wrap="nowrap">
{aiChatEnabled && (
<>
<UnstyledButton
component={Link}
to="/ai"
className={classes.link}
visibleFrom="sm"
onClick={(e: React.MouseEvent) => {
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
return;
}
if (isPageRoute) {
e.preventDefault();
toggleAside("chat");
}
}}
>
{t("AI Chat")}
</UnstyledButton>
<Tooltip label={t("AI Chat")} openDelay={250} withArrow>
<ActionIcon
component={Link}
to="/ai"
variant="subtle"
color="dark"
size="sm"
hiddenFrom="sm"
aria-label={t("AI Chat")}
onClick={(e: React.MouseEvent) => {
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
return;
}
if (isPageRoute) {
e.preventDefault();
toggleAside("chat");
}
}}
>
<IconSparkles size={20} stroke={2} />
</ActionIcon>
</Tooltip>
</>
)}
<NotificationPopover /> <NotificationPopover />
{isCloud() && isTrial && trialDaysLeft !== 0 && ( {isCloud() && isTrial && trialDaysLeft !== 0 && (
<Badge <Badge
@@ -28,4 +28,22 @@
} }
} }
.skipLink {
position: fixed;
left: 8px;
top: 8px;
padding: 8px 12px;
background: var(--mantine-color-blue-6);
color: #fff;
border-radius: 4px;
text-decoration: none;
z-index: 1000;
transform: translateY(-150%);
&:focus {
transform: translateY(0);
outline: 2px solid var(--mantine-color-blue-3);
}
}
@@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next";
import { TableOfContents } from "@/features/editor/components/table-of-contents/table-of-contents.tsx"; import { TableOfContents } from "@/features/editor/components/table-of-contents/table-of-contents.tsx";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { pageEditorAtom } from "@/features/editor/atoms/editor-atoms.ts"; import { pageEditorAtom } from "@/features/editor/atoms/editor-atoms.ts";
import AsideChatPanel from "@/ee/ai-chat/components/aside-chat-panel";
export default function Aside() { export default function Aside() {
const [{ tab }] = useAtom(asideStateAtom); const [{ tab }] = useAtom(asideStateAtom);
@@ -25,6 +26,10 @@ export default function Aside() {
component = <TableOfContents editor={pageEditor} />; component = <TableOfContents editor={pageEditor} />;
title = "Table of contents"; title = "Table of contents";
break; break;
case "chat":
component = <AsideChatPanel />;
title = "AI Chat";
break;
default: default:
component = null; component = null;
title = null; title = null;
@@ -34,12 +39,14 @@ export default function Aside() {
<Box p="md" style={{ height: "100%", display: "flex", flexDirection: "column" }}> <Box p="md" style={{ height: "100%", display: "flex", flexDirection: "column" }}>
{component && ( {component && (
<> <>
{tab !== "chat" && (
<Text mb="md" fw={500}> <Text mb="md" fw={500}>
{t(title)} {t(title)}
</Text> </Text>
)}
{tab === "comments" ? ( {tab === "comments" || tab === "chat" ? (
<CommentListWithTabs /> component
) : ( ) : (
<ScrollArea <ScrollArea
style={{ height: "85vh" }} style={{ height: "85vh" }}
@@ -1,6 +1,7 @@
import { AppShell, Container } from "@mantine/core"; import { AppShell, Container } from "@mantine/core";
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { useTranslation } from "react-i18next";
import SettingsSidebar from "@/components/settings/settings-sidebar.tsx"; import SettingsSidebar from "@/components/settings/settings-sidebar.tsx";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { import {
@@ -10,22 +11,25 @@ import {
sidebarWidthAtom, sidebarWidthAtom,
} from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts"; } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
import { SpaceSidebar } from "@/features/space/components/sidebar/space-sidebar.tsx"; import { SpaceSidebar } from "@/features/space/components/sidebar/space-sidebar.tsx";
import AiChatSidebar from "@/ee/ai-chat/components/ai-chat-sidebar.tsx";
import { AppHeader } from "@/components/layouts/global/app-header.tsx"; import { AppHeader } from "@/components/layouts/global/app-header.tsx";
import Aside from "@/components/layouts/global/aside.tsx"; import Aside from "@/components/layouts/global/aside.tsx";
import classes from "./app-shell.module.css"; import classes from "./app-shell.module.css";
import { useTrialEndAction } from "@/ee/hooks/use-trial-end-action.tsx"; import { useTrialEndAction } from "@/ee/hooks/use-trial-end-action.tsx";
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts"; import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
import GlobalSidebar from "@/components/layouts/global/global-sidebar.tsx";
export default function GlobalAppShell({ export default function GlobalAppShell({
children, children,
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const { t } = useTranslation();
useTrialEndAction(); useTrialEndAction();
const [mobileOpened] = useAtom(mobileSidebarAtom); const [mobileOpened] = useAtom(mobileSidebarAtom);
const toggleMobile = useToggleSidebar(mobileSidebarAtom); const toggleMobile = useToggleSidebar(mobileSidebarAtom);
const [desktopOpened] = useAtom(desktopSidebarAtom); const [desktopOpened] = useAtom(desktopSidebarAtom);
const [{ isAsideOpen }] = useAtom(asideStateAtom); const [{ isAsideOpen, tab: asideTab }] = useAtom(asideStateAtom);
const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom); const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom);
const [isResizing, setIsResizing] = useState(false); const [isResizing, setIsResizing] = useState(false);
const sidebarRef = useRef(null); const sidebarRef = useRef(null);
@@ -72,24 +76,25 @@ export default function GlobalAppShell({
const location = useLocation(); const location = useLocation();
const isSettingsRoute = location.pathname.startsWith("/settings"); const isSettingsRoute = location.pathname.startsWith("/settings");
const isSpaceRoute = location.pathname.startsWith("/s/"); const isSpaceRoute = location.pathname.startsWith("/s/");
const isHomeRoute = location.pathname.startsWith("/home"); const isAiRoute = location.pathname.startsWith("/ai");
const isSpacesRoute = location.pathname === "/spaces";
const isPageRoute = location.pathname.includes("/p/"); const isPageRoute = location.pathname.includes("/p/");
const hideSidebar = isHomeRoute || isSpacesRoute; const showGlobalSidebar = !isSpaceRoute && !isSettingsRoute && !isAiRoute;
return ( return (
<>
<a href="#main-content" className={classes.skipLink}>
{t("Skip to main content")}
</a>
<AppShell <AppShell
header={{ height: 45 }} header={{ height: 45 }}
navbar={ navbar={{
!hideSidebar && {
width: isSpaceRoute ? sidebarWidth : 300, width: isSpaceRoute ? sidebarWidth : 300,
breakpoint: "sm", breakpoint: "sm",
collapsed: { collapsed: {
mobile: !mobileOpened, mobile: !mobileOpened,
desktop: !desktopOpened, desktop: !desktopOpened,
}, },
} }}
}
aside={ aside={
isPageRoute && { isPageRoute && {
width: 350, width: 350,
@@ -102,30 +107,57 @@ export default function GlobalAppShell({
<AppShell.Header px="md" className={classes.header}> <AppShell.Header px="md" className={classes.header}>
<AppHeader /> <AppHeader />
</AppShell.Header> </AppShell.Header>
{!hideSidebar && (
<AppShell.Navbar <AppShell.Navbar
className={classes.navbar} className={classes.navbar}
withBorder={false} withBorder={false}
ref={sidebarRef} ref={sidebarRef}
aria-label={
isSpaceRoute
? t("Space navigation")
: isSettingsRoute
? t("Settings navigation")
: isAiRoute
? t("AI navigation")
: t("Main navigation")
}
> >
{isSpaceRoute && (
<div className={classes.resizeHandle} onMouseDown={startResizing} /> <div className={classes.resizeHandle} onMouseDown={startResizing} />
)}
{isSpaceRoute && <SpaceSidebar />} {isSpaceRoute && <SpaceSidebar />}
{isSettingsRoute && <SettingsSidebar />} {isSettingsRoute && <SettingsSidebar />}
{isAiRoute && <AiChatSidebar />}
{showGlobalSidebar && <GlobalSidebar />}
</AppShell.Navbar> </AppShell.Navbar>
)} <AppShell.Main id="main-content">
<AppShell.Main>
{isSettingsRoute ? ( {isSettingsRoute ? (
<Container size={850}>{children}</Container> <Container size={900} pb={80}>
{children}
</Container>
) : ( ) : (
children children
)} )}
</AppShell.Main> </AppShell.Main>
{isPageRoute && ( {isPageRoute && (
<AppShell.Aside className={classes.aside} p="md" withBorder={false}> <AppShell.Aside
className={classes.aside}
p="md"
withBorder={false}
aria-label={
asideTab === "comments"
? t("Comments")
: asideTab === "toc"
? t("Table of contents")
: asideTab === "chat"
? t("AI Chat")
: undefined
}
>
<Aside /> <Aside />
</AppShell.Aside> </AppShell.Aside>
)} )}
</AppShell> </AppShell>
</>
); );
} }
@@ -0,0 +1,89 @@
.navbar {
height: 100%;
width: 100%;
padding: var(--mantine-spacing-md);
display: flex;
flex-direction: column;
}
.section {
padding-bottom: var(--mantine-spacing-xs);
}
.link {
cursor: pointer;
display: flex;
align-items: center;
text-decoration: none;
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
padding-left: var(--mantine-spacing-xs);
min-height: 30px;
border-radius: var(--mantine-radius-sm);
font-weight: 500;
user-select: none;
@mixin hover {
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-6)
);
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
}
&[data-active] {
&,
& :hover {
background-color: light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
}
}
}
.linkIcon {
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
margin-right: var(--mantine-spacing-sm);
width: rem(16px);
height: rem(16px);
}
.sectionHeader {
padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
font-size: var(--mantine-font-size-xs);
color: var(--mantine-color-dimmed);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.spacer {
flex: 1;
}
.bottomSection {
padding-top: var(--mantine-spacing-xs);
border-top: rem(1px) solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
}
.spaceItem {
cursor: pointer;
display: flex;
align-items: center;
gap: var(--mantine-spacing-sm);
text-decoration: none;
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
padding-left: var(--mantine-spacing-xs);
min-height: 30px;
border-radius: var(--mantine-radius-sm);
font-weight: 500;
user-select: none;
@mixin hover {
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-6)
);
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
}
}
@@ -0,0 +1,154 @@
import { useEffect, useState } from "react";
import { ScrollArea, Text, Divider, Modal, UnstyledButton } from "@mantine/core";
import {
IconHome,
IconClock,
IconStar,
IconLayoutGrid,
IconSettings,
IconUserPlus,
} from "@tabler/icons-react";
import { Link, useLocation } from "react-router-dom";
import classes from "./global-sidebar.module.css";
import { useTranslation } from "react-i18next";
import { useAtom } from "jotai";
import { mobileSidebarAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom";
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar";
import { useFavoritesQuery } from "@/features/favorite/queries/favorite-query";
import { getSpaceUrl } from "@/lib/config";
import { useDisclosure } from "@mantine/hooks";
import { WorkspaceInviteForm } from "@/features/workspace/components/members/components/workspace-invite-form";
import { CustomAvatar } from "@/components/ui/custom-avatar";
import { AvatarIconType } from "@/features/attachments/types/attachment.types";
const mainNavItems = [
{ label: "Home", icon: IconHome, path: "/home" },
{ label: "Favorites", icon: IconStar, path: "/favorites" },
{ label: "Spaces", icon: IconLayoutGrid, path: "/spaces" },
];
export default function GlobalSidebar() {
const { t } = useTranslation();
const location = useLocation();
const [active, setActive] = useState(location.pathname);
const [mobileSidebarOpened] = useAtom(mobileSidebarAtom);
const toggleMobileSidebar = useToggleSidebar(mobileSidebarAtom);
const { data: favoriteSpacesData, isPending: isFavoritesPending } = useFavoritesQuery("space");
const favoriteSpaces = favoriteSpacesData?.pages.flatMap((p) => p.items) ?? [];
const sortedFavoriteSpaces = [...favoriteSpaces]
.filter((fav) => fav.space)
.sort((a, b) => {
const cmp = (a.space!.name ?? "").localeCompare(b.space!.name ?? "", undefined, { sensitivity: "base" });
return cmp !== 0 ? cmp : a.id.localeCompare(b.id);
});
const [inviteOpened, { open: openInvite, close: closeInvite }] =
useDisclosure(false);
useEffect(() => {
setActive(location.pathname);
}, [location.pathname]);
const handleNavClick = () => {
if (mobileSidebarOpened) {
toggleMobileSidebar();
}
};
return (
<div className={classes.navbar}>
<ScrollArea w="100%" style={{ flex: 1 }}>
<div className={classes.section}>
{mainNavItems.map((item) => (
<Link
key={item.label}
className={classes.link}
data-active={active === item.path || undefined}
to={item.path}
onClick={handleNavClick}
>
<item.icon className={classes.linkIcon} stroke={2} />
<span>{t(item.label)}</span>
</Link>
))}
</div>
<Divider my="xs" />
<div className={classes.section}>
<Text className={classes.sectionHeader}>{t("Favorite spaces")}</Text>
{!isFavoritesPending && sortedFavoriteSpaces.length === 0 ? (
<Text size="xs" c="dimmed" pl="xs" py={4}>
{t("Favorite spaces appear here")}
</Text>
) : (
<>
{sortedFavoriteSpaces.slice(0, 10).map((fav) => (
<Link
key={fav.id}
className={classes.spaceItem}
to={getSpaceUrl(fav.space!.slug)}
onClick={handleNavClick}
>
<CustomAvatar
name={fav.space!.name}
avatarUrl={fav.space!.logo}
type={AvatarIconType.SPACE_ICON}
color="initials"
variant="filled"
size={20}
/>
<Text size="sm" fw={500} lineClamp={1}>
{fav.space!.name}
</Text>
</Link>
))}
{sortedFavoriteSpaces.length > 10 && (
<Link
className={classes.spaceItem}
to="/spaces"
onClick={handleNavClick}
>
<Text size="xs" c="dimmed">
{t("View all")}
</Text>
</Link>
)}
</>
)}
</div>
</ScrollArea>
<div className={classes.bottomSection}>
<UnstyledButton
className={classes.link}
onClick={openInvite}
>
<IconUserPlus className={classes.linkIcon} stroke={2} />
<span>{t("Invite People")}</span>
</UnstyledButton>
<Link
className={classes.link}
data-active={active.startsWith("/settings") || undefined}
to="/settings/account/profile"
onClick={handleNavClick}
>
<IconSettings className={classes.linkIcon} stroke={2} />
<span>{t("Settings")}</span>
</Link>
</div>
<Modal
size="550"
opened={inviteOpened}
onClose={closeInvite}
title={t("Invite new members")}
centered
>
<Divider size="xs" mb="xs" />
<ScrollArea h="80%">
<WorkspaceInviteForm onClose={closeInvite} />
</ScrollArea>
</Modal>
</div>
);
}
@@ -29,7 +29,7 @@ export default function AppVersion() {
> >
<Indicator <Indicator
label={t("New update")} label={t("New update")}
color="gray" color="dark"
inline inline
size={16} size={16}
position="middle-end" position="middle-end"
@@ -12,6 +12,8 @@ import { getSsoProviders } from "@/ee/security/services/security-service.ts";
import { getShares } from "@/features/share/services/share-service.ts"; import { getShares } from "@/features/share/services/share-service.ts";
import { getApiKeys } from "@/ee/api-key"; import { getApiKeys } from "@/ee/api-key";
import { getAuditLogs } from "@/ee/audit/services/audit-service"; import { getAuditLogs } from "@/ee/audit/services/audit-service";
import { getVerificationList } from "@/ee/page-verification/services/page-verification-service";
import { getScimTokens } from "@/ee/scim/services/scim-token-service";
export const prefetchWorkspaceMembers = () => { export const prefetchWorkspaceMembers = () => {
const params: QueryParams = { limit: 100, query: "" }; const params: QueryParams = { limit: 100, query: "" };
@@ -89,3 +91,18 @@ export const prefetchAuditLogs = () => {
queryFn: () => getAuditLogs(params), queryFn: () => getAuditLogs(params),
}); });
}; };
export const prefetchVerifiedPages = () => {
const params = { limit: 50 };
queryClient.prefetchQuery({
queryKey: ["verification-list", params],
queryFn: () => getVerificationList(params),
});
};
export const prefetchScimTokens = () => {
queryClient.prefetchQuery({
queryKey: ["scim-token-list", { cursor: undefined }],
queryFn: () => getScimTokens({}),
});
};
@@ -14,6 +14,7 @@ import {
IconWorld, IconWorld,
IconSparkles, IconSparkles,
IconHistory, IconHistory,
IconShieldCheck,
} from "@tabler/icons-react"; } from "@tabler/icons-react";
import { Link, useLocation } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import classes from "./settings.module.css"; import classes from "./settings.module.css";
@@ -30,11 +31,13 @@ import {
prefetchBilling, prefetchBilling,
prefetchGroups, prefetchGroups,
prefetchLicense, prefetchLicense,
prefetchScimTokens,
prefetchShares, prefetchShares,
prefetchSpaces, prefetchSpaces,
prefetchSsoProviders, prefetchSsoProviders,
prefetchWorkspaceMembers, prefetchWorkspaceMembers,
prefetchAuditLogs, prefetchAuditLogs,
prefetchVerifiedPages,
} from "@/components/settings/settings-queries.tsx"; } from "@/components/settings/settings-queries.tsx";
import AppVersion from "@/components/settings/app-version.tsx"; import AppVersion from "@/components/settings/app-version.tsx";
import { mobileSidebarAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts"; import { mobileSidebarAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
@@ -95,6 +98,12 @@ const groupedData: DataGroup[] = [
{ label: "Groups", icon: IconUsersGroup, path: "/settings/groups" }, { label: "Groups", icon: IconUsersGroup, path: "/settings/groups" },
{ label: "Spaces", icon: IconSpaces, path: "/settings/spaces" }, { label: "Spaces", icon: IconSpaces, path: "/settings/spaces" },
{ label: "Public sharing", icon: IconWorld, path: "/settings/sharing" }, { label: "Public sharing", icon: IconWorld, path: "/settings/sharing" },
{
label: "Verified pages",
icon: IconShieldCheck,
path: "/settings/verifications",
feature: Feature.PAGE_VERIFICATION,
},
{ {
label: "API management", label: "API management",
icon: IconKey, icon: IconKey,
@@ -196,7 +205,10 @@ export default function SettingsSidebar() {
} }
break; break;
case "Security & SSO": case "Security & SSO":
prefetchHandler = prefetchSsoProviders; prefetchHandler = () => {
prefetchSsoProviders();
prefetchScimTokens();
};
break; break;
case "Public sharing": case "Public sharing":
prefetchHandler = prefetchShares; prefetchHandler = prefetchShares;
@@ -210,37 +222,14 @@ export default function SettingsSidebar() {
case "Audit log": case "Audit log":
prefetchHandler = prefetchAuditLogs; prefetchHandler = prefetchAuditLogs;
break; break;
case "Verified pages":
prefetchHandler = prefetchVerifiedPages;
break;
default: default:
break; break;
} }
const isDisabled = isItemDisabled(item); const isDisabled = isItemDisabled(item);
const linkElement = (
<Link
onMouseEnter={!isDisabled ? prefetchHandler : undefined}
className={classes.link}
data-active={active.startsWith(item.path) || undefined}
data-disabled={isDisabled || undefined}
key={item.label}
to={isDisabled ? "#" : item.path}
onClick={(e) => {
if (isDisabled) {
e.preventDefault();
return;
}
if (mobileSidebarOpened) {
toggleMobileSidebar();
}
}}
style={{
opacity: isDisabled ? 0.5 : 1,
cursor: isDisabled ? "not-allowed" : "pointer",
}}
>
<item.icon className={classes.linkIcon} stroke={2} />
<span>{t(item.label)}</span>
</Link>
);
if (isDisabled) { if (isDisabled) {
return ( return (
@@ -250,12 +239,41 @@ export default function SettingsSidebar() {
position="right" position="right"
withArrow withArrow
> >
{linkElement} <span
className={classes.link}
data-disabled
role="link"
aria-disabled="true"
tabIndex={0}
style={{
opacity: 0.5,
cursor: "not-allowed",
}}
>
<item.icon className={classes.linkIcon} stroke={2} />
<span>{t(item.label)}</span>
</span>
</Tooltip> </Tooltip>
); );
} }
return linkElement; return (
<Link
onMouseEnter={prefetchHandler}
className={classes.link}
data-active={active.startsWith(item.path) || undefined}
key={item.label}
to={item.path}
onClick={() => {
if (mobileSidebarOpened) {
toggleMobileSidebar();
}
}}
>
<item.icon className={classes.linkIcon} stroke={2} />
<span>{t(item.label)}</span>
</Link>
);
})} })}
</div> </div>
); );
@@ -273,7 +291,7 @@ export default function SettingsSidebar() {
}} }}
variant="transparent" variant="transparent"
c="gray" c="gray"
aria-label="Back" aria-label={t("Back")}
> >
<IconArrowLeft stroke={2} /> <IconArrowLeft stroke={2} />
</ActionIcon> </ActionIcon>
@@ -0,0 +1,68 @@
.root {
position: relative;
}
.track {
display: flex;
gap: var(--mantine-spacing-md);
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
scrollbar-width: none;
-ms-overflow-style: none;
padding: 2px;
margin: -2px;
}
.track::-webkit-scrollbar {
display: none;
}
.track > * {
scroll-snap-align: start;
flex: 0 0 auto;
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
cursor: pointer;
padding: 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
opacity: 0;
pointer-events: none;
transition: opacity 120ms ease, background-color 120ms ease, transform 120ms ease;
z-index: 2;
}
.root:hover .arrow.visible,
.arrow.visible:focus-visible {
opacity: 1;
pointer-events: auto;
}
.arrow:hover {
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5));
}
.arrow:active {
transform: translateY(-50%) scale(0.95);
}
.arrowLeft {
left: -14px;
}
.arrowRight {
right: -14px;
}
@@ -0,0 +1,77 @@
import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import classes from "./card-carousel.module.css";
type Props = {
children: ReactNode;
ariaLabel?: string;
};
export default function CardCarousel({ children, ariaLabel }: Props) {
const { t } = useTranslation();
const trackRef = useRef<HTMLDivElement>(null);
const [canScrollLeft, setCanScrollLeft] = useState(false);
const [canScrollRight, setCanScrollRight] = useState(false);
const updateScrollState = useCallback(() => {
const el = trackRef.current;
if (!el) return;
const maxScroll = el.scrollWidth - el.clientWidth;
setCanScrollLeft(el.scrollLeft > 1);
setCanScrollRight(el.scrollLeft < maxScroll - 1);
}, []);
useEffect(() => {
updateScrollState();
const el = trackRef.current;
if (!el) return;
const observer = new ResizeObserver(updateScrollState);
observer.observe(el);
for (const child of Array.from(el.children)) {
observer.observe(child);
}
return () => observer.disconnect();
}, [updateScrollState, children]);
const scrollBy = (direction: 1 | -1) => {
const el = trackRef.current;
if (!el) return;
el.scrollBy({ left: direction * el.clientWidth * 0.85, behavior: "smooth" });
};
return (
<div className={classes.root}>
<div
ref={trackRef}
className={classes.track}
onScroll={updateScrollState}
{...(ariaLabel ? { role: "region", "aria-label": ariaLabel } : {})}
>
{children}
</div>
<button
type="button"
className={`${classes.arrow} ${classes.arrowLeft} ${canScrollLeft ? classes.visible : ""}`}
onClick={() => scrollBy(-1)}
aria-label={t("Scroll left")}
tabIndex={canScrollLeft ? 0 : -1}
>
<IconChevronLeft size={18} />
</button>
<button
type="button"
className={`${classes.arrow} ${classes.arrowRight} ${canScrollRight ? classes.visible : ""}`}
onClick={() => scrollBy(1)}
aria-label={t("Scroll right")}
tabIndex={canScrollRight ? 0 : -1}
>
<IconChevronRight size={18} />
</button>
</div>
);
}
@@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { Avatar } from "@mantine/core"; import { Avatar, MantineColor } from "@mantine/core";
import { getAvatarUrl } from "@/lib/config.ts"; import { getAvatarUrl } from "@/lib/config.ts";
import { AvatarIconType } from "@/features/attachments/types/attachment.types.ts"; import { AvatarIconType } from "@/features/attachments/types/attachment.types.ts";
@@ -16,11 +16,39 @@ interface CustomAvatarProps {
mt?: string | number; mt?: string | number;
} }
// `color.shade` pairs whose filled background meets WCAG AA (4.5:1) against
// white text. Avoids lime/yellow/green/orange — even their dark shades have
// weak white-text contrast.
const SAFE_INITIALS_COLORS: MantineColor[] = [
"blue.8",
"cyan.9",
"grape.7",
"indigo.7",
"pink.8",
"red.8",
"violet.7",
];
function hashName(input: string) {
let hash = 0;
for (let i = 0; i < input.length; i += 1) {
hash = (hash << 5) - hash + input.charCodeAt(i);
hash |= 0;
}
return Math.abs(hash);
}
function pickInitialsColor(name: string) {
return SAFE_INITIALS_COLORS[hashName(name) % SAFE_INITIALS_COLORS.length];
}
export const CustomAvatar = React.forwardRef< export const CustomAvatar = React.forwardRef<
HTMLInputElement, HTMLInputElement,
CustomAvatarProps CustomAvatarProps
>(({ avatarUrl, name, type, ...props }: CustomAvatarProps, ref) => { >(({ avatarUrl, name, type, color, ...props }: CustomAvatarProps, ref) => {
const avatarLink = getAvatarUrl(avatarUrl, type); const avatarLink = getAvatarUrl(avatarUrl, type);
const resolvedColor =
!color || color === "initials" ? pickInitialsColor(name ?? "") : color;
return ( return (
<Avatar <Avatar
@@ -28,7 +56,7 @@ export const CustomAvatar = React.forwardRef<
src={avatarLink} src={avatarLink}
name={name} name={name}
alt={name} alt={name}
color="initials" color={resolvedColor}
{...props} {...props}
/> />
); );
@@ -0,0 +1,67 @@
import { useState, useEffect } from "react";
import { Modal, Button, Group } from "@mantine/core";
import { useTranslation } from "react-i18next";
import { DestinationPicker } from "./destination-picker";
import {
DestinationPickerModalProps,
DestinationSelection,
} from "./destination-picker.types";
export function DestinationPickerModal({
opened,
onClose,
title,
actionLabel,
onSelect,
loading,
excludePageId,
pageLimit,
}: DestinationPickerModalProps) {
const { t } = useTranslation();
const [selection, setSelection] = useState<DestinationSelection | null>(null);
useEffect(() => {
if (!opened) {
setSelection(null);
}
}, [opened]);
return (
<Modal.Root
opened={opened}
onClose={onClose}
size={550}
padding="lg"
yOffset="10vh"
onClick={(e) => e.stopPropagation()}
>
<Modal.Overlay />
<Modal.Content>
<Modal.Header py={0}>
<Modal.Title fw={500}>{title}</Modal.Title>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body>
<DestinationPicker
onSelectionChange={setSelection}
excludePageId={excludePageId}
pageLimit={pageLimit}
/>
<Group justify="flex-end" mt="md">
<Button variant="default" onClick={onClose}>
{t("Close")}
</Button>
<Button
onClick={() => selection && onSelect(selection)}
disabled={!selection}
loading={loading}
>
{actionLabel}
</Button>
</Group>
</Modal.Body>
</Modal.Content>
</Modal.Root>
);
}
@@ -0,0 +1,128 @@
.searchInput {
margin-bottom: var(--mantine-spacing-sm);
}
.scrollArea {
max-height: 50vh;
}
.row {
padding: 6px 12px;
border-radius: var(--mantine-radius-sm);
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: background-color 150ms ease;
user-select: none;
@mixin hover {
background-color: light-dark(
var(--mantine-color-gray-0),
var(--mantine-color-dark-6)
);
}
}
.selected {
background-color: light-dark(
var(--mantine-color-blue-0),
var(--mantine-color-dark-5)
);
border-left: 2px solid var(--mantine-primary-color-filled);
}
.spaceRow {
composes: row;
font-weight: 500;
}
.pageRow {
composes: row;
font-weight: 400;
}
.disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
.chevron {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--mantine-radius-sm);
flex-shrink: 0;
transition: transform 150ms ease;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
@mixin hover {
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-5)
);
}
}
.chevronExpanded {
transform: rotate(90deg);
}
.loadMore {
text-align: center;
padding: 6px;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
font-size: var(--mantine-font-size-sm);
cursor: pointer;
@mixin hover {
text-decoration: underline;
}
}
.selectedIndicator {
padding: 8px 12px;
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-4));
margin-top: var(--mantine-spacing-xs);
}
.emptyState {
padding: 12px;
text-align: center;
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
}
.searchResult {
composes: row;
}
.pageTitle {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: var(--mantine-font-size-sm);
}
.spaceName {
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
font-size: var(--mantine-font-size-xs);
flex-shrink: 0;
}
.iconWrapper {
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 16px;
line-height: 1;
}
@@ -0,0 +1,168 @@
import { useState, useCallback } from "react";
import { TextInput, ScrollArea, Loader } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { IconSearch, IconFile } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import { useGetSpacesQuery } from "@/features/space/queries/space-query";
import { useSearchSuggestionsQuery } from "@/features/search/queries/search-query";
import { ISpace } from "@/features/space/types/space.types";
import { IPage } from "@/features/page/types/page.types";
import { DestinationSelection } from "./destination-picker.types";
import { SpaceRow } from "./space-row";
import classes from "./destination-picker.module.css";
type DestinationPickerProps = {
onSelectionChange: (selection: DestinationSelection | null) => void;
excludePageId?: string;
pageLimit?: number;
};
export function DestinationPicker({
onSelectionChange,
excludePageId,
pageLimit = 15,
}: DestinationPickerProps) {
const { t } = useTranslation();
const [searchQuery, setSearchQuery] = useState("");
const [selection, setSelection] = useState<DestinationSelection | null>(null);
const [debouncedQuery] = useDebouncedValue(searchQuery, 300);
const { data: spacesData, isLoading: spacesLoading } = useGetSpacesQuery({
limit: 100,
});
const searchEnabled = debouncedQuery && debouncedQuery.length >= 2;
const { data: searchData, isLoading: searchLoading } =
useSearchSuggestionsQuery({
query: searchEnabled ? debouncedQuery : "",
includePages: true,
limit: 20,
});
const isSearching = !!searchEnabled;
const selectedId =
selection?.type === "space" ? selection.spaceId : selection?.pageId ?? null;
const updateSelection = useCallback(
(next: DestinationSelection | null) => {
setSelection(next);
onSelectionChange(next);
},
[onSelectionChange],
);
const handleSearchResultClick = (page: Partial<IPage>) => {
if (!page.space || !page.id) return;
updateSelection({
type: "page",
spaceId: page.space.id,
pageId: page.id,
page,
space: page.space,
});
setSearchQuery("");
};
const handleSelectSpace = useCallback(
(space: ISpace) => {
updateSelection({ type: "space", spaceId: space.id, space });
},
[updateSelection],
);
const handleSelectPage = useCallback(
(page: Partial<IPage>, space: ISpace) => {
if (!page.id) return;
updateSelection({
type: "page",
spaceId: page.spaceId ?? space.id,
pageId: page.id,
page,
space,
});
},
[updateSelection],
);
return (
<>
<TextInput
leftSection={<IconSearch size={16} />}
placeholder={t("Search pages and spaces...")}
variant="filled"
value={searchQuery}
onChange={(e) => setSearchQuery(e.currentTarget.value)}
className={classes.searchInput}
/>
<ScrollArea h="50vh" offsetScrollbars className={classes.scrollArea}>
{isSearching ? (
searchLoading ? (
<div className={classes.emptyState}>
<Loader size="xs" />
</div>
) : searchData?.pages && searchData.pages.length > 0 ? (
searchData.pages.map(
(page) =>
page && (
<div
key={page.id}
className={classes.searchResult}
onClick={() => handleSearchResultClick(page)}
>
<div className={classes.iconWrapper}>
{page.icon ? (
page.icon
) : (
<IconFile
size={16}
color="var(--mantine-color-gray-5)"
/>
)}
</div>
<div className={classes.pageTitle}>
{page.title || t("Untitled")}
</div>
{page.space && (
<div className={classes.spaceName}>
{page.space.name}
</div>
)}
</div>
),
)
) : (
<div className={classes.emptyState}>{t("No results found")}</div>
)
) : spacesLoading ? (
<div className={classes.emptyState}>
<Loader size="xs" />
</div>
) : (
spacesData?.items?.map((space) => (
<SpaceRow
key={space.id}
space={space}
limit={pageLimit}
selectedId={selectedId}
excludePageId={excludePageId}
onSelectSpace={handleSelectSpace}
onSelectPage={handleSelectPage}
/>
))
)}
</ScrollArea>
{selection && (
<div className={classes.selectedIndicator}>
{selection.type === "space"
? selection.space.name
: `${selection.space.name} / ${selection.page.title || t("Untitled")}`}
</div>
)}
</>
);
}
@@ -0,0 +1,23 @@
import { ISpace } from "@/features/space/types/space.types";
import { IPage } from "@/features/page/types/page.types";
export type DestinationSelection =
| { type: "space"; spaceId: string; space: ISpace }
| {
type: "page";
spaceId: string;
pageId: string;
page: Partial<IPage>;
space: Partial<ISpace>;
};
export type DestinationPickerModalProps = {
opened: boolean;
onClose: () => void;
title: string;
actionLabel: string;
onSelect: (selection: DestinationSelection) => void | Promise<void>;
loading?: boolean;
excludePageId?: string;
pageLimit?: number;
};
@@ -0,0 +1,94 @@
import { useInfiniteQuery } from "@tanstack/react-query";
import { Loader } from "@mantine/core";
import { useTranslation } from "react-i18next";
import { getSidebarPages } from "@/features/page/services/page-service";
import { IPage } from "@/features/page/types/page.types";
import { IPagination } from "@/lib/types";
import { PageRow } from "./page-row";
import classes from "./destination-picker.module.css";
type PageChildrenProps = {
spaceId: string;
pageId?: string;
depth: number;
limit: number;
selectedId: string | null;
excludePageId?: string;
onSelectPage: (page: Partial<IPage>) => void;
};
export function PageChildren({
spaceId,
pageId,
depth,
limit,
selectedId,
excludePageId,
onSelectPage,
}: PageChildrenProps) {
const { t } = useTranslation();
const { data, isLoading, hasNextPage, fetchNextPage } = useInfiniteQuery({
queryKey: ["destination-pages", spaceId, pageId ?? "root"],
queryFn: ({ pageParam }) =>
getSidebarPages({
spaceId,
pageId,
limit,
cursor: pageParam,
}),
initialPageParam: undefined as string | undefined,
getNextPageParam: (lastPage: IPagination<IPage>) =>
lastPage.meta?.nextCursor ?? undefined,
});
const pages = data?.pages.flatMap((page) => page.items) ?? [];
if (isLoading) {
return (
<div className={classes.emptyState}>
<Loader size="xs" />
</div>
);
}
if (pages.length === 0) {
return (
<div className={classes.emptyState}>
{pageId ? t("No pages inside") : t("No pages in this space")}
</div>
);
}
return (
<>
{pages.map((page) => (
<PageRow
key={page.id}
page={page}
depth={depth}
limit={limit}
selectedId={selectedId}
excludePageId={excludePageId}
onSelect={onSelectPage}
/>
))}
{hasNextPage && (
<div
className={classes.loadMore}
onClick={() => fetchNextPage()}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
fetchNextPage();
}
}}
role="button"
tabIndex={0}
>
{t("Load more")}
</div>
)}
</>
);
}
@@ -0,0 +1,89 @@
import { useState } from "react";
import { IconChevronRight, IconFile } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import { IPage } from "@/features/page/types/page.types";
import { PageChildren } from "./page-children";
import classes from "./destination-picker.module.css";
type PageRowProps = {
page: Partial<IPage>;
depth: number;
limit: number;
selectedId: string | null;
excludePageId?: string;
onSelect: (page: Partial<IPage>) => void;
};
export function PageRow({
page,
depth,
limit,
selectedId,
excludePageId,
onSelect,
}: PageRowProps) {
const { t } = useTranslation();
const [expanded, setExpanded] = useState(false);
const isExcluded = page.id === excludePageId;
const isSelected = page.id === selectedId;
const rowClasses = [
classes.pageRow,
isSelected && classes.selected,
isExcluded && classes.disabled,
]
.filter(Boolean)
.join(" ");
return (
<>
<div
className={rowClasses}
style={{ paddingLeft: depth * 20 + 12 }}
onClick={() => !isExcluded && onSelect(page)}
>
{page.hasChildren ? (
<div
className={`${classes.chevron} ${expanded ? classes.chevronExpanded : ""}`}
onClick={(e) => {
e.stopPropagation();
setExpanded(!expanded);
}}
>
<IconChevronRight size={14} />
</div>
) : (
<div style={{ width: 20, flexShrink: 0 }} />
)}
<div className={classes.iconWrapper}>
{page.icon ? (
page.icon
) : (
<IconFile
size={16}
color="var(--mantine-color-gray-5)"
/>
)}
</div>
<div className={classes.pageTitle}>
{page.title || t("Untitled")}
</div>
</div>
{expanded && page.hasChildren && (
<PageChildren
spaceId={page.spaceId}
pageId={page.id}
depth={depth + 1}
limit={limit}
selectedId={selectedId}
excludePageId={excludePageId}
onSelectPage={onSelect}
/>
)}
</>
);
}
@@ -0,0 +1,108 @@
import { useState } from "react";
import { Tooltip } from "@mantine/core";
import { IconChevronRight, IconLock } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import { ISpace } from "@/features/space/types/space.types";
import { IPage } from "@/features/page/types/page.types";
import { SpaceRole } from "@/lib/types";
import { CustomAvatar } from "@/components/ui/custom-avatar";
import { AvatarIconType } from "@/features/attachments/types/attachment.types";
import { PageChildren } from "./page-children";
import classes from "./destination-picker.module.css";
type SpaceRowProps = {
space: ISpace;
limit: number;
selectedId: string | null;
excludePageId?: string;
onSelectSpace: (space: ISpace) => void;
onSelectPage: (page: Partial<IPage>, space: ISpace) => void;
};
export function SpaceRow({
space,
limit,
selectedId,
excludePageId,
onSelectSpace,
onSelectPage,
}: SpaceRowProps) {
const { t } = useTranslation();
const [expanded, setExpanded] = useState(false);
const writable =
!!space.membership?.role && space.membership.role !== SpaceRole.READER;
const isSelected = space.id === selectedId;
const rowClasses = [
classes.spaceRow,
isSelected && classes.selected,
!writable && classes.disabled,
]
.filter(Boolean)
.join(" ");
const rowContent = (
<div
className={rowClasses}
onClick={() => writable && onSelectSpace(space)}
>
{writable ? (
<div
className={`${classes.chevron} ${expanded ? classes.chevronExpanded : ""}`}
onClick={(e) => {
e.stopPropagation();
setExpanded(!expanded);
}}
>
<IconChevronRight size={14} />
</div>
) : (
<div style={{ width: 20, flexShrink: 0 }} />
)}
<CustomAvatar
name={space.name}
avatarUrl={space.logo}
type={AvatarIconType.SPACE_ICON}
size={22}
/>
<div className={classes.pageTitle}>{space.name}</div>
{!writable && (
<IconLock
size={14}
color="var(--mantine-color-gray-5)"
/>
)}
</div>
);
return (
<>
{writable ? (
rowContent
) : (
<Tooltip
label={t("You don't have permission to create pages here")}
position="right"
withArrow
>
<div>{rowContent}</div>
</Tooltip>
)}
{expanded && writable && (
<PageChildren
spaceId={space.id}
depth={1}
limit={limit}
selectedId={selectedId}
excludePageId={excludePageId}
onSelectPage={(page) => onSelectPage(page, space)}
/>
)}
</>
);
}
@@ -75,6 +75,9 @@ function EmojiPicker({
variant={actionIconProps?.variant || "transparent"} variant={actionIconProps?.variant || "transparent"}
size={actionIconProps?.size} size={actionIconProps?.size}
onClick={handlers.toggle} onClick={handlers.toggle}
aria-label={t("Pick emoji")}
aria-haspopup="dialog"
aria-expanded={opened}
> >
{icon} {icon}
</ActionIcon> </ActionIcon>
@@ -0,0 +1,105 @@
import { useEffect, useRef } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { useChatInfoQuery } from "../queries/ai-chat-query";
import { useChatStream } from "../hooks/use-chat-stream";
import ChatMessageList from "./chat-message-list";
import ChatEmptyState from "./chat-empty-state";
import ChatInput from "./chat-input";
import type { HomeAiPromptInitialState } from "@/features/home/components/home-ai-prompt";
import classes from "../styles/ai-chat.module.css";
export default function AiChatLayout() {
const { chatId } = useParams<{ chatId: string }>();
const location = useLocation();
const navigate = useNavigate();
const chatInfoQuery = useChatInfoQuery(chatId);
// If the URL points at a chat the user does not own, the info fetch 404s.
// Bounce them back to /ai so they cannot interact with any chat UI (including
// kicking off orphan uploads) tied to a chat they have no access to.
useEffect(() => {
if (chatId && chatInfoQuery.isError) {
navigate("/ai", { replace: true });
}
}, [chatId, chatInfoQuery.isError, navigate]);
const {
messages,
streamingContent,
streamingToolCalls,
isStreaming,
error,
sendMessage,
stopGeneration,
hydrateFromServer,
} = useChatStream(chatId);
const autoSentRef = useRef(false);
useEffect(() => {
if (chatInfoQuery.data?.messages) {
hydrateFromServer(chatInfoQuery.data.messages);
}
}, [chatInfoQuery.data, hydrateFromServer]);
useEffect(() => {
if (autoSentRef.current || chatId) return;
const state = location.state as HomeAiPromptInitialState | null;
if (!state?.initialContent && !state?.initialAttachments?.length) return;
autoSentRef.current = true;
sendMessage(
state.initialContent ?? "",
state.initialMentions ?? [],
state.initialAttachments ?? [],
);
navigate(location.pathname, { replace: true, state: null });
}, [chatId, location, navigate, sendMessage]);
const hasMessages = messages.length > 0 || isStreaming || !!chatId;
// While the redirect effect is running (or if the user is still on this
// component for any reason) never render the chat UI for a forbidden chat.
if (chatId && chatInfoQuery.isError) {
return null;
}
return (
<div className={classes.main}>
{hasMessages ? (
<>
<ChatMessageList
messages={messages}
isStreaming={isStreaming}
streamingContent={streamingContent}
streamingToolCalls={streamingToolCalls}
/>
{error && (
<div
style={{
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-lg)",
color: "var(--mantine-color-red-6)",
fontSize: "var(--mantine-font-size-sm)",
}}
>
{error}
</div>
)}
<div className={classes.inputArea}>
<ChatInput
isStreaming={isStreaming}
onSend={sendMessage}
onStop={stopGeneration}
chatId={chatId}
/>
</div>
</>
) : (
<ChatEmptyState
isStreaming={isStreaming}
onSend={sendMessage}
onStop={stopGeneration}
/>
)}
</div>
);
}
@@ -0,0 +1,167 @@
import { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { ActionIcon, Menu, TextInput } from "@mantine/core";
import { IconDots, IconTrash, IconEdit } from "@tabler/icons-react";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import type { AiChat } from "../types/ai-chat.types";
import classes from "../styles/chat-sidebar.module.css";
type Props = {
chat: AiChat;
isActive: boolean;
onDelete: (chatId: string, title: string | null) => void;
onRename: (chatId: string, title: string) => void;
};
function formatChatDate(
isoString: string | Date,
locale: string | undefined,
): string {
const date = new Date(isoString);
if (Number.isNaN(date.getTime())) return "";
const now = new Date();
const startOfToday = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
).getTime();
const ts = date.getTime();
const sameYear = date.getFullYear() === now.getFullYear();
if (ts >= startOfToday) {
return date.toLocaleTimeString(locale, {
hour: "numeric",
minute: "2-digit",
});
}
if (sameYear) {
return date.toLocaleDateString(locale, {
month: "short",
day: "numeric",
});
}
return date.toLocaleDateString(locale, {
month: "short",
day: "numeric",
year: "numeric",
});
}
export default function AiChatSidebarItem({
chat,
isActive,
onDelete,
onRename,
}: Props) {
const { t, i18n } = useTranslation();
const [renaming, setRenaming] = useState(false);
const [renameValue, setRenameValue] = useState("");
const inputRef = useRef<HTMLInputElement>(null);
const formattedDate = useMemo(
() => formatChatDate(chat.updatedAt, i18n.language),
[chat.updatedAt, i18n.language],
);
useEffect(() => {
if (renaming) {
// Wait for the input to be mounted before selecting.
const id = window.setTimeout(() => inputRef.current?.select(), 0);
return () => window.clearTimeout(id);
}
}, [renaming]);
const startRename = useCallback(() => {
setRenameValue(chat.title || "");
setRenaming(true);
}, [chat.title]);
const submitRename = useCallback(() => {
const trimmed = renameValue.trim();
if (trimmed && trimmed !== chat.title) {
onRename(chat.id, trimmed);
}
setRenaming(false);
}, [renameValue, chat.id, chat.title, onRename]);
if (renaming) {
return (
<div className={classes.chatItem} data-active={isActive || undefined}>
<TextInput
ref={inputRef}
size="xs"
variant="unstyled"
placeholder={t("Chat name")}
value={renameValue}
onChange={(e) => setRenameValue(e.currentTarget.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
submitRename();
} else if (e.key === "Escape") {
e.preventDefault();
setRenaming(false);
}
}}
onBlur={submitRename}
classNames={{ input: classes.chatItemRenameInput }}
style={{ flex: 1 }}
/>
</div>
);
}
return (
<Link
to={`/ai/chat/${chat.id}`}
className={classes.chatItem}
data-active={isActive || undefined}
>
<span className={classes.chatItemTitle}>
{chat.title || t("Untitled chat")}
</span>
<span className={classes.chatItemDate}>{formattedDate}</span>
<div className={classes.chatItemActions}>
<Menu position="bottom-end" withinPortal>
<Menu.Target>
<ActionIcon
variant="subtle"
size="xs"
color="gray"
onClick={(e) => e.preventDefault()}
aria-label={t("Chat menu")}
>
<IconDots size={14} />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item
leftSection={<IconEdit size={14} />}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
startRename();
}}
>
{t("Rename")}
</Menu.Item>
<Menu.Item
leftSection={<IconTrash size={14} />}
color="red"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onDelete(chat.id, chat.title);
}}
>
{t("Delete")}
</Menu.Item>
</Menu.Dropdown>
</Menu>
</div>
</Link>
);
}
@@ -0,0 +1,203 @@
import { useState, useCallback, useEffect, useMemo, useRef } from "react";
import { Link, useNavigate, useParams } from "react-router-dom";
import {
ActionIcon,
Center,
Text,
TextInput,
Loader,
Tooltip,
} from "@mantine/core";
import { modals } from "@mantine/modals";
import { useDebouncedValue } from "@mantine/hooks";
import { IconPlus, IconSearch, IconMessageCircle2 } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import {
useChatsQuery,
useDeleteChatMutation,
useUpdateChatTitleMutation,
useSearchChatsQuery,
} from "../queries/ai-chat-query";
import AiChatSidebarItem from "./ai-chat-sidebar-item";
import { groupChatsByAge } from "../utils/group-chats-by-age";
import classes from "../styles/chat-sidebar.module.css";
export default function AiChatSidebar() {
const { t } = useTranslation();
const navigate = useNavigate();
const { chatId } = useParams<{ chatId: string }>();
const [search, setSearch] = useState("");
const [debouncedSearch] = useDebouncedValue(search, 300);
const chatsQuery = useChatsQuery();
const searchQuery = useSearchChatsQuery(debouncedSearch);
const deleteMutation = useDeleteChatMutation();
const renameMutation = useUpdateChatTitleMutation();
const chats = useMemo(() => {
if (debouncedSearch) {
return searchQuery.data || [];
}
return chatsQuery.data?.pages.flatMap((p) => p.items) || [];
}, [debouncedSearch, searchQuery.data, chatsQuery.data]);
const groupedChats = useMemo(() => groupChatsByAge(chats, t), [chats, t]);
const sentinelRef = useRef<HTMLDivElement>(null);
const { hasNextPage, fetchNextPage, isFetchingNextPage } = chatsQuery;
const isSearching = Boolean(debouncedSearch);
useEffect(() => {
if (isSearching) return;
const sentinel = sentinelRef.current;
if (!sentinel) return;
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) {
fetchNextPage();
}
},
{ threshold: 0.1 },
);
observer.observe(sentinel);
return () => observer.disconnect();
}, [isSearching, hasNextPage, isFetchingNextPage, fetchNextPage]);
const handleNewChat = useCallback(
(event: React.MouseEvent<HTMLAnchorElement>) => {
if (
event.button !== 0 ||
event.ctrlKey ||
event.metaKey ||
event.shiftKey
) {
return;
}
event.preventDefault();
navigate("/ai");
},
[navigate],
);
const handleDelete = useCallback(
(id: string, title: string | null) => {
modals.openConfirmModal({
title: t("Delete chat"),
centered: true,
children: (
<Text size="sm">
{t("Are you sure you want to delete '{{title}}'? This action cannot be undone.", {
title: title || t("Untitled"),
})}
</Text>
),
labels: { confirm: t("Delete"), cancel: t("Cancel") },
confirmProps: { color: "red" },
onConfirm: () => {
deleteMutation.mutate(id, {
onSuccess: () => {
if (chatId === id) {
navigate("/ai");
}
},
});
},
});
},
[deleteMutation, chatId, navigate, t],
);
const handleRename = useCallback(
(chatId: string, title: string) => {
renameMutation.mutate({ chatId, title });
},
[renameMutation],
);
const isLoading = chatsQuery.isLoading || searchQuery.isLoading;
return (
<div className={classes.sidebar}>
<div className={classes.header}>
<span className={classes.title}>{t("AI Chat")}</span>
<Tooltip label={t("New chat")} openDelay={250} withArrow>
<ActionIcon
component={Link}
to="/ai"
variant="subtle"
color="gray"
onClick={handleNewChat}
aria-label={t("New chat")}
>
<IconPlus size={18} />
</ActionIcon>
</Tooltip>
</div>
<TextInput
className={classes.searchInput}
placeholder="Search chats..."
leftSection={<IconSearch size={14} />}
size="xs"
value={search}
onChange={(e) => setSearch(e.currentTarget.value)}
/>
<div className={classes.chatList}>
{isLoading && <Loader size="xs" mx="auto" mt="md" />}
{!isLoading && chats.length === 0 && (
<div className={classes.chatListEmpty}>
<IconMessageCircle2
size={28}
stroke={1.5}
className={classes.chatListEmptyIcon}
/>
<div className={classes.chatListEmptyTitle}>
{isSearching ? t("No chats found") : t("No conversations yet")}
</div>
<div className={classes.chatListEmptyHint}>
{isSearching
? t("Try a different search term.")
: t("Start a new chat to see it here.")}
</div>
</div>
)}
{isSearching
? chats.map((chat) => (
<AiChatSidebarItem
key={chat.id}
chat={chat}
isActive={chat.id === chatId}
onDelete={handleDelete}
onRename={handleRename}
/>
))
: groupedChats.map((group) => (
<div key={group.key} className={classes.chatGroup}>
<div className={classes.chatGroupLabel}>{group.label}</div>
{group.chats.map((chat) => (
<AiChatSidebarItem
key={chat.id}
chat={chat}
isActive={chat.id === chatId}
onDelete={handleDelete}
onRename={handleRename}
/>
))}
</div>
))}
{!isSearching && (
<>
<div ref={sentinelRef} style={{ height: 1 }} />
{isFetchingNextPage && (
<Center py="xs">
<Loader size="xs" />
</Center>
)}
</>
)}
</div>
</div>
);
}
@@ -0,0 +1,67 @@
import { useState } from "react";
import { TextInput, Loader, Text, ScrollArea } from "@mantine/core";
import { IconSearch } from "@tabler/icons-react";
import { useChatsQuery, useSearchChatsQuery } from "../queries/ai-chat-query";
import { useDebouncedValue } from "@mantine/hooks";
import { useTranslation } from "react-i18next";
import classes from "../styles/aside-chat-panel.module.css";
type Props = {
activeChatId: string | undefined;
onSelect: (chatId: string) => void;
};
export default function AsideChatHistory({ activeChatId, onSelect }: Props) {
const { t } = useTranslation();
const [searchValue, setSearchValue] = useState("");
const [debouncedSearch] = useDebouncedValue(searchValue, 300);
const chatsQuery = useChatsQuery();
const searchQuery = useSearchChatsQuery(debouncedSearch);
const isSearching = debouncedSearch.length > 0;
const chats = isSearching
? (searchQuery.data ?? [])
: (chatsQuery.data?.pages.flatMap((p) => p.items) ?? []);
const isLoading = isSearching ? searchQuery.isLoading : chatsQuery.isLoading;
return (
<div>
<TextInput
placeholder={t("Search chats...")}
leftSection={<IconSearch size={14} />}
size="xs"
mb="xs"
value={searchValue}
onChange={(e) => setSearchValue(e.currentTarget.value)}
/>
{isLoading ? (
<div style={{ display: "flex", justifyContent: "center", padding: 16 }}>
<Loader size="sm" />
</div>
) : chats.length === 0 ? (
<Text size="sm" c="dimmed" ta="center" py="md">
{isSearching ? t("No chats found") : t("No chat history")}
</Text>
) : (
<ScrollArea.Autosize mah={300} scrollbars="y">
<div className={classes.historyList}>
{chats.map((chat) => (
<div
key={chat.id}
className={classes.historyItem}
data-active={chat.id === activeChatId || undefined}
onClick={() => onSelect(chat.id)}
>
<span className={classes.historyItemTitle}>
{chat.title || t("Untitled chat")}
</span>
</div>
))}
</div>
</ScrollArea.Autosize>
)}
</div>
);
}
@@ -0,0 +1,258 @@
import { useState, useEffect, useCallback } from "react";
import { ActionIcon, Popover, Tooltip, UnstyledButton } from "@mantine/core";
import {
IconPlus,
IconChevronDown,
IconArrowsDiagonal,
IconX,
IconSparkles,
IconFileText,
IconLanguage,
IconSearch,
} from "@tabler/icons-react";
import { useAtom } from "jotai";
import { useNavigate, useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { asideStateAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom";
import { usePageQuery } from "@/features/page/queries/page-query";
import { extractPageSlugId } from "@/lib";
import { useChatStream } from "../hooks/use-chat-stream";
import { useChatInfoQuery } from "../queries/ai-chat-query";
import ChatMessageList from "./chat-message-list";
import ChatInput from "./chat-input";
import AsideChatHistory from "./aside-chat-history";
import type { ChatAttachment, PageMention } from "../types/ai-chat.types";
import classes from "../styles/aside-chat-panel.module.css";
type QuickAction = {
icon: React.ReactNode;
label: string;
prompt: string;
};
export default function AsideChatPanel() {
const { t } = useTranslation();
const navigate = useNavigate();
const [, setAsideState] = useAtom(asideStateAtom);
const [chatId, setChatId] = useState<string | undefined>(undefined);
const [historyOpen, setHistoryOpen] = useState(false);
const [contextPages, setContextPages] = useState<PageMention[]>([]);
const { pageSlug } = useParams();
const slugId = extractPageSlugId(pageSlug);
const { data: page } = usePageQuery({ pageId: slugId });
const chatInfoQuery = useChatInfoQuery(chatId);
const {
messages,
streamingContent,
streamingToolCalls,
isStreaming,
error,
sendMessage,
stopGeneration,
hydrateFromServer,
} = useChatStream(chatId, {
onChatCreated: (newChatId) => {
setChatId(newChatId);
},
});
useEffect(() => {
if (page && !chatId) {
setContextPages([{ id: page.id, title: page.title || "", slugId: page.slugId }]);
}
}, [page, chatId]);
const handleRemoveContextPage = useCallback((pageId: string) => {
setContextPages((prev) => prev.filter((p) => p.id !== pageId));
}, []);
useEffect(() => {
if (chatInfoQuery.data?.messages) {
hydrateFromServer(chatInfoQuery.data.messages);
}
}, [chatInfoQuery.data, hydrateFromServer]);
// Drop the open chatId if the current user lost access to it (404/403 on
// the info fetch). Reverts the panel to a fresh chat instead of presenting
// an input tied to a chat the user does not own.
useEffect(() => {
if (chatId && chatInfoQuery.isError) {
setChatId(undefined);
}
}, [chatId, chatInfoQuery.isError]);
const handleNewChat = useCallback(
(event: React.MouseEvent<HTMLAnchorElement>) => {
if (
event.button !== 0 ||
event.ctrlKey ||
event.metaKey ||
event.shiftKey
) {
return;
}
event.preventDefault();
setChatId(undefined);
if (page) {
setContextPages([
{ id: page.id, title: page.title || "", slugId: page.slugId },
]);
}
},
[page],
);
const handleSelectChat = useCallback((selectedChatId: string) => {
setChatId(selectedChatId);
setHistoryOpen(false);
}, []);
const handleExpand = useCallback(() => {
if (chatId) {
navigate(`/ai/chat/${chatId}`);
} else {
navigate("/ai");
}
setAsideState({ tab: "", isAsideOpen: false });
}, [chatId, navigate, setAsideState]);
const handleClose = useCallback(() => {
setAsideState({ tab: "", isAsideOpen: false });
}, [setAsideState]);
const handleSend = useCallback(
(content: string, mentions: PageMention[], attachments: ChatAttachment[]) => {
const contextPageId = contextPages.length > 0 ? contextPages[0].id : undefined;
sendMessage(content, mentions, attachments, contextPageId);
},
[sendMessage, contextPages],
);
const handleQuickAction = useCallback(
(prompt: string) => {
handleSend(prompt, [], []);
},
[handleSend],
);
const hasMessages = messages.length > 0 || isStreaming;
const quickActions: QuickAction[] = [
{ icon: <IconFileText size={16} />, label: t("Summarize this page"), prompt: "Summarize this page" },
{ icon: <IconLanguage size={16} />, label: t("Translate this page"), prompt: "Translate this page" },
{ icon: <IconSearch size={16} />, label: t("Analyze for insights"), prompt: "Analyze this page for insights" },
];
return (
<div className={classes.panel}>
<div className={classes.toolbar}>
<Popover
opened={historyOpen}
onChange={setHistoryOpen}
position="bottom-start"
width={280}
shadow="md"
>
<Popover.Target>
<UnstyledButton
className={classes.titleButton}
onClick={() => setHistoryOpen((o) => !o)}
>
<span className={classes.titleText}>
{chatInfoQuery.data?.chat?.title || t("New chat")}
</span>
<IconChevronDown size={16} stroke={1.75} />
</UnstyledButton>
</Popover.Target>
<Popover.Dropdown>
<AsideChatHistory activeChatId={chatId} onSelect={handleSelectChat} />
</Popover.Dropdown>
</Popover>
<div className={classes.toolbarSpacer} />
<Tooltip label={t("New chat")} openDelay={250}>
<ActionIcon
component="a"
href="/ai"
variant="subtle"
color="dark"
onClick={handleNewChat}
>
<IconPlus size={20} stroke={1.75} />
</ActionIcon>
</Tooltip>
<Tooltip label={t("Open full page")} openDelay={250}>
<ActionIcon variant="subtle" color="dark" onClick={handleExpand}>
<IconArrowsDiagonal size={18} stroke={1.5} />
</ActionIcon>
</Tooltip>
<Tooltip label={t("Close")} openDelay={250}>
<ActionIcon variant="subtle" color="dark" onClick={handleClose}>
<IconX size={20} stroke={1.75} />
</ActionIcon>
</Tooltip>
</div>
{error && (
<div
style={{
padding: "var(--mantine-spacing-xs) var(--mantine-spacing-sm)",
color: "var(--mantine-color-red-6)",
fontSize: "var(--mantine-font-size-xs)",
}}
>
{error}
</div>
)}
{hasMessages ? (
<>
<div className={classes.messages} data-aside-chat>
<ChatMessageList
messages={messages}
isStreaming={isStreaming}
streamingContent={streamingContent}
streamingToolCalls={streamingToolCalls}
/>
</div>
</>
) : (
<div className={classes.emptyState}>
<IconSparkles size={36} stroke={1.5} className={classes.emptyStateIcon} />
<div className={classes.emptyStateTitle}>{t("How can I help you today?")}</div>
<div className={classes.quickActions}>
{quickActions.map((action) => (
<button
key={action.label}
type="button"
className={classes.quickAction}
onClick={() => handleQuickAction(action.prompt)}
>
<span className={classes.quickActionIcon}>{action.icon}</span>
{action.label}
</button>
))}
</div>
</div>
)}
<div className={classes.inputArea}>
<ChatInput
isStreaming={isStreaming}
onSend={handleSend}
onStop={stopGeneration}
placeholder={t("Ask anything...")}
autofocus={false}
contextPages={contextPages}
onRemoveContextPage={handleRemoveContextPage}
variant="flat"
chatId={chatId}
/>
</div>
</div>
);
}
@@ -0,0 +1,91 @@
import {
IconSparkles,
IconSearch,
IconFilePlus,
IconEdit,
IconFileText,
} from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import ChatInput from "./chat-input";
import type { ChatAttachment, PageMention } from "../types/ai-chat.types";
import classes from "../styles/ai-chat.module.css";
type Suggestion = {
icon: React.ReactNode;
text: string;
prompt: string;
};
const SUGGESTIONS: Suggestion[] = [
{
icon: <IconSearch size={16} />,
text: "Search across all pages",
prompt: "Search for pages about ",
},
{
icon: <IconFilePlus size={16} />,
text: "Create a new page",
prompt: "Create a new page titled ",
},
{
icon: <IconFileText size={16} />,
text: "Summarize a page",
prompt: "Summarize the page @",
},
{
icon: <IconEdit size={16} />,
text: "Update page content",
prompt: "Update the page @",
},
];
type Props = {
isStreaming: boolean;
onSend: (content: string, mentions: PageMention[], attachments: ChatAttachment[]) => void;
onStop: () => void;
};
export default function ChatEmptyState({ isStreaming, onSend, onStop }: Props) {
const { t } = useTranslation();
const handleSuggestionClick = (prompt: string) => {
onSend(prompt, [], []);
};
return (
<div className={classes.emptyState}>
<IconSparkles size={48} stroke={1.5} className={classes.emptyStateIcon} />
<div className={classes.emptyStateBrand}>{t("Docmost AI")}</div>
<div className={classes.emptyStateTitle}>
{t("What can I help you with?")}
</div>
<div className={classes.emptyStateInput}>
<ChatInput
isStreaming={isStreaming}
onSend={onSend}
onStop={onStop}
placeholder="Ask anything... Use @ to mention pages"
autofocus
/>
</div>
<div className={classes.suggestionsSection}>
<div className={classes.suggestionsLabel}>Get started</div>
<div className={classes.suggestionsGrid}>
{SUGGESTIONS.map((s) => (
<button
key={s.text}
type="button"
className={classes.suggestionCard}
onClick={() => handleSuggestionClick(s.prompt)}
>
<span className={classes.suggestionIcon}>{s.icon}</span>
<span className={classes.suggestionText}>{s.text}</span>
</button>
))}
</div>
</div>
</div>
);
}
@@ -0,0 +1,409 @@
import { useCallback, useRef, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { IconArrowUp, IconPaperclip, IconPlayerStopFilled, IconX, IconFile, IconPhoto, IconPlus, IconAt, IconFileText } from "@tabler/icons-react";
import { Popover } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { EditorContent, ReactNodeViewRenderer, useEditor } from "@tiptap/react";
import { Placeholder } from "@tiptap/extension-placeholder";
import { CharacterCount } from "@tiptap/extensions";
import { StarterKit } from "@tiptap/starter-kit";
import { Mention, LinkExtension } from "@docmost/editor-ext";
import EmojiCommand from "@/features/editor/extensions/emoji-command";
import mentionRenderItems from "@/features/editor/components/mention/mention-suggestion";
import MentionView from "@/features/editor/components/mention/mention-view";
import { uploadChatFile } from "../services/ai-chat-service";
import type { ChatAttachment, PageMention } from "../types/ai-chat.types";
import classes from "../styles/chat-input.module.css";
type PendingAttachment = ChatAttachment & { uploading: boolean };
const IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif"];
const ACCEPTED_FILE_TYPES = ".pdf,.docx,.txt,.csv,.md,.png,.jpg,.jpeg,.webp";
// Kept in sync with MAX_ATTACHMENTS_PER_MESSAGE in apps/server/src/ee/ai-chat/ai-chat-limits.ts
const MAX_ATTACHMENTS_PER_MESSAGE = 5;
type Props = {
isStreaming: boolean;
onSend: (content: string, mentions: PageMention[], attachments: ChatAttachment[]) => void;
onStop: () => void;
placeholder?: string;
autofocus?: boolean;
contextPages?: PageMention[];
onRemoveContextPage?: (pageId: string) => void;
variant?: "card" | "flat";
showDisclaimer?: boolean;
chatId?: string;
};
function extractMentions(json: any): PageMention[] {
const mentions: PageMention[] = [];
const seen = new Set<string>();
function walk(node: any) {
if (node.type === "mention" && node.attrs?.entityType === "page" && node.attrs?.entityId) {
if (!seen.has(node.attrs.entityId)) {
seen.add(node.attrs.entityId);
mentions.push({
id: node.attrs.entityId,
title: node.attrs.label || "",
slugId: node.attrs.slugId || "",
});
}
}
if (node.content) {
for (const child of node.content) {
walk(child);
}
}
}
walk(json);
return mentions;
}
function editorJsonToText(json: any): string {
let text = "";
function walk(node: any) {
if (node.type === "text") {
text += node.text || "";
} else if (node.type === "mention") {
text += `@${node.attrs?.label || ""}`;
} else if (node.type === "paragraph") {
if (text.length > 0) text += "\n";
if (node.content) {
for (const child of node.content) {
walk(child);
}
}
return;
}
if (node.content) {
for (const child of node.content) {
walk(child);
}
}
}
walk(json);
return text;
}
export default function ChatInput({
isStreaming,
onSend,
onStop,
placeholder,
autofocus = true,
contextPages,
onRemoveContextPage,
variant = "card",
showDisclaimer = true,
chatId,
}: Props) {
const chatIdRef = useRef(chatId);
chatIdRef.current = chatId;
const { t } = useTranslation();
const [isEmpty, setIsEmpty] = useState(true);
const [pendingAttachments, setPendingAttachments] = useState<PendingAttachment[]>([]);
const [plusMenuOpen, setPlusMenuOpen] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const onSendRef = useRef(onSend);
onSendRef.current = onSend;
const handleFileSelect = useCallback(async (files: FileList | null) => {
if (!files?.length) return;
const room = MAX_ATTACHMENTS_PER_MESSAGE - pendingAttachments.length;
if (room <= 0) {
notifications.show({
color: "yellow",
message: t("You can attach up to {{max}} files per message.", {
max: MAX_ATTACHMENTS_PER_MESSAGE,
}),
});
if (fileInputRef.current) fileInputRef.current.value = "";
return;
}
const incoming = Array.from(files);
const accepted = incoming.slice(0, room);
if (incoming.length > accepted.length) {
notifications.show({
color: "yellow",
message: t(
"Only the first {{n}} file(s) were added (max {{max}} per message).",
{ n: accepted.length, max: MAX_ATTACHMENTS_PER_MESSAGE },
),
});
}
for (const file of accepted) {
const tempId = `uploading-${Date.now()}-${Math.random()}`;
const ext = file.name.split(".").pop()?.toLowerCase() || "";
const placeholder: PendingAttachment = {
id: tempId,
fileName: file.name,
fileExt: ext,
fileSize: file.size,
mimeType: file.type,
uploading: true,
};
setPendingAttachments((prev) => [...prev, placeholder]);
try {
const uploaded = await uploadChatFile(file, chatIdRef.current);
setPendingAttachments((prev) =>
prev.map((a) =>
a.id === tempId ? { ...uploaded, uploading: false } : a,
),
);
} catch {
setPendingAttachments((prev) => prev.filter((a) => a.id !== tempId));
}
}
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
}, [pendingAttachments.length, t]);
const removeAttachment = useCallback((id: string) => {
setPendingAttachments((prev) => prev.filter((a) => a.id !== id));
}, []);
const handleSubmit = useCallback(() => {
if (!editor || isStreaming) return;
const json = editor.getJSON();
const text = editorJsonToText(json).trim();
const readyAttachments = pendingAttachments.filter((a) => !a.uploading);
if (!text && readyAttachments.length === 0) return;
const mentions = extractMentions(json);
onSendRef.current(text, mentions, readyAttachments);
editor.commands.clearContent();
editor.commands.focus();
setPendingAttachments([]);
}, [isStreaming, pendingAttachments]);
const handleSubmitRef = useRef(handleSubmit);
handleSubmitRef.current = handleSubmit;
const editor = useEditor({
extensions: [
StarterKit.configure({
gapcursor: false,
dropcursor: false,
link: false,
}),
Placeholder.configure({
placeholder: placeholder || "Ask anything... Use @ to mention pages",
}),
CharacterCount.configure({
limit: 50000,
}),
LinkExtension,
EmojiCommand,
Mention.configure({
suggestion: {
allowSpaces: true,
items: () => [],
// @ts-ignore
render: mentionRenderItems,
},
HTMLAttributes: {
class: "mention",
},
}).extend({
addNodeView() {
this.editor.isInitialized = true;
return ReactNodeViewRenderer(MentionView);
},
}),
],
editorProps: {
handleDOMEvents: {
keydown: (_view, event) => {
if (
["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Enter"].includes(
event.key,
)
) {
const emojiCommand = document.querySelector("#emoji-command");
const mentionPopup = document.querySelector("#mention");
if (emojiCommand || mentionPopup) {
return true;
}
}
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
handleSubmitRef.current();
return true;
}
},
},
},
content: "",
editable: true,
immediatelyRender: true,
shouldRerenderOnTransaction: false,
autofocus: autofocus ? "end" : false,
onUpdate: ({ editor: e }) => {
setIsEmpty(!e.getText().trim());
},
});
useEffect(() => {
if (editor && autofocus) {
editor.commands.focus();
}
}, [editor]);
const hasContent = !isEmpty || pendingAttachments.some((a) => !a.uploading) || (contextPages?.length ?? 0) > 0;
const wrapperClass = variant === "flat" ? classes.inputWrapperFlat : classes.inputWrapper;
return (
<>
<div className={wrapperClass} data-chat-input>
<input
ref={fileInputRef}
type="file"
accept={ACCEPTED_FILE_TYPES}
multiple
style={{ display: "none" }}
onChange={(e) => handleFileSelect(e.target.files)}
/>
{((contextPages?.length ?? 0) > 0 || pendingAttachments.length > 0) && (
<div className={classes.attachmentChips}>
{contextPages?.map((page) => (
<div key={page.id} className={classes.attachmentChip}>
<IconFileText size={14} />
<span className={classes.attachmentChipName}>
{page.title || "Untitled"}
</span>
{onRemoveContextPage && (
<button
type="button"
className={classes.attachmentChipRemove}
onClick={() => onRemoveContextPage(page.id)}
aria-label={`Remove ${page.title}`}
>
<IconX size={12} />
</button>
)}
</div>
))}
{pendingAttachments.map((attachment) => (
<div
key={attachment.id}
className={`${classes.attachmentChip} ${attachment.uploading ? classes.attachmentChipUploading : ""}`}
>
{IMAGE_EXTENSIONS.includes(attachment.fileExt) ? (
<IconPhoto size={14} />
) : (
<IconFile size={14} />
)}
<span className={classes.attachmentChipName}>
{attachment.fileName}
</span>
{!attachment.uploading && (
<button
type="button"
className={classes.attachmentChipRemove}
onClick={() => removeAttachment(attachment.id)}
aria-label={`Remove ${attachment.fileName}`}
>
<IconX size={12} />
</button>
)}
</div>
))}
</div>
)}
<EditorContent editor={editor} className={classes.editorContent} />
<div className={classes.actions}>
<Popover opened={plusMenuOpen} onChange={setPlusMenuOpen} position="top-start" width={220} shadow="md">
<Popover.Target>
<button
type="button"
className={classes.plusButton}
onClick={() => setPlusMenuOpen((o) => !o)}
aria-label="Add content"
>
<IconPlus size={14} />
</button>
</Popover.Target>
<Popover.Dropdown p={4}>
<button
type="button"
className={classes.plusMenuItem}
onClick={() => {
fileInputRef.current?.click();
setPlusMenuOpen(false);
}}
disabled={pendingAttachments.length >= MAX_ATTACHMENTS_PER_MESSAGE}
title={
pendingAttachments.length >= MAX_ATTACHMENTS_PER_MESSAGE
? t("Max {{max}} files per message", {
max: MAX_ATTACHMENTS_PER_MESSAGE,
})
: undefined
}
>
<IconPaperclip size={16} className={classes.plusMenuIcon} />
{t("Add files")}
</button>
<button
type="button"
className={classes.plusMenuItem}
onClick={() => {
editor?.commands.insertContent("@");
editor?.commands.focus();
setPlusMenuOpen(false);
}}
>
<IconAt size={16} className={classes.plusMenuIcon} />
Mention a page
</button>
</Popover.Dropdown>
</Popover>
<div style={{ flex: 1 }} />
{isStreaming ? (
<button
type="button"
className={classes.stopButton}
onClick={onStop}
aria-label="Stop generation"
>
<IconPlayerStopFilled size={14} />
</button>
) : (
<button
type="button"
className={classes.sendButton}
onClick={handleSubmit}
disabled={!hasContent}
aria-label="Send message"
>
<IconArrowUp size={16} stroke={2.5} />
</button>
)}
</div>
</div>
{showDisclaimer && (
<div className={classes.disclaimer}>
{t("AI-generated content may not be accurate.")}
</div>
)}
</>
);
}
@@ -0,0 +1,174 @@
import { useEffect, useRef, useCallback, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { IconArrowDown, IconAlertTriangle } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import type { AiChatMessage, AiChatToolCall } from "../types/ai-chat.types";
import ChatMessage from "./chat-message";
import classes from "../styles/ai-chat.module.css";
function ChatMessageErrorFallback() {
const { t } = useTranslation();
return (
<div className={classes.messageErrorFallback}>
<IconAlertTriangle size={14} />
<span>{t("Failed to render this message.")}</span>
</div>
);
}
type Props = {
messages: AiChatMessage[];
isStreaming: boolean;
streamingContent: string;
streamingToolCalls: AiChatToolCall[];
};
const BOTTOM_THRESHOLD_PX = 32;
const SCROLL_UP_THRESHOLD_PX = 5;
const SMOOTH_SCROLL_SETTLE_MS = 600;
export default function ChatMessageList({
messages,
isStreaming,
streamingContent,
streamingToolCalls,
}: Props) {
const containerRef = useRef<HTMLDivElement>(null);
const bottomRef = useRef<HTMLDivElement>(null);
const isAtBottomRef = useRef(true);
const isAutoScrollingRef = useRef(false);
const prevScrollTopRef = useRef(0);
const [showScrollButton, setShowScrollButton] = useState(false);
const scrollToBottom = useCallback((behavior: ScrollBehavior = "smooth") => {
const container = containerRef.current;
if (!container) return;
isAutoScrollingRef.current = true;
const target = container.scrollHeight - container.clientHeight;
container.scrollTo({ top: target, behavior });
prevScrollTopRef.current = target;
isAtBottomRef.current = true;
setShowScrollButton(false);
if (behavior === "smooth") {
setTimeout(() => {
isAutoScrollingRef.current = false;
if (containerRef.current) {
prevScrollTopRef.current = containerRef.current.scrollTop;
}
}, SMOOTH_SCROLL_SETTLE_MS);
} else {
isAutoScrollingRef.current = false;
}
}, []);
const handleScroll = useCallback(() => {
if (isAutoScrollingRef.current) return;
const container = containerRef.current;
if (!container) return;
const currentScrollTop = container.scrollTop;
const scrolledUp =
currentScrollTop < prevScrollTopRef.current - SCROLL_UP_THRESHOLD_PX;
prevScrollTopRef.current = currentScrollTop;
const distanceFromBottom =
container.scrollHeight - currentScrollTop - container.clientHeight;
const atBottom = distanceFromBottom <= BOTTOM_THRESHOLD_PX;
if (scrolledUp) {
isAtBottomRef.current = atBottom;
} else if (atBottom) {
isAtBottomRef.current = true;
}
setShowScrollButton(!atBottom);
}, []);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
container.addEventListener("scroll", handleScroll, { passive: true });
return () => container.removeEventListener("scroll", handleScroll);
}, [handleScroll]);
// Instant scroll during streaming to keep up with rapid updates
useEffect(() => {
if (isAtBottomRef.current) {
scrollToBottom("instant");
}
}, [streamingContent, streamingToolCalls.length, scrollToBottom]);
// Smooth scroll for new messages. Always force-scroll when the latest
// message is from the user (they just sent it), even if they were reading
// scrollback.
useEffect(() => {
const lastMessage = messages[messages.length - 1];
const lastIsUser = lastMessage?.role === "user";
if (lastIsUser || isAtBottomRef.current) {
scrollToBottom("smooth");
return;
}
// No auto-scroll: recompute from actual layout so that chat switches to
// content that doesn't overflow correctly hide the button even when no
// scroll event fires.
const container = containerRef.current;
if (!container) return;
const distanceFromBottom =
container.scrollHeight - container.scrollTop - container.clientHeight;
const atBottom = distanceFromBottom <= BOTTOM_THRESHOLD_PX;
isAtBottomRef.current = atBottom;
setShowScrollButton(!atBottom);
}, [messages, scrollToBottom]);
return (
<div className={classes.messageListWrapper}>
<div ref={containerRef} className={classes.messageList}>
{messages.map((msg) => (
<ErrorBoundary
key={msg.id}
fallback={<ChatMessageErrorFallback />}
>
<ChatMessage message={msg} />
</ErrorBoundary>
))}
{isStreaming && (
<ErrorBoundary
resetKeys={[streamingContent, streamingToolCalls.length]}
fallback={<ChatMessageErrorFallback />}
>
<ChatMessage
message={{
id: "streaming",
chatId: "",
role: "assistant",
content: null,
toolCalls: null,
metadata: null,
createdAt: new Date().toISOString(),
}}
isStreaming
streamingContent={streamingContent}
streamingToolCalls={streamingToolCalls}
/>
</ErrorBoundary>
)}
<div ref={bottomRef} />
</div>
{showScrollButton && (
<button
type="button"
aria-label="Scroll to bottom"
className={classes.scrollToBottomButton}
onClick={() => scrollToBottom("smooth")}
>
<IconArrowDown size={16} stroke={2} />
</button>
)}
</div>
);
}
@@ -0,0 +1,139 @@
import { useCallback } from "react";
import { useNavigate } from "react-router";
import DOMPurify from "dompurify";
import { ActionIcon, Tooltip } from "@mantine/core";
import {
IconCheck,
IconCopy,
IconFile,
IconLoader2,
IconPhoto,
} from "@tabler/icons-react";
import { markdownToHtml } from "@docmost/editor-ext";
import { CopyButton } from "@/components/common/copy-button";
import type { AiChatMessage, AiChatToolCall } from "../types/ai-chat.types";
import ChatToolGroup from "./chat-tool-group";
import classes from "../styles/chat-message.module.css";
import CopyTextButton from "@/components/common/copy.tsx";
const chatSanitizer = DOMPurify();
chatSanitizer.addHook("afterSanitizeAttributes", (node) => {
if (node.tagName === "A") {
const href = node.getAttribute("href") || "";
if (href.startsWith("http://") || href.startsWith("https://")) {
node.setAttribute("target", "_blank");
node.setAttribute("rel", "noopener noreferrer");
}
}
});
const IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif"];
type Props = {
message: AiChatMessage;
isStreaming?: boolean;
streamingContent?: string;
streamingToolCalls?: AiChatToolCall[];
};
export default function ChatMessage({
message,
isStreaming,
streamingContent,
streamingToolCalls,
}: Props) {
const navigate = useNavigate();
const handleContentClick = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
const target = e.target as HTMLElement;
const anchor = target.closest("a");
if (!anchor) return;
const href = anchor.getAttribute("href");
if (href && (href.startsWith("/s/") || href.startsWith("/p/"))) {
e.preventDefault();
navigate(href);
}
},
[navigate],
);
if (message.role === "tool") return null;
const isUser = message.role === "user";
const content = isStreaming ? streamingContent : message.content;
const toolCalls = isStreaming ? streamingToolCalls : message.toolCalls;
if (isUser) {
const displayContent = (content || "").replace(
/\n\n<referenced_pages>[\s\S]*<\/referenced_pages>$/,
"",
);
const attachments =
(message.metadata?.attachments as {
id: string;
fileName: string;
fileExt: string;
}[]) || [];
return (
<div className={classes.userMessage}>
<div className={classes.userBubble}>
{attachments.length > 0 && (
<div className={classes.messageAttachments}>
{attachments.map((a) => (
<span key={a.id} className={classes.messageAttachmentChip}>
{IMAGE_EXTENSIONS.includes(a.fileExt) ? (
<IconPhoto size={13} />
) : (
<IconFile size={13} />
)}
{a.fileName}
</span>
))}
</div>
)}
{displayContent}
</div>
</div>
);
}
return (
<div className={classes.assistantMessage}>
<div className={classes.messageContent}>
{toolCalls && toolCalls.length > 0 && (
<ChatToolGroup toolCalls={toolCalls} isStreaming={isStreaming} />
)}
{content && (
<div
onClick={handleContentClick}
dangerouslySetInnerHTML={{
__html: chatSanitizer.sanitize(
markdownToHtml(content) as string,
{ ADD_ATTR: ["target", "rel"] },
),
}}
/>
)}
{isStreaming && (
<>
{!content && (
<span className={classes.processingIndicator}>
<IconLoader2 size={16} className={classes.processingSpinner} />
Thinking
</span>
)}
<span className={classes.streamingCursor} />
</>
)}
</div>
{!isStreaming && message.content && (
<div className={classes.messageActions}>
<CopyTextButton text={message?.content} />
</div>
)}
</div>
);
}
@@ -0,0 +1,56 @@
import { useState } from "react";
import {
IconChevronRight,
IconChevronDown,
IconLoader2,
} from "@tabler/icons-react";
import type { AiChatToolCall } from "../types/ai-chat.types";
import ChatToolResult, { TOOL_LABELS } from "./chat-tool-result";
import classes from "../styles/chat-message.module.css";
type Props = {
toolCalls: AiChatToolCall[];
isStreaming?: boolean;
};
export default function ChatToolGroup({ toolCalls, isStreaming }: Props) {
const [expanded, setExpanded] = useState(false);
if (!toolCalls || toolCalls.length === 0) return null;
const activeCall =
isStreaming && toolCalls.length > 0
? [...toolCalls].reverse().find((tc) => tc.result === undefined)
: undefined;
const activeLabel = activeCall
? TOOL_LABELS[activeCall.name] || activeCall.name
: null;
return (
<div className={classes.toolGroup}>
<div
className={classes.toolGroupHeader}
onClick={() => setExpanded((prev) => !prev)}
>
{activeLabel ? (
<IconLoader2 size={12} className={classes.processingSpinner} />
) : expanded ? (
<IconChevronDown size={12} />
) : (
<IconChevronRight size={12} />
)}
<span className={classes.toolGroupLabel}>
{activeLabel ? `${activeLabel}` : `Steps ${toolCalls.length}`}
</span>
</div>
{expanded && (
<div className={classes.toolGroupSteps}>
{toolCalls.map((tc) => (
<ChatToolResult key={tc.id} toolCall={tc} />
))}
</div>
)}
</div>
);
}
@@ -0,0 +1,49 @@
import { useState } from "react";
import { IconChevronRight, IconChevronDown } from "@tabler/icons-react";
import type { AiChatToolCall } from "../types/ai-chat.types";
import classes from "../styles/chat-message.module.css";
export const TOOL_LABELS: Record<string, string> = {
list_spaces: "Listed spaces",
search_pages: "Searched pages",
get_page: "Read page",
create_page: "Created page",
update_page: "Updated page",
};
type Props = {
toolCall: AiChatToolCall;
};
export default function ChatToolResult({ toolCall }: Props) {
const [expanded, setExpanded] = useState(false);
const label = TOOL_LABELS[toolCall.name] || toolCall.name;
return (
<div className={classes.toolStep}>
<div
className={classes.toolStepRow}
onClick={() => setExpanded((prev) => !prev)}
>
<span className={classes.toolStepBullet}>·</span>
{expanded ? (
<IconChevronDown size={12} />
) : (
<IconChevronRight size={12} />
)}
<span>{label}</span>
</div>
{expanded && (
<div className={classes.toolStepDetails}>
<pre style={{ margin: 0, whiteSpace: "pre-wrap" }}>
{JSON.stringify(
{ args: toolCall.args, result: toolCall.result },
null,
2,
)}
</pre>
</div>
)}
</div>
);
}
@@ -0,0 +1,67 @@
import { Badge, Group, Text, Switch, Tooltip } from "@mantine/core";
import { useAtom } from "jotai";
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts";
import { notifications } from "@mantine/notifications";
import { useHasFeature } from "@/ee/hooks/use-feature";
import { Feature } from "@/ee/features";
import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label";
export default function EnableAiChat() {
const { t } = useTranslation();
return (
<Group justify="space-between" wrap="nowrap" gap="xl">
<div>
<Group gap="xs" align="center">
<Text size="md">{t("AI Chat")}</Text>
<Badge color="gray" variant="light" size="sm" radius="sm">
{t("Beta")}
</Badge>
</Group>
<Text size="sm" c="dimmed">
{t(
"Enable AI Chat to allow users to have multi-turn conversations with AI about your workspace content.",
)}
</Text>
</div>
<AiChatToggle />
</Group>
);
}
function AiChatToggle() {
const { t } = useTranslation();
const [workspace, setWorkspace] = useAtom(workspaceAtom);
const [checked, setChecked] = useState(workspace?.settings?.ai?.chat);
const hasAccess = useHasFeature(Feature.AI);
const upgradeLabel = useUpgradeLabel();
const handleChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.currentTarget.checked;
try {
const updatedWorkspace = await updateWorkspace({ aiChat: value } as any);
setChecked(value);
setWorkspace(updatedWorkspace);
} catch (err: any) {
notifications.show({
message: err?.response?.data?.message,
color: "red",
});
}
};
return (
<Tooltip label={upgradeLabel} disabled={hasAccess} refProp="rootRef">
<Switch
defaultChecked={checked}
onChange={handleChange}
disabled={!hasAccess}
aria-label={t("Toggle AI Chat")}
/>
</Tooltip>
);
}
@@ -0,0 +1,227 @@
import { useState, useCallback, useEffect, useRef } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import { sendChatMessage } from "../services/ai-chat-service";
import type {
AiChatMessage,
AiChatStreamEvent,
AiChatToolCall,
ChatAttachment,
PageMention,
} from "../types/ai-chat.types";
type ChatStreamOptions = {
onChatCreated?: (chatId: string) => void;
};
export function useChatStream(
chatId: string | undefined,
options?: ChatStreamOptions,
) {
const [messages, setMessages] = useState<AiChatMessage[]>([]);
const [streamingContent, setStreamingContent] = useState("");
const [streamingToolCalls, setStreamingToolCalls] = useState<AiChatToolCall[]>(
[],
);
const [isStreaming, setIsStreaming] = useState(false);
const [error, setError] = useState<string | null>(null);
const [errorCode, setErrorCode] = useState<string | null>(null);
const [isRetryable, setIsRetryable] = useState(false);
const abortRef = useRef<AbortController | null>(null);
const queryClient = useQueryClient();
const navigate = useNavigate();
const currentChatIdRef = useRef(chatId);
currentChatIdRef.current = chatId;
// Tracks which chatId the local `messages` state currently represents.
// Set when we seed from a server fetch AND when we optimistically own a
// freshly-created chat after `chat_created`. This is the single authority
// marker that keeps server-state effects from clobbering in-flight streams.
const hydratedChatIdRef = useRef<string | undefined>(undefined);
// Reset local state when the consumer switches to a different chat.
// Skip the reset if the new chatId is one the hook itself already claimed
// during a new-chat flow — in that case our optimistic state is the truth.
useEffect(() => {
if (chatId && chatId === hydratedChatIdRef.current) return;
hydratedChatIdRef.current = undefined;
setMessages([]);
setError(null);
setErrorCode(null);
setIsRetryable(false);
}, [chatId]);
const hydrateFromServer = useCallback((msgs: AiChatMessage[]) => {
const forId = currentChatIdRef.current;
if (!forId) return;
if (hydratedChatIdRef.current === forId) return;
hydratedChatIdRef.current = forId;
setMessages(msgs);
}, []);
const sendMessage = useCallback(
(content: string, mentions: PageMention[] = [], attachments: ChatAttachment[] = [], contextPageId?: string) => {
if (isStreaming || (!content.trim() && attachments.length === 0)) return;
setError(null);
setErrorCode(null);
setIsRetryable(false);
setIsStreaming(true);
setStreamingContent("");
setStreamingToolCalls([]);
const metadata: Record<string, unknown> = {};
if (mentions.length) {
metadata.mentionedPageIds = mentions.map((m) => m.id);
}
if (attachments.length) {
metadata.attachments = attachments.map((a) => ({
id: a.id,
fileName: a.fileName,
fileExt: a.fileExt,
}));
}
const userMessage: AiChatMessage = {
id: `temp-${Date.now()}`,
chatId: currentChatIdRef.current || "",
role: "user",
content,
toolCalls: null,
metadata: Object.keys(metadata).length ? metadata : null,
createdAt: new Date().toISOString(),
};
setMessages((prev) => [...prev, userMessage]);
const attachmentIds = attachments.map((a) => a.id);
const abortController = sendChatMessage(
{
chatId: currentChatIdRef.current,
content,
mentionedPageIds: mentions.map((m) => m.id),
...(contextPageId && { contextPageId }),
...(attachmentIds.length && { attachmentIds }),
},
(event: AiChatStreamEvent) => {
switch (event.type) {
case "chat_created":
currentChatIdRef.current = event.chatId;
// Claim authority over this new chatId so when the consumer's
// prop catches up via navigation/onChatCreated, the reset effect
// sees a match and preserves our optimistic messages.
hydratedChatIdRef.current = event.chatId;
if (options?.onChatCreated) {
options.onChatCreated(event.chatId);
} else {
navigate(`/ai/chat/${event.chatId}`, { replace: true });
}
queryClient.invalidateQueries({ queryKey: ["ai-chats"] });
break;
case "content":
setStreamingContent((prev) => prev + event.text);
break;
case "tool_call":
setStreamingToolCalls((prev) => [
...prev,
{
id: event.id,
name: event.name,
args: event.args,
},
]);
break;
case "tool_result":
setStreamingToolCalls((prev) =>
prev.map((tc) =>
tc.id === event.id ? { ...tc, result: event.result } : tc,
),
);
break;
case "done": {
setStreamingContent((currentContent) => {
setStreamingToolCalls((currentToolCalls) => {
const assistantMessage: AiChatMessage = {
id: event.messageId,
chatId: currentChatIdRef.current || "",
role: "assistant",
content: currentContent || null,
toolCalls: currentToolCalls.length
? currentToolCalls
: null,
metadata: event.usage ? { tokenUsage: event.usage } : null,
createdAt: new Date().toISOString(),
};
setMessages((prev) => [...prev, assistantMessage]);
return [];
});
return "";
});
setIsStreaming(false);
queryClient.invalidateQueries({
queryKey: ["ai-chat", currentChatIdRef.current],
});
break;
}
case "error":
setError(event.message);
setErrorCode(event.code || null);
setIsRetryable(event.retryable || false);
setIsStreaming(false);
break;
}
},
(errorMsg) => {
setError(errorMsg);
setIsStreaming(false);
},
() => {
setIsStreaming(false);
},
);
abortRef.current = abortController;
},
[isStreaming, navigate, queryClient],
);
const stopGeneration = useCallback(() => {
abortRef.current?.abort();
abortRef.current = null;
setStreamingContent((currentContent) => {
setStreamingToolCalls((currentToolCalls) => {
if (currentContent || currentToolCalls.length > 0) {
const partialMessage: AiChatMessage = {
id: `stopped-${Date.now()}`,
chatId: currentChatIdRef.current || "",
role: "assistant",
content: currentContent || null,
toolCalls: currentToolCalls.length ? currentToolCalls : null,
metadata: null,
createdAt: new Date().toISOString(),
};
setMessages((prev) => [...prev, partialMessage]);
}
return [];
});
return "";
});
setIsStreaming(false);
}, []);
return {
messages,
streamingContent,
streamingToolCalls,
isStreaming,
error,
errorCode,
isRetryable,
sendMessage,
stopGeneration,
hydrateFromServer,
};
}
@@ -0,0 +1,39 @@
import { useParams } from "react-router-dom";
import { ErrorBoundary } from "react-error-boundary";
import { Button } from "@mantine/core";
import { IconAlertTriangle } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import AiChatLayout from "../components/ai-chat-layout";
import { EmptyState } from "@/components/ui/empty-state.tsx";
import classes from "../styles/ai-chat.module.css";
export default function AiChat() {
const { t } = useTranslation();
const { chatId } = useParams<{ chatId: string }>();
return (
<div className={classes.layout}>
<ErrorBoundary
resetKeys={[chatId]}
fallbackRender={({ resetErrorBoundary }) => (
<EmptyState
icon={IconAlertTriangle}
title={t("Failed to load chat. An error occurred.")}
action={
<Button
variant="default"
size="sm"
mt="xs"
onClick={resetErrorBoundary}
>
{t("Try again")}
</Button>
}
/>
)}
>
<AiChatLayout />
</ErrorBoundary>
</div>
);
}
@@ -0,0 +1,61 @@
import {
useQuery,
useMutation,
useQueryClient,
useInfiniteQuery,
} from "@tanstack/react-query";
import {
listChats,
getChatInfo,
deleteChat,
updateChatTitle,
searchChats,
} from "../services/ai-chat-service";
export function useChatsQuery() {
return useInfiniteQuery({
queryKey: ["ai-chats"],
queryFn: ({ pageParam }) =>
listChats({ cursor: pageParam, limit: 30 }),
initialPageParam: undefined as string | undefined,
getNextPageParam: (lastPage) =>
lastPage.meta.hasNextPage ? lastPage.meta.nextCursor : undefined,
});
}
export function useChatInfoQuery(chatId: string | undefined) {
return useQuery({
queryKey: ["ai-chat", chatId],
queryFn: () => getChatInfo(chatId!),
enabled: !!chatId,
});
}
export function useDeleteChatMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (chatId: string) => deleteChat(chatId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["ai-chats"] });
},
});
}
export function useUpdateChatTitleMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ chatId, title }: { chatId: string; title: string }) =>
updateChatTitle(chatId, title),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["ai-chats"] });
},
});
}
export function useSearchChatsQuery(query: string) {
return useQuery({
queryKey: ["ai-chats-search", query],
queryFn: () => searchChats(query),
enabled: query.length > 0,
});
}
@@ -0,0 +1,144 @@
import api from "@/lib/api-client.ts";
import type {
AiChat,
AiChatMessage,
AiChatStreamEvent,
ChatAttachment,
} from "../types/ai-chat.types";
import { IPagination } from "@/lib/types.ts";
export async function createChat(): Promise<AiChat> {
const req = await api.post<AiChat>("/ai/chats/create");
return req.data;
}
export async function listChats(params?: {
limit?: number;
cursor?: string;
}): Promise<IPagination<AiChat>> {
const req = await api.post("/ai/chats", params);
return req.data;
}
export async function getChatInfo(
chatId: string,
): Promise<{ chat: AiChat; messages: AiChatMessage[] }> {
const req = await api.post("/ai/chats/info", { chatId });
return req.data;
}
export async function deleteChat(chatId: string): Promise<void> {
await api.post("/ai/chats/delete", { chatId });
}
export async function updateChatTitle(
chatId: string,
title: string,
): Promise<void> {
await api.post("/ai/chats/update", { chatId, title });
}
export async function searchChats(query: string): Promise<AiChat[]> {
const req = await api.post("/ai/chats/search", { query });
return req.data;
}
export async function uploadChatFile(
file: File,
chatId?: string,
): Promise<ChatAttachment> {
const formData = new FormData();
formData.append("file", file);
if (chatId) {
formData.append("chatId", chatId);
}
return await api.post("/ai/chats/upload", formData, {
headers: { "Content-Type": "multipart/form-data" },
});
}
export function sendChatMessage(
params: {
chatId?: string;
content: string;
mentionedPageIds?: string[];
contextPageId?: string;
attachmentIds?: string[];
},
onEvent: (event: AiChatStreamEvent) => void,
onError?: (error: string) => void,
onComplete?: () => void,
): AbortController {
const abortController = new AbortController();
(async () => {
try {
const response = await fetch("/api/ai/chats/send", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params),
signal: abortController.signal,
credentials: "include",
});
if (!response.ok) {
const errorBody = await response.text();
let errorMessage = `HTTP error ${response.status}`;
try {
const parsed = JSON.parse(errorBody);
errorMessage = parsed.message || errorMessage;
} catch {
// use default
}
onError?.(errorMessage);
return;
}
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
onError?.("Response body is not readable");
return;
}
let buffer = "";
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
if (line.startsWith("data: ")) {
const data = line.slice(6);
if (data === "[DONE]") {
onComplete?.();
return;
}
try {
const parsed = JSON.parse(data) as AiChatStreamEvent;
onEvent(parsed);
} catch {
// Skip invalid JSON
}
}
}
}
} finally {
reader.releaseLock();
}
onComplete?.();
} catch (error: any) {
if (error.name !== "AbortError") {
onError?.(error.message);
}
}
})();
return abortController;
}
@@ -0,0 +1,169 @@
.layout {
display: flex;
height: 100%;
width: 100%;
}
.main {
flex: 1;
display: flex;
flex-direction: column;
height: calc(100vh - 45px - 2 * var(--mantine-spacing-md));
max-width: 900px;
margin: 0 auto;
width: 100%;
}
.messageListWrapper {
flex: 1;
position: relative;
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
width: 100%;
}
.messageList {
flex: 1;
overflow-y: auto;
padding: var(--mantine-spacing-md) var(--mantine-spacing-lg);
}
.messageErrorFallback {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px;
margin-bottom: var(--mantine-spacing-lg);
border-radius: var(--mantine-radius-sm);
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
font-size: var(--mantine-font-size-xs);
}
.scrollToBottomButton {
position: absolute;
bottom: 12px;
left: 50%;
transform: translateX(-50%);
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
cursor: pointer;
padding: 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
z-index: 2;
}
.scrollToBottomButton:hover {
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5));
border-color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-3));
}
.scrollToBottomButton:active {
transform: translateX(-50%) scale(0.95);
}
.inputArea {
padding: var(--mantine-spacing-xs) var(--mantine-spacing-lg) var(--mantine-spacing-lg);
}
/* Empty state - Notion AI style centered layout */
.emptyState {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--mantine-spacing-xl) var(--mantine-spacing-lg);
}
.emptyStateIcon {
width: 48px;
height: 48px;
margin-bottom: var(--mantine-spacing-sm);
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
}
.emptyStateBrand {
font-size: var(--mantine-font-size-xs);
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
margin-bottom: var(--mantine-spacing-xs);
}
.emptyStateTitle {
font-size: 1.5rem;
font-weight: 600;
color: light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0));
margin-bottom: var(--mantine-spacing-xl);
text-align: center;
}
.emptyStateInput {
width: 100%;
max-width: 600px;
margin-bottom: var(--mantine-spacing-xl);
padding: 6px 0;
}
.suggestionsSection {
width: 100%;
max-width: 600px;
}
.suggestionsLabel {
font-size: var(--mantine-font-size-xs);
font-weight: 500;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: var(--mantine-spacing-sm);
}
.suggestionsGrid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--mantine-spacing-sm);
}
.suggestionCard {
display: flex;
align-items: flex-start;
gap: var(--mantine-spacing-sm);
padding: var(--mantine-spacing-sm) var(--mantine-spacing-md);
border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
border-radius: var(--mantine-radius-md);
cursor: pointer;
background: transparent;
transition: background-color 150ms, border-color 150ms;
text-align: left;
width: 100%;
@mixin hover {
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
border-color: light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
}
}
.suggestionIcon {
flex-shrink: 0;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
margin-top: 1px;
}
.suggestionText {
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
line-height: 1.4;
}
@@ -0,0 +1,139 @@
.panel {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.toolbar {
display: flex;
align-items: center;
gap: 4px;
padding: 0 0 var(--mantine-spacing-sm) 0;
border-bottom: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
}
.toolbarSpacer {
flex: 1;
}
.titleButton {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
border-radius: var(--mantine-radius-sm);
font-size: var(--mantine-font-size-sm);
font-weight: 500;
color: light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0));
max-width: 60%;
min-width: 0;
}
.titleButton:hover {
background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));
}
.titleText {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.messages {
flex: 1;
overflow-y: auto;
padding: var(--mantine-spacing-sm) 0;
scroll-behavior: smooth;
}
.inputArea {
padding-top: var(--mantine-spacing-sm);
}
.emptyState {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--mantine-spacing-md);
padding: var(--mantine-spacing-xl) var(--mantine-spacing-sm);
}
.emptyStateIcon {
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
}
.emptyStateTitle {
font-size: var(--mantine-font-size-lg);
font-weight: 600;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
text-align: center;
}
.quickActions {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.quickAction {
display: flex;
align-items: center;
gap: var(--mantine-spacing-sm);
padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
border-radius: var(--mantine-radius-md);
cursor: pointer;
background: transparent;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
font-size: var(--mantine-font-size-sm);
text-align: left;
width: 100%;
transition: background-color 150ms, border-color 150ms;
@mixin hover {
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
border-color: light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
}
}
.quickActionIcon {
flex-shrink: 0;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
}
.historyList {
max-height: 300px;
overflow-y: auto;
}
.historyItem {
display: flex;
align-items: center;
padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
cursor: pointer;
border-radius: var(--mantine-radius-sm);
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
transition: background-color 150ms;
@mixin hover {
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
}
&[data-active] {
background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5));
}
}
.historyItemTitle {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@@ -0,0 +1,242 @@
.inputWrapper {
position: relative;
overflow: hidden;
border: 1px solid
light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
border-radius: 16px;
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
box-shadow: light-dark(
0 2px 40px 4px rgba(0, 0, 0, 0.07),
0 2px 40px 4px rgba(0, 0, 0, 0.5)
);
transition:
border-color 150ms,
box-shadow 150ms;
&:focus-within {
border-color: light-dark(
var(--mantine-color-gray-3),
var(--mantine-color-dark-4)
);
box-shadow: light-dark(
0 4px 48px 6px rgba(0, 0, 0, 0.09),
0 4px 48px 6px rgba(0, 0, 0, 0.6)
);
}
}
.inputWrapperFlat {
position: relative;
overflow: hidden;
border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
border-radius: 12px;
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
box-shadow: none;
transition: border-color 150ms;
&:focus-within {
border-color: light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
}
}
.disclaimer {
margin-top: 6px;
text-align: center;
font-size: var(--mantine-font-size-xs);
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
}
.attachmentChips {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 10px 14px 0;
}
.attachmentChip {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 4px 8px;
border-radius: 8px;
background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
font-size: var(--mantine-font-size-xs);
max-width: 200px;
}
.attachmentChipUploading {
opacity: 0.55;
}
.attachmentChipName {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.attachmentChipRemove {
display: flex;
align-items: center;
justify-content: center;
border: none;
background: none;
cursor: pointer;
padding: 0;
margin-left: 2px;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
border-radius: 50%;
@mixin hover {
color: light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0));
}
}
.editorContent {
overflow: hidden;
:global(.ProseMirror) {
outline: none;
border: none;
background-color: transparent;
padding: 14px 18px 8px;
font-size: 15px;
line-height: 1.6;
max-height: 200px;
overflow-y: auto;
min-height: 24px;
color: light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0));
}
:global(.ProseMirror p) {
margin-block-start: 0;
margin-block-end: 0;
}
:global(.ProseMirror p.is-editor-empty:first-child::before) {
color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-3));
content: attr(data-placeholder);
float: left;
height: 0;
pointer-events: none;
}
}
.actions {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 4px 12px 10px;
gap: var(--mantine-spacing-xs);
}
.sendButton {
width: 28px;
height: 28px;
min-width: 28px;
min-height: 28px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: none;
cursor: pointer;
transition: background-color 150ms, opacity 150ms;
background: light-dark(var(--mantine-color-dark-9), var(--mantine-color-gray-0));
color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-9));
&:disabled {
opacity: 0.25;
cursor: default;
}
@mixin hover {
&:not(:disabled) {
opacity: 0.85;
}
}
}
.attachButton {
display: flex;
align-items: center;
justify-content: center;
border: none;
background: none;
cursor: pointer;
padding: 2px;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
transition: color 150ms;
@mixin hover {
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
}
}
.plusButton {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border-radius: 50%;
border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
background: none;
cursor: pointer;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
transition: color 150ms, background-color 150ms;
@mixin hover {
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
}
}
.plusMenuItem {
display: flex;
align-items: center;
gap: var(--mantine-spacing-sm);
padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
border: none;
background: none;
cursor: pointer;
width: 100%;
font-size: var(--mantine-font-size-sm);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
border-radius: var(--mantine-radius-sm);
transition: background-color 150ms;
@mixin hover {
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
}
&:disabled {
opacity: 0.45;
cursor: not-allowed;
background: none;
}
}
.plusMenuIcon {
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
}
.stopButton {
width: 28px;
height: 28px;
min-width: 28px;
min-height: 28px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
cursor: pointer;
transition: background-color 150ms;
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
@mixin hover {
background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5));
}
}
@@ -0,0 +1,286 @@
.message {
margin-bottom: var(--mantine-spacing-lg);
}
.userMessage {
composes: message;
display: flex;
justify-content: flex-end;
}
.userBubble {
max-width: 75%;
padding: 10px 16px;
border-radius: 18px;
background: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));
color: light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0));
font-size: 15px;
line-height: 1.6;
word-wrap: break-word;
overflow-wrap: break-word;
}
[data-aside-chat] .userBubble {
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
}
.userBubble p {
margin: 0;
}
.messageAttachments {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 6px;
}
.messageAttachmentChip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: 6px;
background: light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-2));
font-size: var(--mantine-font-size-xs);
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.assistantMessage {
composes: message;
}
.messageContent {
font-size: 15px;
line-height: 1.7;
color: light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-1));
word-wrap: break-word;
overflow-wrap: break-word;
}
.messageContent p {
margin: 0 0 0.75em 0;
}
.messageContent p:last-child {
margin-bottom: 0;
}
.messageContent ul,
.messageContent ol {
margin: 0.5em 0 0.75em 0;
padding-left: 1.5em;
}
.messageContent li {
margin-bottom: 0.3em;
}
.messageContent h1,
.messageContent h2,
.messageContent h3 {
margin: 1em 0 0.5em 0;
font-weight: 600;
color: light-dark(var(--mantine-color-gray-9), var(--mantine-color-dark-0));
}
.messageContent h1 {
font-size: 1.4em;
}
.messageContent h2 {
font-size: 1.2em;
}
.messageContent h3 {
font-size: 1.05em;
}
.messageContent pre {
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-7));
padding: var(--mantine-spacing-sm) var(--mantine-spacing-md);
border-radius: var(--mantine-radius-md);
overflow-x: auto;
font-size: var(--mantine-font-size-sm);
margin: 0.75em 0;
}
.messageContent code {
background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));
padding: 2px 6px;
border-radius: 4px;
font-size: 0.88em;
}
.messageContent pre code {
background: none;
padding: 0;
}
.messageContent blockquote {
border-left: 3px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
padding-left: var(--mantine-spacing-md);
margin: 0.75em 0;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-2));
}
.messageContent a {
color: light-dark(var(--mantine-color-blue-7), var(--mantine-color-blue-4));
text-decoration: none;
@mixin hover {
text-decoration: underline;
}
}
.messageContent a[href^="/s/"],
.messageContent a[href^="/p/"] {
color: light-dark(var(--mantine-color-dark-4), var(--mantine-color-dark-1));
font-weight: 500;
text-decoration: none;
cursor: pointer;
@mixin light {
border-bottom: 0.05em solid var(--mantine-color-dark-0);
}
@mixin dark {
border-bottom: 0.05em solid var(--mantine-color-dark-2);
}
@mixin hover {
text-decoration: none;
@mixin light {
border-bottom-color: var(--mantine-color-dark-2);
}
@mixin dark {
border-bottom-color: var(--mantine-color-dark-0);
}
}
}
.messageContent hr {
border: none;
border-top: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
margin: 1em 0;
}
.toolGroup {
margin: 6px 0;
font-size: var(--mantine-font-size-xs);
}
.toolGroupHeader {
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
user-select: none;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
line-height: 1.4;
transition: color 120ms ease;
}
.toolGroupHeader:hover {
color: light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0));
}
.toolGroupLabel {
font-weight: 500;
}
.toolGroupSteps {
margin-top: 4px;
padding-left: 14px;
display: flex;
flex-direction: column;
gap: 2px;
}
.toolStep {
font-size: var(--mantine-font-size-xs);
}
.toolStepRow {
display: inline-flex;
align-items: center;
gap: 4px;
cursor: pointer;
user-select: none;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
line-height: 1.5;
transition: color 120ms ease;
}
.toolStepRow:hover {
color: light-dark(var(--mantine-color-gray-8), var(--mantine-color-dark-0));
}
.toolStepBullet {
display: inline-block;
width: 8px;
text-align: center;
opacity: 0.6;
}
.toolStepDetails {
margin-top: 4px;
margin-left: 18px;
padding: 6px 10px;
border-radius: var(--mantine-radius-sm);
background: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-7));
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
font-size: 11px;
line-height: 1.5;
overflow-x: auto;
}
.messageActions {
display: flex;
align-items: center;
gap: 4px;
margin-top: 4px;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
}
.processingIndicator {
display: inline-flex;
align-items: center;
gap: 6px;
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
font-size: var(--mantine-font-size-sm);
}
.processingSpinner {
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.streamingCursor {
display: inline-block;
width: 2px;
height: 1em;
background: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
animation: blink 1s step-end infinite;
vertical-align: text-bottom;
margin-left: 1px;
}
@keyframes blink {
50% {
opacity: 0;
}
}
@@ -0,0 +1,138 @@
.sidebar {
height: 100%;
width: 100%;
padding: var(--mantine-spacing-md);
display: flex;
flex-direction: column;
gap: var(--mantine-spacing-xs);
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: var(--mantine-spacing-xs);
}
.title {
font-weight: 600;
font-size: var(--mantine-font-size-sm);
}
.searchInput {
margin-bottom: var(--mantine-spacing-xs);
}
.chatList {
flex: 1;
overflow-y: auto;
}
.chatGroup + .chatGroup {
margin-top: var(--mantine-spacing-sm);
}
.chatGroupLabel {
padding: 4px var(--mantine-spacing-xs);
font-size: var(--mantine-font-size-xs);
font-weight: 600;
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2));
user-select: none;
}
.chatListEmpty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--mantine-spacing-xl) var(--mantine-spacing-md);
text-align: center;
gap: 4px;
user-select: none;
}
.chatListEmptyIcon {
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
margin-bottom: var(--mantine-spacing-xs);
}
.chatListEmptyTitle {
font-size: var(--mantine-font-size-sm);
font-weight: 600;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
}
.chatListEmptyHint {
font-size: var(--mantine-font-size-xs);
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-3));
line-height: 1.4;
}
.chatItem {
display: flex;
align-items: center;
padding: 8px var(--mantine-spacing-xs);
border-radius: var(--mantine-radius-sm);
cursor: pointer;
text-decoration: none;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
font-size: var(--mantine-font-size-sm);
user-select: none;
gap: var(--mantine-spacing-xs);
@mixin hover {
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-6)
);
}
&[data-active] {
background-color: light-dark(
var(--mantine-color-gray-2),
var(--mantine-color-dark-6)
);
}
}
.chatItemTitle {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.chatItemDate {
font-size: var(--mantine-font-size-xs);
color: light-dark(var(--mantine-color-gray-5), var(--mantine-color-dark-3));
white-space: nowrap;
transition: opacity 150ms;
}
.chatItemRenameInput {
font-size: var(--mantine-font-size-sm);
padding: 0;
height: auto;
min-height: 0;
background: transparent;
color: inherit;
}
.chatItem:hover .chatItemDate {
opacity: 0;
}
.chatItemActions {
position: absolute;
right: var(--mantine-spacing-xs);
opacity: 0;
transition: opacity 150ms;
}
.chatItem {
position: relative;
}
.chatItem:hover .chatItemActions {
opacity: 1;
}
@@ -0,0 +1,49 @@
export type AiChat = {
id: string;
workspaceId: string;
creatorId: string;
title: string | null;
createdAt: string;
updatedAt: string;
};
export type AiChatToolCall = {
id: string;
name: string;
args: Record<string, unknown>;
result?: unknown;
};
export type AiChatMessage = {
id: string;
chatId: string;
role: 'user' | 'assistant' | 'tool';
content: string | null;
toolCalls: AiChatToolCall[] | null;
metadata: Record<string, unknown> | null;
createdAt: string;
};
export type AiChatStreamEvent =
| { type: 'chat_created'; chatId: string }
| { type: 'content'; text: string }
| { type: 'tool_call'; id: string; name: string; args: Record<string, unknown> }
| { type: 'tool_result'; id: string; result: unknown }
| { type: 'done'; messageId: string; usage?: Record<string, number> }
| { type: 'error'; message: string; code?: string; retryable?: boolean };
export type PageMention = {
id: string;
title: string;
slugId: string;
spaceSlug?: string;
icon?: string;
};
export type ChatAttachment = {
id: string;
fileName: string;
fileExt: string;
fileSize: number;
mimeType: string;
};
@@ -0,0 +1,45 @@
import type { AiChat } from "../types/ai-chat.types";
export type ChatGroup = { key: string; label: string; chats: AiChat[] };
export function groupChatsByAge(
chats: AiChat[],
t: (key: string) => string,
): ChatGroup[] {
if (chats.length === 0) return [];
const now = new Date();
const startOfToday = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
).getTime();
const startOfYesterday = startOfToday - 24 * 60 * 60 * 1000;
const startOfLast7 = startOfToday - 7 * 24 * 60 * 60 * 1000;
const startOfLast30 = startOfToday - 30 * 24 * 60 * 60 * 1000;
const buckets: Record<string, ChatGroup> = {
today: { key: "today", label: t("Today"), chats: [] },
yesterday: { key: "yesterday", label: t("Yesterday"), chats: [] },
last7: { key: "last7", label: t("Previous 7 days"), chats: [] },
last30: { key: "last30", label: t("Previous 30 days"), chats: [] },
older: { key: "older", label: t("Older"), chats: [] },
};
for (const chat of chats) {
const ts = new Date(chat.updatedAt).getTime();
if (ts >= startOfToday) buckets.today.chats.push(chat);
else if (ts >= startOfYesterday) buckets.yesterday.chats.push(chat);
else if (ts >= startOfLast7) buckets.last7.chats.push(chat);
else if (ts >= startOfLast30) buckets.last30.chats.push(chat);
else buckets.older.chats.push(chat);
}
return [
buckets.today,
buckets.yesterday,
buckets.last7,
buckets.last30,
buckets.older,
].filter((b) => b.chats.length > 0);
}
@@ -6,6 +6,7 @@ import useUserRole from "@/hooks/use-user-role.tsx";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import EnableAiSearch from "@/ee/ai/components/enable-ai-search.tsx"; import EnableAiSearch from "@/ee/ai/components/enable-ai-search.tsx";
import EnableGenerativeAi from "@/ee/ai/components/enable-generative-ai.tsx"; import EnableGenerativeAi from "@/ee/ai/components/enable-generative-ai.tsx";
import EnableAiChat from "@/ee/ai-chat/components/enable-ai-chat.tsx";
import McpSettings from "@/ee/ai/components/mcp-settings.tsx"; import McpSettings from "@/ee/ai/components/mcp-settings.tsx";
import { Alert, Stack, Tabs } from "@mantine/core"; import { Alert, Stack, Tabs } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react"; import { IconInfoCircle } from "@tabler/icons-react";
@@ -71,6 +72,7 @@ export default function AiSettings() {
<Stack gap="md"> <Stack gap="md">
{!isCloud() && <EnableAiSearch />} {!isCloud() && <EnableAiSearch />}
<EnableGenerativeAi /> <EnableGenerativeAi />
<EnableAiChat />
</Stack> </Stack>
</Tabs.Panel> </Tabs.Panel>
@@ -31,7 +31,7 @@ export function ApiKeyCreatedModal({
<Modal <Modal
opened={opened} opened={opened}
onClose={onClose} onClose={onClose}
title={t("API key created")} title={t("{{credential}} created", { credential: t("API key") })}
size="lg" size="lg"
> >
<Stack gap="md"> <Stack gap="md">
@@ -41,7 +41,8 @@ export function ApiKeyCreatedModal({
color="red" color="red"
> >
{t( {t(
"Make sure to copy your API key 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!",
{ credential: t("API key") },
)} )}
</Alert> </Alert>
@@ -64,7 +65,7 @@ export function ApiKeyCreatedModal({
</div> </div>
<Button fullWidth onClick={onClose} mt="md"> <Button fullWidth onClick={onClose} mt="md">
{t("I've saved my API key")} {t("I've saved my {{credential}}", { credential: t("API key") })}
</Button> </Button>
</Stack> </Stack>
</Modal> </Modal>
@@ -44,7 +44,7 @@ export function ApiKeyTable({
<Table.Th>{t("Last used")}</Table.Th> <Table.Th>{t("Last used")}</Table.Th>
<Table.Th>{t("Expires")}</Table.Th> <Table.Th>{t("Expires")}</Table.Th>
<Table.Th>{t("Created")}</Table.Th> <Table.Th>{t("Created")}</Table.Th>
<Table.Th></Table.Th> <Table.Th aria-label={t("Action")} />
</Table.Tr> </Table.Tr>
</Table.Thead> </Table.Thead>
@@ -106,7 +106,11 @@ export function ApiKeyTable({
<Table.Td> <Table.Td>
<Menu position="bottom-end" withinPortal> <Menu position="bottom-end" withinPortal>
<Menu.Target> <Menu.Target>
<ActionIcon variant="subtle" color="gray"> <ActionIcon
variant="subtle"
color="gray"
aria-label={t("API key menu")}
>
<IconDots size={16} /> <IconDots size={16} />
</ActionIcon> </ActionIcon>
</Menu.Target> </Menu.Target>
@@ -105,7 +105,7 @@ export function CreateApiKeyModal({
<Modal <Modal
opened={opened} opened={opened}
onClose={handleClose} onClose={handleClose}
title={t("Create API Key")} title={t("Create {{credential}}", { credential: t("API key") })}
size="md" size="md"
> >
<form onSubmit={form.onSubmit((values) => handleSubmit(values))}> <form onSubmit={form.onSubmit((values) => handleSubmit(values))}>
@@ -30,12 +30,14 @@ export function RevokeApiKeyModal({
<Modal <Modal
opened={opened} opened={opened}
onClose={onClose} onClose={onClose}
title={t("Revoke API key")} title={t("Revoke {{credential}}", { credential: t("API key") })}
size="md" size="md"
> >
<Stack gap="md"> <Stack gap="md">
<Text> <Text>
{t("Are you sure you want to revoke this API key")}{" "} {t("Are you sure you want to revoke this {{credential}}", {
credential: t("API key"),
})}{" "}
<strong>{apiKey?.name}</strong>? <strong>{apiKey?.name}</strong>?
</Text> </Text>
<Text size="sm" c="dimmed"> <Text size="sm" c="dimmed">
@@ -53,7 +53,7 @@ export function UpdateApiKeyModal({
<Modal <Modal
opened={opened} opened={opened}
onClose={onClose} onClose={onClose}
title={t("Update API key")} title={t("Update {{credential}}", { credential: t("API key") })}
size="md" size="md"
> >
<form onSubmit={form.onSubmit((values) => handleSubmit(values))}> <form onSubmit={form.onSubmit((values) => handleSubmit(values))}>
@@ -63,7 +63,11 @@ export function useCreateApiKeyMutation() {
return useMutation<IApiKey, Error, ICreateApiKeyRequest>({ return useMutation<IApiKey, Error, ICreateApiKeyRequest>({
mutationFn: (data) => createApiKey(data), mutationFn: (data) => createApiKey(data),
onSuccess: () => { onSuccess: () => {
notifications.show({ message: t("API key created successfully") }); notifications.show({
message: t("{{credential}} created successfully", {
credential: t("API key"),
}),
});
queryClient.invalidateQueries({ queryClient.invalidateQueries({
predicate: (item) => predicate: (item) =>
["api-key-list"].includes(item.queryKey[0] as string), ["api-key-list"].includes(item.queryKey[0] as string),
@@ -33,6 +33,10 @@ export const auditEventLabels: Record<string, string> = {
"api_key.updated": "Updated API key", "api_key.updated": "Updated API key",
"api_key.deleted": "Deleted API key", "api_key.deleted": "Deleted API key",
"scim_token.created": "Created SCIM token",
"scim_token.updated": "Updated SCIM token",
"scim_token.deleted": "Deleted SCIM token",
"space.created": "Created space", "space.created": "Created space",
"space.updated": "Updated space", "space.updated": "Updated space",
"space.deleted": "Deleted space", "space.deleted": "Deleted space",
@@ -58,6 +62,13 @@ export const auditEventLabels: Record<string, string> = {
"page.restriction_removed": "Removed page restriction", "page.restriction_removed": "Removed page restriction",
"page.permission_added": "Added page permission", "page.permission_added": "Added page permission",
"page.permission_removed": "Removed page permission", "page.permission_removed": "Removed page permission",
"page.verification_created": "Created page verification",
"page.verification_updated": "Updated page verification",
"page.verification_removed": "Removed page verification",
"page.verified": "Verified page",
"page.approval_requested": "Requested page approval",
"page.approval_rejected": "Rejected page approval",
"page.marked_obsolete": "Marked page as obsolete",
"share.created": "Created share link", "share.created": "Created share link",
"share.deleted": "Deleted share link", "share.deleted": "Deleted share link",
@@ -136,6 +147,13 @@ export const eventFilterOptions: EventGroup[] = [
{ value: "page.restriction_removed", label: "Removed page restriction" }, { value: "page.restriction_removed", label: "Removed page restriction" },
{ value: "page.permission_added", label: "Added page permission" }, { value: "page.permission_added", label: "Added page permission" },
{ value: "page.permission_removed", label: "Removed page permission" }, { value: "page.permission_removed", label: "Removed page permission" },
{ value: "page.verification_created", label: "Created page verification" },
{ value: "page.verification_updated", label: "Updated page verification" },
{ value: "page.verification_removed", label: "Removed page verification" },
{ value: "page.verified", label: "Verified page" },
{ value: "page.approval_requested", label: "Requested page approval" },
{ value: "page.approval_rejected", label: "Rejected page approval" },
{ value: "page.marked_obsolete", label: "Marked page as obsolete" },
], ],
}, },
{ {
@@ -160,6 +178,14 @@ export const eventFilterOptions: EventGroup[] = [
{ value: "api_key.deleted", label: "Deleted API key" }, { value: "api_key.deleted", label: "Deleted API key" },
], ],
}, },
{
group: "SCIM token",
items: [
{ value: "scim_token.created", label: "Created SCIM token" },
{ value: "scim_token.updated", label: "Updated SCIM token" },
{ value: "scim_token.deleted", label: "Deleted SCIM token" },
],
},
{ {
group: "License", group: "License",
items: [ items: [
@@ -21,6 +21,7 @@ import { useTranslation } from "react-i18next";
import JoinedWorkspaces from "@/ee/components/joined-workspaces.tsx"; import JoinedWorkspaces from "@/ee/components/joined-workspaces.tsx";
import { useJoinedWorkspacesQuery } from "@/ee/cloud/query/cloud-query.ts"; import { useJoinedWorkspacesQuery } from "@/ee/cloud/query/cloud-query.ts";
import { findWorkspacesByEmail } from "@/ee/cloud/service/cloud-service.ts"; import { findWorkspacesByEmail } from "@/ee/cloud/service/cloud-service.ts";
import { AuthLayout } from "@/features/auth/components/auth-layout.tsx";
const formSchema = z.object({ const formSchema = z.object({
hostname: z.string().min(1, { message: "subdomain is required" }), hostname: z.string().min(1, { message: "subdomain is required" }),
@@ -82,7 +83,7 @@ export function CloudLoginForm() {
} }
return ( return (
<div> <AuthLayout>
<Container size={420} className={classes.container}> <Container size={420} className={classes.container}>
<Box p="xl" className={classes.containerBox}> <Box p="xl" className={classes.containerBox}>
<Title order={2} ta="center" fw={500} mb="md"> <Title order={2} ta="center" fw={500} mb="md">
@@ -145,12 +146,12 @@ export function CloudLoginForm() {
</Box> </Box>
</Container> </Container>
<Text ta="center"> <Text ta="center" mb="xl">
{t("Don't have a workspace?")}{" "} {t("Don't have a workspace?")}{" "}
<Anchor component={Link} to={APP_ROUTE.AUTH.CREATE_WORKSPACE} fw={500}> <Anchor component={Link} to={APP_ROUTE.AUTH.CREATE_WORKSPACE} fw={500}>
{t("Create new workspace")} {t("Create new workspace")}
</Anchor> </Anchor>
</Text> </Text>
</div> </AuthLayout>
); );
} }
+3
View File
@@ -8,6 +8,7 @@ export const Feature = {
AI: 'ai', AI: 'ai',
CONFLUENCE_IMPORT: 'import:confluence', CONFLUENCE_IMPORT: 'import:confluence',
DOCX_IMPORT: 'import:docx', DOCX_IMPORT: 'import:docx',
PDF_IMPORT: 'import:pdf',
ATTACHMENT_INDEXING: 'attachment:indexing', ATTACHMENT_INDEXING: 'attachment:indexing',
SECURITY_SETTINGS: 'security:settings', SECURITY_SETTINGS: 'security:settings',
MCP: 'mcp', MCP: 'mcp',
@@ -16,4 +17,6 @@ export const Feature = {
AUDIT_LOGS: 'audit:logs', AUDIT_LOGS: 'audit:logs',
RETENTION: 'retention', RETENTION: 'retention',
SHARING_CONTROLS: 'sharing:controls', SHARING_CONTROLS: 'sharing:controls',
TEMPLATES: 'templates',
VIEWER_COMMENTS: 'comment:viewer',
} as const; } as const;
@@ -1,6 +1,6 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import React from "react"; import React, { useRef } from "react";
import { Button, Group, Modal, Textarea } from "@mantine/core"; import { Button, Divider, Group, Modal, Stack, Textarea } from "@mantine/core";
import { useForm } from "@mantine/form"; import { useForm } from "@mantine/form";
import { zod4Resolver } from "mantine-form-zod-resolver"; import { zod4Resolver } from "mantine-form-zod-resolver";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -49,6 +49,7 @@ interface ActivateLicenseFormProps {
export function ActivateLicenseForm({ onClose }: ActivateLicenseFormProps) { export function ActivateLicenseForm({ onClose }: ActivateLicenseFormProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const activateLicenseMutation = useActivateMutation(); const activateLicenseMutation = useActivateMutation();
const fileInputRef = useRef<HTMLInputElement>(null);
const form = useForm<FormValues>({ const form = useForm<FormValues>({
validate: zod4Resolver(formSchema), validate: zod4Resolver(formSchema),
@@ -63,11 +64,38 @@ export function ActivateLicenseForm({ onClose }: ActivateLicenseFormProps) {
onClose?.(); onClose?.();
} }
function handleFileUpload(event: React.ChangeEvent<HTMLInputElement>) {
const file = event.target.files?.[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
const content = (e.target?.result as string)?.trim();
if (content) {
form.setFieldValue("licenseKey", content);
handleSubmit({ licenseKey: content });
}
};
reader.readAsText(file);
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
}
return ( return (
<form onSubmit={form.onSubmit(handleSubmit)}> <form onSubmit={form.onSubmit(handleSubmit)}>
<input
type="file"
accept=".txt,.license"
ref={fileInputRef}
onChange={handleFileUpload}
hidden
/>
<Stack gap="xs">
<Textarea <Textarea
label={t("License key")} label={t("License key")}
description="Enter a valid enterprise license key. Contact sales@docmost.com to purchase one."
placeholder={t("e.g eyJhb.....")} placeholder={t("e.g eyJhb.....")}
variant="filled" variant="filled"
autosize autosize
@@ -77,7 +105,7 @@ export function ActivateLicenseForm({ onClose }: ActivateLicenseFormProps) {
{...form.getInputProps("licenseKey")} {...form.getInputProps("licenseKey")}
/> />
<Group justify="flex-end" mt="md"> <Group justify="flex-end">
<Button <Button
type="submit" type="submit"
disabled={activateLicenseMutation.isPending} disabled={activateLicenseMutation.isPending}
@@ -86,6 +114,18 @@ export function ActivateLicenseForm({ onClose }: ActivateLicenseFormProps) {
{t("Save")} {t("Save")}
</Button> </Button>
</Group> </Group>
<Divider label={t("Or")} labelPosition="center" />
<Group justify="center">
<Button
variant="light"
onClick={() => fileInputRef.current?.click()}
>
{t("Upload license file")}
</Button>
</Group>
</Stack>
</form> </form>
); );
} }
@@ -2,14 +2,15 @@ import { Group, List, Stack, Table, Text, ThemeIcon } from "@mantine/core";
import { IconCheck } from "@tabler/icons-react"; import { IconCheck } from "@tabler/icons-react";
const enterpriseFeatures = [ const enterpriseFeatures = [
"SSO (SAML, OIDC, LDAP)", "AI Integration (Chat, Search & Assistant)",
"AI Integration (Search & Assistant)",
"Page-level Permissions",
"Audit Logs",
"API Keys",
"MCP Support", "MCP Support",
"SSO (SAML, OIDC, LDAP)",
"Multi-factor Authentication (2FA)", "Multi-factor Authentication (2FA)",
"Page-level Permissions",
"Page verification & approval workflow",
"Audit Logs",
"Enterprise Controls", "Enterprise Controls",
"API Keys",
"Advanced Search Engine Support", "Advanced Search Engine Support",
"Full-text Search in Attachments (PDF, DOCX)", "Full-text Search in Attachments (PDF, DOCX)",
"Resolve Comments", "Resolve Comments",
@@ -68,7 +69,31 @@ export default function OssDetails() {
</List> </List>
<Text size="sm" c="dimmed"> <Text size="sm" c="dimmed">
Contact <a href="mailto:sales@docmost.com?subject=Enterprise%20License%20Inquiry">sales@docmost.com </a> to purchase an enterprise license. Get an enterprise trial key at{" "}
<a
href="https://customers.docmost.com/"
target="_blank"
rel="noopener noreferrer"
>
customers.docmost.com
</a>
.
</Text>
<Text size="sm" c="dimmed">
Visit{" "}
<a
href="https://docmost.com/pricing"
target="_blank"
rel="noopener noreferrer"
>
docmost.com/pricing
</a>{" "}
to purchase an enterprise license.
</Text>
<Text size="sm" c="dimmed">
For inquiries, contact{" "}
<a href="mailto:sales@docmost.com">sales@docmost.com</a>
</Text> </Text>
</Stack> </Stack>
</Stack> </Stack>
@@ -22,6 +22,7 @@ import APP_ROUTE, { getPostLoginRedirect } from "@/lib/app-route";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { z } from "zod/v4"; import { z } from "zod/v4";
import { MfaBackupCodeInput } from "./mfa-backup-code-input"; import { MfaBackupCodeInput } from "./mfa-backup-code-input";
import { AuthLayout } from "@/features/auth/components/auth-layout.tsx";
const formSchema = z.object({ const formSchema = z.object({
code: z code: z
@@ -66,6 +67,7 @@ export function MfaChallenge() {
}; };
return ( return (
<AuthLayout>
<Container size={420} className={classes.container}> <Container size={420} className={classes.container}>
<Paper radius="lg" p={40} className={classes.paper}> <Paper radius="lg" p={40} className={classes.paper}>
<Stack align="center" gap="xl"> <Stack align="center" gap="xl">
@@ -157,5 +159,6 @@ export function MfaChallenge() {
</Stack> </Stack>
</Paper> </Paper>
</Container> </Container>
</AuthLayout>
); );
} }
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
import { MfaSetupModal } from "@/ee/mfa"; import { MfaSetupModal } from "@/ee/mfa";
import APP_ROUTE, { getPostLoginRedirect } from "@/lib/app-route.ts"; import APP_ROUTE, { getPostLoginRedirect } from "@/lib/app-route.ts";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { AuthLayout } from "@/features/auth/components/auth-layout.tsx";
export default function MfaSetupRequired() { export default function MfaSetupRequired() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -15,6 +16,7 @@ export default function MfaSetupRequired() {
}; };
return ( return (
<AuthLayout>
<Container size="sm" py="xl"> <Container size="sm" py="xl">
<Paper shadow="sm" p="xl" radius="md" withBorder> <Paper shadow="sm" p="xl" radius="md" withBorder>
<Stack> <Stack>
@@ -44,5 +46,6 @@ export default function MfaSetupRequired() {
</Stack> </Stack>
</Paper> </Paper>
</Container> </Container>
</AuthLayout>
); );
} }
@@ -140,7 +140,7 @@ export function PagePermissionList({
)} )}
</Group> </Group>
<ScrollArea mah={250} viewportRef={viewportRef}> <ScrollArea.Autosize mah={400} viewportRef={viewportRef}>
{sortedMembers.map((member) => ( {sortedMembers.map((member) => (
<PagePermissionItem <PagePermissionItem
key={`${member.type}-${member.id}`} key={`${member.type}-${member.id}`}
@@ -158,7 +158,7 @@ export function PagePermissionList({
<Loader size="xs" /> <Loader size="xs" />
</Center> </Center>
)} )}
</ScrollArea> </ScrollArea.Autosize>
</> </>
); );
} }
@@ -71,7 +71,10 @@ export function PageShareModal({ readOnly }: PageShareModalProps) {
) : null ) : null
} }
variant="default" variant="default"
onClick={open} onClick={() => {
setActiveTab(isPubliclyShared ? "publish" : hasPagePermissions ? "access" : "publish");
open();
}}
> >
{t("Share")} {t("Share")}
</Button> </Button>
@@ -0,0 +1,232 @@
import { Group, NumberInput, Select, Text } from "@mantine/core";
import { DateInput } from "@mantine/dates";
import { useTranslation } from "react-i18next";
import {
ExpirationMode,
PeriodUnit,
} from "@/ee/page-verification/types/page-verification.types";
export const PERIOD_UNIT_DAYS: Record<PeriodUnit, number> = {
day: 1,
week: 7,
month: 30,
year: 365,
};
export const PERIOD_UNIT_MAX_AMOUNT: Record<PeriodUnit, number> = {
day: 3650,
week: 520,
month: 120,
year: 20,
};
export const PERIOD_AMOUNT_MIN = 1;
export function addDays(days: number, from?: Date): Date {
const date = from ? new Date(from) : new Date();
date.setDate(date.getDate() + days);
return date;
}
function formatShortDate(date: Date): string {
const crossesYear = date.getFullYear() !== new Date().getFullYear();
return date.toLocaleDateString(undefined, {
month: "short",
day: "numeric",
...(crossesYear && { year: "numeric" }),
});
}
function formatLongDate(date: Date): string {
return date.toLocaleDateString(undefined, {
month: "long",
day: "numeric",
year: "numeric",
});
}
export function toLocalDateString(input: Date | string): string {
const d = typeof input === "string" ? new Date(input) : input;
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
function pluralizeUnit(
unit: PeriodUnit,
amount: number,
t: (key: string) => string,
): string {
switch (unit) {
case "day":
return amount === 1 ? t("day") : t("days");
case "week":
return amount === 1 ? t("week") : t("weeks");
case "month":
return amount === 1 ? t("month") : t("months");
case "year":
return amount === 1 ? t("year") : t("years");
}
}
function buildModeOptions(
t: (key: string) => string,
): { value: ExpirationMode; label: string }[] {
return [
{ value: "period", label: t("Period") },
{ value: "fixed", label: t("Fixed date") },
{ value: "indefinite", label: t("Indefinitely") },
];
}
function buildUnitOptions(
t: (key: string) => string,
): { value: PeriodUnit; label: string }[] {
return [
{ value: "day", label: t("Days") },
{ value: "week", label: t("Weeks") },
{ value: "month", label: t("Months") },
{ value: "year", label: t("Years") },
];
}
type ExpirationFieldsProps = {
mode: ExpirationMode;
periodAmount: number;
periodUnit: PeriodUnit;
fixedDate: string;
onModeChange: (mode: ExpirationMode) => void;
onPeriodAmountChange: (amount: number) => void;
onPeriodUnitChange: (unit: PeriodUnit) => void;
onFixedDateChange: (iso: string) => void;
baseDate?: Date;
};
export function ExpirationFields({
mode,
periodAmount,
periodUnit,
fixedDate,
onModeChange,
onPeriodAmountChange,
onPeriodUnitChange,
onFixedDateChange,
baseDate,
}: ExpirationFieldsProps) {
const { t } = useTranslation();
const modeOptions = buildModeOptions(t);
const unitOptions = buildUnitOptions(t);
const unitMax = PERIOD_UNIT_MAX_AMOUNT[periodUnit];
const handleUnitChange = (nextUnit: PeriodUnit) => {
const nextMax = PERIOD_UNIT_MAX_AMOUNT[nextUnit];
if (periodAmount > nextMax) {
onPeriodAmountChange(nextMax);
}
onPeriodUnitChange(nextUnit);
};
const amountValid =
Number.isInteger(periodAmount) &&
periodAmount >= PERIOD_AMOUNT_MIN &&
periodAmount <= unitMax;
const nextDueDate =
mode === "period" && amountValid
? addDays(periodAmount * PERIOD_UNIT_DAYS[periodUnit], baseDate)
: null;
const fixedDateObj = fixedDate ? new Date(fixedDate) : null;
let helperText: string | null = null;
let helperError = false;
if (mode === "period" && !amountValid) {
helperText = t("Maximum is {{max}} {{unit}} for this unit", {
max: unitMax,
unit: pluralizeUnit(periodUnit, unitMax, t),
});
helperError = true;
} else if (mode === "period" && nextDueDate && amountValid) {
helperText = t(
"Re-verifies every {{amount}} {{unit}} · Next due {{date}}",
{
amount: periodAmount,
unit: pluralizeUnit(periodUnit, periodAmount, t),
date: formatShortDate(nextDueDate),
},
);
} else if (mode === "fixed" && fixedDateObj) {
helperText = t(
"Expires on {{date}}. Re-verifying won't change the deadline.",
{ date: formatLongDate(fixedDateObj) },
);
} else if (mode === "indefinite") {
helperText = t("Never expires. Verifiers can re-verify at any time.");
}
return (
<div>
<Group align="flex-start" gap="xs" wrap="wrap">
<Select
data={modeOptions}
value={mode}
onChange={(val) => val && onModeChange(val as ExpirationMode)}
variant="filled"
allowDeselect={false}
style={{ flex: "1 1 140px", minWidth: 140 }}
/>
{mode === "period" && (
<Group
gap="xs"
wrap="nowrap"
style={{ flex: "1 1 220px", minWidth: 220 }}
>
<NumberInput
value={periodAmount}
onChange={(val) => {
const n =
typeof val === "number" ? val : parseInt(String(val), 10);
if (!Number.isNaN(n)) onPeriodAmountChange(n);
}}
min={PERIOD_AMOUNT_MIN}
max={unitMax}
clampBehavior="blur"
variant="filled"
style={{ flex: "0 0 80px" }}
hideControls
/>
<Select
data={unitOptions}
value={periodUnit}
onChange={(val) => val && handleUnitChange(val as PeriodUnit)}
variant="filled"
allowDeselect={false}
style={{ flex: 1, minWidth: 120 }}
/>
</Group>
)}
{mode === "fixed" && (
<DateInput
value={fixedDate || undefined}
onChange={(val) => onFixedDateChange(val ?? "")}
placeholder={t("Pick a date")}
variant="filled"
minDate={addDays(1)}
clearable
style={{ flex: "1 1 200px", minWidth: 180 }}
/>
)}
</Group>
{helperText && (
<Text size="xs" c={helperError ? "red" : "dimmed"} mt={6}>
{helperText}
</Text>
)}
</div>
);
}
@@ -0,0 +1,633 @@
import { useState } from "react";
import {
Button,
Center,
Checkbox,
Divider,
Group,
Loader,
Stack,
Text,
Textarea,
} from "@mantine/core";
import { modals } from "@mantine/modals";
import { useTranslation } from "react-i18next";
import {
useMarkObsoleteMutation,
usePageVerificationInfoQuery,
useRejectApprovalMutation,
useRemoveVerificationMutation,
useSubmitForApprovalMutation,
useUpdateVerificationMutation,
useVerifyPageMutation,
} from "@/ee/page-verification/queries/page-verification-query";
import {
ExpirationMode,
IPageVerificationInfo,
PeriodUnit,
} from "@/ee/page-verification/types/page-verification.types";
import { useTimeAgo } from "@/hooks/use-time-ago";
import { VerifierList } from "./verifier-list";
import {
ExpirationFields,
PERIOD_AMOUNT_MIN,
PERIOD_UNIT_MAX_AMOUNT,
toLocalDateString,
} from "./expiration-fields";
import { VerifierPicker } from "./verifier-picker";
import { MAX_VERIFIERS } from "./user-option";
type ManageVerificationFormProps = {
pageId: string;
onClose: () => void;
};
export function ManageVerificationForm({
pageId,
onClose,
}: ManageVerificationFormProps) {
const { data: info, isLoading } = usePageVerificationInfoQuery(pageId);
if (isLoading || !info) {
return (
<Center py="xl">
<Loader size="sm" />
</Center>
);
}
if (info.type === "qms") {
return <QmsManageContent pageId={pageId} info={info} onClose={onClose} />;
}
return (
<ExpiringManageContent pageId={pageId} info={info} onClose={onClose} />
);
}
type ManageContentProps = {
pageId: string;
info: IPageVerificationInfo;
onClose: () => void;
};
function ExpiringManageContent({ pageId, info, onClose }: ManageContentProps) {
const { t } = useTranslation();
const verifyMutation = useVerifyPageMutation();
const removeMutation = useRemoveVerificationMutation();
const updateMutation = useUpdateVerificationMutation();
const [confirmed, setConfirmed] = useState(false);
const initialMode: ExpirationMode = (info.mode as ExpirationMode) ?? "period";
const initialPeriodAmount = info.periodAmount ?? 1;
const initialPeriodUnit: PeriodUnit =
(info.periodUnit as PeriodUnit) ?? "month";
const initialFixedDate =
initialMode === "fixed" && info.expiresAt
? toLocalDateString(info.expiresAt)
: "";
const [mode, setMode] = useState<ExpirationMode>(initialMode);
const [periodAmount, setPeriodAmount] = useState<number>(initialPeriodAmount);
const [periodUnit, setPeriodUnit] = useState<PeriodUnit>(initialPeriodUnit);
const [fixedDate, setFixedDate] = useState<string>(initialFixedDate);
const verifiedAtAgo = useTimeAgo(info.verifiedAt ?? new Date().toISOString());
const hasExpirationChange =
mode !== initialMode ||
(mode === "period" &&
(periodAmount !== initialPeriodAmount ||
periodUnit !== initialPeriodUnit)) ||
(mode === "fixed" && fixedDate !== initialFixedDate);
const periodValid =
mode !== "period" ||
(Number.isInteger(periodAmount) &&
periodAmount >= PERIOD_AMOUNT_MIN &&
periodAmount <= PERIOD_UNIT_MAX_AMOUNT[periodUnit]);
const fixedDateValid =
mode !== "fixed" ||
(!!fixedDate && new Date(fixedDate).getTime() > Date.now());
const canSaveExpiration = hasExpirationChange && periodValid && fixedDateValid;
const storedFixedExpired =
info.mode === "fixed" &&
!!info.expiresAt &&
new Date(info.expiresAt).getTime() <= Date.now();
const existingVerifierIds = info.verifiers?.map((v) => v.id) ?? [];
const handleVerify = () => {
verifyMutation.mutate(pageId, {
onSuccess: () => {
setConfirmed(false);
onClose();
},
});
};
const handleRemove = () => {
modals.openConfirmModal({
title: t("Remove verification"),
children: (
<Text size="sm">
{t("Are you sure you want to remove verification from this page?")}
</Text>
),
labels: { confirm: t("Remove"), cancel: t("Cancel") },
confirmProps: { color: "red" },
onConfirm: () => removeMutation.mutate(pageId, { onSuccess: onClose }),
});
};
const handleSaveExpiration = () => {
if (!canSaveExpiration) return;
updateMutation.mutate({
pageId,
mode,
...(mode === "period" && {
periodAmount,
periodUnit,
}),
...(mode === "fixed" &&
fixedDate && {
fixedExpiresAt: new Date(fixedDate).toISOString(),
}),
});
};
const handleRemoveVerifier = (userId: string) => {
if (!info.verifiers) return;
const remaining = info.verifiers
.filter((v) => v.id !== userId)
.map((v) => v.id);
updateMutation.mutate({ pageId, verifierIds: remaining });
};
const handleAddVerifier = (userId: string) => {
if (!info.verifiers) return;
if (info.verifiers.some((v) => v.id === userId)) return;
const verifierIds = [...info.verifiers.map((v) => v.id), userId];
updateMutation.mutate({ pageId, verifierIds });
};
const status = info.status;
return (
<Stack>
<Text size="sm" c="dimmed">
{t("Assigned verifiers must periodically re-verify this page.")}
</Text>
{info.verifiedBy && (
<Group gap="sm">
<div>
<Text size="sm">
{status === "expired"
? t("Last verified by {{name}} {{time}} (expired)", {
name: info.verifiedBy.name,
time: verifiedAtAgo,
})
: t("Verified by {{name}} {{time}}", {
name: info.verifiedBy.name,
time: verifiedAtAgo,
})}
</Text>
{info.expiresAt && (
<Text size="xs" c="dimmed">
{t(status === "expired" ? "Expired {{date}}" : "Expires {{date}}", {
date: new Date(info.expiresAt).toLocaleDateString(undefined, {
month: "long",
day: "numeric",
year: "numeric",
}),
})}
</Text>
)}
</div>
</Group>
)}
<Divider />
{info.verifiers && info.verifiers.length > 0 && (
<>
<div>
<Text size="sm" fw={600} tt="uppercase" c="dimmed" mb={4}>
{t("Verifiers")}
</Text>
<VerifierList
verifiers={info.verifiers}
canManage={info.permissions?.canManage}
onRemove={
info.permissions?.canManage ? handleRemoveVerifier : undefined
}
/>
{info.permissions?.canManage &&
info.verifiers.length < MAX_VERIFIERS && (
<div style={{ marginTop: "var(--mantine-spacing-xs)" }}>
<VerifierPicker
excludeIds={existingVerifierIds}
onSelect={(user) => handleAddVerifier(user.value)}
/>
</div>
)}
</div>
<Divider />
</>
)}
{info.permissions?.canManage && (
<>
<div>
<Text size="sm" fw={600} mb={6}>
{t("Expiration")}
</Text>
<ExpirationFields
mode={mode}
periodAmount={periodAmount}
periodUnit={periodUnit}
fixedDate={fixedDate}
onModeChange={setMode}
onPeriodAmountChange={setPeriodAmount}
onPeriodUnitChange={setPeriodUnit}
onFixedDateChange={setFixedDate}
baseDate={
info.verifiedAt ? new Date(info.verifiedAt) : undefined
}
/>
{hasExpirationChange && (
<Button
size="compact-sm"
mt="xs"
color="dark"
onClick={handleSaveExpiration}
loading={updateMutation.isPending}
disabled={!canSaveExpiration}
>
{t("Save")}
</Button>
)}
</div>
<Divider />
</>
)}
{info.permissions?.canVerify && (
<div>
<Text size="sm" fw={600} mb={4}>
{t("Confirm")}
</Text>
<Checkbox
label={t("I've reviewed this page for accuracy")}
checked={confirmed}
onChange={(event) => setConfirmed(event.currentTarget.checked)}
color="dark"
/>
{storedFixedExpired && (
<Text size="xs" c="red" mt={6}>
{t("The fixed expiration date has passed.")}
</Text>
)}
</div>
)}
<Group justify="space-between">
{info.permissions?.canManage && (
<Button
variant="subtle"
color="red"
size="compact-sm"
onClick={handleRemove}
loading={removeMutation.isPending}
>
{t("Remove verification")}
</Button>
)}
{info.permissions?.canVerify && (
<Button
onClick={handleVerify}
disabled={!confirmed || storedFixedExpired}
loading={verifyMutation.isPending}
color={status === "expired" ? "red" : "dark"}
ml="auto"
>
{t("Verify")}
</Button>
)}
</Group>
</Stack>
);
}
function QmsManageContent({ pageId, info, onClose }: ManageContentProps) {
const { t } = useTranslation();
const verifyMutation = useVerifyPageMutation();
const submitMutation = useSubmitForApprovalMutation();
const rejectMutation = useRejectApprovalMutation();
const obsoleteMutation = useMarkObsoleteMutation();
const removeMutation = useRemoveVerificationMutation();
const updateMutation = useUpdateVerificationMutation();
const [confirmed, setConfirmed] = useState(false);
const [showRejectForm, setShowRejectForm] = useState(false);
const [rejectComment, setRejectComment] = useState("");
const verifiedAtAgo = useTimeAgo(info.verifiedAt ?? new Date().toISOString());
const requestedAtAgo = useTimeAgo(
info.requestedAt ?? new Date().toISOString(),
);
const rejectedAtAgo = useTimeAgo(info.rejectedAt ?? new Date().toISOString());
const status = info.status;
const existingVerifierIds = info.verifiers?.map((v) => v.id) ?? [];
const handleSubmitForApproval = () => {
submitMutation.mutate(pageId, { onSuccess: onClose });
};
const handleVerify = () => {
verifyMutation.mutate(pageId, {
onSuccess: () => {
setConfirmed(false);
onClose();
},
});
};
const handleReject = () => {
rejectMutation.mutate(
{ pageId, comment: rejectComment || undefined },
{
onSuccess: () => {
setShowRejectForm(false);
setRejectComment("");
onClose();
},
},
);
};
const handleMarkObsolete = () => {
modals.openConfirmModal({
title: t("Mark as obsolete"),
children: (
<Stack gap="xs">
<Text size="sm">
{t(
"Are you sure you want to mark this page as obsolete? This action cannot be undone.",
)}
</Text>
<Text size="sm" c="dimmed">
{t(
"To restore this page, you will need to remove verification and set it up again.",
)}
</Text>
</Stack>
),
labels: { confirm: t("Mark obsolete"), cancel: t("Cancel") },
confirmProps: { color: "red" },
onConfirm: () =>
obsoleteMutation.mutate(pageId, { onSuccess: onClose }),
});
};
const handleRemove = () => {
modals.openConfirmModal({
title: t("Remove verification"),
children: (
<Text size="sm">
{t("Are you sure you want to remove verification from this page?")}
</Text>
),
labels: { confirm: t("Remove"), cancel: t("Cancel") },
confirmProps: { color: "red" },
onConfirm: () => removeMutation.mutate(pageId, { onSuccess: onClose }),
});
};
const handleRemoveVerifier = (userId: string) => {
if (!info.verifiers) return;
const remaining = info.verifiers
.filter((v) => v.id !== userId)
.map((v) => v.id);
updateMutation.mutate({ pageId, verifierIds: remaining });
};
const handleAddVerifier = (userId: string) => {
if (!info.verifiers) return;
if (info.verifiers.some((v) => v.id === userId)) return;
const verifierIds = [...info.verifiers.map((v) => v.id), userId];
updateMutation.mutate({ pageId, verifierIds });
};
const canManageVerifiers =
info.permissions?.canManage && status !== "obsolete";
return (
<Stack>
<Text size="sm" c="dimmed">
{t("Pages move through draft, approval, and approved stages.")}
</Text>
{status === "draft" && (
<>
{info.rejectedBy && info.rejectedAt && (
<div>
<Text size="sm" c="red">
{t("Returned by {{name}} {{time}}", {
name: info.rejectedBy.name,
time: rejectedAtAgo,
})}
</Text>
{info.rejectionComment && (
<Text size="sm" c="dimmed" mt={4} fs="italic">
&ldquo;{info.rejectionComment}&rdquo;
</Text>
)}
</div>
)}
{!info.rejectedBy && (
<Text size="sm">{t("No approval has been requested yet.")}</Text>
)}
</>
)}
{status === "in_approval" && (
<div>
<Text size="sm">
{t("Submitted by {{name}} {{time}}", {
name: info.requestedBy?.name ?? t("Someone"),
time: requestedAtAgo,
})}
</Text>
</div>
)}
{status === "approved" && info.verifiedBy && (
<div>
<Text size="sm">
{t("Approved by {{name}} {{time}}", {
name: info.verifiedBy.name,
time: verifiedAtAgo,
})}
</Text>
</div>
)}
{status === "obsolete" && (
<Text size="sm" c="dimmed">
{t("This document has been marked as obsolete.")}
</Text>
)}
<Divider />
{info.verifiers && info.verifiers.length > 0 && (
<>
<div>
<Text size="sm" fw={600} tt="uppercase" c="dimmed" mb={4}>
{t("Verifiers")}
</Text>
<VerifierList
verifiers={info.verifiers}
canManage={canManageVerifiers}
onRemove={canManageVerifiers ? handleRemoveVerifier : undefined}
/>
{canManageVerifiers && info.verifiers.length < MAX_VERIFIERS && (
<div style={{ marginTop: "var(--mantine-spacing-xs)" }}>
<VerifierPicker
excludeIds={existingVerifierIds}
onSelect={(user) => handleAddVerifier(user.value)}
/>
</div>
)}
</div>
<Divider />
</>
)}
{status === "in_approval" && info.permissions?.canVerify && (
<>
{showRejectForm ? (
<div>
<Text size="sm" fw={600} mb={4}>
{t("Rejection comment")}
</Text>
<Textarea
value={rejectComment}
onChange={(e) => setRejectComment(e.currentTarget.value)}
placeholder={t("Reason for returning this document...")}
minRows={2}
variant="filled"
maxLength={500}
/>
<Group justify="flex-end" mt="sm" gap="xs">
<Button
variant="subtle"
color="gray"
size="compact-sm"
onClick={() => {
setShowRejectForm(false);
setRejectComment("");
}}
>
{t("Cancel")}
</Button>
<Button
color="red"
onClick={handleReject}
loading={rejectMutation.isPending}
>
{t("Confirm rejection")}
</Button>
</Group>
</div>
) : (
<div>
<Checkbox
label={t("I've reviewed this page for accuracy")}
checked={confirmed}
onChange={(event) => setConfirmed(event.currentTarget.checked)}
color="dark"
/>
</div>
)}
</>
)}
<Group justify="space-between">
{info.permissions?.canManage && (
<Button
variant="subtle"
color="red"
size="compact-sm"
onClick={handleRemove}
loading={removeMutation.isPending}
>
{t("Remove verification")}
</Button>
)}
<Group gap="xs" ml="auto">
{status === "draft" && info.permissions?.canSubmitForApproval && (
<Button
onClick={handleSubmitForApproval}
loading={submitMutation.isPending}
color="dark"
>
{t("Submit for approval")}
</Button>
)}
{status === "in_approval" &&
info.permissions?.canVerify &&
!showRejectForm && (
<>
<Button
variant="light"
color="red"
onClick={() => setShowRejectForm(true)}
>
{t("Reject")}
</Button>
<Button
onClick={handleVerify}
disabled={!confirmed}
loading={verifyMutation.isPending}
color="dark"
>
{t("Approve")}
</Button>
</>
)}
{status === "approved" && (
<>
{info.permissions?.canSubmitForApproval && (
<Button
variant="light"
onClick={handleSubmitForApproval}
loading={submitMutation.isPending}
>
{t("Re-submit for approval")}
</Button>
)}
{info.permissions?.canMarkObsolete && (
<Button
variant="light"
color="gray"
onClick={handleMarkObsolete}
loading={obsoleteMutation.isPending}
>
{t("Mark obsolete")}
</Button>
)}
</>
)}
</Group>
</Group>
</Stack>
);
}
@@ -0,0 +1,278 @@
.chooser {
display: flex;
flex-direction: column;
gap: 8px;
}
.subhead {
font-size: 12px;
line-height: 1.5;
color: light-dark(
var(--mantine-color-gray-6),
var(--mantine-color-dark-2)
);
margin-bottom: 2px;
max-width: 52ch;
}
.card {
position: relative;
display: block;
width: 100%;
padding: 14px 16px 12px;
border: 1px solid
light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
border-radius: 10px;
background: light-dark(
var(--mantine-color-white),
var(--mantine-color-dark-7)
);
cursor: pointer;
text-align: left;
overflow: hidden;
transition:
border-color 220ms cubic-bezier(0.16, 1, 0.3, 1),
transform 220ms cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1),
background-color 220ms cubic-bezier(0.16, 1, 0.3, 1);
}
.card::before {
content: "";
position: absolute;
inset: 0;
background: radial-gradient(
120% 90% at 100% 0%,
light-dark(rgba(15, 15, 20, 0.035), rgba(255, 255, 255, 0.04)),
transparent 55%
);
opacity: 0;
transition: opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);
pointer-events: none;
}
.card:hover {
border-color: light-dark(
var(--mantine-color-dark-9),
var(--mantine-color-gray-3)
);
transform: translateY(-2px);
box-shadow:
0 1px 0 0
light-dark(
rgba(15, 15, 20, 0.04),
rgba(255, 255, 255, 0.04)
),
0 18px 36px -22px
light-dark(rgba(15, 15, 20, 0.22), rgba(0, 0, 0, 0.6));
}
.card:hover::before {
opacity: 1;
}
.card:focus-visible {
outline: none;
border-color: light-dark(
var(--mantine-color-dark-9),
var(--mantine-color-gray-3)
);
box-shadow: 0 0 0 3px
light-dark(
rgba(15, 15, 20, 0.08),
rgba(255, 255, 255, 0.12)
);
}
.titleRow {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 2px;
}
.iconStamp {
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 7px;
background: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-6)
);
color: light-dark(
var(--mantine-color-dark-7),
var(--mantine-color-gray-2)
);
transition:
background-color 220ms cubic-bezier(0.16, 1, 0.3, 1),
color 220ms cubic-bezier(0.16, 1, 0.3, 1),
transform 320ms cubic-bezier(0.16, 1, 0.3, 1);
flex-shrink: 0;
}
.card:hover .iconStamp {
background: light-dark(
var(--mantine-color-dark-9),
var(--mantine-color-gray-1)
);
color: light-dark(
var(--mantine-color-gray-0),
var(--mantine-color-dark-9)
);
transform: rotate(-4deg);
}
.title {
font-size: 15px;
font-weight: 600;
letter-spacing: -0.01em;
color: light-dark(
var(--mantine-color-dark-9),
var(--mantine-color-gray-0)
);
line-height: 1.25;
margin: 0;
}
.description {
font-size: 12px;
color: light-dark(
var(--mantine-color-gray-7),
var(--mantine-color-dark-1)
);
margin: 0;
line-height: 1.45;
max-width: 52ch;
}
.rule {
height: 1px;
background: light-dark(
var(--mantine-color-gray-2),
var(--mantine-color-dark-5)
);
margin: 10px 0 8px;
}
.meta {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 10px;
}
.metaItem {
display: flex;
align-items: center;
gap: 8px;
font-size: 11.5px;
color: light-dark(
var(--mantine-color-gray-7),
var(--mantine-color-dark-1)
);
line-height: 1.35;
}
.metaIcon {
flex-shrink: 0;
color: light-dark(
var(--mantine-color-gray-5),
var(--mantine-color-dark-2)
);
}
.cardFooter {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 8px;
border-top: 1px dashed
light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-5));
gap: 12px;
}
.bestFor {
font-size: 10.5px;
color: light-dark(
var(--mantine-color-gray-6),
var(--mantine-color-dark-2)
);
font-style: italic;
letter-spacing: 0.005em;
}
.arrow {
display: flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
color: light-dark(
var(--mantine-color-gray-5),
var(--mantine-color-dark-2)
);
transition:
transform 260ms cubic-bezier(0.16, 1, 0.3, 1),
color 220ms cubic-bezier(0.16, 1, 0.3, 1);
}
.card:hover .arrow {
transform: translateX(4px);
color: light-dark(
var(--mantine-color-dark-9),
var(--mantine-color-gray-0)
);
}
.backButton {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12px;
font-weight: 500;
color: light-dark(
var(--mantine-color-gray-6),
var(--mantine-color-dark-2)
);
background: none;
border: none;
cursor: pointer;
padding: 4px 8px;
margin-left: -8px;
border-radius: 6px;
transition:
color 150ms ease,
background-color 150ms ease;
}
.backButton:hover {
color: light-dark(
var(--mantine-color-dark-9),
var(--mantine-color-gray-0)
);
background: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-6)
);
}
.configureHeader {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 4px;
}
.configureEyebrow {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.14em;
color: light-dark(
var(--mantine-color-gray-6),
var(--mantine-color-dark-2)
);
}
@@ -0,0 +1,200 @@
import {
ActionIcon,
Group,
Menu,
Modal,
Text,
ThemeIcon,
Tooltip,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import {
IconRosetteDiscountCheckFilled,
IconShieldCheck,
} from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { extractPageSlugId } from "@/lib";
import { usePageQuery } from "@/features/page/queries/page-query";
import { usePageVerificationInfoQuery } from "@/ee/page-verification/queries/page-verification-query";
import { useHasFeature } from "@/ee/hooks/use-feature";
import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label";
import { Feature } from "@/ee/features";
import { SetupVerificationForm } from "./setup-verification-form";
import { ManageVerificationForm } from "./manage-verification-form";
import { getStatusColor, getStatusLabel } from "./verification-status";
type PageVerificationModalProps = {
pageId: string;
opened: boolean;
onClose: () => void;
};
export function PageVerificationModal({
pageId,
opened,
onClose,
}: PageVerificationModalProps) {
const { t } = useTranslation();
const { data: verificationInfo } = usePageVerificationInfoQuery(
opened ? pageId : undefined,
);
const status = verificationInfo?.status ?? "none";
return (
<Modal
opened={opened}
onClose={onClose}
aria-label={status === "none" ? t("Set up verification") : t("Verify page")}
title={
<Group gap="xs">
<IconShieldCheck
size={20}
stroke={1.5}
color={
status === "verified" || status === "approved"
? "var(--mantine-color-blue-6)"
: status === "expired"
? "var(--mantine-color-red-6)"
: undefined
}
/>
<Text fw={600}>
{status === "none" ? t("Set up verification") : t("Verify page")}
</Text>
</Group>
}
size={520}
>
{status === "none" ? (
<SetupVerificationForm pageId={pageId} onClose={onClose} />
) : (
<ManageVerificationForm pageId={pageId} onClose={onClose} />
)}
</Modal>
);
}
type PageVerificationBadgeProps = {
readOnly?: boolean;
};
export function PageVerificationBadge({
readOnly,
}: PageVerificationBadgeProps) {
const { t } = useTranslation();
const { pageSlug } = useParams();
const pageSlugId = extractPageSlugId(pageSlug);
const hasVerificationFeature = useHasFeature(Feature.PAGE_VERIFICATION);
const [opened, { open, close }] = useDisclosure(false);
const { data: page } = usePageQuery({ pageId: pageSlugId });
const pageId = page?.id;
const { data: verificationInfo, isLoading } = usePageVerificationInfoQuery(
hasVerificationFeature ? pageId : undefined,
);
const upgradeLabel = useUpgradeLabel();
if (!pageId) return null;
if (!hasVerificationFeature) {
if (readOnly) return null;
return (
<Tooltip
label={`${t("Add verification")}${upgradeLabel}`}
withArrow
openDelay={250}
>
<ThemeIcon variant="subtle" color="gray">
<IconShieldCheck size={20} stroke={1.5} />
</ThemeIcon>
</Tooltip>
);
}
if (isLoading) return null;
const status = verificationInfo?.status ?? "none";
if (status === "none" && readOnly) return null;
return (
<>
{status !== "none" ? (
<Tooltip label={getStatusLabel(status, t)} withArrow openDelay={250}>
<Group
gap={4}
onClick={open}
style={{ cursor: "pointer" }}
wrap="nowrap"
>
<IconRosetteDiscountCheckFilled
size={18}
color={`var(--mantine-color-${getStatusColor(status).replace(".", "-")})`}
/>
<Text size="sm" c={getStatusColor(status)}>
{getStatusLabel(status, t)}
</Text>
</Group>
</Tooltip>
) : !readOnly ? (
<Tooltip label={t("Set up verification")} withArrow openDelay={250}>
<ActionIcon
variant="subtle"
color="gray"
aria-label={t("Set up verification")}
onClick={open}
>
<IconShieldCheck size={20} stroke={1.5} />
</ActionIcon>
</Tooltip>
) : null}
<PageVerificationModal pageId={pageId} opened={opened} onClose={close} />
</>
);
}
type PageVerificationMenuItemProps = {
pageId?: string;
onClick: () => void;
};
export function PageVerificationMenuItem({
pageId,
onClick,
}: PageVerificationMenuItemProps) {
const { t } = useTranslation();
const hasVerificationFeature = useHasFeature(Feature.PAGE_VERIFICATION);
const upgradeLabel = useUpgradeLabel();
const { data: verificationInfo } = usePageVerificationInfoQuery(
hasVerificationFeature ? pageId : undefined,
);
const hasVerification =
!!verificationInfo && verificationInfo.status !== "none";
const label = hasVerification
? t("Edit verification")
: t("Add verification");
const menuItem = (
<Menu.Item
disabled={!hasVerificationFeature}
leftSection={<IconShieldCheck size={16} />}
onClick={hasVerificationFeature ? onClick : undefined}
>
{label}
</Menu.Item>
);
if (!hasVerificationFeature) {
return (
<Tooltip label={upgradeLabel} position="left" withinPortal={false}>
{menuItem}
</Tooltip>
);
}
return menuItem;
}
@@ -0,0 +1,335 @@
import { useEffect, useRef, useState } from "react";
import {
Button,
Checkbox,
Divider,
Group,
Stack,
Text,
UnstyledButton,
} from "@mantine/core";
import {
IconArrowLeft,
IconArrowRight,
IconCertificate2,
IconCheck,
IconRefresh,
} from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import { useAtom } from "jotai";
import classes from "./page-verification-modal.module.css";
import { currentUserAtom } from "@/features/user/atoms/current-user-atom";
import { useSetupVerificationMutation } from "@/ee/page-verification/queries/page-verification-query";
import {
ExpirationMode,
PeriodUnit,
VerificationType,
} from "@/ee/page-verification/types/page-verification.types";
import {
ExpirationFields,
PERIOD_AMOUNT_MIN,
PERIOD_UNIT_MAX_AMOUNT,
} from "./expiration-fields";
import { VerifierPicker } from "./verifier-picker";
import { VerifierList } from "./verifier-list";
import { MAX_VERIFIERS, UserOptionItem } from "./user-option";
type WorkflowChooserProps = {
onSelect: (type: VerificationType) => void;
};
function WorkflowChooser({ onSelect }: WorkflowChooserProps) {
const { t } = useTranslation();
return (
<Stack gap="md">
<Text className={classes.subhead}>
{t("Choose how this page should stay accurate.")}
</Text>
<div className={classes.chooser}>
<UnstyledButton
component="button"
type="button"
className={classes.card}
onClick={() => onSelect("expiring" as VerificationType)}
>
<div className={classes.titleRow}>
<span className={classes.iconStamp}>
<IconRefresh size={15} stroke={1.7} />
</span>
<h3 className={classes.title}>{t("Recurring verification")}</h3>
</div>
<p className={classes.description}>
{t("Verifiers re-confirm this page on a schedule.")}
</p>
<div className={classes.rule} />
<div className={classes.meta}>
<div className={classes.metaItem}>
<IconCheck size={13} stroke={2.4} className={classes.metaIcon} />
{t("Re-verify on a schedule (e.g every 30 days )")}
</div>
</div>
<div className={classes.cardFooter}>
<span className={classes.bestFor}>
{t("Best for runbooks, FAQs, living documentation")}
</span>
<span className={classes.arrow}>
<IconArrowRight size={16} stroke={1.8} />
</span>
</div>
</UnstyledButton>
<UnstyledButton
component="button"
type="button"
className={classes.card}
onClick={() => onSelect("qms" as VerificationType)}
>
<div className={classes.titleRow}>
<span className={classes.iconStamp}>
<IconCertificate2 size={15} stroke={1.7} />
</span>
<h3 className={classes.title}>{t("Approval workflow")}</h3>
</div>
<p className={classes.description}>
{t("Formal document lifecycle with named approvers.")}
</p>
<div className={classes.rule} />
<div className={classes.meta}>
<div className={classes.metaItem}>
<IconCheck size={13} stroke={2.4} className={classes.metaIcon} />
{t("Draft → In approval → Approved → Obsolete")}
</div>
<div className={classes.metaItem}>
<IconCheck size={13} stroke={2.4} className={classes.metaIcon} />
{t("Designed for ISO 9001, ISO 13485, and FDA")}
</div>
</div>
<div className={classes.cardFooter}>
<span className={classes.bestFor}>
{t("Best for SOPs and controlled documents")}
</span>
<span className={classes.arrow}>
<IconArrowRight size={16} stroke={1.8} />
</span>
</div>
</UnstyledButton>
</div>
</Stack>
);
}
type SetupVerificationFormProps = {
pageId: string;
onClose: () => void;
};
export function SetupVerificationForm({
pageId,
onClose,
}: SetupVerificationFormProps) {
const { t } = useTranslation();
const setupMutation = useSetupVerificationMutation();
const [currentUser] = useAtom(currentUserAtom);
const [type, setType] = useState<VerificationType | null>(null);
const [mode, setMode] = useState<ExpirationMode>("period");
const [periodAmount, setPeriodAmount] = useState<number>(1);
const [periodUnit, setPeriodUnit] = useState<PeriodUnit>("month");
const [fixedDate, setFixedDate] = useState<string>("");
const [confirmed, setConfirmed] = useState(false);
const [selectedVerifiers, setSelectedVerifiers] = useState<UserOptionItem[]>(
[],
);
const didInitCurrentUser = useRef(false);
useEffect(() => {
if (!didInitCurrentUser.current && currentUser?.user) {
didInitCurrentUser.current = true;
const u = currentUser.user;
setSelectedVerifiers([
{
value: u.id,
label: u.name,
email: u.email,
avatarUrl: u.avatarUrl,
},
]);
}
}, [currentUser]);
const isQms = type === "qms";
const canAddMore = selectedVerifiers.length < MAX_VERIFIERS;
if (type === null) {
return <WorkflowChooser onSelect={setType} />;
}
const handleAddVerifier = (user: UserOptionItem) => {
setSelectedVerifiers((prev) =>
prev.some((v) => v.value === user.value) ? prev : [...prev, user],
);
};
const handleRemoveVerifier = (userId: string) => {
setSelectedVerifiers((prev) => prev.filter((v) => v.value !== userId));
};
const handleSetup = () => {
if (selectedVerifiers.length === 0) return;
setupMutation.mutate(
{
pageId,
type,
...(!isQms && {
mode,
...(mode === "period" && {
periodAmount,
periodUnit,
}),
...(mode === "fixed" &&
fixedDate && {
fixedExpiresAt: new Date(fixedDate).toISOString(),
}),
}),
verifierIds: selectedVerifiers.map((v) => v.value),
},
{
onSuccess: () => {
if (!isQms) {
onClose();
}
},
},
);
};
const periodValid =
mode !== "period" ||
(Number.isInteger(periodAmount) &&
periodAmount >= PERIOD_AMOUNT_MIN &&
periodAmount <= PERIOD_UNIT_MAX_AMOUNT[periodUnit]);
const fixedDateValid =
mode !== "fixed" ||
(!!fixedDate && new Date(fixedDate).getTime() > Date.now());
const hasVerifiers = selectedVerifiers.length > 0;
const canSubmit = isQms
? hasVerifiers
: hasVerifiers && confirmed && periodValid && fixedDateValid;
return (
<Stack>
<div>
<button
type="button"
className={classes.backButton}
onClick={() => setType(null)}
>
<IconArrowLeft size={12} stroke={2.2} />
{t("Back")}
</button>
<div className={classes.configureHeader}>
<span className={classes.iconStamp}>
{isQms ? (
<IconCertificate2 size={16} stroke={1.6} />
) : (
<IconRefresh size={16} stroke={1.6} />
)}
</span>
<div>
<span className={classes.configureEyebrow}>
{isQms ? t("Quality management") : t("Recurring")}
</span>
<Text size="sm" c="dimmed" mt={2}>
{isQms
? t("Pages move through draft, approval, and approved stages.")
: t(
"Assigned verifiers must periodically re-verify this page.",
)}
</Text>
</div>
</div>
</div>
<div>
<Text size="sm" fw={600} tt="uppercase" c="dimmed" mb={4}>
{t("Verifiers")}
</Text>
{selectedVerifiers.length > 0 && (
<div style={{ marginBottom: "var(--mantine-spacing-xs)" }}>
<VerifierList
verifiers={selectedVerifiers.map((v) => ({
id: v.value,
name: v.label,
email: v.email,
avatarUrl: v.avatarUrl,
}))}
canManage
onRemove={handleRemoveVerifier}
/>
</div>
)}
{canAddMore && (
<VerifierPicker
excludeIds={selectedVerifiers.map((v) => v.value)}
onSelect={handleAddVerifier}
/>
)}
</div>
{!isQms && (
<>
<Divider />
<div>
<Text size="sm" fw={600} mb={6}>
{t("Expiration")}
</Text>
<ExpirationFields
mode={mode}
periodAmount={periodAmount}
periodUnit={periodUnit}
fixedDate={fixedDate}
onModeChange={setMode}
onPeriodAmountChange={setPeriodAmount}
onPeriodUnitChange={setPeriodUnit}
onFixedDateChange={setFixedDate}
/>
</div>
<Divider />
<div>
<Text size="sm" fw={600} mb={4}>
{t("Confirm")}
</Text>
<Checkbox
label={t("I've reviewed this page for accuracy")}
checked={confirmed}
onChange={(event) => setConfirmed(event.currentTarget.checked)}
color="dark"
/>
</div>
</>
)}
<Group justify="flex-end">
<Button
onClick={handleSetup}
disabled={!canSubmit}
loading={setupMutation.isPending}
color="dark"
>
{isQms ? t("Set up") : t("Verify")}
</Button>
</Group>
</Stack>
);
}
@@ -0,0 +1,43 @@
import { Group, SelectProps, Text } from "@mantine/core";
import { CustomAvatar } from "@/components/ui/custom-avatar";
import { IUser } from "@/features/user/types/user.types";
export const MAX_VERIFIERS = 5;
export type UserOptionItem = {
value: string;
label: string;
email: string;
avatarUrl: string;
};
export function toUserOptions(users: IUser[] | undefined): UserOptionItem[] {
return (users ?? []).map((user) => ({
value: user.id,
label: user.name,
email: user.email,
avatarUrl: user.avatarUrl,
}));
}
export const renderUserSelectOption: SelectProps["renderOption"] = ({
option,
}) => (
<Group gap="sm" wrap="nowrap">
<CustomAvatar
avatarUrl={option["avatarUrl"]}
size={20}
name={option.label}
/>
<div>
<Text size="sm" lineClamp={1}>
{option.label}
</Text>
{option["email"] && (
<Text size="xs" c="dimmed" lineClamp={1}>
{option["email"]}
</Text>
)}
</div>
</Group>
);
@@ -0,0 +1,218 @@
import {
Table,
Text,
Group,
Skeleton,
Anchor,
Badge,
Avatar,
Tooltip,
} from "@mantine/core";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
IVerificationListItem,
VerificationStatus,
} from "@/ee/page-verification/types/page-verification.types";
import { CustomAvatar } from "@/components/ui/custom-avatar";
import { buildPageUrl } from "@/features/page/page.utils";
import { format } from "date-fns";
import NoTableResults from "@/components/common/no-table-results";
const MAX_VISIBLE_VERIFIERS = 5;
type VerificationListTableProps = {
items?: IVerificationListItem[];
isLoading: boolean;
};
function statusBadge(status: VerificationStatus | null, t: (s: string) => string) {
switch (status) {
case "verified":
return <Badge color="green" variant="light" size="sm">{t("Verified")}</Badge>;
case "expiring":
return <Badge color="orange" variant="light" size="sm">{t("Expiring")}</Badge>;
case "expired":
return <Badge color="red" variant="light" size="sm">{t("Expired")}</Badge>;
case "approved":
return <Badge color="green" variant="light" size="sm">{t("Approved")}</Badge>;
case "draft":
return <Badge color="gray" variant="light" size="sm">{t("Draft")}</Badge>;
case "in_approval":
return <Badge color="blue" variant="light" size="sm">{t("In approval")}</Badge>;
case "obsolete":
return <Badge color="red" variant="light" size="sm">{t("Obsolete")}</Badge>;
default:
return null;
}
}
function verifiedUntilText(item: IVerificationListItem, t: (s: string) => string): string {
if (item.type === "qms") {
if (item.status === "approved") return t("Indefinitely");
return "—";
}
if (!item.expiresAt) return t("Indefinitely");
const expires = new Date(item.expiresAt);
const now = new Date();
if (expires <= now) return t("Expired");
return format(expires, "MMM d, yyyy");
}
function TableSkeleton() {
return (
<>
{Array.from({ length: 8 }).map((_, i) => (
<Table.Tr key={i}>
<Table.Td>
<div>
<Skeleton height={14} width={160} mb={4} />
<Skeleton height={10} width={100} />
</div>
</Table.Td>
<Table.Td>
<Group gap={8} wrap="nowrap">
<Skeleton circle height={24} />
<Skeleton circle height={24} />
<Skeleton circle height={24} />
</Group>
</Table.Td>
<Table.Td>
<Skeleton height={14} width={100} />
</Table.Td>
<Table.Td>
<Skeleton height={20} width={60} />
</Table.Td>
</Table.Tr>
))}
</>
);
}
export default function VerificationListTable({
items,
isLoading,
}: VerificationListTableProps) {
const { t } = useTranslation();
return (
<Table.ScrollContainer minWidth={600}>
<Table highlightOnHover verticalSpacing="xs">
<Table.Thead>
<Table.Tr>
<Table.Th>{t("Page")}</Table.Th>
<Table.Th>{t("Verifiers")}</Table.Th>
<Table.Th>{t("Verified until")}</Table.Th>
<Table.Th>{t("Status")}</Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{isLoading ? (
<TableSkeleton />
) : items && items.length > 0 ? (
items.map((item) => {
const verifiers = item.verifiers ?? [];
const pageUrl = buildPageUrl(
item.spaceSlug,
item.pageSlugId,
item.pageTitle ?? undefined,
);
return (
<Table.Tr key={item.id}>
<Table.Td>
<Anchor
size="sm"
underline="never"
style={{ color: "var(--mantine-color-text)" }}
component={Link}
to={pageUrl}
>
<Text fz="sm" fw={500} lineClamp={1}>
{item.pageIcon ? `${item.pageIcon} ` : ""}
{item.pageTitle || t("Untitled")}
</Text>
</Anchor>
<Text fz="xs" c="dimmed" lineClamp={1}>
{item.spaceName}
</Text>
</Table.Td>
<Table.Td>
{verifiers.length === 1 ? (
<Group gap={8} wrap="nowrap">
<CustomAvatar
size="sm"
avatarUrl={verifiers[0].avatarUrl}
name={verifiers[0].name}
/>
<Text fz="sm" lineClamp={1}>
{verifiers[0].name}
</Text>
</Group>
) : verifiers.length > 1 ? (
<Tooltip.Group openDelay={300} closeDelay={100}>
<Avatar.Group spacing={8}>
{verifiers
.slice(0, MAX_VISIBLE_VERIFIERS)
.map((verifier) => (
<Tooltip
key={verifier.id}
label={verifier.name}
withArrow
>
<CustomAvatar
size="sm"
avatarUrl={verifier.avatarUrl}
name={verifier.name}
/>
</Tooltip>
))}
{verifiers.length > MAX_VISIBLE_VERIFIERS && (
<Tooltip
withArrow
label={verifiers
.slice(MAX_VISIBLE_VERIFIERS)
.map((v) => (
<div key={v.id}>{v.name}</div>
))}
>
<Avatar size="sm" color="gray">
+{verifiers.length - MAX_VISIBLE_VERIFIERS}
</Avatar>
</Tooltip>
)}
</Avatar.Group>
</Tooltip.Group>
) : (
<Text fz="sm" c="dimmed">
</Text>
)}
</Table.Td>
<Table.Td>
<Text fz="sm" style={{ whiteSpace: "nowrap" }}>
{verifiedUntilText(item, t)}
</Text>
</Table.Td>
<Table.Td>
{statusBadge(item.status as VerificationStatus, t)}
</Table.Td>
</Table.Tr>
);
})
) : (
<NoTableResults colSpan={4} />
)}
</Table.Tbody>
</Table>
</Table.ScrollContainer>
);
}
@@ -0,0 +1,43 @@
import { VerificationStatus } from "@/ee/page-verification/types/page-verification.types";
export function getStatusColor(status: VerificationStatus): string {
switch (status) {
case "verified":
case "approved":
return "blue.7";
case "expiring":
case "in_approval":
return "orange.8";
case "expired":
return "red.7";
case "draft":
case "obsolete":
return "gray.6";
default:
return "gray.6";
}
}
export function getStatusLabel(
status: VerificationStatus,
t: (key: string) => string,
): string {
switch (status) {
case "verified":
return t("Verified");
case "expiring":
return t("Review needed");
case "expired":
return t("Verification expired");
case "draft":
return t("Draft");
case "in_approval":
return t("In Approval");
case "approved":
return t("Approved");
case "obsolete":
return t("Obsolete");
default:
return "";
}
}
@@ -0,0 +1,70 @@
import { ActionIcon, Group, Text, Tooltip } from "@mantine/core";
import { IconX } from "@tabler/icons-react";
import { CustomAvatar } from "@/components/ui/custom-avatar";
import { IVerifier } from "@/ee/page-verification/types/page-verification.types";
import { useTranslation } from "react-i18next";
type VerifierListProps = {
verifiers: IVerifier[];
canManage?: boolean;
onRemove?: (userId: string) => void;
};
export function VerifierList({
verifiers,
canManage,
onRemove,
}: VerifierListProps) {
const { t } = useTranslation();
if (verifiers.length === 0) return null;
return (
<>
{verifiers.map((verifier, index) => (
<Group
key={verifier.id}
justify="space-between"
wrap="nowrap"
py={6}
style={{
borderBottom:
index < verifiers.length - 1
? "1px solid var(--mantine-color-gray-1)"
: undefined,
}}
>
<Group gap="sm" wrap="nowrap" style={{ minWidth: 0 }}>
<CustomAvatar
avatarUrl={verifier.avatarUrl}
name={verifier.name}
size={28}
/>
<div style={{ minWidth: 0 }}>
<Text size="sm" truncate="end">
{verifier.name}
</Text>
{verifier.email && (
<Text size="xs" c="dimmed" truncate="end">
{verifier.email}
</Text>
)}
</div>
</Group>
{canManage && onRemove && (
<Tooltip label={t("Remove")} withArrow>
<ActionIcon
variant="subtle"
color="gray"
size="sm"
onClick={() => onRemove(verifier.id)}
>
<IconX size={14} />
</ActionIcon>
</Tooltip>
)}
</Group>
))}
</>
);
}
@@ -0,0 +1,65 @@
import { useState } from "react";
import { Select } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { useTranslation } from "react-i18next";
import { useSearchSuggestionsQuery } from "@/features/search/queries/search-query";
import {
renderUserSelectOption,
toUserOptions,
UserOptionItem,
} from "./user-option";
type VerifierPickerProps = {
excludeIds: string[];
disabled?: boolean;
onSelect: (user: UserOptionItem) => void;
placeholder?: string;
};
export function VerifierPicker({
excludeIds,
disabled,
onSelect,
placeholder,
}: VerifierPickerProps) {
const { t } = useTranslation();
const [searchValue, setSearchValue] = useState("");
const [debouncedQuery] = useDebouncedValue(searchValue, 300);
const { data: suggestion } = useSearchSuggestionsQuery({
query: debouncedQuery,
includeUsers: true,
includeGroups: false,
preload: true,
});
const excludeSet = new Set(excludeIds);
const options = toUserOptions(suggestion?.users).filter(
(u) => !excludeSet.has(u.value),
);
const handleChange = (userId: string | null) => {
if (!userId) return;
const picked = options.find((u) => u.value === userId);
if (!picked) return;
onSelect(picked);
setSearchValue("");
};
return (
<Select
data={options}
value={null}
onChange={handleChange}
renderOption={renderUserSelectOption}
placeholder={placeholder ?? t("Add verifier")}
searchable
searchValue={searchValue}
onSearchChange={setSearchValue}
filter={({ options }) => options}
variant="filled"
disabled={disabled}
nothingFoundMessage={t("No user found")}
/>
);
}
@@ -0,0 +1,5 @@
export * from "./components/page-verification-modal";
export * from "./components/verifier-list";
export * from "./queries/page-verification-query";
export * from "./services/page-verification-service";
export * from "./types/page-verification.types";
@@ -0,0 +1,127 @@
import { useState, useMemo } from "react";
import { Group, MultiSelect, Select, Space, TextInput } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { Helmet } from "react-helmet-async";
import { useTranslation } from "react-i18next";
import { IconSearch } from "@tabler/icons-react";
import SettingsTitle from "@/components/settings/settings-title";
import { getAppName } from "@/lib/config";
import Paginate from "@/components/common/paginate";
import { useCursorPaginate } from "@/hooks/use-cursor-paginate";
import { useVerificationListQuery } from "@/ee/page-verification/queries/page-verification-query";
import { IVerificationListParams } from "@/ee/page-verification/types/page-verification.types";
import VerificationListTable from "@/ee/page-verification/components/verification-list-table";
import { useGetSpacesQuery } from "@/features/space/queries/space-query";
export default function VerifiedPages() {
const { t } = useTranslation();
const { cursor, goNext, goPrev, resetCursor } = useCursorPaginate();
const [searchValue, setSearchValue] = useState("");
const [debouncedSearch] = useDebouncedValue(searchValue, 300);
const [spaceFilter, setSpaceFilter] = useState<string[]>([]);
const [typeFilter, setTypeFilter] = useState<string | null>(null);
const { data: spacesData } = useGetSpacesQuery({ limit: 100 });
const spaceOptions = useMemo(
() =>
spacesData?.items?.map((space) => ({
value: space.id,
label: space.name,
})) ?? [],
[spacesData],
);
const typeOptions = [
{ value: "expiring", label: t("Expiring") },
{ value: "qms", label: t("QMS") },
];
const params: IVerificationListParams = useMemo(
() => ({
cursor,
limit: 50,
spaceIds: spaceFilter.length > 0 ? spaceFilter : undefined,
type: typeFilter as IVerificationListParams["type"],
query: debouncedSearch || undefined,
}),
[cursor, spaceFilter, typeFilter, debouncedSearch],
);
const { data, isLoading } = useVerificationListQuery(params);
const handleSpaceChange = (value: string[]) => {
setSpaceFilter(value);
resetCursor();
};
const handleTypeChange = (value: string | null) => {
setTypeFilter(value);
resetCursor();
};
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearchValue(e.currentTarget.value);
resetCursor();
};
return (
<>
<Helmet>
<title>
{t("Verified pages")} - {getAppName()}
</title>
</Helmet>
<SettingsTitle title={t("Verified pages")} />
<Group mb="md" gap="sm">
<TextInput
placeholder={t("Search by title")}
leftSection={<IconSearch size={16} />}
value={searchValue}
onChange={handleSearchChange}
size="sm"
w={220}
/>
{/*
<MultiSelect
placeholder={t("Filter by space")}
data={spaceOptions}
value={spaceFilter}
onChange={handleSpaceChange}
clearable
searchable
w={220}
size="sm"
/>
<Select
placeholder={t("Filter by type")}
data={typeOptions}
value={typeFilter}
onChange={handleTypeChange}
clearable
w={160}
size="sm"
/>
*/}
</Group>
<VerificationListTable items={data?.items} isLoading={isLoading} />
<Space h="md" />
{data?.items && data.items.length > 0 && (
<Paginate
hasPrevPage={data?.meta?.hasPrevPage}
hasNextPage={data?.meta?.hasNextPage}
onNext={() => goNext(data?.meta?.nextCursor)}
onPrev={goPrev}
/>
)}
</>
);
}
@@ -0,0 +1,202 @@
import {
keepPreviousData,
useMutation,
useQuery,
useQueryClient,
UseQueryResult,
} from "@tanstack/react-query";
import {
IPageVerificationInfo,
ISetupVerification,
IUpdateVerification,
IVerificationListItem,
IVerificationListParams,
} from "@/ee/page-verification/types/page-verification.types";
import {
getVerificationInfo,
getVerificationList,
markObsolete,
rejectApproval,
removeVerification,
setupVerification,
submitForApproval,
updateVerification,
verifyPage,
} from "@/ee/page-verification/services/page-verification-service";
import { notifications } from "@mantine/notifications";
import { useTranslation } from "react-i18next";
import { IPagination } from "@/lib/types";
export function usePageVerificationInfoQuery(
pageId: string | undefined,
): UseQueryResult<IPageVerificationInfo, Error> {
return useQuery({
queryKey: ["page-verification-info", pageId],
queryFn: () => getVerificationInfo(pageId!),
enabled: !!pageId,
});
}
export function useSetupVerificationMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, ISetupVerification>({
mutationFn: (data) => setupVerification(data),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", variables.pageId],
});
notifications.show({ message: t("Verification enabled") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to enable verification"),
color: "red",
});
},
});
}
export function useUpdateVerificationMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, IUpdateVerification>({
mutationFn: (data) => updateVerification(data),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", variables.pageId],
});
notifications.show({ message: t("Verification updated") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to update verification"),
color: "red",
});
},
});
}
export function useRemoveVerificationMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, string>({
mutationFn: (pageId) => removeVerification(pageId),
onSuccess: (_, pageId) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", pageId],
});
notifications.show({ message: t("Verification removed") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to remove verification"),
color: "red",
});
},
});
}
export function useVerifyPageMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, string>({
mutationFn: (pageId) => verifyPage(pageId),
onSuccess: (_, pageId) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", pageId],
});
notifications.show({ message: t("Page verified") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to verify page"),
color: "red",
});
},
});
}
export function useSubmitForApprovalMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, string>({
mutationFn: (pageId) => submitForApproval(pageId),
onSuccess: (_, pageId) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", pageId],
});
notifications.show({ message: t("Submitted for approval") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to submit for approval"),
color: "red",
});
},
});
}
export function useRejectApprovalMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, { pageId: string; comment?: string }>({
mutationFn: (data) => rejectApproval(data),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", variables.pageId],
});
notifications.show({ message: t("Approval rejected") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to reject approval"),
color: "red",
});
},
});
}
export function useMarkObsoleteMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<void, Error, string>({
mutationFn: (pageId) => markObsolete(pageId),
onSuccess: (_, pageId) => {
queryClient.invalidateQueries({
queryKey: ["page-verification-info", pageId],
});
notifications.show({ message: t("Page marked as obsolete") });
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({
message: errorMessage || t("Failed to mark as obsolete"),
color: "red",
});
},
});
}
export function useVerificationListQuery(
params?: IVerificationListParams,
): UseQueryResult<IPagination<IVerificationListItem>, Error> {
return useQuery({
queryKey: ["verification-list", params],
queryFn: () => getVerificationList(params),
placeholderData: keepPreviousData,
});
}
@@ -0,0 +1,61 @@
import api from "@/lib/api-client";
import {
IPageVerificationInfo,
ISetupVerification,
IUpdateVerification,
IVerificationListItem,
IVerificationListParams,
} from "@/ee/page-verification/types/page-verification.types";
import { IPagination } from "@/lib/types";
export async function getVerificationInfo(
pageId: string,
): Promise<IPageVerificationInfo> {
const req = await api.post<IPageVerificationInfo>(
"/pages/verification-info",
{ pageId },
);
return req.data;
}
export async function setupVerification(
data: ISetupVerification,
): Promise<void> {
await api.post("/pages/create-verification", data);
}
export async function updateVerification(
data: IUpdateVerification,
): Promise<void> {
await api.post("/pages/update-verification", data);
}
export async function removeVerification(pageId: string): Promise<void> {
await api.post("/pages/delete-verification", { pageId });
}
export async function verifyPage(pageId: string): Promise<void> {
await api.post("/pages/verify", { pageId });
}
export async function submitForApproval(pageId: string): Promise<void> {
await api.post("/pages/submit-for-approval", { pageId });
}
export async function rejectApproval(data: {
pageId: string;
comment?: string;
}): Promise<void> {
await api.post("/pages/reject-approval", data);
}
export async function markObsolete(pageId: string): Promise<void> {
await api.post("/pages/mark-obsolete", { pageId });
}
export async function getVerificationList(
params?: IVerificationListParams,
): Promise<IPagination<IVerificationListItem>> {
const req = await api.post("/pages/verifications", { ...params });
return req.data;
}
@@ -0,0 +1,104 @@
export type VerificationType = "expiring" | "qms";
export type ExpirationMode = "period" | "fixed" | "indefinite";
export type PeriodUnit = "day" | "week" | "month" | "year";
export type VerificationStatus =
| "verified"
| "expiring"
| "expired"
| "draft"
| "in_approval"
| "approved"
| "obsolete"
| "none";
export type IUserRef = {
id: string;
name: string;
avatarUrl: string | null;
};
export type IVerifier = {
id: string;
name: string;
avatarUrl: string | null;
email: string;
};
export type IPageVerificationInfo = {
id?: string;
pageId?: string;
type?: VerificationType;
mode?: ExpirationMode | null;
periodAmount?: number | null;
periodUnit?: PeriodUnit | null;
status: VerificationStatus;
verifiedAt?: string | null;
verifiedBy?: IUserRef | null;
expiresAt?: string | null;
requestedAt?: string | null;
requestedBy?: IUserRef | null;
rejectedAt?: string | null;
rejectedBy?: IUserRef | null;
rejectionComment?: string | null;
verifiers?: IVerifier[];
permissions?: IPageVerificationPermissions;
};
export type IPageVerificationPermissions = {
canVerify: boolean;
canManage: boolean;
canSubmitForApproval: boolean;
canMarkObsolete: boolean;
};
export type ISetupVerification = {
pageId: string;
type?: VerificationType;
mode?: ExpirationMode;
periodAmount?: number;
periodUnit?: PeriodUnit;
fixedExpiresAt?: string;
verifierIds: string[];
};
export type IUpdateVerification = {
pageId: string;
mode?: ExpirationMode;
periodAmount?: number;
periodUnit?: PeriodUnit;
fixedExpiresAt?: string;
verifierIds?: string[];
};
export type IVerificationListItem = {
id: string;
pageId: string;
spaceId: string;
type: VerificationType;
status: VerificationStatus | null;
mode: ExpirationMode | null;
periodAmount: number | null;
periodUnit: PeriodUnit | null;
verifiedAt: string | null;
expiresAt: string | null;
createdAt: string;
pageTitle: string | null;
pageSlugId: string;
pageIcon: string | null;
spaceName: string;
spaceSlug: string;
verifiers: IUserRef[];
};
export type IVerificationListParams = {
spaceIds?: string[];
verifierId?: string;
type?: VerificationType;
cursor?: string;
beforeCursor?: string;
limit?: number;
query?: string;
};
@@ -9,6 +9,7 @@ import {
import { notifications } from "@mantine/notifications"; import { notifications } from "@mantine/notifications";
import APP_ROUTE from "@/lib/app-route.ts"; import APP_ROUTE from "@/lib/app-route.ts";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AuthLayout } from "@/features/auth/components/auth-layout.tsx";
export default function VerifyEmail() { export default function VerifyEmail() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -59,6 +60,7 @@ export default function VerifyEmail() {
if (token) { if (token) {
return ( return (
<AuthLayout>
<Container size={420} className={classes.container}> <Container size={420} className={classes.container}>
<Box p="xl" className={classes.containerBox}> <Box p="xl" className={classes.containerBox}>
<Title order={2} ta="center" fw={500} mb="md"> <Title order={2} ta="center" fw={500} mb="md">
@@ -69,10 +71,12 @@ export default function VerifyEmail() {
</Text> </Text>
</Box> </Box>
</Container> </Container>
</AuthLayout>
); );
} }
return ( return (
<AuthLayout>
<Container size={420} className={classes.container}> <Container size={420} className={classes.container}>
<Box p="xl" className={classes.containerBox}> <Box p="xl" className={classes.containerBox}>
<Title order={2} ta="center" fw={500} mb="md"> <Title order={2} ta="center" fw={500} mb="md">
@@ -103,5 +107,6 @@ export default function VerifyEmail() {
)} )}
</Box> </Box>
</Container> </Container>
</AuthLayout>
); );
} }
@@ -0,0 +1,64 @@
import "@/features/editor/styles/index.css";
import { useEffect, useState } from "react";
import { useParams, useSearchParams } from "react-router-dom";
import ReadonlyPageEditor from "@/features/editor/readonly-page-editor";
import { Container } from "@mantine/core";
type PdfRenderData = {
pageId: string;
title: string;
content: any;
};
export default function PdfRenderPage() {
const { pageId } = useParams<{ pageId: string }>();
const [searchParams] = useSearchParams();
const token = searchParams.get("token");
const [data, setData] = useState<PdfRenderData | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (!pageId || !token) {
setError("Missing page ID or token");
return;
}
fetch('/api/pdf-export/render', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pageId, token }),
})
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then((result) => setData(result.data))
.catch((err) => setError(err.message));
}, [pageId, token]);
useEffect(() => {
if (data?.title) {
document.title = data.title;
}
}, [data?.title]);
if (error) {
return <div>{error}</div>;
}
if (!data) {
return null;
}
return (
<Container size={900} p={0}>
<ReadonlyPageEditor
key={data.pageId}
title={data.title}
content={data.content}
pageId={data.pageId}
/>
</Container>
);
}
@@ -0,0 +1,78 @@
import { Modal, TextInput, Button, Group, Stack } from "@mantine/core";
import { useForm } from "@mantine/form";
import { zod4Resolver } from "mantine-form-zod-resolver";
import { z } from "zod/v4";
import { useTranslation } from "react-i18next";
import { useCreateScimTokenMutation } from "@/ee/scim/queries/scim-token-query";
import { IScimToken } from "@/ee/scim/types/scim-token.types";
interface CreateScimTokenModalProps {
opened: boolean;
onClose: () => void;
onSuccess: (response: IScimToken) => void;
}
const formSchema = z.object({
name: z.string().min(1, "Name is required"),
});
type FormValues = z.infer<typeof formSchema>;
export function CreateScimTokenModal({
opened,
onClose,
onSuccess,
}: CreateScimTokenModalProps) {
const { t } = useTranslation();
const createMutation = useCreateScimTokenMutation();
const form = useForm<FormValues>({
validate: zod4Resolver(formSchema),
initialValues: { name: "" },
});
const handleSubmit = async (data: FormValues) => {
try {
const created = await createMutation.mutateAsync({ name: data.name });
onSuccess(created);
form.reset();
onClose();
} catch (err) {
//
}
};
const handleClose = () => {
form.reset();
onClose();
};
return (
<Modal
opened={opened}
onClose={handleClose}
title={t("Create {{credential}}", { credential: t("SCIM token") })}
size="md"
>
<form onSubmit={form.onSubmit((values) => handleSubmit(values))}>
<Stack gap="md">
<TextInput
label={t("Name")}
placeholder={t("Enter a descriptive name")}
data-autofocus
required
{...form.getInputProps("name")}
/>
<Group justify="flex-end" mt="md">
<Button variant="default" onClick={handleClose}>
{t("Cancel")}
</Button>
<Button type="submit" loading={createMutation.isPending}>
{t("Create")}
</Button>
</Group>
</Stack>
</form>
</Modal>
);
}
@@ -0,0 +1,55 @@
import { Group, Text, Switch, Tooltip } from "@mantine/core";
import { useAtom } from "jotai";
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts";
import { notifications } from "@mantine/notifications";
import { useHasFeature } from "@/ee/hooks/use-feature.ts";
import { Feature } from "@/ee/features.ts";
import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label.ts";
export default function EnableScim() {
const { t } = useTranslation();
const [workspace, setWorkspace] = useAtom(workspaceAtom);
const [checked, setChecked] = useState(workspace?.isScimEnabled ?? false);
const hasAccess = useHasFeature(Feature.SCIM);
const upgradeLabel = useUpgradeLabel();
const handleChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.currentTarget.checked;
try {
const updatedWorkspace = await updateWorkspace({ isScimEnabled: value });
setChecked(value);
setWorkspace(updatedWorkspace);
} catch (err) {
notifications.show({
message: err?.response?.data?.message,
color: "red",
});
}
};
return (
<Group justify="space-between" wrap="nowrap" gap="xl">
<div>
<Text size="md">{t("Enable SCIM")}</Text>
<Text size="sm" c="dimmed">
{t(
"Automatically provision users and groups from your identity provider via SCIM.",
)}
</Text>
</div>
<Tooltip label={upgradeLabel} disabled={hasAccess} refProp="rootRef">
<Switch
labelPosition="left"
defaultChecked={checked}
onChange={handleChange}
disabled={!hasAccess}
aria-label={t("Toggle SCIM provisioning")}
/>
</Tooltip>
</Group>
);
}
@@ -0,0 +1,61 @@
import { Modal, Text, Button, Group, Stack } from "@mantine/core";
import { useTranslation } from "react-i18next";
import { useRevokeScimTokenMutation } from "@/ee/scim/queries/scim-token-query";
import { IScimToken } from "@/ee/scim/types/scim-token.types";
interface RevokeScimTokenModalProps {
opened: boolean;
onClose: () => void;
scimToken: IScimToken | null;
}
export function RevokeScimTokenModal({
opened,
onClose,
scimToken,
}: RevokeScimTokenModalProps) {
const { t } = useTranslation();
const revokeMutation = useRevokeScimTokenMutation();
const handleRevoke = async () => {
if (!scimToken) return;
await revokeMutation.mutateAsync({ tokenId: scimToken.id });
onClose();
};
return (
<Modal
opened={opened}
onClose={onClose}
title={t("Revoke {{credential}}", { credential: t("SCIM token") })}
size="md"
>
<Stack gap="md">
<Text>
{t("Are you sure you want to revoke this {{credential}}", {
credential: t("SCIM token"),
})}{" "}
<strong>{scimToken?.name}</strong>?
</Text>
<Text size="sm" c="dimmed">
{t(
"This action cannot be undone. Your identity provider will stop syncing immediately.",
)}
</Text>
<Group justify="flex-end" mt="md">
<Button variant="default" onClick={onClose}>
{t("Cancel")}
</Button>
<Button
color="red"
onClick={handleRevoke}
loading={revokeMutation.isPending}
>
{t("Revoke")}
</Button>
</Group>
</Stack>
</Modal>
);
}

Some files were not shown because too many files have changed in this diff Show More