Compare commits

...

500 Commits
v0.2.1 ... main

Author SHA1 Message Date
60a8ed6826 sync 2025-10-25 02:08:29 +01:00
f5684b792e fix duplicated page parenting (#1692) 2025-10-23 15:00:11 +01:00
042836cb6d sync 2025-10-07 21:09:55 +01:00
4f1f0ba513 fix 2025-10-07 21:06:59 +01:00
3164b6981c feat: api keys management (EE) (#1665)
* feat: api keys (EE)

* improvements

* fix table

* fix route

* remove token suffix

* api settings

* Fix

* fix

* fix

* fix
2025-10-07 21:05:13 +01:00
16c1e864af fix comment space 2025-10-07 18:44:37 +01:00
c9b1cad982 sync 2025-10-07 18:39:30 +01:00
bf8cf6254f feat: Typesense search driver (EE) (#1664)
* feat: typesense driver (EE) - WIP

* feat: typesense driver (EE) - WIP

* feat: typesense

* sync

* fix
2025-10-07 17:34:32 +01:00
3135030376 fix editor converter (#1647) 2025-09-30 16:07:19 +01:00
3fae41a5ca fix: editor performance improvements (#1648)
* Switch to useEditorState
* change shouldRerenderOnTransaction to false
2025-09-30 14:04:01 +01:00
b50e25600a sync 2025-09-28 16:44:33 +01:00
1f3b0c7276 cloud fix 2025-09-24 21:25:39 +01:00
3c4cab0d2a v0.23.2 2025-09-18 18:00:28 +01:00
4de25a8b94 invalidate queries on space deletion 2025-09-18 15:52:53 +01:00
cf5bbb10df fix import html processing 2025-09-18 15:34:13 +01:00
ac17521717 sync 2025-09-18 13:24:16 +01:00
9ac180f719 fix: enhance page import (#1570)
* change import process

* fix processor

* fix page name in notion import

* preserve confluence table bg color

* sync
2025-09-17 23:50:27 +01:00
46669fea56 (cloud) disable page sharing in trial mode 2025-09-17 23:36:13 +01:00
fe6ecdf1f1 fix: update combobox props in SpaceSelect component (#1564)
Added 'keepMounted: false' and 'dropdownPadding: 0' to comboboxProps for improved dropdown behavior and appearance in the SpaceSelect sidebar component.
2025-09-17 13:36:12 +01:00
04ae1d7270 Allow lastColumnResizable in table 2025-09-15 22:34:29 +01:00
1280f96f37 feat: implement space and workspace icons (#1558)
* feat: implement space and workspace icons
- Create reusable AvatarUploader component supporting avatars, space icons, and workspace icons
- Add Sharp package for server-side image resizing and optimization
- Create reusable AvatarUploader component supporting avatars, space icons, and workspace icons
- Support removing icons

* add workspace logo support
- add upload loader
- add white background to transparent image
- other fixes and enhancements

* dark mode

* fixes

* cleanup
2025-09-15 21:11:37 +01:00
61d1cf88a7 fix: reset file inputs after import 2025-09-15 12:52:31 +01:00
f413720e15 - sync
- reinstantiate S3 client to fix file upload errors during import
- delete import zip file after use
2025-09-14 03:00:23 +01:00
8e16ad952a v0.23.1 2025-09-13 03:15:53 +01:00
7ada3cb1f9 fix: page import task (#1551)
* fix import

* - fix notion importer
- support notion page icon import
- fix horizontal rule css
- rename service file

* sync

* 3 mins delay
2025-09-13 03:14:59 +01:00
47c54174b3 sync 2025-09-11 00:50:15 +01:00
dc0650289d sync 2025-09-04 15:07:01 -07:00
091e790b83 fix attachment search in cloud 2025-09-04 14:22:40 -07:00
ae24ea29ba v0.23.0 2025-09-04 13:42:59 -07:00
9df6061e1a lock file 2025-09-04 13:42:33 -07:00
31053e2b20 update mermaid 2025-09-04 13:41:55 -07:00
eb8e8507ea use debug 2025-09-04 13:27:15 -07:00
c99bfb8ef1 make print better 2025-09-04 13:22:43 -07:00
26ea04e2a3 sync 2025-09-04 12:25:53 -07:00
6cc58c57f5 sync 2025-09-04 12:16:30 -07:00
7d2ff346fa UI fixes 2025-09-04 11:35:04 -07:00
b08d37fbf0 fix 2025-09-04 10:57:17 -07:00
d43ee77617 remove debug log 2025-09-04 09:40:17 -07:00
5d91eb4f5f feat: queue imported attachments for indexing 2025-09-04 09:38:30 -07:00
3e9f6b11cc Remove version from docker-compose.yml [deprecated] (#1011) 2025-09-04 03:55:32 +01:00
db55de9406 feat: progressive web app (#614)
* feat: progressive web app

* replace icons

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-09-04 01:33:52 +01:00
1919eba340 New Crowdin updates (#1522)
* 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)
2025-09-03 13:17:08 -07:00
7951b2e0c6 New Crowdin updates (#1509)
* 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 (English)

* New translations translation.json (Portuguese, Brazilian)

* 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 (English)

* New translations translation.json (Portuguese, Brazilian)
2025-09-03 18:28:30 +01:00
73b78f625d more translations 2025-09-03 10:11:19 -07:00
cf7534de3d fix version display 2025-09-03 09:37:29 -07:00
adec36d544 fix: adjust margins
- use default browser highlight background
2025-09-02 21:45:38 -07:00
f9e10805f0 sync 2025-09-02 21:38:14 -07:00
00e499b3e5 Fixing extra page bug on print (#1478) 2025-09-03 05:25:48 +01:00
5ee6e46535 checkbox aligned to text (#1486) 2025-09-03 05:23:28 +01:00
1f797c3d27 fix: confluence drawio import (#1518)
* POC

* WIP - working

* WIP

* WIP

* sync

* fix drawio preview image
2025-09-03 05:19:09 +01:00
f12866cf42 feat(EE): full-text search in attachments (#1502)
* feat(EE): fulltext search in attachments

* feat: global search
- search filters
- attachments search ui
- and more

* fix import

* fix import

* rename migration

* add GIN index

* fix table name

* sanitize
2025-09-02 05:27:01 +01:00
dcbb65d799 feat(EE): LDAP integration (#1515)
* LDAP - WIP

* WIP

* add hasGeneratedPassword

* fix jotai atom

* - don't require password confirmation for MFA is user has auto generated password (LDAP)
- cleanups

* fix

* reorder

* update migration

* update default

* fix type error
2025-09-02 04:59:01 +01:00
5968764508 feat: emoji callout icon (#1323) 2025-08-31 21:16:52 +01:00
242fb6bb57 fix: set mermaid theme based on computed color scheme (#1438) 2025-08-31 20:48:59 +01:00
74cd890bdd feat(EE): implement SSO group sync for SAML and OIDC (#1452)
* feat: implement SSO group synchronization for SAML and OIDC

- Add group_sync column to auth_providers table
- Extract groups from SAML attributes (memberOf, groups, roles)
- Extract groups from OIDC claims (groups, roles)
- Implement case-insensitive group matching with auto-creation
- Sync user groups on each SSO login
- Ensure only one provider can have group sync enabled at a time
- Add group sync toggle to SAML and OIDC configuration forms

* rename column
2025-08-31 20:33:37 +01:00
509622af54 ignore type error 2025-08-31 12:20:40 -07:00
937386e42b fix: hide table handles in readonly mode 2025-08-31 12:08:02 -07:00
60a373f488 fix: readonly editor table responsiveness 2025-08-31 12:04:27 -07:00
73ee6ee8c3 feat: subpages (child pages) list node (#1462)
* feat: subpages list node

* disable user-select

* support subpages node list in public pages
2025-08-31 18:54:52 +01:00
7d1e5bce0d feat: table row/column drag and drop (#1467)
* chore: add dev container

* feat: add drag handle when hovering cell

* feat: add column drag and drop

* feat: add support for row drag and drop

* refactor: extract preview controllers

* fix: hover issue

* refactor: add handle controller

* chore: f

* chore: remove log

* chore: remove dev files

* feat: hide other drop indicators when table dnd working

* feat: add auto scroll and bug fix

* chore: f

* fix: firefox
2025-08-31 18:53:27 +01:00
aa58e272d6 fix: exclude deleted pages (#1494) 2025-08-31 09:11:33 +01:00
08135a2fba sync 2025-08-12 11:09:26 -07:00
d92a94244f sync 2025-08-12 10:21:17 -07:00
5012a68d85 sync 2025-08-06 10:19:35 -07:00
5a3377790e feat: debug mode env variable (#1450) 2025-08-06 18:16:30 +01:00
3b85f4b616 fix: enforce C collation for page position ordering to ensure consistent behavior in Postgres 17+ (#1446)
- Add explicit C collation to position ordering queries to fix incorrect page placement in PostgreSQL 17+
- Ensures consistent ASCII-based ordering regardless of database locale settings
- Fixes issue where new pages were incorrectly placed at random positions instead of bottom
2025-08-04 09:49:29 +01:00
cb2a0398c7 fix: invalidate trashed page from tree state 2025-08-04 00:42:13 -07:00
95b7be61df fix: hide trash from can view permission (#1445) 2025-08-04 08:35:28 +01:00
b0c557272d fix nested taskList in markdown export (#1443) 2025-08-04 08:01:18 +01:00
dddfd48934 feat: add attachments support for single page exports (#1440)
* feat: add attachments support for single page exports
- Add includeAttachments option to page export modal and API
- Fix internal page url in single page exports in cloud

* remove redundant line

* preserve export state
2025-08-04 08:01:11 +01:00
aa6eec754e fix: exclude trashed pages from position generation 2025-08-04 00:00:06 -07:00
97a7701f5d fix local storage copy function (#1442) 2025-08-04 03:20:18 +01:00
b97eb85d05 sync 2025-08-03 03:59:08 -07:00
1615e0f4ad v0.22.2 2025-08-01 16:15:02 -07:00
1cb2535de3 fix trash in search (#1439)
- delete share if page is trashed
2025-08-02 00:14:00 +01:00
83bc273cb0 cleanup 2025-08-01 07:05:25 -07:00
c7beaa3742 v0.22.1 2025-08-01 06:54:28 -07:00
4a228e5a51 fix comment replies 2025-08-01 06:51:56 -07:00
edff375476 sync 2025-08-01 02:54:11 -07:00
95016b2bfc sync 2025-08-01 02:51:55 -07:00
ca83712364 cleanup 2025-08-01 02:26:14 -07:00
39550fe906 fix: duplicate page position bug (#1431) 2025-07-30 18:07:06 +01:00
e74ecb2604 v0.22.0 2025-07-29 15:22:46 -07:00
992fb23160 update lock file 2025-07-29 15:04:38 -07:00
d58a3bba9b update linkify 2025-07-29 14:59:50 -07:00
6ef47fc432 show button only if necessary 2025-07-29 14:59:23 -07:00
9e6765d83c fix 2025-07-29 14:51:55 -07:00
ec0ed5c630 fix import 2025-07-29 14:50:59 -07:00
77b334ea37 reorder migration 2025-07-29 14:49:19 -07:00
5da92a538a feat: add unaccent support for accent-insensitive search (#1402)
- Add PostgreSQL unaccent and pg_trgm extensions
- Create immutable f_unaccent wrapper function for performance
- Update all search queries to use f_unaccent for accent-insensitive matching
- Add 1MB limit to tsvector content to prevent errors on large documents
- Update full-text search trigger to use f_unaccent
- Fix MultiSelect client-side filtering to show server results properly
2025-07-29 22:47:13 +01:00
f90c5a636b cleanup comment 2025-07-29 14:30:45 -07:00
6db93ef0c7 upsell 2025-07-29 14:28:40 -07:00
a3d058042f New Crowdin updates (#1342)
* New translations translation.json (German)

* New translations translation.json (Spanish)

* New translations translation.json (Russian)

* New translations translation.json (Spanish)

* New translations translation.json (Russian)

* New translations translation.json (French)

* 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 (Ukrainian)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (Spanish)

* New translations translation.json (Russian)

* New translations translation.json (French)

* 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 (Ukrainian)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)
2025-07-29 21:53:16 +01:00
4ab9261cf5 sync 2025-07-29 13:41:07 -07:00
ca9558b246 feat(EE): resolve comments (#1420)
* feat: resolve comment (EE)

* Add resolve to comment mark in editor (EE)

* comment ui permissions

* sticky comment state tabs (EE)

* cleanup

* feat: add space_id to comments and allow space admins to delete any comment

- Add space_id column to comments table with data migration from pages
- Add last_edited_by_id, resolved_by_id, and updated_at columns to comments
- Update comment deletion permissions to allow space admins to delete any comment
- Backfill space_id on old comments

* fix foreign keys
2025-07-29 21:36:48 +01:00
ec12e80423 feat: trash for deleted pages in space (#325)
* initial commit

* added recycle bin modal, updated api routes

* updated page service & controller, recycle bin modal

* updated page-query.ts, use-tree-mutation.ts, recycled-pages.ts

* removed quotes from openRestorePageModal prompt

* Updated page.repo.ts

* move button to space menu

* fix react issues

* opted to reload to enact changes in the client

* lint

* hide deleted pages in recents, handle restore child page

* fix null check

* WIP

* WIP

* feat: implement dedicated trash page
- Replace modal-based trash view with dedicated route `/s/:spaceSlug/trash`
- Add pagination support for deleted pages
- Other improvements

* fix translation

* trash cleanup cron

* cleanup

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-07-29 21:20:49 +01:00
28fcb11cb4 update passport-saml (#1418) 2025-07-29 19:30:53 +01:00
6b627d289c fix xss in generic iframe embed (#1419) 2025-07-29 19:28:48 +01:00
78bce0e29d fix: validate public avatar path (#1416) 2025-07-28 18:17:06 +01:00
0bd7ecb9b0 feat: enhance table cells with rich content support (#1409)
- Support multiple content types in table cells and headers: paragraphs, headings, lists (bullet/ordered/task), blockquotes, callouts, images, videos, attachments, math blocks, toggles, and code blocks
- Add custom table extension with smart Tab key handling for list indentation within tables
- Preserve default table navigation when not in lists
2025-07-28 08:22:22 +01:00
1f815880a4 Revert "feat: set mermaid theme based on computed color scheme (#1397)" (#1412)
This reverts commit 32c7ecd9cf.
2025-07-26 01:34:15 +01:00
37b9056070 sync 2025-07-24 16:38:32 -07:00
ad5cf1e18b feat: add resizable embed component │ (#1401)
- Created reusable ResizableWrapper component
- Added drag-to-resize functionality for embeds
2025-07-25 00:23:14 +01:00
32c7ecd9cf feat: set mermaid theme based on computed color scheme (#1397)
Use Mantine's `useComputedColorScheme` hook to dynamically configure mermaid's theme.
- When the computed color scheme is "light", the theme is set to "default".
- Otherwise, it is set to "dark".
2025-07-25 00:22:27 +01:00
b30bf61dc4 feat: home space list (#1400) 2025-07-25 00:21:40 +01:00
662460252f feat(EE): MFA implementation (#1381)
* feat(EE): MFA implementation for enterprise edition
- Add TOTP-based two-factor authentication
- Add backup codes support
- Add MFA enforcement at workspace level
- Add MFA setup and challenge UI pages
- Support MFA for login and password reset flows
- Add MFA validation for secure pages
* fix types
* remove unused object
* sync
* remove unused type
* sync
* refactor: rename MFA enabled field to is_enabled
* sync
2025-07-25 00:18:53 +01:00
8522844673 feat: duplicate page in same space (#1394)
* fix internal links in copies pages

* feat: duplicate page in same space

* fix children
2025-07-21 21:39:57 +01:00
f8dc9845a7 fix page tree api atom (#1391)
- The tree api atom state is not always set, which makes it impossble to create new pages since the buttons rely on it.
- this should fix it.
2025-07-21 05:02:40 +01:00
4dfed2b2af queue import attachments upload (#1353) 2025-07-19 18:00:06 +01:00
44e592763d feat: quick theme toggle and Mantine 8 upgrade (#1369)
* upgrade to mantine v8

* feat: quick theme toggle
2025-07-15 06:28:27 +01:00
90488a95b1 feat: table background color, cell header and align (#1352)
* feat: add toggle header cell button to table cell menu

Added ability to toggle header cells directly from the table cell menu. This enhancement includes:
- New toggle header cell button with IconTableRow icon
- Consistent UI/UX with existing table menu patterns
- Proper internationalization support

* fix: typo in aria-label for toggle header cell button

* feat: add table cell background color picker

- Extended TableCell and TableHeader to support backgroundColor attribute
- Created TableBackgroundColor component with 21 color options
- Integrated color picker into table cell menu using Mantine UI
- Added support for both regular cells and header cells
- Updated imports to use custom TableHeader from @docmost/editor-ext

* feat: add text alignment to table cell menu

- Created TableTextAlignment component with left, center, and right alignment options
- Integrated alignment selector into table cell menu
- Shows current alignment icon in the button
- Displays checkmark next to active alignment in dropdown

* background colors

* table background color in dark mode

* add bg color name

* rename color attribute

* increase minimum table width
2025-07-15 06:27:48 +01:00
9f39987404 fix: nested ordered-list style (#1351)
* feat: dynamic ordered-list style
* fix nested task list import
2025-07-15 02:43:59 +01:00
16ec218ba7 fix: deactivated user check 2025-07-14 10:28:42 -07:00
608783b5cf (cloud) billing copy 2025-07-14 03:56:26 -07:00
5f5f1484db throw early 2025-07-14 03:53:07 -07:00
f4082171ec feat: display user email below name in multi-member-select dropdown (#1355)
- Added email field to user items mapping
- Updated renderMultiSelectOption to show email in smaller, dimmed text
- Email only displays for user type options, not groups
2025-07-14 10:37:13 +01:00
6792a191b1 feat: Ctrl/Cmd+S: prevent 'Save As' dialog (#1272)
* init

* remove: force save

* switch from event.key to event.code by sanua356
2025-07-14 10:36:24 +01:00
e51a93221c more checks for collab auth token (#1345) 2025-07-14 10:35:03 +01:00
e856c8eb69 (cloud) fix: updates to billing (#1367)
* billing updates (cloud)

* old billing grace period
2025-07-14 10:34:18 +01:00
c2c165528b fix: seamlessly update editor collab token on expiration (#1366) 2025-07-14 07:19:06 +01:00
9fa2b9636c make sure editor is ready for editor search 2025-07-13 15:38:29 -07:00
29388636bf feat: find and replace in editor (#689)
* feat: page find and replace

* * Refactor search and replace directory

* bugfix scroll

* Fix search and replace functionality for macOS and improve UX

- Fixed cmd+f shortcut to work on macOS (using 'Mod' key instead of 'Control')
- Added search functionality to title editor
- Fixed "Not found" message showing when search term is empty
- Fixed tooltip error when clicking replace button
- Changed replace button from icon to text for consistency
- Reduced width of search input fields for better UI
- Fixed result index after replace operation to prevent out-of-bounds error
- Added missing translation strings for search and replace dialog
- Updated tooltip to show platform-specific shortcuts (⌘F on Mac, Ctrl-F on others)

* Hide replace functionality for users with view-only permissions

- Added editable prop to SearchAndReplaceDialog component
- Pass editable state from PageEditor to SearchAndReplaceDialog
- Conditionally render replace button based on edit permissions
- Hide replace input section for view-only users
- Disable Alt+R shortcut when user lacks edit permissions

* Fix search dialog not closing properly when navigating away

- Clear all state (search text, replace text) when closing dialog
- Reset replace button visibility state on close
- Clear editor search term to remove highlights
- Ensure dialog closes properly when route changes

* fix: preserve text marks (comments, etc.) when replacing text in search and replace

- Collect all marks that span the text being replaced using nodesBetween
- Apply collected marks to the replacement text to maintain formatting
- Fixes issue where comment marks were being removed during text replacement

* ignore type error

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-07-10 04:40:07 +01:00
f80004817c sync 2025-07-08 16:05:34 -07:00
ac79a185de fix ctrl-a for codeblocks (#1336) 2025-07-08 22:13:21 +01:00
27a9c0ebe4 sync 2025-07-07 14:55:09 -07:00
81ffa6f459 sync 2025-07-03 04:12:24 -07:00
5364702b69 fix: comments block on edge and older browser (#1310)
* fix: overflow on edge and older browser
2025-07-01 05:14:08 +01:00
232cea8cc9 sync 2025-06-27 03:20:01 -07:00
b9643d3584 sync 2025-06-27 03:07:51 -07:00
9f144d35fb posthog integration (cloud) (#1304) 2025-06-27 10:58:36 +01:00
e44c170873 fix editor flickers on collab reconnection (#1295)
* fix editor flickers on reconnection

* cleanup

* adjust copy
2025-06-27 10:58:18 +01:00
1be39d4353 sync 2025-06-27 02:22:11 -07:00
36d028ef4d sync 2025-06-24 05:53:59 -07:00
f5a36c60e8 feat: tiered billing (cloud) (#1294)
* feat: tiered billing (cloud)

* custom tier
2025-06-24 13:22:38 +01:00
d5b84ae0b8 Only allow changing the email if the correct password is provided (#1288)
* fix

* fix overwriting password

* finalize

* BadRequestException

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-06-24 09:02:55 +01:00
e775e4dd8c fix(editor): prevent text color removal from other list items when setting color in lists (#1289)
Only unset color when 'Default' is selected. This ensures setting color on one list item does not remove it from others.
2025-06-23 19:31:30 +01:00
65b01038d7 v0.21.0 2025-06-18 14:28:14 -07:00
e07cb57b01 sync 2025-06-18 14:25:40 -07:00
2b53e0a455 fix: add import size limit to static window config 2025-06-18 13:58:41 -07:00
b9b3406b28 Fix: Prevent premature focus change in TitleEditor when pressing Enter during IME composition (#730)
* fix: Prevents key events during text composition

Stops handling title key events when composing text,
ensuring proper input behavior during IME use.

* Refines IME composition event checks

Separates IME composition control from shift key logic and adds a Safari-specific keyCode check to prevent premature focus shifts during IME input.
2025-06-18 21:33:35 +01:00
728cac0a34 fix word counter (#1269) 2025-06-18 21:32:11 +01:00
d35e16010b handle empty invitation 2025-06-18 13:10:32 -07:00
15791d4e59 sync 2025-06-18 12:50:43 -07:00
3318e13225 fix: use JWT expiry time for cookie duration (#1268)
* Set default jwt expiry to 90 days.
2025-06-18 20:50:11 +01:00
080900610d cleanup 2025-06-17 16:14:06 -07:00
d1dc6977ab feat: edit mode preference (#666)
* lock/unlock pages

* remove using isLocked column - add default page edit state preference

* * Move state management to editors (avoids flickers on edit mode switch)
* Rename variables
* Add strings to translation file
* Memoize components in page component
* Fix title editor sending update request on editable state change

* fixed errors merging main

* Fix embed view in read-only mode

* remove unused line

* sync

* fix responsiveness on mobile

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-06-18 00:11:47 +01:00
5f62448894 less create workspace form fields in cloud (#1265)
* sync

* less signup form fields in cloud

* min length
2025-06-17 23:56:07 +01:00
44445fbf46 fix: enforce SSO in invitation signups (#1258) 2025-06-15 20:25:15 +01:00
1c674efddd fix: revert tiptap version (#1255) 2025-06-13 21:38:49 +01:00
ccf7e34e99 feat: ukrainian language support (#1250) 2025-06-11 23:31:45 +01:00
f39d48d6ee New Crowdin updates (#1063)
* New translations translation.json
2025-06-11 23:21:01 +01:00
f584ea84b0 chore: upgrade packages (#1242)
* upgrade tiptap editor extensions

* upgrade packages

* fix type issue
2025-06-11 23:18:39 +01:00
bc0c4d6258 fix: make link popup work on safari (#1243)
* fix: make link popup work on safari

* fix: second iteration

* chore: cleanup

* chore: format

* chore: undo unused stuff
2025-06-11 23:09:59 +01:00
d8da307a61 feat: enhance excalidraw (#1240)
* WIP

* use next excalidraw version

* support local persistence for excalidraw library.

Co-authored-by: Drauggy <n.fomenko@safe-tech.ru>

---------

Co-authored-by: Drauggy <n.fomenko@safe-tech.ru>
2025-06-09 23:25:36 +01:00
50b3f9ddd9 generic iframe embed (#1234) 2025-06-09 22:32:23 +01:00
0029f84d50 feat: toggle table header row and column (#1203)
* feat: toggle table header row and column
* switch position
2025-06-09 05:39:43 +01:00
6d024fc3de feat: bulk page imports (#1219)
* refactor imports - WIP

* Add readstream

* WIP

* fix attachmentId render

* fix attachmentId render

* turndown video tag

* feat: add stream upload support and improve file handling

- Add stream upload functionality to storage drivers\n- Improve ZIP file extraction with better encoding handling\n- Fix attachment ID rendering issues\n- Add AWS S3 upload stream support\n- Update dependencies for better compatibility

* WIP

* notion formatter

* move embed parser to editor-ext package

* import embeds

* utility files

* cleanup

* Switch from happy-dom to cheerio
* Refine code

* WIP

* bug fixes and UI

* sync

* WIP

* sync

* keep import modal mounted

* Show modal during upload

* WIP

* WIP
2025-06-09 04:29:27 +01:00
ce1503af85 fix: sidebar list when changing workspace (#1150)
* init

* navigate in overview if current page is in deleted node

* fix: implement pagination in sidebar-pages queries

* fix: appendNodeChildren()

Preserve deeper children if they exist and remove node if deleted
2025-06-08 03:27:09 +01:00
69447fc375 Merge branch 'main' of https://github.com/docmost/docmost 2025-05-21 08:43:56 -07:00
858ff9da06 sync 2025-05-20 09:27:30 -07:00
343b2976c2 #1186/chore: add support language abap syntax highlight (#1188) 2025-05-19 20:05:31 +01:00
7491224d0f hide shared page branding in EE (#1193)
* hide shared page branding in EE

* Hide branding in business plan
2025-05-17 19:17:34 +01:00
4a0b4040ed Add second plan (#1187) 2025-05-17 19:03:01 +01:00
e3ba817723 feat: comment editor emoji picker and ctrl+enter action (#1121)
* commenteditor-emoji-picker

* capture Mac command key
* remove tooltip

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-05-16 20:01:27 +01:00
b0491d5da4 feat: create new page from mention (#1153)
* init

* create page in relative parent root
2025-05-16 19:15:11 +01:00
1c200dbd0f fix(table-hover): adjust row height to prevent unexpected scrollbar on hover (#1124)
fix: Hover table style height error causing scrollbar to appear #1108
2025-05-16 16:26:05 +01:00
fb7e4a7956 fix: copy/move select (#1174) 2025-05-16 16:24:31 +01:00
1413033568 feat: realtime comments (#1144)
* init

* fix: close bubblemenu after comment and wait before scroll

* scroll to comment when click

* highlight comment animation
2025-05-16 16:18:23 +01:00
00f4588c21 fix title update (#1154) 2025-05-16 16:11:29 +01:00
3a75251e75 fix alignment in shared page (#1123) 2025-05-16 16:00:47 +01:00
c6bca6a602 fix deprecated kysely usage 2025-05-09 16:44:33 +01:00
55d1a2c932 Fix typo in enforce-sso.tsx (#1145) 2025-05-09 11:11:02 +01:00
bc3cb2d63f fix: increase random subdomain suffix 2025-05-07 15:10:58 +01:00
7adbf85030 v0.20.4 2025-04-30 14:44:58 +01:00
de7982fe30 feat: copy page to different space (#1118)
* Add copy page to space endpoint
* copy storage function
* copy function
* feat: copy attachments too
* Copy page - WIP
* fix type
* sync
* cleanup
2025-04-30 14:43:16 +01:00
0402f7efb5 sync 2025-04-30 14:33:01 +01:00
8327251ab6 fix typo 2025-04-29 23:30:12 +01:00
e8847bd9cd fix: handle unhandled exceptions (#1116)
* Handle unhandled exceptions
* cleanup
2025-04-29 23:29:00 +01:00
9bbd62e0f0 v0.20.3 2025-04-24 23:22:53 +01:00
0289c5cb09 Reduce markdown checkbox space 2025-04-24 23:19:39 +01:00
7993532111 fix page export (#1081) 2025-04-24 23:18:54 +01:00
31e5c0c660 v0.20.2 2025-04-24 17:57:14 +01:00
33c314d4e8 remove clickoutside hook 2025-04-24 17:56:54 +01:00
08f223899a cloud trial refactor 2025-04-23 16:07:58 +01:00
c528f7e858 v0.20.1 2025-04-23 14:34:28 +01:00
c26a851d52 feat: enhance public sharing (#1057)
* fix tree nodes sort

* remove comment mark in shares

* remove clickoutside hook for now

* feat: search in shared pages

* fix user-select

* use Link

* render page icons
2025-04-23 14:32:35 +01:00
de5f90309c v0.20.0 2025-04-22 22:49:45 +01:00
0ec3ff2965 Add empty placeholder text 2025-04-22 22:48:12 +01:00
acffeacdbc fix TOC 2025-04-22 22:47:34 +01:00
00d92a3690 New Crowdin updates (#1008)
* New translations translation.json (Russian)

* New translations translation.json (Russian)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (Spanish)

* 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 (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)
2025-04-22 20:57:07 +01:00
3430f715ec feat: remember and restore previous route when exiting settings (#1046)
Improves user experience by allowing users to return to the previous
page after visiting the Settings section.

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-04-22 20:47:57 +01:00
6c422011ac feat: public page sharing (#1012)
* Share - WIP

* - public attachment links
- WIP

* WIP

* WIP

* Share - WIP

* WIP

* WIP

* include userRole in space object

* WIP

* Server render shared page meta tags

* disable user select

* Close Navbar on outside click on mobile

* update shared page spaceId

* WIP

* fix

* close sidebar on click

* close sidebar

* defaults

* update copy

* Store share key in lowercase

* refactor page breadcrumbs

* Change copy

* add link ref

* open link button

* add meta og:title

* add twitter tags

* WIP

* make shares/info endpoint public

* fix

* * add /p/ segment to share urls
* minore fixes

* change mobile breadcrumb icon
2025-04-22 20:37:32 +01:00
3e8824435d update vite and axios 2025-04-22 20:28:27 +01:00
37a1804db9 Revert "switch to vite rolldown (#1048)" (#1050)
This reverts commit 1a1b2c8682.
2025-04-22 20:00:36 +01:00
882f3093bd search space members by email (#1049) 2025-04-22 19:37:06 +01:00
1a1b2c8682 switch to vite rolldown (#1048)
* switch to vite rolldown

* update
2025-04-22 15:52:44 +01:00
10b67929ea Update README.md 2025-04-21 21:50:21 +01:00
5c957fda8d fix: nested tree open state 2025-04-21 19:24:25 +01:00
862f6d4820 use non-esm nanoid version (#1040) 2025-04-19 19:45:09 +01:00
de57d05199 0.10.2 2025-04-15 12:48:40 +01:00
89ec990232 sync ee 2025-04-15 12:46:28 +01:00
49d0f1cc9a Add click handler 2025-04-11 13:41:43 +01:00
268001ae26 v0.10.1 2025-04-11 13:23:42 +01:00
27fa45a769 fix local attachment paths in exports (#1013) 2025-04-11 13:18:44 +01:00
f9711918a3 fix comment editor padding 2025-04-11 12:32:54 +01:00
29bb52db0c v0.10.0 2025-04-09 19:14:51 +01:00
f2241db5ee remove beta message 2025-04-09 19:14:33 +01:00
58d1855a36 fix hash check 2025-04-09 19:03:27 +01:00
7fe3c5f177 * time ago hook 2025-04-09 18:47:39 +01:00
5fd477d074 collapse by default in node-edit mode 2025-04-09 15:46:29 +01:00
4aa5d7e326 hide history action menu for can-view role (#1001) 2025-04-09 15:42:29 +01:00
7f7f2bccd0 fix toggle node in non-edit mode 2025-04-09 15:37:18 +01:00
a9f370660b New Crowdin updates (#1005)
* 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 (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)

* 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 (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)
2025-04-08 17:28:33 +01:00
117c7049ff fix 2025-04-08 17:15:09 +01:00
cd10365f71 new translations 2025-04-08 17:10:48 +01:00
ee30d9d0f2 New Crowdin updates (#1003)
* New translations translation.json (French)

* New translations translation.json (Italian)

* New translations translation.json (Japanese)

* New translations translation.json (Korean)

* New translations translation.json (Russian)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)
2025-04-08 17:10:08 +01:00
276ececbf2 cleanup 2025-04-08 17:06:32 +01:00
fa194a497c cleanup 2025-04-08 17:04:43 +01:00
1eaba6e77f fix: bug fixes (#1000)
* sort by groups first

* add scroll area

* fix group members pagination

* move pagination to the right
2025-04-08 13:34:00 +01:00
651e5f6153 null check 2025-04-08 11:59:47 +01:00
7431804a46 feat: delete workspace member (#987)
* add delete user endpoint (server)

* delete user (UI)

* prevent token generation

* more checks
2025-04-07 19:26:03 +01:00
3559358d14 fix pagination issue where user is not part of any space 2025-04-07 19:09:02 +01:00
06270ff747 - fixes
- allow mail from address override
- queue cloud emails
2025-04-07 19:07:10 +01:00
233536314f feat: add Table of contents (#981)
* chore: add table of contents module

* refactor

* lint

* null check

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-04-05 19:03:42 +01:00
17ce3bab8a feat: move page between spaces (#988)
* feat: Move the page to another space

- The ability to move a page to another space has been added

* feat: Move the page to another space
* feat: Move the page to another space

- Correction of the visibility attribute of elements that extend beyond the boundaries of the space selection modal window

* feat: Move the page to another space

- Added removal of query keys when moving pages

* feat: Move the page to another space

- Fix locales

* feat: Move the page to another space
* feat: Move the page to another space

- Fix docker compose

* feat: Move the page to another space

* feat: Move the page to another space

- Some refactor

* feat: Move the page to another space

- Attachments update

* feat: Move the page to another space

- The function of searching for attachments by page ID and updating attachments has been combined

* feat: Move the page to another space

- Fix variable name

* feat: Move the page to another space

- Move current space to parameter of component SpaceSelectionModal

* refactor ui

---------

Co-authored-by: plekhanov <astecom@mail.ru>
2025-04-04 23:44:18 +01:00
b27d1708b0 queue trial ended job (#992) 2025-04-04 23:35:08 +01:00
64f0531093 feat: keep track of page contributors (#959)
* WIP

* feat: store and retrieve page contributors
2025-04-04 13:03:57 +01:00
8aa604637e feat: nested toggle block (#671)
* feat: nested toggle block

* fix: md export

* fix detailsButton icon alignment

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-04-04 13:01:39 +01:00
7ca2b437d4 sync 2025-04-03 14:08:06 +01:00
595bd1dc81 Fix editor connection loop (#986)
* fix editor connection loop

* remove query refresh
2025-04-03 14:05:34 +01:00
a74d3feae4 fix: make collab ready reliable on tab return 2025-03-27 14:39:43 +00:00
e40faf97ec v0.9.0 2025-03-23 14:07:30 +00:00
bbe4fe99f9 don't replace line breaks 2025-03-23 13:57:05 +00:00
8300c5b731 update env file 2025-03-23 13:14:20 +00:00
13039cfacc telemetry module (#934)
* update lockfile

* fix color check

* telemetry

* complete

* Use interval
2025-03-23 13:12:41 +00:00
593f41a050 adds missing command for down migration (#908) 2025-03-22 15:30:37 +00:00
f8ce160906 feat: add version check (#922)
* Add version endpoint

* version indicator

* refetch

* * Translate strings
* Handle error
2025-03-22 15:29:10 +00:00
c824b5b570 fix collab token refresh which leads to collab editor reconnection loop (#933) 2025-03-22 15:15:50 +00:00
37e760d76c * fix color check
* update lock file
2025-03-22 12:31:01 +00:00
442fa23399 Refetch space list on mount 2025-03-17 11:49:42 +00:00
2e5990d057 Move suspense above popover dropdown 2025-03-17 11:23:57 +00:00
15bdbf74cd null check 2025-03-17 11:23:18 +00:00
3d9a7d808b Revert "feat: auto focus emoji-picker search when opened (#894)" (#900)
This reverts commit 573457403e.
2025-03-17 11:17:44 +00:00
f45bdddb23 feat: billing sync (cloud) (#899)
* Set page history to 5 minutes interval

* * Configure default queue options

* sync

* * stripe seats sync (cloud)
2025-03-17 11:00:23 +00:00
21c3ad0ecc feat: enhance editor uploads (#895)
* * multi-file paste support
* allow media files (image/videos) to be attachments
* insert trailing node if file placeholder is at the end of the editor

* fix video align
2025-03-15 18:27:26 +00:00
573457403e feat: auto focus emoji-picker search when opened (#894)
Co-authored-by: JonasRingeis <jonas.ringeis@otto.de>
2025-03-15 18:25:01 +00:00
d021d0a38f fix 2025-03-14 23:02:42 +00:00
96dfe9f817 fix: page title editor bugs (#892)
* Fix page title

* compare empty page title

* Properly handle null tree node name and icon
2025-03-14 22:41:34 +00:00
598361992e fix trial days 2025-03-14 22:40:35 +00:00
210d1474ea Add Dutch translation (#877) 2025-03-13 15:26:23 +00:00
5f520689ed prevent overflow 2025-03-13 15:23:35 +00:00
2a535de29d New Crowdin updates (#840) 2025-03-13 15:10:28 +00:00
f45d9dc5a0 feat: add page stats to page menu (#876) 2025-03-13 14:54:18 +00:00
f7a14e23cd fix editor flickers (#875) 2025-03-13 08:58:21 +00:00
1f40e9b960 fix drag handle visibility (#868) 2025-03-12 13:17:59 +00:00
fea6518352 fix: VSCode markdown pasting (#857)
* fix vscode markdown pasting

* fix markdown -> html formatting
2025-03-10 02:38:22 +00:00
061a02ce51 Make codeblock comment more legible in light mode 2025-03-10 02:15:15 +00:00
2205ce0c3b prevent slider flickers 2025-03-10 01:15:21 +00:00
a812cdcf15 enable shouldRerenderOnTransaction 2025-03-09 22:49:58 +00:00
30acc6676a exclude billing webhook endpoint 2025-03-08 19:08:02 +00:00
5c9e0a2630 * prefetch sso providers in settings
* hide sso enforcement in standard plan
2025-03-08 18:26:34 +00:00
fd36076ae7 feat: disconnect collab websocket on idle tabs (#848)
* disconnect real-time collab if user is idle
* log yjs document disconnect and unload in dev mode
* no longer set editor to read-only mode on collab websocket disconnection
* treat delayed collab websocket "connecting" state as disconnected
* increase maxDebounce to 45 seconds
* add reset handle to useIdle hook
2025-03-08 18:16:23 +00:00
dd52eb15ca fix: table header in exported markdown (#769) 2025-03-07 12:16:49 +00:00
6776e073b6 feat: adding family 6 in uri to configure for both 4 and 6 (#807)
* feat: adding family 6 in uri to configure for both 4 and 6
* feat: adding redis family in websocket config
2025-03-07 12:12:19 +00:00
7a47da9273 Add emoji command to title editor 2025-03-07 11:57:28 +00:00
e62bc6c250 feat: editor emoji picker (#775)
* feat: emoji picker

* fix: lazy load emoji data

* loading animation (for slow connection)

* parsing :shortcode: and replace with emoji + add extension to title-editor

* fix

* Remove title editor support
* Remove shortcuts support
* Cleanup

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-03-07 11:53:06 +00:00
4f9e588494 sort workspace list 2025-03-07 11:51:04 +00:00
05a3dfa26d Option to log db queries in dev mode (#827) 2025-03-07 00:06:25 +00:00
8826cca539 fix space translations (#826) 2025-03-07 00:03:57 +00:00
1988feb9ce exclude /health/live endpoint 2025-03-06 23:45:41 +00:00
e9b7273489 remove cloud env check 2025-03-06 22:30:24 +00:00
315afd6818 fix cookie name 2025-03-06 21:44:53 +00:00
93ea31feb0 sync 2025-03-06 21:09:05 +00:00
3b4e414c97 * configurable trial days
* hide create sso provider in cloud
2025-03-06 21:06:24 +00:00
d925c95fc9 add pnpm to packageManager for consistency 2025-03-06 18:54:33 +00:00
4511db1526 fix 2025-03-06 18:32:25 +00:00
56d9e46fd3 * Upgrade Dockerfile to node 22
* Pin pnpm to pnpm@10.4.0
2025-03-06 18:29:15 +00:00
cdea149ce7 * Update EE license fil
* State license in Readme file
2025-03-06 17:59:22 +00:00
16254802e3 Add api prefix to attachment nodes 2025-03-06 14:19:29 +00:00
a7dd9b9198 Hide version in cloud 2025-03-06 14:17:20 +00:00
b81c9ee10c feat: cloud and ee (#805)
* stripe init
git submodules for enterprise modules

* * Cloud billing UI - WIP
* Proxy websockets in dev mode
* Separate workspace login and creation for cloud
* Other fixes

* feat: billing (cloud)

* * add domain service
* prepare links from workspace hostname

* WIP

* Add exchange token generation
* Validate JWT token type during verification

* domain service

* add SkipTransform decorator

* * updates (server)
* add new packages
* new sso migration file

* WIP

* Fix hostname generation

* WIP

* WIP

* Reduce input error font-size
* set max password length

* jwt package

* license page - WIP

* * License management UI
* Move license key store to db

* add reflector

* SSO enforcement

* * Add default plan
* Add usePlan hook

* * Fix auth container margin in mobile
* Redirect login and home to select page in cloud

* update .gitignore

* Default to yearly

* * Trial messaging
* Handle ended trials

* Don't set to readonly on collab disconnect (Cloud)

* Refine trial (UI)
* Fix bug caused by using jotai optics atom in AppHeader component

* configurable database maximum pool

* Close SSO form on save

* wip

* sync

* Only show sign-in in cloud

* exclude base api part from workspaceId check

* close db connection beforeApplicationShutdown

* Add health/live endpoint

* clear cookie on hostname change

* reset currentUser atom

* Change text

* return 401 if workspace does not match

* feat: show user workspace list in cloud login page

* sync

* Add home path

* Prefetch to speed up queries

* * Add robots.txt
* Disallow login and forgot password routes

* wildcard user-agent

* Fix space query cache

* fix

* fix

* use space uuid for recent pages

* prefetch billing plans

* enhance license page

* sync
2025-03-06 13:38:37 +00:00
91596be70e fix: add missing awaits (#814) 2025-03-06 10:14:30 +00:00
72f64e7b10 revert sentry (#808)
* revert sentry
* remove sentry env
2025-02-27 15:58:32 +00:00
3cfb17bb62 fix sentry 2025-02-27 14:44:28 +00:00
fe5066c7b5 v0.8.4 2025-02-27 14:34:38 +00:00
e13be904cd cleanup 2025-02-27 14:18:25 +00:00
fda5c7d60f push files left (#360) (#804) 2025-02-26 18:33:50 +00:00
7fc1a782a7 feat: add copy invite link to invitation action menu (#360)
* +copy invite link to clipboard from invite action menu

* -remove log to console for copy link action

* Refactor copy invite link feature

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-02-26 18:28:44 +00:00
54d27af76a * Add SENTRY_DNS env variable
* Commit lock file
2025-02-26 17:38:25 +00:00
0065f29634 feat: sentry (#802) 2025-02-26 15:42:19 +00:00
7d034e8a8b enable trustProxy 2025-02-26 13:16:11 +00:00
81b6c7ef69 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-02-26 13:14:45 +00:00
89f6b0a8c2 feat: add stats to standalone collab server (#798)
* Log APP_URL on startup

* add stats endpoint to standalone collab server
2025-02-26 13:00:01 +00:00
ad1571b902 Log APP_URL on startup 2025-02-26 11:49:58 +00:00
4b9ab4f63c feat: standalone collab server (#767)
* feat: standalone collab server

* * custom collab server port env
* fix collab start script command

* * API prefix
* Log startup PORT

* Tweak collab debounce
2025-02-25 13:15:51 +00:00
08829ea721 v0.8.3 2025-02-22 12:25:49 +00:00
6c502b4749 pin react-email version (#779) 2025-02-22 12:16:02 +00:00
6b41538b60 v0.8.2 2025-02-21 13:16:16 +00:00
496f5d7384 pin s3 package to 3.701.0 2025-02-21 13:15:19 +00:00
32c7a16d06 fix: accept invitation password hashing (#773) 2025-02-21 12:48:25 +00:00
64ecef09bc upgrade to NestJS 11 (#766)
* upgrade to nest 11

* update dependencies
2025-02-20 21:17:03 +00:00
3e5cb92621 v0.8.1 2025-02-18 16:59:27 +00:00
fd5ad2f576 fix signup email 2025-02-18 16:26:16 +00:00
74a5360561 v0.8.0 2025-02-18 11:14:16 +00:00
7580e8d1fe fix pagination limit 2025-02-15 14:15:39 +00:00
f92d63261d Implement space member search (#731)
* Hide pagination buttons if there is nothing to paginate
* Create reusable hook for search and pagination
2025-02-15 14:14:30 +00:00
4d51986250 update dependences (#729) 2025-02-14 16:59:19 +00:00
e209aaa272 feat: internal page links and mentions (#604)
* Work on mentions

* fix: properly parse page slug

* fix editor suggestion bugs

* mentions must start with whitespace

* add icon to page mention render

* feat: backlinks - WIP

* UI - WIP

* permissions check
* use FTS for page suggestion

* cleanup

* WIP

* page title fallback

* feat: handle internal link paste

* link styling

* WIP

* Switch back to LIKE operator for search suggestion

* WIP
* scope to workspaceId
* still create link for pages not found

* select necessary columns

* cleanups
2025-02-14 15:36:44 +00:00
0ef6b1978a feat: UI pagination and members search (#724)
* feat: pagination (UI)

* Fixes

* feat: add search to member list page

* responsiveness
2025-02-13 23:28:00 +00:00
ae842f94d0 * fix: popover does not close when clicking outside in SwitchSpace. (#720) 2025-02-12 16:14:21 +00:00
7121771f92 fix workspace setup 2025-02-12 15:33:08 +00:00
040d6625df fix: enforce 32-character minimum length for APP_SECRET (#702)
* Enforce 32 characters minimum APP_SECRET length

* update APP_SECRET comment
2025-02-06 17:46:32 +00:00
33ddd92198 * fix codeblock tab-size (#703)
* hide codeblock menu group during printing
2025-02-06 17:43:31 +00:00
54e8d60840 New language options (es-ES, it-IT, ja-JP, ko-KR, ru-RU) (#701) 2025-02-06 16:47:41 +00:00
db986038c2 New Crowdin updates (#659)
New translations
2025-02-06 16:44:48 +00:00
de0b5f0046 feat: add text alignment (#667)
* feat: text alignment

* fix text case

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-02-06 16:24:36 +00:00
638b811857 fix import 2025-02-03 21:51:09 +00:00
d775a61c95 fix client side env variable refresh (#695) 2025-02-03 21:47:38 +00:00
0f74f03264 fix name extraction from email 2025-01-30 22:13:23 +00:00
f8b93ce93f fix: switch space bug (#692) 2025-01-30 21:14:11 +00:00
85d18b8cc8 Set default language on invitation signup (#691)
* Default language selection to en-US if locale is undefined (Client)
2025-01-30 13:25:10 +00:00
4d9fe6f804 Fix invitation signup redirect (#690)
* Fix invitation signup redirect
2025-01-30 12:54:02 +00:00
85159a2c95 * fix 401 redirect in auth routes (#674)
* fix config getter
2025-01-26 14:01:08 +00:00
990612793f refactor: switch to HttpOnly cookie (#660)
* Switch to httpOnly cookie
* create endpoint to retrieve temporary collaboration token

* cleanups
2025-01-22 22:11:11 +00:00
f2235fd2a2 update katex (#658) 2025-01-22 18:08:31 +00:00
2044cbb21c fix translation
* fix filesize formatting
2025-01-16 15:29:09 +00:00
3d52b82cd4 v0.7.0 2025-01-16 13:15:39 +00:00
89a2dd602b fix punycode DeprecationWarning error (#631) 2025-01-16 13:13:14 +00:00
3cb954db69 fix: editor improvements (#583)
* delete unused component

* return page prosemirror content

* prefetch pages

* use prosemirro json content on editor

* cache page query with id and slug as key

* Show notice on collaboration disconnection

* enable scroll while typing

* enable immediatelyRender

* avoid image break in PDF print

* Comment editor rendering props
2025-01-16 12:48:35 +00:00
71cfe3cd8e fix: add cancel button for editing comments (#580)
* fix: add cancel button for editing comments

* cleanup

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-01-15 16:37:57 +00:00
f7efb6c2c9 Fix: Ensure only one emoji list appears (#572)
* Fix: Ensure only one emoji list appears

* fix: refactor logic

* remove unused file node-id-atoms

* small fix

* align with Mantine UI

* close emoji picker on escape

* translate string

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2025-01-15 16:07:26 +00:00
59b514fa26 New Crowdin updates (#630)
* New translations translation.json
2025-01-15 14:18:05 +00:00
0c1f9304f4 New Crowdin updates (#627)
New translations translation.json
2025-01-15 14:12:48 +00:00
e876214eeb fix: embed provider name in error message 2025-01-11 22:25:51 +00:00
5fece5fc68 feat: google sheets embed (#615) 2025-01-11 22:22:06 +00:00
f3dbf7cc5d feat: add new languages to selection (#626)
* Add new languages to selection

* more translations
2025-01-11 22:11:31 +00:00
f7ac6bb4bb New Crowdin updates (#605)
* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (Spanish)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (English)

* New translations translation.json (Portuguese, Brazilian)

* New translations translation.json (French)

* New translations translation.json (German)

* New translations translation.json (Chinese Simplified)

* New translations translation.json (Portuguese, Brazilian)
2025-01-11 15:38:32 +00:00
1f5ffe7f9d Fix empty translation value 2025-01-11 15:34:27 +00:00
95715421c6 fix: move markdown clipboard extension to client app 2025-01-04 21:25:05 +00:00
f5bc99b449 fix: link paste handler (#609)
* feat: support pasting markdown

* fix link paste handler
2025-01-04 20:47:49 +00:00
287b833838 feat: support pasting markdown (#606) 2025-01-04 16:57:36 +00:00
0cbbcb8eb1 Update Crowdin configuration file 2025-01-04 13:22:31 +00:00
670ee64179 Support I18n (#243)
* feat: support i18n

* feat: wip support i18n

* feat: complete space translation

* feat: complete page translation

* feat: update space translation

* feat: update workspace translation

* feat: update group translation

* feat: update workspace translation

* feat: update page translation

* feat: update user translation

* chore: update pnpm-lock

* feat: add query translation

* refactor: merge to single file

* chore: remove necessary code

* feat: save language to BE

* fix: only load current language

* feat: save language to locale column

* fix: cleanups

* add language menu to preferences page

* new translations

* translate editor

* Translate editor placeholders

* translate space selection component

---------

Co-authored-by: Philip Okugbe <phil@docmost.com>
Co-authored-by: Philip Okugbe <16838612+Philipinho@users.noreply.github.com>
2025-01-04 13:17:17 +00:00
290b7d9d94 v0.6.2 2024-12-14 20:39:19 +00:00
2503bfd3a2 fix: prevent CDNs from caching attachments (#562) 2024-12-14 19:55:49 +00:00
f48d6dd60b fix: don't throw error while parsing auth tokens 2024-12-12 14:29:25 +00:00
1302b1b602 v0.6.1 2024-12-11 14:55:06 +00:00
89a3f4cfc2 v0.6.1 2024-12-11 14:54:19 +00:00
e48b1c0dae fix: markdown math import (#529)
* fix: markdown math block import

* fix: block and inline math import

* cleanup
2024-12-09 15:08:25 +00:00
4a2a5a7a4d fix: postgres and redis url validation (#548) 2024-12-09 14:56:15 +00:00
532001fd82 chore: fix linting (#544)
* fix: eslint (server)

* fix: eslint (client)

* commit package lock file

* fix linting
2024-12-09 14:51:31 +00:00
e6bf4cdd6c fix: fix markdown import file button (#542) 2024-12-06 12:26:55 +00:00
a9a4a26db5 fix export controller reference in module 2024-11-30 20:42:31 +00:00
ede5633415 fix export fileName 2024-11-30 20:40:53 +00:00
a25cf84671 fix: add spaceId 2024-11-30 20:29:13 +00:00
a37d558bac v0.6.0 2024-11-30 20:06:44 +00:00
ddb0f9225f fix: uuid7 for commentId (#524) 2024-11-30 20:04:50 +00:00
c717847ca8 chore: update packages (#507) 2024-11-30 19:54:04 +00:00
fe83557767 feat: space export (#506)
* wip

* Space export
* option to export pages with children
* include attachments in exports
* unified export UI

* cleanup

* fix: change export icon

* add export button to space settings

* cleanups

* export name
2024-11-30 19:47:22 +00:00
9fa432dba9 feat: support tab key in code block (#523) 2024-11-30 14:40:05 +00:00
c6aaefecbd fix: clear local cache on logout (#519) 2024-11-28 20:35:53 +00:00
311d81bc71 fix wrong tree sync bug (#514) 2024-11-28 19:39:38 +00:00
f178e6654f fix: properly support redis db (#517) 2024-11-28 18:54:28 +00:00
ca186f3c0e fix: return direct embed urls if present (#516) 2024-11-28 18:53:49 +00:00
a16d5d1bf4 feat: websocket rooms (#515) 2024-11-28 18:53:29 +00:00
d97baf5824 add env variable (#513) 2024-11-28 18:48:25 +00:00
8349d8271c fix: allow space in inline math (#508) 2024-11-28 18:48:08 +00:00
2e6d16dbc3 fix: full width bug on smaller screens (#518) 2024-11-28 18:44:42 +00:00
4107793e73 fix: disable user-select 2024-11-28 15:55:10 +00:00
a1b6ac7f3e fix: close space selection popover onClickOutside (#485) 2024-11-27 02:32:12 +00:00
dd0319a14d fix: index imported content (#495) 2024-11-20 13:36:36 +00:00
8194c7d42d fix: focus editor on bottom click (#484) 2024-11-13 20:00:25 +00:00
d01ced078b * Reduce code block font-size
* Make inline code more distinctive
2024-11-13 11:36:55 -08:00
da9c971050 fix breadcrumb clipping (#457) 2024-11-13 19:15:37 +00:00
4e7af507c6 fix tree dnd 2024-11-06 19:29:12 -08:00
f7426a0b45 fix: use clsx 2024-11-01 10:09:52 +00:00
b85b34d6b1 feat: resizable sidebar (#452)
* feat: resizable sidebar

* only expand space sidebar
2024-11-01 10:05:03 +00:00
e064e58f79 Fix sidebar responsivity (#453)
* navbar height fix. has to be cleaned up
* use parent height for tree
* cleanups
2024-11-01 09:41:23 +00:00
4f1a97ceb9 Revert "fix: prevent default browser save behavior (#450)" (#451)
This reverts commit d07338861b.
2024-10-30 12:23:31 +00:00
d07338861b fix: prevent default browser save behavior (#450) 2024-10-30 11:41:23 +00:00
95159625aa v0.5.0 2024-10-29 19:50:44 +00:00
9e0fbae1de fix: save excalidraw diagram in light mode only 2024-10-29 19:39:08 +00:00
a52c86a180 fix: add drawio dark mode support 2024-10-29 19:37:49 +00:00
31feb38def fix: sync color scheme with excalidraw 2024-10-29 19:33:08 +00:00
ba32e42ece fix: filter out redundant group 2024-10-29 19:15:26 +00:00
a574d13f43 fix: email overflow 2024-10-29 18:44:59 +00:00
ab70cee278 feat: third-party embeds (#423)
* wip

* Add more providers

* icons

* unify embed providers (Youtube)

* fix case

* YT music

* remove redundant code
2024-10-29 18:13:20 +00:00
978fadd6b9 fix: improve sidebar page tree syncing (#407)
* sync node deletion

* tree sync improvements

* fix cache bug

* fix debounced page title

* fix
2024-10-26 15:48:40 +01:00
b57be9c736 fix: rename edit -> save 2024-10-14 12:29:11 +01:00
d4b219d608 add COPY patches to Dockerfile (#400) 2024-10-14 09:13:36 +01:00
36e720920b fix: bug fixes (#397)
* Add more html page titles

* Make tables responsive

* fix react query keys

* Add tooltip to sidebar toggle

* fix: trim inputs

* fix inputs
2024-10-13 17:09:45 +01:00
fa3c8a03e1 fix: remove space tree delete shortcut key (#394) 2024-10-12 13:14:29 +01:00
46d92fbabc v0.4.1 2024-10-11 11:39:12 +01:00
e17b975aaa Revert "Add alignment styles for task list items (#378)" (#390)
This reverts commit 2721ab6a29.
2024-10-11 11:37:39 +01:00
038d21b438 v0.4.0 2024-10-10 22:03:16 +01:00
078361b367 add local editor-ext to client package.json
* update vite
2024-10-10 21:57:36 +01:00
384f11f2b7 make file upload size limit configurable (#386) 2024-10-10 21:28:28 +01:00
e333eee08b fix: base64 encoded drawio image decoded to Latin-1 instead of UTF-8 (#369) 2024-10-10 15:39:04 +01:00
7ec6a36515 fix: removed font overwrite for KaTeX elements (#377) 2024-10-10 15:35:20 +01:00
2721ab6a29 Add alignment styles for task list items (#378) 2024-10-09 18:52:20 +01:00
a2bc374f47 fix: horizontal scrollbar always shown on math block (#353) 2024-09-30 02:39:57 +01:00
eaa80a5546 fix: disconnect Redis health checker (#351) 2024-09-29 10:00:24 +01:00
e9e668bd39 fix: use environment service for refresh token's expiration (#337) 2024-09-21 10:41:26 +01:00
9390b39e35 Implement nodemailer ignore tls property (#299) 2024-09-20 17:57:50 +01:00
2ae3816324 fix: send "invitation accepted" email to inviter (#331)
The email says "${invitedUserName} has accepted your invitation ...", so it makes more sense to send it to the inviter instead of the invitee.
2024-09-19 22:19:04 +01:00
e96330afbf fix: text casing 2024-09-19 15:59:56 +01:00
e56f7933f4 fix: refactor forgot password system (#329)
* refactor forgot password system

* ready
2024-09-19 15:51:51 +01:00
b152c858b4 fix: add user tokens repo to database module 2024-09-18 20:28:39 +01:00
e43ea66442 add forgot-password ui (#273) 2024-09-17 15:53:05 +01:00
f34812653e feat(backend): forgot password (#250)
* feat(backend): forgot password

* feat: apply feedback from code review

* chore(auth): validate the minimum length of 'newPassword'

* chore(auth): make token has an expiry of 1 hour

* chore: rename all occurrences of 'code' to 'token'

* chore(backend): provide value on nanoIdGen method
2024-09-17 15:52:47 +01:00
6a3a7721be features and bug fixes (#322)
* fix page import title bug

* fix youtube embed in markdown export

* add link to rendered file html

* fix: markdown callout import

* update local generateJSON

* feat: switch spaces from sidebar

* remove unused package

* feat: editor date menu command

* fix date description

* update default locale code

* feat: add more code highlight languages
2024-09-17 15:40:49 +01:00
fb27282886 feat: delete space and edit space slug (#307)
* feat: make space slug editable

* feat: delete space

* client
2024-09-16 17:43:40 +01:00
dea9f4c063 remove unnecessary log 2024-09-13 22:37:38 +01:00
0b6730c06f fix page export failure when title contains non-ASCII characters (#309) 2024-09-13 17:40:24 +01:00
be0d97661a update README 2024-09-04 18:56:14 +01:00
4e2b23c97e v0.3.1 2024-09-03 10:49:38 +01:00
dc3ce27762 fix collaboration websocket 2024-09-03 10:48:47 +01:00
8af2d4e8cf file content-disposition 2024-09-02 16:39:07 +01:00
73ddec4ca7 v0.3.0 2024-09-02 15:56:24 +01:00
2b9765fb35 lazy load (#237) 2024-09-02 15:51:28 +01:00
7fdd355cc3 Reduce version text size 2024-09-02 13:08:01 +01:00
6c6b47599a update dependencies 2024-09-02 12:43:33 +01:00
7e6a71fa2d add HR divider to slash menu 2024-09-02 01:28:15 +01:00
1141796f24 Show version
* Add default mermaid content
2024-09-01 17:30:34 +01:00
11dbc079be Add home link to logo 2024-09-01 16:24:20 +01:00
87b99f8646 feat: draw.io (diagrams.net) integration (#215)
* draw.io init

* updates
2024-09-01 12:26:20 +01:00
38e9eef2dc feat: excalidraw integration (#214)
* update tiptap version

* excalidraw init

* cleanup

* better file handling and other fixes

* use different modal to fix excalidraw cursor position issue
* see https://github.com/excalidraw/excalidraw/issues/7312
* fix websocket in vite dev mode

* WIP

* add align attribute

* fix table

* menu icons

* Render image in excalidraw html
* add size to custom SVG components

* rewrite undefined font urls
2024-08-31 19:11:07 +01:00
77b541ec71 Fix mime attribute 2024-08-26 17:12:59 +01:00
7dc37b933f feat: editor file attachments (#194)
* fix current slider value

* WIP

* changes to extension attributes

* update command title
2024-08-26 12:38:47 +01:00
7e80797e3f feat: mermaid diagram integration (#202) 2024-08-24 18:30:07 +01:00
17475bf123 feat: code block language selection (#198)
* code block language selection

* cleanup

* Add copy button
2024-08-24 18:12:19 +01:00
4433d5174d Add Source Label to Dockerfile (#157) 2024-08-20 13:09:36 +01:00
c810d0b314 fix: added env variable for support for forcepathstyle on s3 (#181) 2024-08-20 13:05:59 +01:00
463480ae67 v0.2.10 (fix) 2024-08-07 23:03:00 +02:00
2449d69fab v2.9.10 2024-08-07 22:22:49 +02:00
e0d74fcb0e Fix: editor formatting (#137)
* reduce space between list items

* reduce spacing

* Make inline code readable in dark mode
* Disable spellcheck in code

* fix numbered list in toggle block
2024-08-04 10:06:22 +02:00
4967849e3a add SMTP_SECURE 2024-08-02 11:19:12 +02:00
0a447e91bb fix markdown import 2024-07-22 18:39:44 +01:00
48e76aa9f4 v0.2.8 2024-07-22 16:36:06 +01:00
2bd6422a35 Show new workspace role on change 2024-07-22 16:35:00 +01:00
407a1aff3b only owner can assign owner role (#108)
* backend fix: b4bc184cb3
2024-07-22 16:18:09 +01:00
b4bc184cb3 prevent admin role from managing owner role (backend) 2024-07-22 16:16:33 +01:00
109dbdbe02 cleanup log 2024-07-22 15:59:43 +01:00
2df7de5828 fix table commands type error 2024-07-22 15:43:43 +01:00
373fc86e47 preserve details tag in markdown export 2024-07-22 14:09:52 +01:00
5052a9ea40 Support math export in Markdown 2024-07-22 13:20:00 +01:00
cd47c79d86 Make math node handling better 2024-07-22 13:05:07 +01:00
78746938b7 fix export format state 2024-07-22 13:02:13 +01:00
4d2936627c fix: generate ydoc state during page import to prevent duplicate nodes on the editor 2024-07-22 11:02:43 +01:00
d2ecd28047 fix: localize attachment type
* fixes #86
2024-07-22 10:58:32 +01:00
bb92ca75e9 use logger 2024-07-21 21:57:31 +01:00
8f3e2ff663 fix editor placeholder bug 2024-07-21 20:50:08 +01:00
89f6311e46 * Make page import handling better 2024-07-21 20:48:33 +01:00
e5a97d2a26 v0.2.7 2024-07-20 18:21:12 +01:00
7f0fd45f3a singular & plural count 2024-07-20 18:20:10 +01:00
078959dfa0 v0.2.6 2024-07-20 18:05:56 +01:00
937a07059a feat: implement Markdown and HTML page imports (#85)
* page import feature
* make file interceptor common

* replace @tiptap/html
* update tiptap version

* reduce table margin

* update tiptap version

* switch to upstream drag handle lib (fixes table dragging)

* WIP

* Page import module and other fixes

* working page imports

* extract page title from h1 heading

* finalize page imports

* cleanup unused imports

* add menu arrow
2024-07-20 17:59:04 +01:00
227ac30d5e add STMP_SECURE and changed auth config (#81)
* add STMP_SECURE and changed auth config
* relocated logic to mail.provider.ts
2024-07-19 12:54:55 +01:00
a2ae341934 v0.2.5 2024-07-12 18:05:59 +01:00
3c70e40d16 add table header by default 2024-07-12 16:53:33 +01:00
14197d7365 add cookie duration 2024-07-12 14:52:09 +01:00
f388540293 feat: Individual page export in Markdown and HTML formats (#80)
* fix maths node

* render default html width

* Add page export module
* with support for html and markdown exports

* Page export UI
* Add PDF print too

* remove unused import
2024-07-12 14:45:09 +01:00
b43de81013 cleanup 2024-07-07 16:36:14 +01:00
6659adc7fe v0.2.4 2024-07-07 16:31:28 +01:00
24adff9679 Merge pull request #74 from docmost/remove-redundant-page-slug_id-index
remove redundant page slug_id index
2024-07-07 16:29:21 +01:00
e960b8c1a9 create migration 2024-07-07 16:27:43 +01:00
1958067110 Revert "remove redundant slug_id index"
This reverts commit 3e519ebcd8.
2024-07-07 16:16:13 +01:00
3e519ebcd8 remove redundant slug_id index 2024-07-07 16:07:43 +01:00
07cd650205 Merge pull request #73 from docmost/fix/case-insensitive-email
make emails case-insensitive
2024-07-07 15:51:14 +01:00
949d782a28 make emails case-insensitive 2024-07-07 15:49:43 +01:00
295d4325bf update tiptap hocuspocus 2024-07-07 15:36:36 +01:00
40a40bb3c7 Merge pull request #71 from docmost/aws_env_option
Add support for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
2024-07-07 09:49:31 +01:00
bc1579b022 fix condition check 2024-07-07 09:48:43 +01:00
85b3073681 Merge pull request #57 from will2hew/will/url-setup
CORS setup and Vite devServer proxy
2024-07-07 09:42:51 +01:00
4af3a54649 Allow AWS SDK use AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY 2024-07-07 09:24:19 +01:00
c4c169b17a Merge pull request #64 from docmost/feat/health
Add health check
2024-07-06 01:06:17 +01:00
a0536d852f cleanup indicators 2024-07-05 23:05:19 +01:00
f12f93b373 increase startup db retry limit 2024-07-05 19:00:55 +01:00
35dcd5f254 refactor health module 2024-07-05 18:59:26 +01:00
9496ec9b57 prevent database error from crashing server 2024-07-05 18:59:16 +01:00
5ace7616d0 cors setup and dev server proxy 2024-07-05 16:25:00 +12:00
ce6a05ab66 cr - add redis check and logging 2024-07-05 13:40:51 +12:00
7383673636 v0.2.3 2024-07-05 00:49:08 +01:00
3e7b2495c5 Merge pull request #51 from docmost/private-attachments
make page attachments private
2024-07-05 00:47:51 +01:00
0fc8edeb52 Merge pull request #55 from docmost/fix/bug-fixes
Fix: missing tree, editor font and responsive recent pages
2024-07-05 00:45:32 +01:00
bbf865b2f6 cleanup debug log 2024-07-05 00:41:30 +01:00
0c622a0dc1 use sane font-weight 2024-07-05 00:33:59 +01:00
f52cd011a4 remove unused imports 2024-07-05 00:33:12 +01:00
a4d53468c3 fix tree state 2024-07-05 00:30:56 +01:00
66773dfaca Add health check and dev script 2024-07-05 10:10:08 +12:00
cc93abfb7e make pages table responsive 2024-07-04 21:13:43 +01:00
13f26f9c31 make page attachments private 2024-07-04 16:01:35 +01:00
a4ec2dac6c v0.2.2 2024-07-03 13:01:00 +01:00
681d7c789c merge: fix/media-in-firefox
fix media visibility in firefox
2024-07-03 11:57:03 +01:00
9f583174a9 fix media visibility in firefox 2024-07-03 11:53:09 +01:00
05633082c5 feat/fuzzy-match-menu
added fuzzy matching logic for menu search
2024-07-03 11:25:21 +01:00
491fbad4ac feat/full-width
add full page width user preference
2024-07-03 11:24:32 +01:00
e824aeced7 Add width option to page menu 2024-07-03 11:23:42 +01:00
8f056d1071 add full page width preference 2024-07-03 11:00:42 +01:00
99cf6dab62 added fuzzy matching logic for menu search 2024-07-01 16:49:36 +05:30
696 changed files with 54084 additions and 9553 deletions

View File

@ -2,7 +2,7 @@
APP_URL=http://localhost:3000
PORT=3000
# make sure to replace this.
# minimum of 32 characters. Generate one with: openssl rand -hex 32
APP_SECRET=REPLACE_WITH_LONG_SECRET
JWT_TOKEN_EXPIRES_IN=30d
@ -19,6 +19,10 @@ AWS_S3_SECRET_ACCESS_KEY=
AWS_S3_REGION=
AWS_S3_BUCKET=
AWS_S3_ENDPOINT=
AWS_S3_FORCE_PATH_STYLE=
# default: 50mb
FILE_UPLOAD_SIZE_LIMIT=
# options: smtp | postmark
MAIL_DRIVER=smtp
@ -30,7 +34,16 @@ SMTP_HOST=127.0.0.1
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_SECURE=false
SMTP_IGNORETLS=false
# Postmark driver config
POSTMARK_TOKEN=
# for custom drawio server
DRAWIO_URL=
DISABLE_TELEMETRY=false
# Enable debug logging in production (default: false)
DEBUG_MODE=false

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
.env
.env.dev
.env.prod
data
# compiled output
/dist

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "apps/server/src/ee"]
path = apps/server/src/ee
url = https://github.com/docmost/ee

View File

@ -1,4 +1,5 @@
FROM node:21-alpine AS base
FROM node:22-alpine AS base
LABEL org.opencontainers.image.source="https://github.com/docmost/docmost"
FROM base AS builder
@ -6,7 +7,7 @@ WORKDIR /app
COPY . .
RUN npm install -g pnpm
RUN npm install -g pnpm@10.4.0
RUN pnpm install --frozen-lockfile
RUN pnpm build
@ -29,7 +30,10 @@ COPY --from=builder /app/packages/editor-ext/package.json /app/packages/editor-e
COPY --from=builder /app/package.json /app/package.json
COPY --from=builder /app/pnpm*.yaml /app/
RUN npm install -g pnpm
# Copy patches
COPY --from=builder /app/patches /app/patches
RUN npm install -g pnpm@10.4.0
RUN chown -R node:node /app

View File

@ -4,32 +4,59 @@
Open-source collaborative wiki and documentation software.
<br />
<a href="https://docmost.com"><strong>Website</strong></a> |
<a href="https://docmost.com/docs"><strong>Documentation</strong></a>
<a href="https://docmost.com/docs"><strong>Documentation</strong></a> |
<a href="https://twitter.com/DocmostHQ"><strong>Twitter / X</strong></a>
</p>
</div>
<br />
> [!NOTE]
> Docmost is currently in **beta**. We value your feedback as we progress towards a stable release.
## Getting started
To get started with Docmost, please refer to our [documentation](https://docmost.com/docs).
To get started with Docmost, please refer to our [documentation](https://docmost.com/docs) or try our [cloud version](https://docmost.com/pricing) .
## Features
- Real-time collaboration
- Diagrams (Draw.io, Excalidraw and Mermaid)
- Spaces
- Permissions management
- Groups
- Comments
- Page history
- Search
- File attachment
- File attachments
- Embeds (Airtable, Loom, Miro and more)
- Translations (10+ languages)
### Screenshots
#### Screenshots
<p align="center">
<img alt="home" src="https://docmost.com/screenshots/home.png" width="70%">
<img alt="editor" src="https://docmost.com/screenshots/editor.png" width="70%">
</p>
### Contributing
See the [development doc](https://docmost.com/docs/self-hosting/development)
### License
Docmost core is licensed under the open-source AGPL 3.0 license.
Enterprise features are available under an enterprise license (Enterprise Edition).
All files in the following directories are licensed under the Docmost Enterprise license defined in `packages/ee/License`.
- apps/server/src/ee
- apps/client/src/ee
- packages/ee
### Contributing
See the [development documentation](https://docmost.com/docs/self-hosting/development)
## Thanks
Special thanks to;
<img width="100" alt="Crowdin" src="https://github.com/user-attachments/assets/a6c3d352-e41b-448d-b6cd-3fbca3109f07" />
[Crowdin](https://crowdin.com/) for providing access to their localization platform.
<img width="48" alt="Algolia-mark-square-white" src="https://github.com/user-attachments/assets/6ccad04a-9589-4965-b6a1-d5cb1f4f9e94" />
[Algolia](https://www.algolia.com/) for providing full-text search to the docs.

View File

@ -1,22 +0,0 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'plugin:@tanstack/eslint-plugin-query/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
}

View File

@ -0,0 +1,36 @@
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import pluginQuery from "@tanstack/eslint-plugin-query";
export default tseslint.config(
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
"@tanstack/query": pluginQuery,
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": "off",
"react-hooks/exhaustive-deps": "off",
"@typescript-eslint/no-unused-expressions": "off",
"no-useless-escape": "off",
},
},
);

View File

@ -2,10 +2,19 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no" />
<title>Docmost</title>
<meta name="theme-color" content="#1f1f1f" media="(prefers-color-scheme: dark)" />
<meta name="theme-color" content="#f6f7f9" media="(prefers-color-scheme: light)" />
<link rel="manifest" href="/manifest.json" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="apple-mobile-web-app-title" content="Docmost" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<!--meta-tags-->
</head>
<body>
<div id="root"></div>

View File

@ -1,67 +1,86 @@
{
"name": "client",
"private": true,
"version": "0.2.1",
"version": "0.23.2",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
"lint": "eslint .",
"preview": "vite preview",
"format": "prettier --write \"src/**/*.tsx\" \"src/**/*.ts\""
},
"dependencies": {
"@casl/ability": "^6.7.1",
"@casl/ability": "^6.7.2",
"@casl/react": "^4.0.0",
"@docmost/editor-ext": "workspace:*",
"@emoji-mart/data": "^1.2.1",
"@emoji-mart/react": "^1.1.1",
"@mantine/core": "^7.11.0",
"@mantine/form": "^7.11.0",
"@mantine/hooks": "^7.11.0",
"@mantine/modals": "^7.11.0",
"@mantine/notifications": "^7.11.0",
"@mantine/spotlight": "^7.11.0",
"@tabler/icons-react": "^3.7.0",
"@tanstack/react-query": "^5.48.0",
"@tiptap/extension-code-block-lowlight": "^2.4.0",
"axios": "^1.7.2",
"@excalidraw/excalidraw": "0.18.0-864353b",
"@mantine/core": "^8.1.3",
"@mantine/dates": "^8.3.2",
"@mantine/form": "^8.1.3",
"@mantine/hooks": "^8.1.3",
"@mantine/modals": "^8.1.3",
"@mantine/notifications": "^8.1.3",
"@mantine/spotlight": "^8.1.3",
"@tabler/icons-react": "^3.34.0",
"@tanstack/react-query": "^5.80.6",
"@tiptap/extension-character-count": "^2.10.3",
"alfaaz": "^1.1.0",
"axios": "^1.9.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"emoji-mart": "^5.6.0",
"jotai": "^2.8.3",
"file-saver": "^2.0.5",
"highlightjs-sap-abap": "^0.3.0",
"i18next": "^23.14.0",
"i18next-http-backend": "^2.6.1",
"jotai": "^2.12.5",
"jotai-optics": "^0.4.0",
"js-cookie": "^3.0.5",
"jwt-decode": "^4.0.0",
"katex": "^0.16.10",
"lowlight": "^3.1.0",
"katex": "0.16.22",
"lowlight": "^3.3.0",
"mantine-form-zod-resolver": "^1.3.0",
"mermaid": "^11.11.0",
"mitt": "^3.0.1",
"posthog-js": "^1.255.1",
"react": "^18.3.1",
"react-arborist": "^3.4.0",
"react-arborist": "3.4.0",
"react-clear-modal": "^2.0.15",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
"react-drawio": "^1.0.1",
"react-error-boundary": "^4.1.2",
"react-helmet-async": "^2.0.5",
"react-moveable": "^0.56.0",
"react-router-dom": "^6.24.0",
"socket.io-client": "^4.7.5",
"react-i18next": "^15.0.1",
"react-router-dom": "^7.0.1",
"semver": "^7.7.2",
"socket.io-client": "^4.8.1",
"tippy.js": "^6.3.7",
"zod": "^3.23.8"
"tiptap-extension-global-drag-handle": "^0.1.18",
"zod": "^3.25.56"
},
"devDependencies": {
"@tanstack/eslint-plugin-query": "^5.47.0",
"@eslint/js": "^9.16.0",
"@tanstack/eslint-plugin-query": "^5.62.1",
"@types/file-saver": "^2.0.7",
"@types/js-cookie": "^3.0.6",
"@types/katex": "^0.16.7",
"@types/node": "20.14.9",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^9.5.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"@types/node": "22.10.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.4.1",
"eslint": "^9.15.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.16",
"globals": "^15.13.0",
"optics-ts": "^2.4.1",
"postcss": "^8.4.38",
"postcss-preset-mantine": "^1.15.0",
"postcss": "^8.4.49",
"postcss-preset-mantine": "^1.17.0",
"postcss-simple-vars": "^7.0.1",
"prettier": "^3.3.2",
"typescript": "^5.5.2",
"vite": "^5.3.1"
"prettier": "^3.4.1",
"typescript": "^5.7.2",
"typescript-eslint": "^8.17.0",
"vite": "^6.3.5"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

View File

@ -0,0 +1,531 @@
{
"Account": "Konto",
"Active": "Aktiv",
"Add": "Hinzufügen",
"Add group members": "Gruppenmitglieder hinzufügen",
"Add groups": "Gruppen hinzufügen",
"Add members": "Mitglieder hinzufügen",
"Add to groups": "Zu Gruppen hinzufügen",
"Add space members": "Bereichsmitglieder hinzufügen",
"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 page?": "Sind Sie sicher, dass Sie diese Seite löschen möchten?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Sind Sie sicher, dass Sie diesen Benutzer aus der Gruppe entfernen möchten? Der Benutzer verliert den Zugang zu den Ressourcen, auf die diese Gruppe zugreifen kann.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Sind Sie sicher, dass Sie diesen Benutzer aus dem Bereich entfernen möchten? Der Benutzer verliert den gesamten Zugang zu diesem Bereich.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Sind Sie sicher, dass Sie diese Version wiederherstellen möchten? Alle nicht versionierten Änderungen gehen verloren.",
"Can become members of groups and spaces in workspace": "Kann Mitglied von Gruppen und Bereichen im Arbeitsbereich werden",
"Can create and edit pages in space.": "Kann Seiten im Bereich erstellen und bearbeiten.",
"Can edit": "Kann bearbeiten",
"Can manage workspace": "Kann Arbeitsbereich verwalten",
"Can manage workspace but cannot delete it": "Kann Arbeitsbereich verwalten, aber nicht löschen",
"Can view": "Kann anzeigen",
"Can view pages in space but not edit.": "Kann Seiten im Bereich anzeigen, aber nicht bearbeiten.",
"Cancel": "Abbrechen",
"Change email": "E-Mail ändern",
"Change password": "Passwort ändern",
"Change photo": "Foto ändern",
"Choose a role": "Wählen Sie eine Rolle",
"Choose your preferred color scheme.": "Wählen Sie Ihr bevorzugtes Farbschema.",
"Choose your preferred interface language.": "Wählen Sie Ihre bevorzugte Benutzersprache.",
"Choose your preferred page width.": "Wählen Sie Ihre bevorzugte Seitenbreite.",
"Confirm": "Bestätigen",
"Copy link": "Link kopieren",
"Create": "Erstellen",
"Create group": "Gruppe erstellen",
"Create page": "Seite erstellen",
"Create space": "Bereich erstellen",
"Create workspace": "Arbeitsbereich erstellen",
"Current password": "Aktuelles Passwort",
"Dark": "Dunkel",
"Date": "Datum",
"Delete": "Löschen",
"Delete group": "Gruppe löschen",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Sind Sie sicher, dass Sie diese Seite löschen möchten? Dadurch werden ihre Unterseiten und die Seitengeschichte gelöscht. Diese Aktion ist unwiderruflich.",
"Description": "Beschreibung",
"Details": "Einzelheiten",
"e.g ACME": "z.B. ACME",
"e.g ACME Inc": "z.B. ACME Inc.",
"e.g Developers": "z.B. Entwickler",
"e.g Group for developers": "z.B. Gruppe für Entwickler",
"e.g product": "z.B. Produkt",
"e.g Product Team": "z.B. Produktteam",
"e.g Sales": "z.B. Vertrieb",
"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",
"Edit": "Bearbeiten",
"Read": "Lesen",
"Edit group": "Gruppe bearbeiten",
"Email": "E-Mail",
"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 emails addresses": "gültige E-Mail-Adressen eingeben",
"Enter your current password": "Geben Sie Ihr aktuelles Passwort 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 preferred email": "Geben Sie Ihre neue bevorzugte E-Mail ein",
"Enter your password": "Geben Sie Ihr Passwort ein",
"Error fetching page data.": "Fehler beim Abrufen der Seitendaten.",
"Error loading page history.": "Fehler beim Laden der Seitengeschichte.",
"Export": "Exportieren",
"Failed to create page": "Erstellung der Seite fehlgeschlagen",
"Failed to delete page": "Löschen der Seite fehlgeschlagen",
"Failed to fetch recent pages": "Fehler beim Abrufen der letzten Seiten",
"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 update data": "Aktualisierung der Daten fehlgeschlagen",
"Full access": "Voller Zugriff",
"Full page width": "Volle Seitenbreite",
"Full width": "Volle Breite",
"General": "Allgemein",
"Group": "Gruppe",
"Group description": "Gruppenbeschreibung",
"Group name": "Gruppenname",
"Groups": "Gruppen",
"Has full access to space settings and pages.": "Hat vollen Zugriff auf die Bereichseinstellungen und Seiten.",
"Home": "Startseite",
"Import pages": "Seiten importieren",
"Import pages & space settings": "Seiten und Bereichseinstellungen importieren",
"Importing pages": "Seiten werden importiert",
"invalid invitation link": "ungültiger Einladungslink",
"Invitation signup": "Einladung zur Anmeldung",
"Invite by email": "Einladen per E-Mail",
"Invite members": "Mitglieder einladen",
"Invite new members": "Neue Mitglieder 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 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",
"Language": "Sprache",
"Light": "Hell",
"Link copied": "Link kopiert",
"Login": "Anmelden",
"Logout": "Abmelden",
"Manage Group": "Gruppe verwalten",
"Manage members": "Mitglieder verwalten",
"member": "Mitglied",
"Member": "Mitglied",
"members": "Mitglieder",
"Members": "Mitglieder",
"My preferences": "Meine Voreinstellungen",
"My Profile": "Mein Profil",
"My profile": "Mein Profil",
"Name": "Name",
"New email": "Neue E-Mail",
"New page": "Neue Seite",
"New password": "Neues Passwort",
"No group found": "Keine Gruppe gefunden",
"No page history saved yet.": "Es wurde noch keine Seitengeschichte gespeichert.",
"No pages yet": "Noch keine Seiten",
"No results found...": "Keine Ergebnisse gefunden...",
"No user found": "Kein Benutzer gefunden",
"Overview": "Überblick",
"Owner": "Besitzer",
"page": "Seite",
"Page deleted successfully": "Seite erfolgreich gelöscht",
"Page history": "Seitengeschichte",
"Page import is in progress. Please do not close this tab.": "Der Seitenimport läuft. Bitte schließen Sie diesen Tab nicht.",
"Pages": "Seiten",
"pages": "Seiten",
"Password": "Passwort",
"Password changed successfully": "Passwort erfolgreich geändert",
"Pending": "Ausstehend",
"Please confirm your action": "Bitte bestätigen Sie Ihre Aktion",
"Preferences": "Vorlieben",
"Print PDF": "PDF drucken",
"Profile": "Profil",
"Recently updated": "Kürzlich aktualisiert",
"Remove": "Entfernen",
"Remove group member": "Gruppenmitglied entfernen",
"Remove space member": "Bereichsmitglied entfernen",
"Restore": "Wiederherstellen",
"Role": "Rolle",
"Save": "Speichern",
"Search": "Suche",
"Search for groups": "Suche nach Gruppen",
"Search for users": "Suche nach Benutzern",
"Search for users and groups": "Suche nach Benutzern und Gruppen",
"Search...": "Suche...",
"Select language": "Sprache auswählen",
"Select role": "Rolle auswählen",
"Select role to assign to all invited members": "Rolle für alle eingeladenen Mitglieder auswählen",
"Select theme": "Design auswählen",
"Send invitation": "Einladung senden",
"Invitation sent": "Einladung gesendet",
"Settings": "Einstellungen",
"Setup workspace": "Arbeitsbereich einrichten",
"Sign In": "Anmelden",
"Sign Up": "Registrieren",
"Slug": "Slug",
"Space": "Bereich",
"Space description": "Bereichsbeschreibung",
"Space menu": "Bereichsmenü",
"Space name": "Bereichsname",
"Space settings": "Bereichseinstellungen",
"Space slug": "Slug des Bereichs",
"Spaces": "Bereiche",
"Spaces you belong to": "Bereiche, denen Sie angehören",
"No space found": "Keine Bereiche gefunden",
"Search for spaces": "Nach Bereichen suchen",
"Start typing to search...": "Anfangen zu tippen, um zu suchen...",
"Status": "Status",
"Successfully imported": "Erfolgreich importiert",
"Successfully restored": "Erfolgreich wiederhergestellt",
"System settings": "Systemeinstellungen",
"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.",
"Toggle full page width": "Volle Seitenbreite umschalten",
"Unable to import pages. Please try again.": "Seiten konnten nicht importiert werden. Bitte versuchen Sie es erneut.",
"untitled": "ohne Titel",
"Untitled": "Ohne Titel",
"Updated successfully": "Erfolgreich aktualisiert",
"User": "Benutzer",
"Workspace": "Arbeitsbereich",
"Workspace Name": "Arbeitsbereichsname",
"Workspace settings": "Arbeitsbereich-Einstellungen",
"You can change your password here.": "Hier können Sie Ihr Passwort ändern.",
"Your Email": "Ihre E-Mail",
"Your import is complete.": "Ihr Import ist abgeschlossen.",
"Your name": "Ihr Name",
"Your Name": "Ihr Name",
"Your password": "Ihr Passwort",
"Your password must be a minimum of 8 characters.": "Ihr Passwort muss mindestens 8 Zeichen lang sein.",
"Sidebar toggle": "Seitenleiste umschalten",
"Comments": "Kommentare",
"404 page not found": "404 Seite nicht gefunden",
"Sorry, we can't find the page you are looking for.": "Entschuldigung, wir können die gesuchte Seite nicht finden.",
"Take me back to homepage": "Zurück zur Startseite",
"Forgot password": "Passwort vergessen",
"Forgot your password?": "Passwort vergessen?",
"A password reset link has been sent to your email. Please check your inbox.": "Ein Link zum Zurücksetzen des Passworts wurde an Ihre E-Mail gesendet. Bitte überprüfen Sie Ihren Posteingang.",
"Send reset link": "Zurücksetzungslink senden",
"Password reset": "Passwort zurücksetzen",
"Your new password": "Ihr neues Passwort",
"Set password": "Passwort festlegen",
"Write a comment": "Einen Kommentar schreiben",
"Reply...": "Antworten...",
"Error loading comments.": "Fehler beim Laden der Kommentare.",
"No comments yet.": "Noch keine Kommentare.",
"Edit comment": "Kommentar bearbeiten",
"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?",
"Comment created successfully": "Kommentar erfolgreich erstellt",
"Error creating comment": "Fehler beim Erstellen des Kommentars",
"Comment updated successfully": "Kommentar erfolgreich aktualisiert",
"Failed to update comment": "Aktualisierung des Kommentars fehlgeschlagen",
"Comment deleted successfully": "Kommentar erfolgreich gelöscht",
"Failed to delete comment": "Löschen des Kommentars fehlgeschlagen",
"Comment resolved successfully": "Kommentar erfolgreich gelöst",
"Comment re-opened successfully": "Kommentar erfolgreich wieder geöffnet",
"Comment unresolved successfully": "Kommentar erfolgreich ungelöst",
"Failed to resolve comment": "Lösen des Kommentars fehlgeschlagen",
"Resolve comment": "Kommentar lösen",
"Unresolve comment": "Kommentar nicht lösen",
"Resolve Comment Thread": "Kommentarthread lösen",
"Unresolve Comment Thread": "Kommentarthread nicht lösen",
"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?",
"Resolved": "Gelöst",
"No active comments.": "Keine aktiven Kommentare.",
"No resolved comments.": "Keine gelösten Kommentare.",
"Revoke invitation": "Einladung widerrufen",
"Revoke": "Widerrufen",
"Don't": "Nicht",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Sind Sie sicher, dass Sie diese Einladung widerrufen möchten? Der Benutzer kann dem Arbeitsbereich nicht beitreten.",
"Resend invitation": "Einladung erneut senden",
"Anyone with this link can join this workspace.": "Jeder mit diesem Link kann dem Arbeitsbereich beitreten.",
"Invite link": "Einladungslink",
"Copy": "Kopieren",
"Copy to space": "In Raum kopieren",
"Copied": "Kopiert",
"Duplicate": "Duplizieren",
"Select a user": "Benutzer auswählen",
"Select a group": "Gruppe auswählen",
"Export all pages and attachments in this space.": "Alle Seiten und Anhänge in diesem Bereich exportieren.",
"Delete space": "Bereich löschen",
"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.",
"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",
"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",
"Include subpages": "Unterseiten einbeziehen",
"Include attachments": "Anhänge einbeziehen",
"Select export format": "Exportformat auswählen",
"Export failed:": "Export fehlgeschlagen:",
"export error": "Exportfehler",
"Export page": "Seite exportieren",
"Export space": "Bereich exportieren",
"Export {{type}}": "Exportiere {{type}}",
"File exceeds the {{limit}} attachment limit": "Datei überschreitet das Anhängelimit von {{limit}}",
"Align left": "Links ausrichten",
"Align right": "Rechts ausrichten",
"Align center": "Zentrieren",
"Justify": "Blocksatz",
"Merge cells": "Zellen zusammenführen",
"Split cell": "Zelle teilen",
"Delete column": "Spalte löschen",
"Delete row": "Zeile löschen",
"Add left column": "Linke Spalte hinzufügen",
"Add right column": "Rechte Spalte hinzufügen",
"Add row above": "Zeile oben hinzufügen",
"Add row below": "Zeile unten hinzufügen",
"Delete table": "Tabelle löschen",
"Info": "Info",
"Success": "Erfolg",
"Warning": "Warnung",
"Danger": "Gefahr",
"Mermaid diagram error:": "Fehler im Mermaid-Diagramm:",
"Invalid Mermaid diagram": "Ungültiges Mermaid-Diagramm",
"Double-click to edit Draw.io diagram": "Zum Bearbeiten des Draw.io-Diagramms doppelklicken",
"Exit": "Beenden",
"Save & Exit": "Speichern & Beenden",
"Double-click to edit Excalidraw diagram": "Zum Bearbeiten des Excalidraw-Diagramms doppelklicken",
"Paste link": "Link einfügen",
"Edit link": "Link bearbeiten",
"Remove link": "Link entfernen",
"Add link": "Link hinzufügen",
"Please enter a valid url": "Bitte geben Sie eine gültige URL ein",
"Empty equation": "Leere Gleichung",
"Invalid equation": "Ungültige Gleichung",
"Color": "Farbe",
"Text color": "Textfarbe",
"Default": "Standard",
"Blue": "Blau",
"Green": "Grün",
"Purple": "Lila",
"Red": "Rot",
"Yellow": "Gelb",
"Orange": "Orange",
"Pink": "Rosa",
"Gray": "Grau",
"Embed link": "Link einbetten",
"Invalid {{provider}} embed link": "Ungültiger {{provider}}-Einbettungslink",
"Embed {{provider}}": "{{provider}} einbetten",
"Enter {{provider}} link to embed": "Geben Sie den Einbettungslink für {{provider}} ein",
"Bold": "Fett",
"Italic": "Kursiv",
"Underline": "Unterstreichen",
"Strike": "Durchstreichen",
"Code": "Code",
"Comment": "Kommentar",
"Text": "Text",
"Heading 1": "Überschrift 1",
"Heading 2": "Überschrift 2",
"Heading 3": "Überschrift 3",
"To-do List": "To-do-Liste",
"Bullet List": "Aufzählungsliste",
"Numbered List": "Nummerierte Liste",
"Blockquote": "Blockzitat",
"Just start typing with plain text.": "Tippen Sie einfach mit normalem Text los.",
"Track tasks with a to-do list.": "Verfolgen Sie Aufgaben mit einer To-do-Liste.",
"Big section heading.": "Große Abschnittsüberschrift.",
"Medium section heading.": "Mittlere Abschnittsüberschrift.",
"Small section heading.": "Kleine Abschnittsüberschrift.",
"Create a simple bullet list.": "Erstellen Sie eine einfache Aufzählungsliste.",
"Create a list with numbering.": "Erstellen Sie eine nummerierte Liste.",
"Create block quote.": "Erstellen Sie ein Blockzitat.",
"Insert code snippet.": "Code-Snippet 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 video from your device.": "Laden Sie ein beliebiges Video von Ihrem Gerät hoch.",
"Upload any file from your device.": "Laden Sie eine beliebige Datei von Ihrem Gerät hoch.",
"Table": "Tabelle",
"Insert a table.": "Tabelle einfügen.",
"Insert collapsible block.": "Einklappbaren Block einfügen.",
"Video": "Video",
"Divider": "Trennlinie",
"Quote": "Zitat",
"Image": "Bild",
"File attachment": "Dateianhang",
"Toggle block": "Block umschalten",
"Callout": "Hinweisbox",
"Insert callout notice.": "Hinweisbox einfügen.",
"Math inline": "Mathe inline",
"Insert inline math equation.": "Mathe-Gleichung inline einfügen.",
"Math block": "Matheblock",
"Insert math equation": "Mathe-Gleichung einfügen",
"Mermaid diagram": "Mermaid-Diagramm",
"Insert mermaid diagram": "Mermaid-Diagramm einfügen",
"Insert and design Drawio diagrams": "Drawio-Diagramme einfügen und gestalten",
"Insert current date": "Aktuelles Datum einfügen",
"Draw and sketch excalidraw diagrams": "Excalidraw-Diagramme zeichnen und skizzieren",
"Multiple": "Mehrere",
"Heading {{level}}": "Überschrift {{level}}",
"Toggle title": "Titel umschalten",
"Write anything. Enter \"/\" for commands": "Schreiben Sie irgendetwas. Geben Sie \"/\" für Befehle ein",
"Names do not match": "Namen stimmen nicht überein",
"Today, {{time}}": "Heute, {{time}}",
"Yesterday, {{time}}": "Gestern, {{time}}",
"Space created successfully": "Der Bereich wurde erfolgreich erstellt",
"Space updated successfully": "Der Bereich wurde erfolgreich aktualisiert",
"Space deleted successfully": "Der Bereich wurde erfolgreich gelöscht",
"Members added successfully": "Mitglieder erfolgreich hinzugefügt",
"Member removed successfully": "Mitglied erfolgreich entfernt",
"Member role updated successfully": "Mitgliederrolle erfolgreich aktualisiert",
"Created by: <b>{{creatorName}}</b>": "Erstellt von: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Erstellt am: {{time}}",
"Edited by {{name}} {{time}}": "Bearbeitet von {{name}} {{time}}",
"Word count: {{wordCount}}": "Wortanzahl: {{wordCount}}",
"Character count: {{characterCount}}": "Zeichenzahl: {{characterCount}}",
"New update": "Neues Update",
"{{latestVersion}} is available": "{{latestVersion}} ist verfügbar",
"Default page edit mode": "Standard-Seitenbearbeitungsmodus",
"Choose your preferred page edit mode. Avoid accidental edits.": "Wählen Sie Ihren bevorzugten Seitenbearbeitungsmodus. Vermeiden Sie versehentliche Bearbeitungen.",
"Reading": "Lesen",
"Delete member": "Mitglied löschen",
"Member deleted successfully": "Mitglied erfolgreich gelöscht",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Sind Sie sicher, dass Sie dieses Arbeitsbereichsmitglied löschen möchten? Diese Aktion ist unwiderruflich.",
"Move": "Verschieben",
"Move page": "Seite verschieben",
"Move page to a different space.": "Seite in einen anderen Bereich verschieben.",
"Real-time editor connection lost. Retrying...": "Echtzeit-Editor-Verbindung verloren. Wiederholen...",
"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.",
"Share": "Teilen",
"Public sharing": "Öffentliches Teilen",
"Shared by": "Geteilt von",
"Shared at": "Geteilt am",
"Inherits public sharing from": "Erbt das öffentliche Teilen von",
"Share to web": "Im Web teilen",
"Shared to web": "Im Web geteilt",
"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",
"Include sub-pages": "Unterseiten einbeziehen",
"Make sub-pages public too": "Unterseiten auch öffentlich machen",
"Allow search engines to index page": "Suchmaschinen erlauben, die Seite zu indexieren",
"Open page": "Seite öffnen",
"Page": "Seite",
"Delete public share link": "Öffentlichen Freigabelink 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?",
"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",
"Share deleted successfully": "Freigabe erfolgreich gelöscht",
"Share not found": "Freigabe nicht gefunden",
"Failed to share page": "Fehler beim Teilen der Seite",
"Copy page": "Seite kopieren",
"Copy page to a different space.": "Seite in einen anderen Bereich kopieren.",
"Page copied successfully": "Seite erfolgreich kopiert",
"Page duplicated successfully": "Seite erfolgreich dupliziert",
"Find": "Finden",
"Not found": "Nicht gefunden",
"Previous Match (Shift+Enter)": "Vorheriger Treffer (Shift+Enter)",
"Next match (Enter)": "Nächster Treffer (Enter)",
"Match case (Alt+C)": "Groß-/Kleinschreibung beachten (Alt+C)",
"Replace": "Ersetzen",
"Close (Escape)": "Schließen (Escape)",
"Replace (Enter)": "Ersetzen (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Alle ersetzen (Ctrl+Alt+Enter)",
"Replace all": "Alle ersetzen",
"View all spaces": "Alle Räume anzeigen",
"Error": "Fehler",
"Failed to disable MFA": "Deaktivierung der MFA fehlgeschlagen",
"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.",
"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 disabled": "Zwei-Faktor-Authentifizierung wurde deaktiviert",
"2-step verification": "2-Schritt-Verifizierung",
"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.",
"Add 2FA method": "2FA-Methode hinzufügen",
"Backup codes": "Sicherungscodes",
"Disable": "Deaktivieren",
"Invalid verification code": "Ungültiger Bestätigungscode",
"New backup codes have been generated": "Neue Sicherungscodes wurden generiert",
"Failed to regenerate backup codes": "Fehler beim Generieren neuer Sicherungscodes",
"About backup codes": "Über Sicherungscodes",
"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.",
"Confirm password": "Passwort bestätigen",
"Generate new backup codes": "Neue Sicherungscodes generieren",
"Save your new backup codes": "Speichern Sie Ihre neuen Sicherungscodes",
"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",
"I've saved my backup codes": "Ich habe meine Sicherungscodes gespeichert",
"Failed to setup MFA": "Fehler beim Einrichten der MFA",
"Setup & Verify": "Einrichten & Überprüfen",
"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",
"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:",
"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",
"Failed to generate QR code. Please try again.": "Fehler beim Generieren des QR-Codes. Bitte versuchen Sie es erneut.",
"Backup": "Sicherung",
"Save codes": "Codes speichern",
"Save your backup codes": "Speichern Sie Ihre Sicherungscodes",
"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",
"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",
"Your workspace requires two-factor authentication for all users": "Ihr Arbeitsbereich erfordert die 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.",
"Set up two-factor authentication": "Zwei-Faktor-Authentifizierung einrichten",
"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.",
"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 must be at least 8 characters": "Passwort muss mindestens 8 Zeichen lang sein",
"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",
"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",
"Need help authenticating?": "Brauchen Sie Hilfe bei der Authentifizierung?",
"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.",
"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 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",
"Use authenticator app instead": "Stattdessen Authenticator-App verwenden",
"Verify backup code": "Sicherungscode überprüfen",
"Use backup code": "Sicherungscode verwenden",
"Enter one of your backup codes": "Geben Sie einen Ihrer Sicherungscodes ein",
"Backup code": "Sicherungscode",
"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",
"Trash": "Papierkorb",
"Pages in trash will be permanently deleted after 30 days.": "Seiten im Papierkorb werden nach 30 Tagen endgültig gelöscht.",
"Deleted": "Gelöscht",
"No pages in trash": "Keine Seiten im Papierkorb",
"Permanently delete page?": "Seite endgültig löschen?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Sind Sie sicher, dass Sie '{{title}}' endgültig löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
"Restore '{{title}}' and its sub-pages?": "'{{title}}' und seine Unterseiten wiederherstellen?",
"Move to trash": "In den Papierkorb verschieben",
"Move this page to trash?": "Diese Seite in den Papierkorb verschieben?",
"Restore page": "Seite wiederherstellen",
"Page moved to trash": "Seite in den Papierkorb verschoben",
"Page restored successfully": "Seite erfolgreich wiederhergestellt",
"Deleted by": "Gelöscht von",
"Deleted at": "Gelöscht am",
"Preview": "Vorschau",
"Subpages": "Unterseiten",
"Failed to load subpages": "Fehler beim Laden von Unterseiten",
"No subpages": "Keine Unterseiten",
"Subpages (Child pages)": "Unterseiten (Untergeordnete Seiten)",
"List all subpages of the current page": "Alle Unterseiten der aktuellen Seite auflisten",
"Attachments": "Anhänge",
"All spaces": "Alle Bereiche",
"Unknown": "Unbekannt",
"Find a space": "Einen Bereich finden",
"Search in all your spaces": "In all deinen Bereichen suchen",
"Type": "Art",
"Enterprise": "Unternehmen",
"Download attachment": "Anhang herunterladen",
"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.",
"Enter valid domain names separated by comma or space": "Geben Sie gültige Domainnamen ein, durch Kommas oder Leerzeichen getrennt",
"Enforce two-factor authentication": "Erzwingen der Zwei-Faktor-Authentifizierung",
"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",
"Display name": "Anzeigename",
"Allow signup": "Registrierung erlauben",
"Enabled": "Aktiviert",
"Advanced Settings": "Erweiterte Einstellungen",
"Enable TLS/SSL": "TLS/SSL aktivieren",
"Use secure connection to LDAP server": "Sichere Verbindung zum LDAP-Server verwenden",
"Group sync": "Gruppensynchronisation",
"No SSO providers found.": "Keine SSO-Anbieter gefunden.",
"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?",
"Action": "Aktion",
"{{ssoProviderType}} configuration": "{{ssoProviderType}}-Konfiguration"
}

View File

@ -0,0 +1,558 @@
{
"Account": "Account",
"Active": "Active",
"Add": "Add",
"Add group members": "Add group members",
"Add groups": "Add groups",
"Add members": "Add members",
"Add to groups": "Add to groups",
"Add space members": "Add space members",
"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?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Are you sure you want to remove this user from the space? The user will lose all access to this space.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Are you sure you want to restore this version? Any changes not versioned will be lost.",
"Can become members of groups and spaces in workspace": "Can become members of groups and spaces in workspace",
"Can create and edit pages in space.": "Can create and edit pages in space.",
"Can edit": "Can edit",
"Can manage workspace": "Can manage workspace",
"Can manage workspace but cannot delete it": "Can manage workspace but cannot delete it",
"Can view": "Can view",
"Can view pages in space but not edit.": "Can view pages in space but not edit.",
"Cancel": "Cancel",
"Change email": "Change email",
"Change password": "Change password",
"Change photo": "Change photo",
"Choose a role": "Choose a role",
"Choose your preferred color scheme.": "Choose your preferred color scheme.",
"Choose your preferred interface language.": "Choose your preferred interface language.",
"Choose your preferred page width.": "Choose your preferred page width.",
"Confirm": "Confirm",
"Copy link": "Copy link",
"Create": "Create",
"Create group": "Create group",
"Create page": "Create page",
"Create space": "Create space",
"Create workspace": "Create workspace",
"Current password": "Current password",
"Dark": "Dark",
"Date": "Date",
"Delete": "Delete",
"Delete group": "Delete group",
"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",
"e.g ACME Inc": "e.g 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",
"Email": "Email",
"Enter a strong password": "Enter a strong password",
"Enter valid email addresses separated by comma or space max_50": "Enter valid email addresses separated by comma or space [max: 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",
"Error fetching page data.": "Error fetching page data.",
"Error loading page history.": "Error loading page history.",
"Export": "Export",
"Failed to create page": "Failed to create page",
"Failed to delete page": "Failed to delete page",
"Failed to fetch recent pages": "Failed to fetch recent 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 update data": "Failed to update data",
"Full access": "Full access",
"Full page width": "Full page width",
"Full width": "Full width",
"General": "General",
"Group": "Group",
"Group description": "Group description",
"Group name": "Group name",
"Groups": "Groups",
"Has full access to space settings and pages.": "Has full access to space settings and pages.",
"Home": "Home",
"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",
"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",
"Language": "Language",
"Light": "Light",
"Link copied": "Link copied",
"Login": "Login",
"Logout": "Logout",
"Manage Group": "Manage Group",
"Manage members": "Manage members",
"member": "member",
"Member": "Member",
"members": "members",
"Members": "Members",
"My preferences": "My preferences",
"My Profile": "My Profile",
"My profile": "My profile",
"Name": "Name",
"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 results found...": "No results found...",
"No user found": "No user found",
"Overview": "Overview",
"Owner": "Owner",
"page": "page",
"Page deleted successfully": "Page deleted successfully",
"Page history": "Page history",
"Page import is in progress. Please do not close this tab.": "Page import is in progress. Please do not close this tab.",
"Pages": "Pages",
"pages": "pages",
"Password": "Password",
"Password changed successfully": "Password changed successfully",
"Pending": "Pending",
"Please confirm your action": "Please confirm your action",
"Preferences": "Preferences",
"Print PDF": "Print PDF",
"Profile": "Profile",
"Recently updated": "Recently updated",
"Remove": "Remove",
"Remove group member": "Remove group member",
"Remove space member": "Remove space member",
"Restore": "Restore",
"Role": "Role",
"Save": "Save",
"Search": "Search",
"Search for groups": "Search for groups",
"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",
"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",
"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.": "Your password must be a minimum of 8 characters.",
"Sidebar toggle": "Sidebar toggle",
"Comments": "Comments",
"404 page not found": "404 page not found",
"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",
"Password reset": "Password reset",
"Your new password": "Your new password",
"Set password": "Set password",
"Write a comment": "Write a comment",
"Reply...": "Reply...",
"Error loading comments.": "Error loading comments.",
"No comments yet.": "No comments yet.",
"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?",
"Comment created successfully": "Comment created successfully",
"Error creating comment": "Error creating comment",
"Comment updated successfully": "Comment updated successfully",
"Failed to update comment": "Failed to update comment",
"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.",
"No resolved comments.": "No resolved comments.",
"Revoke invitation": "Revoke invitation",
"Revoke": "Revoke",
"Don't": "Don't",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Are you sure you want to revoke this invitation? The user will not be able to join the workspace.",
"Resend invitation": "Resend invitation",
"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",
"Select a group": "Select a group",
"Export all pages and attachments in this space.": "Export all pages and attachments in this space.",
"Delete space": "Delete space",
"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.": "Type the space name <b>{{spaceName}}</b> to confirm your action.",
"Format": "Format",
"Include subpages": "Include subpages",
"Include attachments": "Include attachments",
"Select export format": "Select export format",
"Export failed:": "Export failed:",
"export error": "export error",
"Export page": "Export page",
"Export space": "Export space",
"Export {{type}}": "Export {{type}}",
"File exceeds the {{limit}} attachment limit": "File exceeds the {{limit}} attachment limit",
"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",
"Delete row": "Delete row",
"Add left column": "Add left column",
"Add right column": "Add right column",
"Add row above": "Add row above",
"Add row below": "Add row below",
"Delete table": "Delete table",
"Info": "Info",
"Success": "Success",
"Warning": "Warning",
"Danger": "Danger",
"Mermaid diagram error:": "Mermaid diagram error:",
"Invalid Mermaid diagram": "Invalid Mermaid diagram",
"Double-click to edit Draw.io diagram": "Double-click to edit Draw.io diagram",
"Exit": "Exit",
"Save & Exit": "Save & Exit",
"Double-click to edit Excalidraw diagram": "Double-click to edit Excalidraw diagram",
"Paste link": "Paste link",
"Edit link": "Edit link",
"Remove link": "Remove link",
"Add link": "Add link",
"Please enter a valid url": "Please enter a valid url",
"Empty equation": "Empty equation",
"Invalid equation": "Invalid equation",
"Color": "Color",
"Text color": "Text color",
"Default": "Default",
"Blue": "Blue",
"Green": "Green",
"Purple": "Purple",
"Red": "Red",
"Yellow": "Yellow",
"Orange": "Orange",
"Pink": "Pink",
"Gray": "Gray",
"Embed link": "Embed link",
"Invalid {{provider}} embed link": "Invalid {{provider}} embed link",
"Embed {{provider}}": "Embed {{provider}}",
"Enter {{provider}} link to embed": "Enter {{provider}} link to embed",
"Bold": "Bold",
"Italic": "Italic",
"Underline": "Underline",
"Strike": "Strike",
"Code": "Code",
"Comment": "Comment",
"Text": "Text",
"Heading 1": "Heading 1",
"Heading 2": "Heading 2",
"Heading 3": "Heading 3",
"To-do List": "To-do List",
"Bullet List": "Bullet List",
"Numbered List": "Numbered List",
"Blockquote": "Blockquote",
"Just start typing with plain text.": "Just start typing with plain text.",
"Track tasks with a to-do list.": "Track tasks with a to-do list.",
"Big section heading.": "Big section heading.",
"Medium section heading.": "Medium section heading.",
"Small section heading.": "Small section heading.",
"Create a simple bullet list.": "Create a simple bullet list.",
"Create a list with numbering.": "Create a list with numbering.",
"Create block quote.": "Create block quote.",
"Insert code snippet.": "Insert code snippet.",
"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 file from your device.": "Upload any file from your device.",
"Table": "Table",
"Insert a table.": "Insert a table.",
"Insert collapsible block.": "Insert collapsible block.",
"Video": "Video",
"Divider": "Divider",
"Quote": "Quote",
"Image": "Image",
"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",
"Insert mermaid diagram": "Insert mermaid diagram",
"Insert and design Drawio diagrams": "Insert and design Drawio diagrams",
"Insert current date": "Insert current date",
"Draw and sketch excalidraw diagrams": "Draw and sketch excalidraw diagrams",
"Multiple": "Multiple",
"Heading {{level}}": "Heading {{level}}",
"Toggle title": "Toggle title",
"Write anything. Enter \"/\" for commands": "Write anything. Enter \"/\" for commands",
"Names do not match": "Names do not match",
"Today, {{time}}": "Today, {{time}}",
"Yesterday, {{time}}": "Yesterday, {{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>": "Created by: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Created at: {{time}}",
"Edited by {{name}} {{time}}": "Edited by {{name}} {{time}}",
"Word count: {{wordCount}}": "Word count: {{wordCount}}",
"Character count: {{characterCount}}": "Character count: {{characterCount}}",
"New update": "New update",
"{{latestVersion}} is available": "{{latestVersion}} is available",
"Default page edit mode": "Default page edit mode",
"Choose your preferred page edit mode. Avoid accidental edits.": "Choose your preferred page edit mode. Avoid accidental edits.",
"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.",
"Move": "Move",
"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.": "Add headings (H1, H2, H3) to generate a table of contents.",
"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",
"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)": "Previous Match (Shift+Enter)",
"Next match (Enter)": "Next match (Enter)",
"Match case (Alt+C)": "Match case (Alt+C)",
"Replace": "Replace",
"Close (Escape)": "Close (Escape)",
"Replace (Enter)": "Replace (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Replace all (Ctrl+Alt+Enter)",
"Replace all": "Replace all",
"View all spaces": "View all spaces",
"Error": "Error",
"Failed to disable MFA": "Failed to disable 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": "Add 2FA method",
"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",
"Setup & Verify": "Setup & Verify",
"Add to authenticator": "Add to authenticator",
"1. Scan this QR code with your authenticator app": "1. Scan this QR code with your authenticator app",
"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. Enter the 6-digit code from your authenticator",
"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": "Password must be at least 8 characters",
"Please enter a 6-digit code": "Please enter a 6-digit code",
"Code must be exactly 6 digits": "Code must be exactly 6 digits",
"Enter the 6-digit code found in your authenticator app": "Enter the 6-digit code found in your authenticator app",
"Need help authenticating?": "Need help authenticating?",
"MFA QR Code": "MFA QR Code",
"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 30 days.": "Pages in trash will be permanently deleted after 30 days.",
"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.": "Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.",
"Restore '{{title}}' and its sub-pages?": "Restore '{{title}}' and its sub-pages?",
"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.": "Only users with email addresses from these domains can signup via 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",
"Display name": "Display name",
"Allow signup": "Allow signup",
"Enabled": "Enabled",
"Advanced Settings": "Advanced Settings",
"Enable TLS/SSL": "Enable TLS/SSL",
"Use secure connection to LDAP server": "Use secure connection to LDAP server",
"Group sync": "Group sync",
"No SSO providers found.": "No SSO providers found.",
"Delete SSO provider": "Delete SSO provider",
"Are you sure you want to delete this SSO provider?": "Are you sure you want to delete this SSO provider?",
"Action": "Action",
"{{ssoProviderType}} configuration": "{{ssoProviderType}} configuration",
"Icon": "Icon",
"Upload image": "Upload image",
"Remove image": "Remove image",
"Failed to remove image": "Failed to remove image",
"Image exceeds 10MB limit.": "Image exceeds 10MB limit.",
"Image removed successfully": "Image removed successfully",
"API key": "API key",
"API key created successfully": "API key created successfully",
"API keys": "API keys",
"API management": "API management",
"Are you sure you want to revoke this API key": "Are you sure you want to revoke this API key",
"Create API Key": "Create API Key",
"Custom expiration date": "Custom expiration date",
"Enter a descriptive token name": "Enter a descriptive token name",
"Expiration": "Expiration",
"Expired": "Expired",
"Expires": "Expires",
"I've saved my API key": "I've saved my API key",
"Last use": "Last Used",
"No API keys found": "No API keys found",
"No expiration": "No expiration",
"Revoke API key": "Revoke API key",
"Revoked successfully": "Revoked successfully",
"Select expiration date": "Select expiration date",
"This action cannot be undone. Any applications using this API key will stop working.": "This action cannot be undone. Any applications using this API key will stop working.",
"Update API key": "Update API key",
"Manage API keys for all users in the workspace": "Manage API keys for all users in the workspace"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Cuenta",
"Active": "Activo",
"Add": "Agregar",
"Add group members": "Agregar miembros del grupo",
"Add groups": "Agregar grupos",
"Add members": "Agregar miembros",
"Add to groups": "Agregar a grupos",
"Add space members": "Agregar miembros al espacio",
"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 page?": "¿Está seguro de que desea eliminar esta página?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "¿Está seguro de que desea eliminar a este usuario del grupo? El usuario perderá acceso a los recursos a los que tiene acceso este grupo.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "¿Está seguro de que desea eliminar a este usuario del espacio? El usuario perderá todo acceso a este espacio.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "¿Está seguro de que desea restaurar esta versión? Cualquier cambio no versionado se perderá.",
"Can become members of groups and spaces in workspace": "Pueden convertirse en miembros de grupos y espacios en el espacio de trabajo",
"Can create and edit pages in space.": "Puede crear y editar páginas en el espacio.",
"Can edit": "Puede editar",
"Can manage workspace": "Puede gestionar el espacio de trabajo",
"Can manage workspace but cannot delete it": "Puede gestionar el espacio de trabajo pero no puede eliminarlo",
"Can view": "Puede ver",
"Can view pages in space but not edit.": "Puede ver páginas en el espacio pero no editarlas.",
"Cancel": "Cancelar",
"Change email": "Cambiar correo electrónico",
"Change password": "Cambiar contraseña",
"Change photo": "Cambiar foto",
"Choose a role": "Seleccione un rol",
"Choose your preferred color scheme.": "Elige tu esquema de color preferido.",
"Choose your preferred interface language.": "Elige tu idioma de interfaz preferido.",
"Choose your preferred page width.": "Elige el ancho de página que prefieras.",
"Confirm": "Confirmar",
"Copy link": "Copiar enlace",
"Create": "Crear",
"Create group": "Crear grupo",
"Create page": "Crear página",
"Create space": "Crear espacio",
"Create workspace": "Crear espacio de trabajo",
"Current password": "Contraseña actual",
"Dark": "Oscuro",
"Date": "Fecha",
"Delete": "Eliminar",
"Delete group": "Eliminar grupo",
"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",
"Details": "Detalles",
"e.g ACME": "ej: ACME",
"e.g ACME Inc": "ej: ACME Inc",
"e.g Developers": "ej: Desarrolladores",
"e.g Group for developers": "ej: Grupo para desarrolladores",
"e.g product": "ej: producto",
"e.g Product Team": "ej: Equipo de Producto",
"e.g Sales": "ej: Ventas",
"e.g Space for product team": "ej: Espacio para el equipo de producto",
"e.g Space for sales team to collaborate": "ej: Espacio para que el equipo de ventas colabore",
"Edit": "Editar",
"Read": "Leer",
"Edit group": "Editar grupo",
"Email": "Correo electrónico",
"Enter a strong password": "Introduce una contraseña fuerte",
"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 your current password": "Introduce tu contraseña actual",
"enter your full name": "introduzca su nombre completo",
"Enter your new password": "Ingrese su nueva contraseña",
"Enter your new preferred email": "Introduce tu nuevo correo electrónico preferido",
"Enter your password": "Introduce tu contraseña",
"Error fetching page data.": "Error al obtener los datos de la página.",
"Error loading page history.": "Error al cargar el historial de la página.",
"Export": "Exportar",
"Failed to create page": "No se pudo crear la página",
"Failed to delete page": "No se pudo eliminar la página",
"Failed to fetch recent pages": "Error al obtener las páginas recientes",
"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 update data": "No se pudo actualizar los datos",
"Full access": "Acceso completo",
"Full page width": "Ancho de página completa",
"Full width": "Ancho completo",
"General": "General",
"Group": "Grupo",
"Group description": "Descripción del grupo",
"Group name": "Nombre del grupo",
"Groups": "Grupos",
"Has full access to space settings and pages.": "Tiene acceso completo a la configuración y páginas del espacio.",
"Home": "Inicio",
"Import pages": "Importar páginas",
"Import pages & space settings": "Importar páginas y configuraciones del espacio",
"Importing pages": "Importando páginas",
"invalid invitation link": "enlace de invitación no válido",
"Invitation signup": "Registro por invitación",
"Invite by email": "Invitar por correo electrónico",
"Invite members": "Invitar a miembros",
"Invite new members": "Invitar a nuevos miembros",
"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",
"Join the workspace": "Unirse al espacio de trabajo",
"Language": "Idioma",
"Light": "Claro",
"Link copied": "Enlace copiado",
"Login": "Iniciar sesión",
"Logout": "Cerrar sesión",
"Manage Group": "Gestionar Grupo",
"Manage members": "Gestionar miembros",
"member": "miembro",
"Member": "Miembro",
"members": "miembros",
"Members": "Miembros",
"My preferences": "Mis preferencias",
"My Profile": "Mi Perfil",
"My profile": "Mi perfil",
"Name": "Nombre",
"New email": "Nuevo correo electrónico",
"New page": "Nueva página",
"New password": "Nueva contraseña",
"No group found": "No se encontró grupo",
"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 results found...": "No se encontraron resultados...",
"No user found": "No se encontró usuario",
"Overview": "Visión general",
"Owner": "Propietario",
"page": "página",
"Page deleted successfully": "Página eliminada con éxito",
"Page history": "Historial de la página",
"Page import is in progress. Please do not close this tab.": "La importación de la página está en curso. Por favor, no cierre esta pestaña.",
"Pages": "Páginas",
"pages": "páginas",
"Password": "Contraseña",
"Password changed successfully": "Contraseña cambiada con éxito",
"Pending": "Pendiente",
"Please confirm your action": "Por favor, confirme su acción",
"Preferences": "Preferencias",
"Print PDF": "Imprimir PDF",
"Profile": "Perfil",
"Recently updated": "Recientemente actualizado",
"Remove": "Eliminar",
"Remove group member": "Eliminar miembro del grupo",
"Remove space member": "Eliminar miembro del espacio",
"Restore": "Restaurar",
"Role": "Rol",
"Save": "Guardar",
"Search": "Buscar",
"Search for groups": "Buscar grupos",
"Search for users": "Buscar usuarios",
"Search for users and groups": "Buscar usuarios y grupos",
"Search...": "Buscar...",
"Select language": "Seleccionar idioma",
"Select role": "Seleccionar rol",
"Select role to assign to all invited members": "Seleccionar rol para asignar a todos los miembros invitados",
"Select theme": "Seleccionar tema",
"Send invitation": "Enviar invitación",
"Invitation sent": "Invitación enviada",
"Settings": "Ajustes",
"Setup workspace": "Configurar espacio de trabajo",
"Sign In": "Iniciar sesión",
"Sign Up": "Registrarse",
"Slug": "Identificador",
"Space": "Espacio",
"Space description": "Descripción del espacio",
"Space menu": "Menú de espacio",
"Space name": "Nombre del espacio",
"Space settings": "Configuración del espacio",
"Space slug": "Identificador del espacio",
"Spaces": "Espacios",
"Spaces you belong to": "Espacios a los que perteneces",
"No space found": "No se encontró espacio",
"Search for spaces": "Buscar espacios",
"Start typing to search...": "Empieza a escribir para buscar...",
"Status": "Estado",
"Successfully imported": "Importado con éxito",
"Successfully restored": "Restaurado con éxito",
"System settings": "Configuración del sistema",
"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.",
"Toggle full page width": "Alternar el ancho de página completa",
"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",
"Updated successfully": "Actualizado con éxito",
"User": "Usuario",
"Workspace": "Espacio de trabajo",
"Workspace Name": "Nombre del espacio de trabajo",
"Workspace settings": "Configuración del espacio de trabajo",
"You can change your password here.": "Puede cambiar su contraseña aquí.",
"Your Email": "Su correo electrónico",
"Your import is complete.": "Su importación está completa.",
"Your name": "Tu nombre",
"Your Name": "Tu Nombre",
"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.",
"Sidebar toggle": "Alternar barra lateral",
"Comments": "Comentarios",
"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.",
"Take me back to homepage": "Llévame de vuelta a la página de inicio",
"Forgot password": "Olvidó la 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.",
"Send reset link": "Enviar enlace de restablecimiento",
"Password reset": "Restablecimiento de contraseña",
"Your new password": "Tu nueva contraseña",
"Set password": "Establecer contraseña",
"Write a comment": "Escribir un comentario",
"Reply...": "Responder...",
"Error loading comments.": "Error al cargar comentarios.",
"No comments yet.": "No hay comentarios todavía.",
"Edit comment": "Editar comentario",
"Delete comment": "Eliminar comentario",
"Are you sure you want to delete this comment?": "¿Está seguro de que desea eliminar este comentario?",
"Comment created successfully": "Comentario creado con éxito",
"Error creating comment": "Error al crear comentario",
"Comment updated successfully": "Comentario actualizado con éxito",
"Failed to update comment": "No se pudo actualizar el comentario",
"Comment deleted successfully": "Comentario eliminado con éxito",
"Failed to delete comment": "No se pudo eliminar el comentario",
"Comment resolved successfully": "Comentario resuelto con éxito",
"Comment re-opened successfully": "Comentario reabierto con éxito",
"Comment unresolved successfully": "Comentario no resuelto con éxito",
"Failed to resolve comment": "No se pudo resolver el comentario",
"Resolve comment": "Resolver comentario",
"Unresolve comment": "No resolver comentario",
"Resolve Comment Thread": "Resolver hilo de comentarios",
"Unresolve Comment Thread": "No resolver hilo de comentarios",
"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?",
"Resolved": "Resuelto",
"No active comments.": "No hay comentarios activos.",
"No resolved comments.": "No hay comentarios resueltos.",
"Revoke invitation": "Revocar invitación",
"Revoke": "Revocar",
"Don't": "No",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "¿Está seguro de que desea revocar esta invitación? El usuario no podrá unirse al espacio de trabajo.",
"Resend invitation": "Reenviar invitación",
"Anyone with this link can join this workspace.": "Cualquiera con este enlace puede unirse a este espacio de trabajo.",
"Invite link": "Enlace de invitación",
"Copy": "Copiar",
"Copy to space": "Copiar al espacio",
"Copied": "Copiado",
"Duplicate": "Duplicar",
"Select a user": "Seleccionar un usuario",
"Select a group": "Seleccionar un grupo",
"Export all pages and attachments in this space.": "Exportar todas las páginas y archivos adjuntos en este espacio.",
"Delete space": "Eliminar espacio",
"Are you sure you want to delete this space?": "¿Está seguro de que desea eliminar este espacio?",
"Delete this space with all its pages and data.": "Eliminar este espacio con todas sus páginas y datos.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Todas las páginas, comentarios, archivos adjuntos y permisos en este espacio se eliminarán de forma irreversible.",
"Confirm space name": "Confirmar nombre del espacio",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Escribe el nombre del espacio <b>{{spaceName}}</b> para confirmar tu acción.",
"Format": "Formato",
"Include subpages": "Incluir subpáginas",
"Include attachments": "Incluir adjuntos",
"Select export format": "Seleccionar formato de exportación",
"Export failed:": "Exportación fallida:",
"export error": "error de exportación",
"Export page": "Exportar página",
"Export space": "Exportar espacio",
"Export {{type}}": "Exportar {{type}}",
"File exceeds the {{limit}} attachment limit": "El archivo supera el límite de {{limit}} adjuntos",
"Align left": "Alinear a la izquierda",
"Align right": "Alinear a la derecha",
"Align center": "Alinear al centro",
"Justify": "Justificar",
"Merge cells": "Combinar celdas",
"Split cell": "Dividir celda",
"Delete column": "Eliminar columna",
"Delete row": "Eliminar fila",
"Add left column": "Agregar columna izquierda",
"Add right column": "Agregar columna derecha",
"Add row above": "Agregar fila arriba",
"Add row below": "Agregar fila debajo",
"Delete table": "Eliminar tabla",
"Info": "Información",
"Success": "Satisfactorio",
"Warning": "Advertencia",
"Danger": "Peligro",
"Mermaid diagram error:": "Error en diagrama de Mermaid:",
"Invalid Mermaid diagram": "Diagrama de Mermaid no válido",
"Double-click to edit Draw.io diagram": "Doble clic para editar el diagrama de Draw.io",
"Exit": "Salir",
"Save & Exit": "Guardar y Salir",
"Double-click to edit Excalidraw diagram": "Doble clic para editar el diagrama de Excalidraw",
"Paste link": "Pegar enlace",
"Edit link": "Editar enlace",
"Remove link": "Eliminar enlace",
"Add link": "Agregar enlace",
"Please enter a valid url": "Por favor, ingrese una URL válida",
"Empty equation": "Ecuación vacía",
"Invalid equation": "Ecuación no válida",
"Color": "Color",
"Text color": "Color del texto",
"Default": "Predeterminado",
"Blue": "Azul",
"Green": "Verde",
"Purple": "Morado",
"Red": "Rojo",
"Yellow": "Amarillo",
"Orange": "Naranja",
"Pink": "Rosa",
"Gray": "Gris",
"Embed link": "Enlace adjunto",
"Invalid {{provider}} embed link": "Enlace incrustado {{provider}} no válido",
"Embed {{provider}}": "Incrustar {{provider}}",
"Enter {{provider}} link to embed": "Introduzca el enlace de {{provider}} para incrustar",
"Bold": "Negrita",
"Italic": "Cursiva",
"Underline": "Subrayar",
"Strike": "Tachar",
"Code": "Código",
"Comment": "Comentario",
"Text": "Texto",
"Heading 1": "Encabezado 1",
"Heading 2": "Encabezado 2",
"Heading 3": "Encabezado 3",
"To-do List": "Lista de cosas por hacer",
"Bullet List": "Lista con viñetas",
"Numbered List": "Lista numerada",
"Blockquote": "Cita en bloque",
"Just start typing with plain text.": "Simplemente comienza a escribir con texto sin formato.",
"Track tasks with a to-do list.": "Administra tareas con una lista de tareas pendientes.",
"Big section heading.": "Gran encabezado de sección.",
"Medium section heading.": "Encabezado de sección mediano.",
"Small section heading.": "Pequeño encabezado de sección.",
"Create a simple bullet list.": "Crear una lista con viñetas simple.",
"Create a list with numbering.": "Crear una lista con numeración.",
"Create block quote.": "Crear una cita en bloque.",
"Insert code snippet.": "Insertar fragmento de código.",
"Insert horizontal rule divider": "Insertar regla horizontal",
"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 file from your device.": "Sube cualquier archivo desde tu dispositivo.",
"Table": "Tabla",
"Insert a table.": "Insertar una tabla.",
"Insert collapsible block.": "Insertar bloque desplegable.",
"Video": "Vídeo",
"Divider": "Divisor",
"Quote": "Cita",
"Image": "Imagen",
"File attachment": "Adjunto de archivo",
"Toggle block": "Alternar bloque",
"Callout": "Aviso",
"Insert callout notice.": "Insertar aviso de llamada.",
"Math inline": "Matemáticas en línea",
"Insert inline math equation.": "Insertar ecuación matemática en línea.",
"Math block": "Bloque de matemáticas",
"Insert math equation": "Insertar ecuación matemática",
"Mermaid diagram": "Diagrama de Mermaid",
"Insert mermaid diagram": "Insertar diagrama de Mermaid",
"Insert and design Drawio diagrams": "Insertar y diseñar diagramas Drawio",
"Insert current date": "Insertar fecha actual",
"Draw and sketch excalidraw diagrams": "Dibujar y esbozar diagramas de Excalidraw",
"Multiple": "Múltiple",
"Heading {{level}}": "Encabezado {{level}}",
"Toggle title": "Alternar título",
"Write anything. Enter \"/\" for commands": "Escribe cualquier cosa. Ingresa \"/\" para comandos",
"Names do not match": "Los nombres no coinciden",
"Today, {{time}}": "Hoy, {{time}}",
"Yesterday, {{time}}": "Ayer, {{time}}",
"Space created successfully": "Espacio creado con éxito",
"Space updated successfully": "Espacio actualizado con éxito",
"Space deleted successfully": "Espacio eliminado con éxito",
"Members added successfully": "Miembros añadidos con éxito",
"Member removed successfully": "Miembro eliminado con éxito",
"Member role updated successfully": "Rol de miembro actualizado con éxito",
"Created by: <b>{{creatorName}}</b>": "Creado por: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Creado a: {{time}}",
"Edited by {{name}} {{time}}": "Editado por {{name}} {{time}}",
"Word count: {{wordCount}}": "Conteo de palabras: {{wordCount}}",
"Character count: {{characterCount}}": "Recuento de caracteres: {{characterCount}}",
"New update": "Nueva actualización",
"{{latestVersion}} is available": "{{latestVersion}} está disponible",
"Default page edit mode": "Modo de edición de página predeterminado",
"Choose your preferred page edit mode. Avoid accidental edits.": "Elige tu modo de edición de página preferido. Evita ediciones accidentales.",
"Reading": "Leyendo",
"Delete member": "Eliminar miembro",
"Member deleted successfully": "Miembro eliminado con éxito",
"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.",
"Move": "Mover",
"Move page": "Mover página",
"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...",
"Table of contents": "Í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",
"Public sharing": "Compartición pública",
"Shared by": "Compartido por",
"Shared at": "Compartido en",
"Inherits public sharing from": "Hereda la compartición pública de",
"Share to web": "Compartir 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",
"Make this page publicly accessible": "Hacer esta página accesible públicamente",
"Include sub-pages": "Incluir 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",
"Open page": "Abrir página",
"Page": "Página",
"Delete public share link": "Eliminar enlace de compartición pública",
"Delete share": "Eliminar compartición",
"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í",
"Share deleted successfully": "Compartición eliminada con éxito",
"Share not found": "Compartición no encontrada",
"Failed to share page": "Error al compartir la página",
"Copy page": "Copiar página",
"Copy page to a different space.": "Copiar página en otro espacio",
"Page copied successfully": "Página copiada exitosamente",
"Page duplicated successfully": "Página duplicada con éxito",
"Find": "Buscar",
"Not found": "No encontrado",
"Previous Match (Shift+Enter)": "Coincidencia anterior (Shift+Enter)",
"Next match (Enter)": "Siguiente coincidencia (Enter)",
"Match case (Alt+C)": "Distinguir mayúsculas y minúsculas (Alt+C)",
"Replace": "Reemplazar",
"Close (Escape)": "Cerrar (Escape)",
"Replace (Enter)": "Reemplazar (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Reemplazar todo (Ctrl+Alt+Enter)",
"Replace all": "Reemplazar todo",
"View all spaces": "Ver todos los espacios",
"Error": "Error",
"Failed to disable MFA": "No se pudo desactivar MFA",
"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.",
"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 disabled": "La autenticación de dos factores ha sido desactivada",
"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.",
"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",
"Backup codes": "Códigos de seguridad",
"Disable": "Desactivar",
"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",
"Failed to regenerate backup codes": "No se pudo regenerar los códigos de seguridad",
"About backup codes": "Acerca de los códigos de seguridad",
"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.",
"Confirm password": "Confirmar contraseña",
"Generate new backup codes": "Generar nuevos códigos de seguridad",
"Save your new backup codes": "Guarda tus nuevos códigos de seguridad",
"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",
"I've saved my backup codes": "He guardado mis códigos de seguridad",
"Failed to setup MFA": "No se pudo configurar MFA",
"Setup & Verify": "Configurar y verificar",
"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",
"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:",
"2. Enter the 6-digit code from your authenticator": "2. Introduce el código de 6 dígitos de tu autenticador",
"Verify and enable": "Verificar y activar",
"Failed to generate QR code. Please try again.": "No se pudo generar el código QR. Por favor, intente de nuevo.",
"Backup": "Respaldo",
"Save codes": "Guardar códigos",
"Save your backup codes": "Guarda tus códigos de seguridad",
"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",
"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",
"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.",
"Set up two-factor authentication": "Configurar la autenticación de dos factores",
"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.",
"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 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",
"Code must be exactly 6 digits": "El código debe ser exactamente de 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",
"Need help authenticating?": "¿Necesitas ayuda para autenticar?",
"MFA QR Code": "Código QR 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.",
"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 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",
"Use authenticator app instead": "Usar la aplicación autenticadora en su lugar",
"Verify backup code": "Verificar código de seguridad",
"Use backup code": "Usar código de seguridad",
"Enter one of your backup codes": "Introduce uno de tus códigos de seguridad",
"Backup code": "Código de seguridad",
"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",
"Trash": "Papelera",
"Pages in trash will be permanently deleted after 30 days.": "Las páginas en la papelera serán eliminadas permanentemente después de 30 días.",
"Deleted": "Eliminado",
"No pages in trash": "No hay páginas en la papelera",
"Permanently delete page?": "¿Eliminar página permanentemente?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "¿Está seguro de que desea eliminar '{{title}}' permanentemente? Esta acción no se puede deshacer.",
"Restore '{{title}}' and its sub-pages?": "¿Restaurar '{{title}}' y sus subpáginas?",
"Move to trash": "Mover a la papelera",
"Move this page to trash?": "¿Mover esta página a la papelera?",
"Restore page": "Restaurar página",
"Page moved to trash": "Página movida a la papelera",
"Page restored successfully": "Página restaurada con éxito",
"Deleted by": "Eliminado por",
"Deleted at": "Eliminado en",
"Preview": "Vista previa",
"Subpages": "Subpáginas",
"Failed to load subpages": "Error al cargar subpáginas",
"No subpages": "Sin subpáginas",
"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",
"Attachments": "Adjuntos",
"All spaces": "Todos los espacios",
"Unknown": "Desconocido",
"Find a space": "Encontrar un espacio",
"Search in all your spaces": "Buscar en todos tus espacios",
"Type": "Tipo",
"Enterprise": "Empresa",
"Download attachment": "Descargar adjunto",
"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.",
"Enter valid domain names separated by comma or space": "Introduce nombres de dominio válidos separados por coma o espacio",
"Enforce two-factor authentication": "Aplicar 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.",
"Toggle MFA enforcement": "Alternar la aplicación de MFA",
"Display name": "Nombre para mostrar",
"Allow signup": "Permitir registro",
"Enabled": "Habilitado",
"Advanced Settings": "Configuración avanzada",
"Enable TLS/SSL": "Habilitar TLS/SSL",
"Use secure connection to LDAP server": "Usar conexión segura al servidor LDAP",
"Group sync": "Sincronización de grupos",
"No SSO providers found.": "No se encontraron proveedores de SSO.",
"Delete SSO provider": "Eliminar proveedor de SSO",
"Are you sure you want to delete this SSO provider?": "¿Está seguro de que desea eliminar este proveedor de SSO?",
"Action": "Acción",
"{{ssoProviderType}} configuration": "Configuración de {{ssoProviderType}}"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Compte",
"Active": "Actif",
"Add": "Ajouter",
"Add group members": "Ajouter des membres au groupe",
"Add groups": "Ajouter des groupes",
"Add members": "Ajouter des membres",
"Add to groups": "Ajouter aux groupes",
"Add space members": "Ajouter des membres à l'espace",
"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 page?": "Êtes-vous sûr de vouloir supprimer cette page ?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Êtes-vous sûr de vouloir retirer cet utilisateur du groupe ? L'utilisateur perdra l'accès aux ressources auxquelles ce groupe a accès.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Êtes-vous sûr de vouloir retirer cet utilisateur de l'espace ? L'utilisateur perdra tout accès à cet espace.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Êtes-vous sûr de vouloir restaurer cette version ? Toutes les modifications non versionnées seront perdues.",
"Can become members of groups and spaces in workspace": "Peut devenir membre de groupes et d'espaces dans l'espace de travail",
"Can create and edit pages in space.": "Peut créer et modifier des pages dans l'espace.",
"Can edit": "Peut modifier",
"Can manage workspace": "Peut gérer l'espace de travail",
"Can manage workspace but cannot delete it": "Peut gérer l'espace de travail mais ne peut pas le supprimer",
"Can view": "Peut voir",
"Can view pages in space but not edit.": "Peut voir les pages dans l'espace mais ne peut pas les modifier.",
"Cancel": "Annuler",
"Change email": "Changer le courriel",
"Change password": "Changer le mot de passe",
"Change photo": "Changer la photo",
"Choose a role": "Choisir un rôle",
"Choose your preferred color scheme.": "Choisissez votre palette de couleurs préférée.",
"Choose your preferred interface language.": "Choisissez votre langue d'interface préférée.",
"Choose your preferred page width.": "Choisissez votre largeur de page préférée.",
"Confirm": "Confirmer",
"Copy link": "Copier le lien",
"Create": "Créer",
"Create group": "Créer groupe",
"Create page": "Créer page",
"Create space": "Créer espace",
"Create workspace": "Créer espace de travail",
"Current password": "Mot de passe actuel",
"Dark": "Sombre",
"Date": "Date",
"Delete": "Supprimer",
"Delete group": "Supprimer groupe",
"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",
"Details": "Détails",
"e.g ACME": "par ex. ACME",
"e.g ACME Inc": "par ex. ACME Inc",
"e.g Developers": "par ex. Développeurs",
"e.g Group for developers": "par ex. Groupe pour développeurs",
"e.g product": "par ex. produit",
"e.g Product Team": "par ex. Équipe Produit",
"e.g Sales": "par ex. Ventes",
"e.g Space for product team": "par ex. Espace pour l'équipe produit",
"e.g Space for sales team to collaborate": "par ex. Espace pour l'équipe de vente pour collaborer",
"Edit": "Modifier",
"Read": "Lire",
"Edit group": "Modifier groupe",
"Email": "Email",
"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 emails addresses": "entrez des adresses email valides",
"Enter your current password": "Entrez votre mot de passe actuel",
"enter your full name": "entrez votre nom complet",
"Enter your new password": "Entrez votre nouveau mot de passe",
"Enter your new preferred email": "Entrez votre nouvel email préféré",
"Enter your password": "Entrez votre mot de passe",
"Error fetching page data.": "Erreur lors de la récupération des données de la page.",
"Error loading page history.": "Erreur lors du chargement de l'historique de la page.",
"Export": "Exporter",
"Failed to create page": "Échec de la création de la page",
"Failed to delete page": "Échec de la suppression de la page",
"Failed to fetch recent pages": "Échec de la récupération des pages récentes",
"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 update data": "Échec de la mise à jour des données",
"Full access": "Accès complet",
"Full page width": "Largeur de page complète",
"Full width": "Largeur complète",
"General": "Général",
"Group": "Groupe",
"Group description": "Description du groupe",
"Group name": "Nom du groupe",
"Groups": "Groupes",
"Has full access to space settings and pages.": "A un accès complet aux paramètres de l'espace et aux pages.",
"Home": "Accueil",
"Import pages": "Importer des pages",
"Import pages & space settings": "Importer des pages et paramètres de l'espace",
"Importing pages": "Importation des pages",
"invalid invitation link": "lien d'invitation invalide",
"Invitation signup": "Inscription par invitation",
"Invite by email": "Inviter par email",
"Invite members": "Inviter des membres",
"Invite new members": "Inviter de nouveaux membres",
"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",
"Join the workspace": "Rejoindre l'espace de travail",
"Language": "Langue",
"Light": "Clair",
"Link copied": "Lien copié",
"Login": "Connexion",
"Logout": "Déconnexion",
"Manage Group": "Gérer le groupe",
"Manage members": "Gérer les membres",
"member": "membre",
"Member": "Membre",
"members": "membres",
"Members": "Membres",
"My preferences": "Mes préférences",
"My Profile": "Mon Profil",
"My profile": "Mon profil",
"Name": "Nom",
"New email": "Nouvel email",
"New page": "Nouvelle page",
"New password": "Nouveau mot de passe",
"No group found": "Aucun groupe trouvé",
"No page history saved yet.": "Aucun historique de la page enregistré pour l'instant.",
"No pages yet": "Aucune page pour l'instant",
"No results found...": "Aucun résultat trouvé...",
"No user found": "Aucun utilisateur trouvé",
"Overview": "Vue d'ensemble",
"Owner": "Propriétaire",
"page": "page",
"Page deleted successfully": "Page supprimée avec succès",
"Page history": "Historique de la page",
"Page import is in progress. Please do not close this tab.": "L'importation de la page est en cours. Veuillez ne pas fermer cet onglet.",
"Pages": "Pages",
"pages": "pages",
"Password": "Mot de passe",
"Password changed successfully": "Mot de passe changé avec succès",
"Pending": "En attente",
"Please confirm your action": "Veuillez confirmer votre action",
"Preferences": "Préférences",
"Print PDF": "Imprimer PDF",
"Profile": "Profil",
"Recently updated": "Récemment mis à jour",
"Remove": "Retirer",
"Remove group member": "Retirer un membre du groupe",
"Remove space member": "Retirer un membre de l'espace",
"Restore": "Restaurer",
"Role": "Rôle",
"Save": "Enregistrer",
"Search": "Rechercher",
"Search for groups": "Rechercher des groupes",
"Search for users": "Rechercher des utilisateurs",
"Search for users and groups": "Rechercher des utilisateurs et des groupes",
"Search...": "Rechercher...",
"Select language": "Sélectionner la langue",
"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 theme": "Sélectionner le thème",
"Send invitation": "Envoyer l'invitation",
"Invitation sent": "Invitation envoyée",
"Settings": "Paramètres",
"Setup workspace": "Configurer l'espace de travail",
"Sign In": "Se connecter",
"Sign Up": "S'inscrire",
"Slug": "Slug",
"Space": "Espace",
"Space description": "Description de l'espace",
"Space menu": "Menu de l'espace",
"Space name": "Nom de l'espace",
"Space settings": "Paramètres de l'espace",
"Space slug": "Slug de l'espace",
"Spaces": "Espaces",
"Spaces you belong to": "Espaces auxquels vous appartenez",
"No space found": "Aucun espace trouvé",
"Search for spaces": "Rechercher des espaces",
"Start typing to search...": "Commencez à taper pour rechercher...",
"Status": "Statut",
"Successfully imported": "Importé avec succès",
"Successfully restored": "Restauré avec succès",
"System settings": "Paramètres systè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.",
"Toggle full page width": "Basculer sur la largeur complète de la page",
"Unable to import pages. Please try again.": "Impossible d'importer les pages. Veuillez réessayer.",
"untitled": "sans titre",
"Untitled": "Sans titre",
"Updated successfully": "Mis à jour avec succès",
"User": "Utilisateur",
"Workspace": "Espace de travail",
"Workspace Name": "Nom de l'espace de travail",
"Workspace settings": "Paramètres de l'espace de travail",
"You can change your password here.": "Vous pouvez changer votre mot de passe ici.",
"Your Email": "Votre Email",
"Your import is complete.": "Votre importation est terminée.",
"Your name": "Votre nom",
"Your Name": "Votre Nom",
"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.",
"Sidebar toggle": "Bascule de la barre latérale",
"Comments": "Commentaires",
"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.",
"Take me back to homepage": "Ramenez-moi à la page d'accueil",
"Forgot 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.",
"Send reset link": "Envoyer le lien de réinitialisation",
"Password reset": "Réinitialisation du mot de passe",
"Your new password": "Votre nouveau mot de passe",
"Set password": "Définir le mot de passe",
"Write a comment": "Écrire un commentaire",
"Reply...": "Répondre...",
"Error loading comments.": "Erreur lors du chargement des commentaires.",
"No comments yet.": "Pas de commentaires pour l'instant.",
"Edit comment": "Modifier 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 ?",
"Comment created successfully": "Commentaire créé avec succès",
"Error creating comment": "Erreur lors de la création du commentaire",
"Comment updated successfully": "Commentaire mis à jour avec succès",
"Failed to update comment": "Échec de la mise à jour du commentaire",
"Comment deleted successfully": "Commentaire supprimé avec succès",
"Failed to delete comment": "Échec de la suppression du commentaire",
"Comment resolved successfully": "Commentaire résolu avec succès",
"Comment re-opened successfully": "Commentaire rouvert avec succès",
"Comment unresolved successfully": "Commentaire non résolu avec succès",
"Failed to resolve comment": "Échec de la résolution du commentaire",
"Resolve comment": "Résoudre le commentaire",
"Unresolve comment": "Désorganiser le commentaire",
"Resolve Comment Thread": "Résoudre le fil de commentaires",
"Unresolve Comment Thread": "Désorganiser le fil de commentaires",
"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 ?",
"Resolved": "Résolu",
"No active comments.": "Aucun commentaire actif.",
"No resolved comments.": "Aucun commentaire résolu.",
"Revoke invitation": "Révoquer l'invitation",
"Revoke": "Révoquer",
"Don't": "Ne pas",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Êtes-vous sûr de vouloir révoquer cette invitation ? L'utilisateur ne pourra pas rejoindre l'espace de travail.",
"Resend invitation": "Renvoyer l'invitation",
"Anyone with this link can join this workspace.": "Toute personne ayant ce lien peut rejoindre cet espace de travail.",
"Invite link": "Lien d'invitation",
"Copy": "Copier",
"Copy to space": "Copier dans l'espace",
"Copied": "Copié",
"Duplicate": "Dupliquer",
"Select a user": "Sélectionner un utilisateur",
"Select a group": "Sélectionner un groupe",
"Export all pages and attachments in this space.": "Exporter toutes les pages et pièces jointes dans cet espace.",
"Delete space": "Supprimer l'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.",
"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",
"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",
"Include subpages": "Inclure les sous-pages",
"Include attachments": "Inclure les pièces jointes",
"Select export format": "Sélectionner le format d'exportation",
"Export failed:": "Échec de l'exportation :",
"export error": "exporter l'erreur",
"Export page": "Exporter la page",
"Export space": "Exporter l'espace",
"Export {{type}}": "Exporter {{type}}",
"File exceeds the {{limit}} attachment limit": "Le fichier dépasse la limite de {{limit}} pièces jointes",
"Align left": "Aligner à gauche",
"Align right": "Aligner à droite",
"Align center": "Aligner au centre",
"Justify": "Justifier",
"Merge cells": "Fusionner les cellules",
"Split cell": "Diviser la cellule",
"Delete column": "Supprimer la colonne",
"Delete row": "Supprimer la ligne",
"Add left column": "Ajouter colonne à gauche",
"Add right column": "Ajouter colonne à droite",
"Add row above": "Ajouter une ligne au-dessus",
"Add row below": "Ajouter une ligne en dessous",
"Delete table": "Supprimer le tableau",
"Info": "Info",
"Success": "Succès",
"Warning": "Avertissement",
"Danger": "Danger",
"Mermaid diagram error:": "Erreur de diagramme Mermaid :",
"Invalid Mermaid diagram": "Diagramme Mermaid invalide",
"Double-click to edit Draw.io diagram": "Double-cliquez pour modifier le diagramme Draw.io",
"Exit": "Quitter",
"Save & Exit": "Enregistrer & Quitter",
"Double-click to edit Excalidraw diagram": "Double-cliquez pour modifier le diagramme Excalidraw",
"Paste link": "Coller le lien",
"Edit link": "Modifier le lien",
"Remove link": "Supprimer le lien",
"Add link": "Ajouter un lien",
"Please enter a valid url": "Veuillez entrer une URL valide",
"Empty equation": "Équation vide",
"Invalid equation": "Équation invalide",
"Color": "Couleur",
"Text color": "Couleur du texte",
"Default": "Par défaut",
"Blue": "Bleu",
"Green": "Vert",
"Purple": "Violet",
"Red": "Rouge",
"Yellow": "Jaune",
"Orange": "Orange",
"Pink": "Rose",
"Gray": "Gris",
"Embed link": "Intégrer un lien",
"Invalid {{provider}} embed link": "Lien d'intégration {{provider}} non valide",
"Embed {{provider}}": "Intégrer {{provider}}",
"Enter {{provider}} link to embed": "Entrez le lien {{provider}} à intégrer",
"Bold": "Gras",
"Italic": "Italique",
"Underline": "Souligner",
"Strike": "Barrer",
"Code": "Code",
"Comment": "Commentaire",
"Text": "Texte",
"Heading 1": "Titre 1",
"Heading 2": "Titre 2",
"Heading 3": "Titre 3",
"To-do List": "Liste de tâches",
"Bullet List": "Liste à puces",
"Numbered List": "Liste numérotée",
"Blockquote": "Bloc de citation",
"Just start typing with plain text.": "Commencez simplement à taper avec du texte brut.",
"Track tasks with a to-do list.": "Suivez les tâches avec une liste de tâches.",
"Big section heading.": "Grand titre de section.",
"Medium section heading.": "Titre de section moyen.",
"Small section heading.": "Petit titre de section.",
"Create a simple bullet list.": "Créez une simple liste à puces.",
"Create a list with numbering.": "Créez une liste numérotée.",
"Create block quote.": "Créez un bloc de citation.",
"Insert code snippet.": "Insérez un extrait de code.",
"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 video from your device.": "Téléchargez n'importe quelle vidéo depuis votre appareil.",
"Upload any file from your device.": "Téléchargez n'importe quel fichier depuis votre appareil.",
"Table": "Tableau",
"Insert a table.": "Insérez un tableau.",
"Insert collapsible block.": "Insérer un bloc repliable.",
"Video": "Vidéo",
"Divider": "Diviseur",
"Quote": "Citation",
"Image": "Image",
"File attachment": "Pièce jointe",
"Toggle block": "Basculer le bloc",
"Callout": "Appel",
"Insert callout notice.": "Insérer un avis d'appel.",
"Math inline": "Mathématiques en ligne",
"Insert inline math equation.": "Insérez une équation mathématique en ligne.",
"Math block": "Bloc mathématiques",
"Insert math equation": "Insérer une équation mathématique",
"Mermaid diagram": "Diagramme Mermaid",
"Insert mermaid diagram": "Insérer un diagramme Mermaid",
"Insert and design Drawio diagrams": "Insérer et concevoir des diagrammes Drawio",
"Insert current date": "Insérer la date actuelle",
"Draw and sketch excalidraw diagrams": "Dessiner et esquisser des diagrammes Excalidraw",
"Multiple": "Multiple",
"Heading {{level}}": "Titre {{level}}",
"Toggle title": "Basculer le titre",
"Write anything. Enter \"/\" for commands": "Écrivez n'importe quoi. Entrez \"/\" pour les commandes",
"Names do not match": "Les noms ne correspondent pas",
"Today, {{time}}": "Aujourd'hui, {{time}}",
"Yesterday, {{time}}": "Hier, {{time}}",
"Space created successfully": "Espace créé avec succès",
"Space updated successfully": "Espace mis à jour avec succès",
"Space deleted successfully": "Espace supprimé avec succès",
"Members added successfully": "Membres ajoutés avec succès",
"Member removed successfully": "Membre supprimé 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 at: {{time}}": "Créé à : {{time}}",
"Edited by {{name}} {{time}}": "Modifié par {{name}} {{time}}",
"Word count: {{wordCount}}": "Nombre de mots : {{wordCount}}",
"Character count: {{characterCount}}": "Nombre de caractères : {{characterCount}}",
"New update": "Nouvelle mise à jour",
"{{latestVersion}} is available": "{{latestVersion}} est disponible",
"Default page edit mode": "Mode d'édition de page par défaut",
"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",
"Delete member": "Supprimer le membre",
"Member deleted successfully": "Membre supprimé avec succès",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Êtes-vous sûr de vouloir supprimer ce membre de l'espace de travail? Cette action est irréversible.",
"Move": "Déplacer",
"Move page": "Déplacer la page",
"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...",
"Table of contents": "",
"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",
"Public sharing": "Partage public",
"Shared by": "Partagé par",
"Shared at": "Partagé à",
"Inherits public sharing from": "Hérite du partage public de",
"Share to web": "Partager 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",
"Make this page publicly accessible": "Rendre cette page accessible au public",
"Include sub-pages": "Inclure les sous-pages",
"Make sub-pages public too": "Rendre également les sous-pages publiques",
"Allow search engines to index page": "Autoriser les moteurs de recherche à indexer la page",
"Open page": "Ouvrir la page",
"Page": "Page",
"Delete public share link": "Supprimer le lien de partage public",
"Delete share": "Supprimer le partage",
"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",
"Share deleted successfully": "Partage supprimé avec succès",
"Share not found": "Partage non trouvé",
"Failed to share page": "Échec du partage de la page",
"Copy page": "Copier la page",
"Copy page to a different space.": "Copier la page dans un autre espace.",
"Page copied successfully": "Page copiée avec succès",
"Page duplicated successfully": "Page dupliquée avec succès",
"Find": "Trouver",
"Not found": "Non trouvé",
"Previous Match (Shift+Enter)": "Correspondance précédente (Shift+Entrée)",
"Next match (Enter)": "Correspondance suivante (Entrée)",
"Match case (Alt+C)": "Respecter la casse (Alt+C)",
"Replace": "Remplacer",
"Close (Escape)": "Fermer (Échapper)",
"Replace (Enter)": "Remplacer (Entrée)",
"Replace all (Ctrl+Alt+Enter)": "Tout remplacer (Ctrl+Alt+Entrée)",
"Replace all": "Tout remplacer",
"View all spaces": "Voir tous les espaces",
"Error": "Erreur",
"Failed to disable MFA": "Impossible de désactiver l'A2F",
"Disable two-factor authentication": "Désactiver l'authentification à 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.",
"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 disabled": "L'authentification à deux facteurs a été désactivée",
"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.",
"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",
"Backup codes": "Codes de sauvegarde",
"Disable": "Désactiver",
"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",
"Failed to regenerate backup codes": "Échec de la régénération des codes de sauvegarde",
"About backup codes": "À propos des codes de sauvegarde",
"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.",
"Confirm password": "Confirmer le mot de passe",
"Generate new backup codes": "Générer de nouveaux codes de sauvegarde",
"Save your new backup codes": "Enregistrez vos nouveaux codes de sauvegarde",
"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",
"I've saved my backup codes": "J'ai enregistré mes codes de sauvegarde",
"Failed to setup MFA": "Échec de la configuration de l'A2F",
"Setup & Verify": "Configurer et vérifier",
"Add to authenticator": "Ajouter à l'authentification",
"1. Scan this QR code with your authenticator app": "1. Scannez ce code QR avec votre application d'authentification",
"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 :",
"2. Enter the 6-digit code from your authenticator": "2. Entrez le code à 6 chiffres de votre authentificateur",
"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.",
"Backup": "Sauvegarde",
"Save codes": "Enregistrer les codes",
"Save your backup codes": "Enregistrez vos codes de sauvegarde",
"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",
"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",
"Your workspace requires two-factor authentication for all users": "Votre espace de travail nécessite l'authentification à 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.",
"Set up two-factor authentication": "Configurer l'authentification à deux facteurs",
"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.",
"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 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",
"Code must be exactly 6 digits": "Le code doit être exactement de 6 chiffres",
"Enter the 6-digit code found in your authenticator app": "Entrez le code à 6 chiffres trouvé dans votre application d'authentification",
"Need help authenticating?": "Besoin d'aide pour l'authentification ?",
"MFA QR Code": "Code QR de l'A2F",
"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 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.",
"Two-factor authentication": "Authentification à deux facteurs",
"Use authenticator app instead": "Utilisez l'application d'authentification à la place",
"Verify backup code": "Vérifier le code de sauvegarde",
"Use backup code": "Utiliser le code de sauvegarde",
"Enter one of your backup codes": "Entrez un de vos codes de sauvegarde",
"Backup code": "Code de sauvegarde",
"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",
"Trash": "Corbeille",
"Pages in trash will be permanently deleted after 30 days.": "Les pages dans la corbeille seront définitivement supprimées après 30 jours.",
"Deleted": "Supprimé",
"No pages in trash": "Aucune page dans la corbeille",
"Permanently delete page?": "Supprimer définitivement la page ?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Êtes-vous sûr de vouloir supprimer définitivement « {{title}} » ? Cette action ne peut pas être annulée.",
"Restore '{{title}}' and its sub-pages?": "Restaurer « {{title}} » et ses sous-pages ?",
"Move to trash": "Déplacer vers la corbeille",
"Move this page to trash?": "Déplacer cette page vers la corbeille ?",
"Restore page": "Restaurer la page",
"Page moved to trash": "Page déplacée vers la corbeille",
"Page restored successfully": "Page restaurée avec succès",
"Deleted by": "Supprimé par",
"Deleted at": "Supprimé à",
"Preview": "Aperçu",
"Subpages": "Sous-pages",
"Failed to load subpages": "Échec du chargement des sous-pages",
"No subpages": "Pas de sous-pages",
"Subpages (Child pages)": "Sous-pages (Pages enfants)",
"List all subpages of the current page": "Lister toutes les sous-pages de la page actuelle",
"Attachments": "Pièces jointes",
"All spaces": "Tous les espaces",
"Unknown": "Inconnu",
"Find a space": "Trouver un espace",
"Search in all your spaces": "Rechercher dans tous vos espaces",
"Type": "Type",
"Enterprise": "Entreprise",
"Download attachment": "Télécharger la pièce jointe",
"Allowed email domains": "Domaines de messagerie 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.",
"Enter valid domain names separated by comma or space": "Entrez des noms de domaine valides séparés par une virgule ou un espace",
"Enforce two-factor authentication": "Imposer l'authentification à 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.",
"Toggle MFA enforcement": "Basculer l'application de l'AMF",
"Display name": "Nom d'affichage",
"Allow signup": "Autoriser l'inscription",
"Enabled": "Activé",
"Advanced Settings": "Paramètres avancés",
"Enable TLS/SSL": "Activer TLS/SSL",
"Use secure connection to LDAP server": "Utiliser une connexion sécurisée au serveur LDAP",
"Group sync": "Synchronisation de groupe",
"No SSO providers found.": "Aucun fournisseur SSO trouvé.",
"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 ?",
"Action": "Action",
"{{ssoProviderType}} configuration": "Configuration {{ssoProviderType}}"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Account",
"Active": "Attivo",
"Add": "Aggiungi",
"Add group members": "Aggiungi membri al gruppo",
"Add groups": "Aggiungi gruppi",
"Add members": "Aggiungi membri",
"Add to groups": "Aggiungi ai gruppi",
"Add space members": "Aggiungi membri allo spazio",
"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 page?": "Sei sicuro di voler eliminare questa pagina?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Sei sicuro di voler rimuovere questo utente dal gruppo? L'utente perderà l'accesso alle risorse accessibili da questo gruppo.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Sei sicuro di voler rimuovere questo utente dallo spazio? L'utente perderà tutti gli accessi a questo spazio.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Sei sicuro di voler ripristinare questa versione? Qualsiasi modifica non versionata verrà persa.",
"Can become members of groups and spaces in workspace": "Può diventare membro di gruppi e spazi nell'area di lavoro",
"Can create and edit pages in space.": "Può creare e modificare le pagine nello spazio.",
"Can edit": "Può modificare",
"Can manage workspace": "Può gestire l'area di lavoro",
"Can manage workspace but cannot delete it": "Può gestire lo spazio di lavoro ma non può eliminarlo",
"Can view": "Può visualizzare",
"Can view pages in space but not edit.": "Può visualizzare le pagine nello spazio ma non può modificarle.",
"Cancel": "Annulla",
"Change email": "Cambia email",
"Change password": "Cambia password",
"Change photo": "Cambia foto",
"Choose a role": "Scegli un ruolo",
"Choose your preferred color scheme.": "Scegli il tema che preferisci.",
"Choose your preferred interface language.": "Scegli la lingua da utilizzare per l'interfaccia.",
"Choose your preferred page width.": "Scegli la larghezza della pagina che preferisci.",
"Confirm": "Conferma",
"Copy link": "Copia link",
"Create": "Crea",
"Create group": "Crea gruppo",
"Create page": "Crea pagina",
"Create space": "Crea spazio",
"Create workspace": "Crea area di lavoro",
"Current password": "Password attuale",
"Dark": "Scuro",
"Date": "Data",
"Delete": "Elimina",
"Delete group": "Elimina gruppo",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Sei sicuro di voler eliminare questa pagina? Verranno cancellate anche le sue sottopagine e la cronologia. Questa azione è irreversibile.",
"Description": "Descrizione",
"Details": "Dettagli",
"e.g ACME": "es. ACME",
"e.g ACME Inc": "es. ACME Inc",
"e.g Developers": "es. Sviluppatori",
"e.g Group for developers": "es. Gruppo per gli sviluppatori",
"e.g product": "es. prodotto",
"e.g Product Team": "es. Team di Prodotto",
"e.g Sales": "es. Vendite",
"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",
"Edit": "Modifica",
"Read": "Leggi",
"Edit group": "Modifica gruppo",
"Email": "Email",
"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 emails addresses": "inserisci degli indirizzi email validi",
"Enter your current password": "Inserisci la tua password attuale",
"enter your full name": "inserisci il tuo nome completo",
"Enter your new password": "Inserisci la tua nuova password",
"Enter your new preferred email": "Inserisci la tua nuova email preferita",
"Enter your password": "Inserisci la tua password",
"Error fetching page data.": "Si è verificato un errore durante il recupero dei dati della pagina.",
"Error loading page history.": "Si è verificato un errore durante il caricamento della cronologia della pagina.",
"Export": "Esporta",
"Failed to create page": "Impossibile creare la pagina",
"Failed to delete page": "Impossibile eliminare la pagina",
"Failed to fetch recent pages": "Impossibile recuperare le pagine recenti",
"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 update data": "Impossibile aggiornare i dati",
"Full access": "Accesso completo",
"Full page width": "Pagina a larghezza intera",
"Full width": "Larghezza intera",
"General": "Generale",
"Group": "Gruppo",
"Group description": "Descrizione del gruppo",
"Group name": "Nome del gruppo",
"Groups": "Gruppi",
"Has full access to space settings and pages.": "Ha pieno accesso alle impostazioni dello spazio e alle sue pagine.",
"Home": "Casa",
"Import pages": "Importa pagine",
"Import pages & space settings": "Importa pagine e impostazioni dello spazio",
"Importing pages": "Importazione pagine",
"invalid invitation link": "link di invito non valido",
"Invitation signup": "Iscrizione invito",
"Invite by email": "Invita tramite email",
"Invite members": "Invita membri",
"Invite new members": "Invita nuovi membri",
"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",
"Join the workspace": "Unisciti all'area di lavoro",
"Language": "Lingua",
"Light": "Chiaro",
"Link copied": "Link copiato",
"Login": "Login",
"Logout": "Esci",
"Manage Group": "Gestisci Gruppo",
"Manage members": "Gestisci membri",
"member": "membro",
"Member": "Membro",
"members": "membri",
"Members": "Membri",
"My preferences": "Le mie preferenze",
"My Profile": "Il Mio Profilo",
"My profile": "Il mio profilo",
"Name": "Nome",
"New email": "Nuova email",
"New page": "Nuova pagina",
"New password": "Nuova password",
"No group found": "Nessun gruppo trovato",
"No page history saved yet.": "La pagina non ha una cronologia per ora.",
"No pages yet": "Nessuna pagina per ora",
"No results found...": "Nessun risultato trovato...",
"No user found": "Nessun utente trovato",
"Overview": "Panoramica",
"Owner": "Proprietario",
"page": "pagina",
"Page deleted successfully": "Pagina eliminata con successo",
"Page history": "Cronologia della pagina",
"Page import is in progress. Please do not close this tab.": "L'importazione della pagina è in corso. Si prega di non chiudere questa scheda.",
"Pages": "Pagine",
"pages": "pagine",
"Password": "Password",
"Password changed successfully": "Password cambiata con successo",
"Pending": "In sospeso",
"Please confirm your action": "Si prega di confermare la propria azione",
"Preferences": "Preferenze",
"Print PDF": "Stampa PDF",
"Profile": "Profilo",
"Recently updated": "Aggiornato di recente",
"Remove": "Rimuovi",
"Remove group member": "Rimuovi membro dal gruppo",
"Remove space member": "Rimuovi membro dallo spazio",
"Restore": "Ripristina",
"Role": "Ruolo",
"Save": "Salva",
"Search": "Cerca",
"Search for groups": "Cerca un gruppo",
"Search for users": "Cerca un utente",
"Search for users and groups": "Cerca un utente o un gruppo",
"Search...": "Cerca...",
"Select language": "Seleziona una lingua",
"Select role": "Seleziona un ruolo",
"Select role to assign to all invited members": "Seleziona il ruolo da assegnare a tutti i membri invitati",
"Select theme": "Seleziona un tema",
"Send invitation": "Invia invito",
"Invitation sent": "Invito inviato",
"Settings": "Impostazioni",
"Setup workspace": "Configura l'area di lavoro",
"Sign In": "Accedi",
"Sign Up": "Registrati",
"Slug": "Slug",
"Space": "Spazio",
"Space description": "Descrizione dello spazio",
"Space menu": "Menu spazio",
"Space name": "Nome dello spazio",
"Space settings": "Impostazioni dello spazio",
"Space slug": "Slug dello spazio",
"Spaces": "Spazi",
"Spaces you belong to": "Spazi a cui appartieni",
"No space found": "Nessuno spazio trovato",
"Search for spaces": "Cerca uno spazio",
"Start typing to search...": "Inizia a digitare per cercare...",
"Status": "Stato",
"Successfully imported": "Importato con successo",
"Successfully restored": "Ripristinato con successo",
"System settings": "Impostazioni di sistema",
"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.",
"Toggle full page width": "Attiva/disattiva pagina a larghezza intera",
"Unable to import pages. Please try again.": "Impossibile importare le pagine. Riprova.",
"untitled": "senza titolo",
"Untitled": "Senza titolo",
"Updated successfully": "Aggiornato con successo",
"User": "Utente",
"Workspace": "Area di lavoro",
"Workspace Name": "Nome dell'area di lavoro",
"Workspace settings": "Impostazioni dell'area di lavoro",
"You can change your password here.": "Qui puoi cambiare la tua password.",
"Your Email": "La tua email",
"Your import is complete.": "La tua importazione è completata.",
"Your name": "Il tuo nome",
"Your Name": "Il Tuo Nome",
"Your password": "La tua password",
"Your password must be a minimum of 8 characters.": "La tua password deve contenere almeno 8 caratteri.",
"Sidebar toggle": "Attiva/disattiva barra laterale",
"Comments": "Commenti",
"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.",
"Take me back to homepage": "Torna all'homepage",
"Forgot password": "Password dimenticata",
"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.",
"Send reset link": "Invia link per il ripristino della password",
"Password reset": "Reimposta password",
"Your new password": "La tua nuova password",
"Set password": "Imposta password",
"Write a comment": "Scrivi un commento",
"Reply...": "Rispondi...",
"Error loading comments.": "Si è verificato un errore durante il caricamento dei commenti.",
"No comments yet.": "Nessun commento per ora.",
"Edit comment": "Modifica commento",
"Delete comment": "Elimina commento",
"Are you sure you want to delete this comment?": "Sei sicuro di voler eliminare questo commento?",
"Comment created successfully": "Commento creato con successo",
"Error creating comment": "Si è verificato un errore durante la creazione del commento",
"Comment updated successfully": "Commento aggiornato con successo",
"Failed to update comment": "Impossibile aggiornare il commento",
"Comment deleted successfully": "Commento eliminato con successo",
"Failed to delete comment": "Impossibile eliminare il commento",
"Comment resolved successfully": "Commento risolto con successo",
"Comment re-opened successfully": "Commento riaperto con successo",
"Comment unresolved successfully": "Commento non risolto con successo",
"Failed to resolve comment": "Impossibile risolvere il commento",
"Resolve comment": "Risolvi commento",
"Unresolve comment": "Annulla risoluzione commento",
"Resolve Comment Thread": "Risolvi discussione commenti",
"Unresolve Comment Thread": "Annulla risoluzione discussione commenti",
"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?",
"Resolved": "Risolto",
"No active comments.": "Nessun commento attivo.",
"No resolved comments.": "Nessun commento risolto.",
"Revoke invitation": "Revoca invito",
"Revoke": "Revoca",
"Don't": "Non",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Sei sicuro di voler revocare questo invito? L'utente non potrà unirsi all'area di lavoro.",
"Resend invitation": "Rispedisci invito",
"Anyone with this link can join this workspace.": "Chiunque con questo link può unirsi a questa area di lavoro.",
"Invite link": "Link d'invito",
"Copy": "Copia",
"Copy to space": "Copia nello spazio",
"Copied": "Copiato",
"Duplicate": "Duplica",
"Select a user": "Seleziona un utente",
"Select a group": "Seleziona un gruppo",
"Export all pages and attachments in this space.": "Esporta tutte le pagine e gli allegati di questo spazio.",
"Delete space": "Elimina 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.",
"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",
"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",
"Include subpages": "Includi sottopagine",
"Include attachments": "Includi allegati",
"Select export format": "Seleziona formato di esportazione",
"Export failed:": "Esportazione fallita:",
"export error": "errore di esportazione",
"Export page": "Esporta pagina",
"Export space": "Esporta spazio",
"Export {{type}}": "Esporta {{type}}",
"File exceeds the {{limit}} attachment limit": "Il file supera il limite per gli allegati di {{limit}}",
"Align left": "Allinea a sinistra",
"Align right": "Allinea a destra",
"Align center": "Allinea al centro",
"Justify": "Giustifica",
"Merge cells": "Unisci celle",
"Split cell": "Dividi cella",
"Delete column": "Elimina colonna",
"Delete row": "Elimina riga",
"Add left column": "Aggiungi colonna a sinistra",
"Add right column": "Aggiungi colonna a destra",
"Add row above": "Aggiungi riga sopra",
"Add row below": "Aggiungi riga sotto",
"Delete table": "Elimina tabella",
"Info": "Informazioni",
"Success": "Successo",
"Warning": "Avviso",
"Danger": "Pericolo",
"Mermaid diagram error:": "Errore nel diagramma di Mermaid:",
"Invalid Mermaid diagram": "Diagramma di Mermaid non valido",
"Double-click to edit Draw.io diagram": "Fai doppio clic per modificare il diagramma di Draw.io",
"Exit": "Esci",
"Save & Exit": "Salva ed esci",
"Double-click to edit Excalidraw diagram": "Fai doppio clic per modificare il diagramma di Excalidraw",
"Paste link": "Incolla link",
"Edit link": "Modifica link",
"Remove link": "Rimuovi link",
"Add link": "Aggiungi link",
"Please enter a valid url": "Per favore inserisci un URL valido",
"Empty equation": "Equazione vuota",
"Invalid equation": "Equazione non valida",
"Color": "Colore",
"Text color": "Colore del testo",
"Default": "Predefinito",
"Blue": "Blu",
"Green": "Verde",
"Purple": "Viola",
"Red": "Rosso",
"Yellow": "Giallo",
"Orange": "Arancione",
"Pink": "Rosa",
"Gray": "Grigio",
"Embed link": "Incorpora collegamento",
"Invalid {{provider}} embed link": "Link di incorporamento {{provider}} non valido",
"Embed {{provider}}": "Incorpora {{provider}}",
"Enter {{provider}} link to embed": "Inserisci il link {{provider}} per incorporare",
"Bold": "Grassetto",
"Italic": "Corsivo",
"Underline": "Sottolineato",
"Strike": "Barrato",
"Code": "Codice",
"Comment": "Commento",
"Text": "Testo",
"Heading 1": "Intestazione 1",
"Heading 2": "Intestazione 2",
"Heading 3": "Intestazione 3",
"To-do List": "Lista delle cose da fare",
"Bullet List": "Elenco Puntato",
"Numbered List": "Elenco Numerato",
"Blockquote": "Citazione",
"Just start typing with plain text.": "Inizia a digitare con testo semplice.",
"Track tasks with a to-do list.": "Tieni traccia delle attività con una lista di cose da fare.",
"Big section heading.": "Intestazione di una grande sezione.",
"Medium section heading.": "Intestazione di sezione media.",
"Small section heading.": "Piccolo titolo di sezione.",
"Create a simple bullet list.": "Crea un semplice elenco puntato.",
"Create a list with numbering.": "Crea un elenco numerato.",
"Create block quote.": "Crea blocco citazione.",
"Insert code snippet.": "Inserisci frammento di codice.",
"Insert horizontal rule divider": "Inserisci divisore di regola orizzontale",
"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 file from your device.": "Carica qualsiasi file dal tuo dispositivo.",
"Table": "Tabella",
"Insert a table.": "Inserisci una tabella.",
"Insert collapsible block.": "Inserisci blocco comprimibile.",
"Video": "Video",
"Divider": "Divisore",
"Quote": "Preventivo",
"Image": "Immagine",
"File attachment": "Allegato file",
"Toggle block": "Attiva blocco",
"Callout": "Avviso",
"Insert callout notice.": "Inserisci avviso di richiamo.",
"Math inline": "Matematica in linea",
"Insert inline math equation.": "Inserisci equazione matematica in linea.",
"Math block": "Blocco matematico",
"Insert math equation": "Inserisci equazione matematica",
"Mermaid diagram": "Diagramma di Mermaid",
"Insert mermaid diagram": "Inserisci un diagramma di Mermaid",
"Insert and design Drawio diagrams": "Inserisci e progetta diagrammi Drawio",
"Insert current date": "Inserisci la data corrente",
"Draw and sketch excalidraw diagrams": "Disegna e schizza diagrammi excalidraw",
"Multiple": "Multiplo",
"Heading {{level}}": "Intestazione {{level}}",
"Toggle title": "Attiva/disattiva titolo",
"Write anything. Enter \"/\" for commands": "Scrivi qualcosa. Digita \"/\" per i comandi",
"Names do not match": "I nomi non corrispondono",
"Today, {{time}}": "Oggi, {{time}}",
"Yesterday, {{time}}": "Ieri, {{time}}",
"Space created successfully": "Spazio creato con successo",
"Space updated successfully": "Spazio aggiornato con successo",
"Space deleted successfully": "Spazio eliminato con successo",
"Members added successfully": "Membri aggiunti con successo",
"Member removed successfully": "Membro rimosso con successo",
"Member role updated successfully": "Ruolo del membro aggiornato con successo",
"Created by: <b>{{creatorName}}</b>": "Creato da: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Creato il: {{time}}",
"Edited by {{name}} {{time}}": "Modificato da {{name}} il {{time}}",
"Word count: {{wordCount}}": "Conteggio parole: {{wordCount}}",
"Character count: {{characterCount}}": "Conteggio caratteri: {{characterCount}}",
"New update": "Nuovo aggiornamento",
"{{latestVersion}} is available": "{{latestVersion}} è disponibile",
"Default page edit mode": "Modalità di modifica pagina predefinita",
"Choose your preferred page edit mode. Avoid accidental edits.": "Scegli la tua modalità di modifica della pagina preferita. Evita modifiche accidentali.",
"Reading": "Lettura",
"Delete member": "Elimina membro",
"Member deleted successfully": "Membro eliminato con successo",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Sei sicuro di voler eliminare questo membro del workspace? Questa azione è irreversibile.",
"Move": "Sposta",
"Move page": "Sposta pagina",
"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...",
"Table of contents": "Indice dei contenuti",
"Add headings (H1, H2, H3) to generate a table of contents.": "Aggiungi intestazioni (H1, H2, H3) per generare un sommario.",
"Share": "Condividi",
"Public sharing": "Condivisione pubblica",
"Shared by": "Condiviso da",
"Shared at": "Condiviso il",
"Inherits public sharing from": "Eredita la condivisione pubblica da",
"Share to web": "Condividi su web",
"Shared to web": "Condiviso su web",
"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",
"Include sub-pages": "Includi sotto-pagine",
"Make sub-pages public too": "Rendi pubbliche anche le sotto-pagine",
"Allow search engines to index page": "Permetti ai motori di ricerca di indicizzare la pagina",
"Open page": "Apri pagina",
"Page": "Pagina",
"Delete public share link": "Elimina il link di condivisione pubblica",
"Delete share": "Elimina condivisione",
"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",
"Share deleted successfully": "Condivisione eliminata con successo",
"Share not found": "Condivisione non trovata",
"Failed to share page": "Condivisione della pagina fallita",
"Copy page": "Copia pagina",
"Copy page to a different space.": "Copia pagina in un altro spazio.",
"Page copied successfully": "Pagina copiata con successo",
"Page duplicated successfully": "Pagina duplicata con successo",
"Find": "Trova",
"Not found": "Non trovato",
"Previous Match (Shift+Enter)": "Corrispondenza precedente (Shift+Invio)",
"Next match (Enter)": "Corrispondenza successiva (Invio)",
"Match case (Alt+C)": "Maiuscole/minuscole (Alt+C)",
"Replace": "Sostituisci",
"Close (Escape)": "Chiudi (Esc)",
"Replace (Enter)": "Sostituisci (Invio)",
"Replace all (Ctrl+Alt+Enter)": "Sostituisci tutto (Ctrl+Alt+Invio)",
"Replace all": "Sostituisci tutto",
"View all spaces": "Visualizza tutti gli spazi",
"Error": "Errore",
"Failed to disable MFA": "Disabilitazione MFA non riuscita",
"Disable two-factor authentication": "Disabilita 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.",
"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 disabled": "Autenticazione a due fattori disabilitata",
"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.",
"Two-factor authentication is active on your account.": "L'autenticazione a due fattori è attiva sul tuo account.",
"Add 2FA method": "Aggiungi metodo 2FA",
"Backup codes": "Codici di backup",
"Disable": "Disabilita",
"Invalid verification code": "Codice di verifica non valido",
"New backup codes have been generated": "Nuovi codici di backup generati",
"Failed to regenerate backup codes": "Rigenerazione codici di backup non riuscita",
"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.",
"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.",
"Confirm password": "Conferma password",
"Generate new backup codes": "Genera nuovi codici di backup",
"Save your new backup codes": "Salva i tuoi nuovi codici di backup",
"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",
"I've saved my backup codes": "Ho salvato i miei codici di backup",
"Failed to setup MFA": "Impostazione MFA non riuscita",
"Setup & Verify": "Imposta e Verifica",
"Add to authenticator": "Aggiungi ad authenticator",
"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?",
"Enter this code manually in your authenticator app:": "Inserisci questo codice manualmente nella tua app di autenticazione:",
"2. Enter the 6-digit code from your authenticator": "2. Inserisci il codice a 6 cifre dal tuo autenticatore",
"Verify and enable": "Verifica e abilita",
"Failed to generate QR code. Please try again.": "Generazione del codice QR non riuscita. Si prega di riprovare.",
"Backup": "Backup",
"Save codes": "Salva codici",
"Save your backup codes": "Salva i tuoi codici di 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.": "Questi codici 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.",
"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 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",
"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",
"Cancel and logout": "Annulla e disconnetti",
"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.",
"Password is required": "La password è richiesta",
"Password must be at least 8 characters": "La password deve essere di almeno 8 caratteri",
"Please enter a 6-digit code": "Inserisci un codice a 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",
"Need help authenticating?": "Hai bisogno di aiuto per autenticarti?",
"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.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Reimpostazione della password riuscita. Accedi con la tua nuova password e completa 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.",
"Two-factor authentication": "Autenticazione a due fattori",
"Use authenticator app instead": "Usa l'app di autenticazione invece",
"Verify backup code": "Verifica codice di backup",
"Use backup code": "Usa codice di backup",
"Enter one of your backup codes": "Inserisci uno dei tuoi codici di backup",
"Backup code": "Codice di backup",
"Enter one of your backup codes. Each backup code can only be used once.": "Inserisci uno dei tuoi codici di backup. Ogni codice di backup può essere utilizzato solo una volta.",
"Verify": "Verifica",
"Trash": "Cestino",
"Pages in trash will be permanently deleted after 30 days.": "Le pagine nel cestino verranno eliminate definitivamente dopo 30 giorni.",
"Deleted": "Eliminato",
"No pages in trash": "Nessuna pagina nel cestino",
"Permanently delete page?": "Eliminare definitivamente la pagina?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Sei sicuro di voler eliminare definitivamente '{{title}}'? Questa azione non può essere annullata.",
"Restore '{{title}}' and its sub-pages?": "Ripristinare '{{title}}' e le sue sottopagine?",
"Move to trash": "Sposta nel cestino",
"Move this page to trash?": "Spostare questa pagina nel cestino?",
"Restore page": "Ripristina pagina",
"Page moved to trash": "Pagina spostata nel cestino",
"Page restored successfully": "Pagina ripristinata con successo",
"Deleted by": "Eliminato da",
"Deleted at": "Eliminato il",
"Preview": "Anteprima",
"Subpages": "Sottopagine",
"Failed to load subpages": "Caricamento delle sottopagine non riuscito",
"No subpages": "Nessuna sottopagina",
"Subpages (Child pages)": "Sottopagine (Pagine figlie)",
"List all subpages of the current page": "Elenca tutte le sottopagine della pagina corrente",
"Attachments": "Allegati",
"All spaces": "Tutti gli spazi",
"Unknown": "Sconosciuto",
"Find a space": "Trova uno spazio",
"Search in all your spaces": "Cerca in tutti i tuoi spazi",
"Type": "Tipo",
"Enterprise": "Impresa",
"Download attachment": "Scarica allegato",
"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.",
"Enter valid domain names separated by comma or space": "Inserisci nomi di dominio validi separati da virgole o spazi",
"Enforce two-factor authentication": "Imponi 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.",
"Toggle MFA enforcement": "Attiva disattiva l'applicazione MFA",
"Display name": "Nome visualizzato",
"Allow signup": "Consenti iscrizione",
"Enabled": "Abilitato",
"Advanced Settings": "Impostazioni avanzate",
"Enable TLS/SSL": "Abilita TLS/SSL",
"Use secure connection to LDAP server": "Usa connessione sicura al server LDAP",
"Group sync": "Sincronizzazione gruppi",
"No SSO providers found.": "Nessun provider SSO trovato.",
"Delete SSO provider": "Elimina provider SSO",
"Are you sure you want to delete this SSO provider?": "Sei sicuro di voler eliminare questo provider SSO?",
"Action": "Azione",
"{{ssoProviderType}} configuration": "Configurazione {{ssoProviderType}}"
}

View File

@ -0,0 +1,531 @@
{
"Account": "アカウント",
"Active": "アクティブ",
"Add": "追加",
"Add group members": "グループメンバーを追加",
"Add groups": "グループを追加",
"Add members": "メンバーを追加",
"Add to groups": "グループに追加",
"Add space members": "スペースメンバーを追加",
"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 page?": "このページを削除してもよろしいですか?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "このユーザをグループから削除してもよろしいですか? ユーザはこのグループがアクセス権を持つリソースにアクセスできなくなります。",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "このユーザをスペースから削除してもよろしいですか? ユーザはこのスペースへのアクセス権をすべて失います。",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "このバージョンを復元してもよろしいですか? バージョン管理されていない変更は失われます。",
"Can become members of groups and spaces in workspace": "ワークスペース内のグループやスペースのメンバーになることができます",
"Can create and edit pages in space.": "スペース内のページを作成および編集できます。",
"Can edit": "編集可能",
"Can manage workspace": "ワークスペースを管理できます",
"Can manage workspace but cannot delete it": "ワークスペースを管理できますが、削除はできません",
"Can view": "閲覧可能",
"Can view pages in space but not edit.": "スペース内のページを閲覧できますが、編集はできません。",
"Cancel": "キャンセル",
"Change email": "メールアドレスの変更",
"Change password": "パスワードの変更",
"Change photo": "画像の変更",
"Choose a role": "ロールを選んでください",
"Choose your preferred color scheme.": "お好みのカラースキームを選択してください。",
"Choose your preferred interface language.": "お好みのインターフェース言語を選択してください。",
"Choose your preferred page width.": "左右の余白を縮小する場合はオンにしてください。",
"Confirm": "確認",
"Copy link": "リンクをコピー",
"Create": "新規作成",
"Create group": "グループを作成",
"Create page": "新規ページ",
"Create space": "新規スペース",
"Create workspace": "ワークスペースを作成",
"Current password": "現在のパスワード",
"Dark": "ダーク",
"Date": "日付",
"Delete": "削除",
"Delete group": "グループを削除",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "このページを削除してもよろしいですか?この操作により、子ページおよびページ履歴が削除されます。この操作は元に戻せません。",
"Description": "説明",
"Details": "詳細",
"e.g ACME": "例: 山田太郎",
"e.g ACME Inc": "例: 株式会社サンプル",
"e.g Developers": "例: エンジニア",
"e.g Group for developers": "例: エンジニアグループ",
"e.g product": "例: product",
"e.g Product Team": "例: 製品チーム",
"e.g Sales": "例: 営業",
"e.g Space for product team": "例: 製品チームのスペース",
"e.g Space for sales team to collaborate": "例: 営業チーム連携用スペース",
"Edit": "編集",
"Read": "読む",
"Edit group": "グループを編集",
"Email": "メールアドレス",
"Enter a strong password": "強力なパスワードを入力してください",
"Enter valid email addresses separated by comma or space max_50": "有効なメールアドレスをカンマまたはスペースで区切って入力してください(最大 50 個)",
"enter valid emails addresses": "有効なメールアドレスを入力してください",
"Enter your current password": "現在のパスワードを入力してください",
"enter your full name": "氏名を入力してください",
"Enter your new password": "新しいパスワードを入力してください",
"Enter your new preferred email": "新しいメールアドレスを入力してください",
"Enter your password": "パスワードを入力してください",
"Error fetching page data.": "ページデータ取得中にエラーが発生しました。",
"Error loading page history.": "ページ履歴の読み込み中にエラーが発生しました。",
"Export": "エクスポート",
"Failed to create page": "ページの作成に失敗しました",
"Failed to delete page": "ページの削除に失敗しました",
"Failed to fetch recent pages": "最近のページを取得できませんでした",
"Failed to import pages": "ページのインポートに失敗しました",
"Failed to load page. An error occurred.": "ページの読み込みに失敗しました。エラーが発生しました。",
"Failed to update data": "データの更新に失敗しました",
"Full access": "フルアクセス",
"Full page width": "フルページ幅で表示",
"Full width": "左右の余白を縮小",
"General": "一般",
"Group": "グループ",
"Group description": "グループ説明",
"Group name": "グループ名",
"Groups": "グループ",
"Has full access to space settings and pages.": "スペース設定とページにフルアクセスできます。",
"Home": "ホーム",
"Import pages": "ページをインポート",
"Import pages & space settings": "ページとスペース設定をインポート",
"Importing pages": "ページをインポートしています",
"invalid invitation link": "招待リンクが間違っています",
"Invitation signup": "招待登録",
"Invite by email": "メールアドレスで招待する",
"Invite members": "メンバーを招待する",
"Invite new members": "新しいメンバーを招待する",
"Invited members who are yet to accept their invitation will appear here.": "招待をまだ承諾していないメンバーはここに表示されます。",
"Invited members will be granted access to spaces the groups can access": "招待されたメンバーは、グループがアクセスできるスペースにアクセス権が付与されます",
"Join the workspace": "ワークスペースに参加",
"Language": "言語",
"Light": "ライト",
"Link copied": "リンクをコピーしました",
"Login": "ログイン",
"Logout": "ログアウト",
"Manage Group": "グループを管理",
"Manage members": "メンバーを管理",
"member": "メンバー",
"Member": "メンバー",
"members": "メンバー",
"Members": "メンバー",
"My preferences": "個人設定",
"My Profile": "プロフィール",
"My profile": "プロフィール",
"Name": "名前",
"New email": "新しいメールアドレス",
"New page": "新規ページ",
"New password": "新しいパスワード",
"No group found": "グループが見つかりません",
"No page history saved yet.": "まだページの履歴が保存されていません。",
"No pages yet": "ページがありません",
"No results found...": "結果が見つかりませんでした...",
"No user found": "ユーザがいません",
"Overview": "概要",
"Owner": "所有者",
"page": "ページ",
"Page deleted successfully": "ページが正常に削除されました",
"Page history": "ページの履歴",
"Page import is in progress. Please do not close this tab.": "ページのインポートが進行中です。このタブを閉じないでください。",
"Pages": "ページ",
"pages": "ページ",
"Password": "パスワード",
"Password changed successfully": "パスワードが正常に変更されました",
"Pending": "保留中",
"Please confirm your action": "アクションを確認してください",
"Preferences": "設定",
"Print PDF": "PDFを印刷",
"Profile": "プロフィール",
"Recently updated": "最近の更新",
"Remove": "削除",
"Remove group member": "グループメンバーを削除",
"Remove space member": "スペースメンバーを削除",
"Restore": "復元",
"Role": "役割",
"Save": "保存",
"Search": "検索",
"Search for groups": "グループを検索",
"Search for users": "ユーザーを検索",
"Search for users and groups": "ユーザーとグループを検索",
"Search...": "検索する語句を入力",
"Select language": "言語を選択",
"Select role": "ロールを選択",
"Select role to assign to all invited members": "招待されたすべてのメンバーに割り当てるロールを選択してください",
"Select theme": "テーマを選択",
"Send invitation": "招待を送る",
"Invitation sent": "招待が送信されました",
"Settings": "設定",
"Setup workspace": "ワークスペースを設定する",
"Sign In": "サインイン",
"Sign Up": "アカウント登録",
"Slug": "Slug (URL用文字列)",
"Space": "スペース",
"Space description": "スペース説明",
"Space menu": "スペースメニュー",
"Space name": "スペース名",
"Space settings": "スペース設定",
"Space slug": "スペースのSlug (URL用文字列)",
"Spaces": "スペース",
"Spaces you belong to": "所属しているスペース",
"No space found": "スペースが見つかりません",
"Search for spaces": "スペースを検索",
"Start typing to search...": "検索を開始するには入力してください...",
"Status": "ステータス",
"Successfully imported": "インポートに成功しました",
"Successfully restored": "正常に復元されました",
"System settings": "システム設定",
"Theme": "テーマ",
"To change your email, you have to enter your password and new email.": "メールアドレスを変更するには、パスワードと新しいメールアドレスを入力する必要があります。",
"Toggle full page width": "ページ幅を切り替える",
"Unable to import pages. Please try again.": "ページをインポートできません。もう一度お試しください。",
"untitled": "無題",
"Untitled": "無題",
"Updated successfully": "正常に更新されました",
"User": "ユーザー",
"Workspace": "ワークスペース",
"Workspace Name": "ワークスペース名",
"Workspace settings": "ワークスペース設定",
"You can change your password here.": "パスワードを変更できます。",
"Your Email": "メールアドレス",
"Your import is complete.": "インポートが完了しました。",
"Your name": "名前",
"Your Name": "名前",
"Your password": "パスワード",
"Your password must be a minimum of 8 characters.": "パスワードは最低 8 文字必要です。",
"Sidebar toggle": "サイドバー切り替え",
"Comments": "コメント",
"404 page not found": "404 ページが見つかりません",
"Sorry, we can't find the page you are looking for.": "お探しのページが見つかりません。",
"Take me back to homepage": "ホームに戻る",
"Forgot password": "パスワードを忘れた",
"Forgot your password?": "パスワードを忘れましたか?",
"A password reset link has been sent to your email. Please check your inbox.": "パスワードリセットリンクがあなたのメールアドレスに送信されました。受信箱を確認してください。",
"Send reset link": "リセットリンクを送る",
"Password reset": "パスワードリセット",
"Your new password": "新しいパスワード",
"Set password": "パスワードを設定",
"Write a comment": "コメントを書く",
"Reply...": "返信...",
"Error loading comments.": "コメントの読み込み中にエラーが発生しました。",
"No comments yet.": "コメントがありません。",
"Edit comment": "コメントを編集する",
"Delete comment": "コメントを削除する",
"Are you sure you want to delete this comment?": "このコメントを削除してもよろしいですか?",
"Comment created successfully": "コメントが作成されました",
"Error creating comment": "コメントの作成中にエラーが発生しました",
"Comment updated successfully": "コメントが更新されました",
"Failed to update comment": "コメントの更新に失敗しました",
"Comment deleted successfully": "コメントが削除されました",
"Failed to delete comment": "コメントの削除に失敗しました",
"Comment resolved successfully": "コメントが解決されました",
"Comment re-opened successfully": "コメントが再開されました",
"Comment unresolved successfully": "コメントが再解決されました",
"Failed to resolve comment": "コメントの解決に失敗しました",
"Resolve comment": "コメントを解決",
"Unresolve comment": "コメントを再解決",
"Resolve 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 unresolve this comment thread?": "このコメントスレッドを再解決しますか?",
"Resolved": "解決済",
"No active comments.": "アクティブなコメントはありません。",
"No resolved comments.": "解決されたコメントはありません。",
"Revoke invitation": "招待を取り消す",
"Revoke": "取り消す",
"Don't": "取り消さない",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "この招待を取り消してもよろしいですか? ユーザはワークスペースに参加できなくなります。",
"Resend invitation": "招待を再度送る",
"Anyone with this link can join this workspace.": "このリンクを持っている人は誰でもこのワークスペースに参加できます。",
"Invite link": "招待リンク",
"Copy": "コピー",
"Copy to space": "スペースにコピー",
"Copied": "コピーしました",
"Duplicate": "複製",
"Select a user": "ユーザを選択",
"Select a group": "グループを選択",
"Export all pages and attachments in this space.": "このスペースのすべてのページと添付ファイルをエクスポートします。",
"Delete space": "スペースを削除",
"Are you sure you want to delete this space?": "このスペースを削除してもよろしいですか?",
"Delete this space with all its pages and data.": "このスペースおよびスペース内のすべてのページとデータを削除します。",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "このスペース内のすべてのページ、コメント、添付ファイル、および権限は完全に削除されます。",
"Confirm space name": "スペース名を確認する",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "アクションを確認するためにスペース名 <b>{{spaceName}}</b> を入力してください。",
"Format": "フォーマット",
"Include subpages": "サブページを含める",
"Include attachments": "添付ファイルを含める",
"Select export format": "エクスポート形式を選択",
"Export failed:": "エクスポートに失敗しました:",
"export error": "エクスポートエラー",
"Export page": "エクスポートページ",
"Export space": "エクスポートスペース",
"Export {{type}}": "{{type}}をエクスポート",
"File exceeds the {{limit}} attachment limit": "ファイルが{{limit}}の添付制限を超えています",
"Align left": "左揃え",
"Align right": "右揃え",
"Align center": "中央揃え",
"Justify": "両端揃え",
"Merge cells": "セルを結合",
"Split cell": "セルを分割",
"Delete column": "列を削除",
"Delete row": "行を削除",
"Add left column": "左側に列を追加",
"Add right column": "右側の列を追加",
"Add row above": "上に行を追加",
"Add row below": "下に行を追加",
"Delete table": "テーブルを削除",
"Info": "情報",
"Success": "成功",
"Warning": "警告",
"Danger": "危険",
"Mermaid diagram error:": "Mermaid コードエラー",
"Invalid Mermaid diagram": "無効な Mermaid コードです",
"Double-click to edit Draw.io diagram": "ダブルクリックしてDraw.ioの図を編集",
"Exit": "終了",
"Save & Exit": "保存して終了",
"Double-click to edit Excalidraw diagram": "ダブルクリックしてExcalidraw図を編集",
"Paste link": "リンクを貼り付け",
"Edit link": "リンクを編集",
"Remove link": "リンクを削除",
"Add link": "リンクを追加",
"Please enter a valid url": "有効なURLを入力してください",
"Empty equation": "空の数式です",
"Invalid equation": "不正な数式です",
"Color": "カラー",
"Text color": "テキストカラー",
"Default": "デフォルト",
"Blue": "青色",
"Green": "緑色",
"Purple": "紫色",
"Red": "赤色",
"Yellow": "黄色",
"Orange": "オレンジ色",
"Pink": "ピンク色",
"Gray": "灰色",
"Embed link": "リンクを埋め込む",
"Invalid {{provider}} embed link": "埋め込まれた {{provider}} のリンクは無効です",
"Embed {{provider}}": "埋め込まれた {{provider}}",
"Enter {{provider}} link to embed": "埋め込みたい {{provider}} のリンクを入力してください",
"Bold": "太字",
"Italic": "斜線",
"Underline": "下線",
"Strike": "打ち消し線",
"Code": "コードブロック",
"Comment": "コメント",
"Text": "テキスト",
"Heading 1": "見出し 1",
"Heading 2": "見出し 2",
"Heading 3": "見出し 3",
"To-do List": "To-doリスト",
"Bullet List": "箇条書きリスト",
"Numbered List": "番号付きリスト",
"Blockquote": "引用",
"Just start typing with plain text.": "すぐに文章を書き始められます。",
"Track tasks with a to-do list.": "Todoリストでタスクを追跡します。",
"Big section heading.": "大きいフォントのセクション見出しです。",
"Medium section heading.": "中くらいのフォントのセクション見出しです。",
"Small section heading.": "小さいフォントのセクション見出しです。",
"Create a simple bullet list.": "シンプルな箇条書きのリストを作成します。",
"Create a list with numbering.": "番号付きのリストを作成します。",
"Create block quote.": "引用文を作成します。",
"Insert code snippet.": "コードスニペットを入力します。",
"Insert horizontal rule divider": "水平線を挿入します。",
"Upload any image from your device.": "画像をアップロードします。",
"Upload any video from your device.": "動画をアップロードします。",
"Upload any file from your device.": "ファイルをアップロードします。",
"Table": "テーブル",
"Insert a table.": "表を挿入します。",
"Insert collapsible block.": "折りたたみ可能なブロックを挿入します。",
"Video": "動画",
"Divider": "区切り線",
"Quote": "引用",
"Image": "画像",
"File attachment": "ファイル添付",
"Toggle block": "ブロックを切り替える",
"Callout": "コールアウト",
"Insert callout notice.": "コールアウトブロックを挿入します。",
"Math inline": "インライン数式",
"Insert inline math equation.": "インライン数式を挿入します。",
"Math block": "数式ブロック",
"Insert math equation": "数式を挿入します",
"Mermaid diagram": "Mermaidコード",
"Insert mermaid diagram": "Mermaidコードを記述して図を挿入します",
"Insert and design Drawio diagrams": "Drawioの図を挿入してデザインします",
"Insert current date": "今日の日付を挿入します",
"Draw and sketch excalidraw diagrams": "Excalidrawの図を埋め込みます",
"Multiple": "複数",
"Heading {{level}}": "見出し {{level}}",
"Toggle title": "タイトルの表示/非表示を切り替える",
"Write anything. Enter \"/\" for commands": "文字を入力するか、「/」でコマンドを呼び出します",
"Names do not match": "名前が一致しません",
"Today, {{time}}": "今日、{{time}}",
"Yesterday, {{time}}": "昨日、{{time}}",
"Space created successfully": "スペースを作成しました",
"Space updated successfully": "スペースを更新しました",
"Space deleted successfully": "スペースが削除されました",
"Members added successfully": "メンバーを追加しました",
"Member removed successfully": "メンバーが削除されました",
"Member role updated successfully": "メンバーのロールを更新しました",
"Created by: <b>{{creatorName}}</b>": "作成者: <b>{{creatorName}}</b>",
"Created at: {{time}}": "が作成しました:{{time}}",
"Edited by {{name}} {{time}}": "最終編集: {{name}} {{time}}",
"Word count: {{wordCount}}": "ワード数: {{wordCount}}",
"Character count: {{characterCount}}": "文字数: {{characterCount}}",
"New update": "新規更新",
"{{latestVersion}} is available": "{{latestVersion}}は利用可能です",
"Default page edit mode": "デフォルトのページ編集モード",
"Choose your preferred page edit mode. Avoid accidental edits.": "希望のページ編集モードを選択してください。誤って編集を防ぎます。",
"Reading": "読み取り",
"Delete member": "メンバーを削除する",
"Member deleted successfully": "メンバーが削除されました",
"Are you sure you want to delete this workspace member? This action is irreversible.": "ワークスペースメンバーを削除してもよろしいですか?この操作は元に戻せません。",
"Move": "移動",
"Move page": "ページを移動",
"Move page to a different space.": "ページを別のスペースに移動します。",
"Real-time editor connection lost. Retrying...": "リアルタイムエディターの接続が失われました。再試行しています…",
"Table of contents": "目次",
"Add headings (H1, H2, H3) to generate a table of contents.": "見出しH1、H2、H3を追加して目次を生成します。",
"Share": "共有",
"Public sharing": "公開共有",
"Shared by": "共有者",
"Shared at": "共有日時",
"Inherits public sharing from": "から公開共有を継承する",
"Share to web": "ウェブで共有",
"Shared to web": "ウェブに共有済み",
"Anyone with the link can view this page": "リンクを持っている人はこのページを閲覧できます",
"Make this page publicly accessible": "このページを公開します",
"Include sub-pages": "サブページを含む",
"Make sub-pages public too": "サブページも公開する",
"Allow search engines to index page": "検索エンジンにページのインデックス作成を許可する",
"Open page": "ページを開く",
"Page": "ページ",
"Delete public share link": "公開リンクを削除",
"Delete share": "共有を削除",
"Are you sure you want to delete this shared link?": "この共有リンクを削除してもよろしいですか?",
"Publicly shared pages from spaces you are a member of will appear here": "メンバーであるスペースからの公開ページがここに表示されます",
"Share deleted successfully": "共有が正常に削除されました",
"Share not found": "共有が見つかりません",
"Failed to share page": "ページの共有に失敗しました",
"Copy page": "ページをコピー",
"Copy page to a different space.": "ページを別のスペースにコピーします。",
"Page copied successfully": "ページのコピーに成功しました",
"Page duplicated successfully": "ページが正常に複製されました",
"Find": "検索",
"Not found": "見つかりません",
"Previous Match (Shift+Enter)": "前の一致 (Shift+Enter)",
"Next match (Enter)": "次の一致 (Enter)",
"Match case (Alt+C)": "大文字小文字を区別 (Alt+C)",
"Replace": "置換",
"Close (Escape)": "閉じる (Escape)",
"Replace (Enter)": "置換 (Enter)",
"Replace all (Ctrl+Alt+Enter)": "すべて置換 (Ctrl+Alt+Enter)",
"Replace all": "すべて置換",
"View all spaces": "すべてのスペースを表示",
"Error": "エラー",
"Failed to disable MFA": "MFAの無効化に失敗しました",
"Disable two-factor authentication": "二要素認証を無効化",
"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:": "二要素認証を無効化するにはパスワードを入力してください:",
"Two-factor authentication has been enabled": "二要素認証が有効になりました",
"Two-factor authentication has been disabled": "二要素認証が無効になりました",
"2-step verification": "2段階確認",
"Protect your account with an additional verification layer when signing in.": "サインイン時に追加の認証レイヤーでアカウントを保護します。",
"Two-factor authentication is active on your account.": "二要素認証がアカウントで有効です。",
"Add 2FA method": "2FAメソッドを追加",
"Backup codes": "バックアップコード",
"Disable": "無効にする",
"Invalid verification code": "無効な認証コード",
"New backup codes have been generated": "新しいバックアップコードが生成されました",
"Failed to regenerate 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.": "バックアップコードは、認証アプリへのアクセスを失った場合にアカウントにアクセスするために使用できます。各コードは一度しか使用できません。",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "いつでも新しいバックアップコードを再生成できます。これにより、既存のすべてのコードが無効になります。",
"Confirm password": "パスワードを確認",
"Generate 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.": "これらのコードを安全な場所に保存してください。古いバックアップコードは無効です。",
"Your new backup codes": "新しいバックアップコード",
"I've saved my backup codes": "バックアップコードを保存しました",
"Failed to setup MFA": "MFAの設定に失敗しました",
"Setup & Verify": "設定と確認",
"Add to authenticator": "認証アプリに追加",
"1. Scan this QR code with your authenticator app": "1. このQRコードを認証アプリでスキャンしてください",
"Can't scan the code?": "コードをスキャンできませんか?",
"Enter this code manually in your authenticator app:": "このコードを認証アプリに手動で入力してください:",
"2. Enter the 6-digit code from your authenticator": "2. 認証アプリからの6桁のコードを入力してください",
"Verify and enable": "確認と有効化",
"Failed to generate QR code. Please try again.": "QRコードの生成に失敗しました。再試行してください。",
"Backup": "バックアップ",
"Save 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.": "これらのコードは、認証アプリへのアクセスを失った場合にアカウントにアクセスするために使用できます。各コードは一度しか使用できません。",
"Print": "印刷",
"Two-factor authentication has been set up. Please log in again.": "二要素認証が設定されました。再度ログインしてください。",
"Two-Factor authentication required": "二要素認証が必要です",
"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.": "ワークスペースへのアクセスを続けるには、二要素認証を設定する必要があります。これにより、アカウントに追加のセキュリティ層が追加されます。",
"Set up two-factor authentication": "二要素認証を設定",
"Cancel and logout": "キャンセルしてログアウト",
"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.": "これにより、認証アプリからの確認コードが必要となり、アカウントに追加のセキュリティ層が追加されます。",
"Password is required": "パスワードが必要です",
"Password must be at least 8 characters": "パスワードは8文字以上必要です",
"Please enter a 6-digit code": "6桁のコードを入力してください",
"Code must be exactly 6 digits": "コードは正確に6桁である必要があります",
"Enter the 6-digit code found in your authenticator app": "認証アプリに表示された6桁のコードを入力してください",
"Need help authenticating?": "認証に関するヘルプが必要ですか?",
"MFA QR Code": "MFA QRコード",
"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 to set up two-factor authentication.": "パスワードのリセットが成功しました。二要素認証を設定するために新しいパスワードでログインしてください。",
"Password reset was successful. Please log in with your new password.": "パスワードのリセットが成功しました。新しいパスワードでログインしてください。",
"Two-factor authentication": "二要素認証",
"Use authenticator app instead": "代わりに認証アプリを使用",
"Verify backup code": "バックアップコードを確認",
"Use backup code": "バックアップコードを使用",
"Enter one of your backup codes": "バックアップコードのいずれかを入力してください",
"Backup code": "バックアップコード",
"Enter one of your backup codes. Each backup code can only be used once.": "バックアップコードのいずれかを入力してください。各バックアップコードは一度しか使用できません。",
"Verify": "確認",
"Trash": "ごみ箱",
"Pages in trash will be permanently deleted after 30 days.": "ごみ箱内のページは30日後に完全に削除されます。",
"Deleted": "削除",
"No pages in trash": "ごみ箱にページがありません",
"Permanently delete page?": "ページを完全に削除しますか?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "{{title}}』を完全に削除しますか? この操作は元に戻せません。",
"Restore '{{title}}' and its sub-pages?": "{{title}}』とそのサブページを復元しますか?",
"Move to trash": "ごみ箱に移動",
"Move this page to trash?": "このページをごみ箱に移動しますか?",
"Restore page": "ページを復元",
"Page moved to trash": "ページがごみ箱に移動されました",
"Page restored successfully": "ページが正常に復元されました",
"Deleted by": "削除者",
"Deleted at": "削除日時",
"Preview": "プレビュー",
"Subpages": "サブページ",
"Failed to load subpages": "サブページの読み込みに失敗しました",
"No subpages": "サブページがありません",
"Subpages (Child pages)": "サブページ(子ページ)",
"List all subpages of the current page": "現在のページのすべてのサブページをリスト",
"Attachments": "添付ファイル",
"All spaces": "すべてのスペース",
"Unknown": "不明",
"Find a space": "スペースを探す",
"Search in all your spaces": "あなたのすべてのスペースで検索",
"Type": "タイプ",
"Enterprise": "エンタープライズ",
"Download attachment": "添付ファイルをダウンロード",
"Allowed email domains": "許可されたメールドメイン",
"Only users with email addresses from these domains can signup via SSO.": "これらのドメインからのメールアドレスを持つユーザーのみがSSOで登録できます。",
"Enter valid domain names separated by comma or space": "コンマまたはスペースで区切って有効なドメイン名を入力してください",
"Enforce two-factor authentication": "二要素認証を強制する",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "一度強制されると、すべてのメンバーはワークスペースにアクセスするために二要素認証を有効にする必要があります。",
"Toggle MFA enforcement": "MFAの強制を切り替える",
"Display name": "表示名",
"Allow signup": "登録を許可する",
"Enabled": "有効",
"Advanced Settings": "詳細設定",
"Enable TLS/SSL": "TLS/SSLを有効にする",
"Use secure connection to LDAP server": "LDAPサーバーへの安全な接続を使用する",
"Group sync": "グループ同期",
"No SSO providers found.": "SSOプロバイダーが見つかりませんでした。",
"Delete SSO provider": "SSOプロバイダーを削除する",
"Are you sure you want to delete this SSO provider?": "このSSOプロバイダーを削除してもよろしいですか",
"Action": "アクション",
"{{ssoProviderType}} configuration": "{{ssoProviderType}}の構成"
}

View File

@ -0,0 +1,531 @@
{
"Account": "계정",
"Active": "활성",
"Add": "추가",
"Add group members": "팀에 사용자 추가",
"Add groups": "팀 생성",
"Add members": "사용자 추가",
"Add to groups": "팀에 추가",
"Add space members": "Space에 사용자 추가",
"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 page?": "이 페이지를 삭제하시겠습니까?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "이 사용자를 팀에서 제거하시겠습니까? 사용자는 이 팀이 가진 모든 권한을 잃게 됩니다.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "이 사용자를 Space에서 제거하시겠습니까? 사용자는 이 Space에 대한 모든 접근 권한을 잃게 됩니다.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "이 버전으로 복원하시겠습니까? 저장되지 않은 모든 변경사항이 손실됩니다.",
"Can become members of groups and spaces in workspace": "Workspace 내 팀 및 Space의 사용자가 될 수 있습니다.",
"Can create and edit pages in space.": "Space에 페이지를 생성하고 편집할 수 있습니다.",
"Can edit": "편집할 수 있음",
"Can manage workspace": "Workspace를 관리할 수 있음",
"Can manage workspace but cannot delete it": "Workspace를 관리할 수 있지만, 삭제는 불가능.",
"Can view": "볼 수 있음",
"Can view pages in space but not edit.": "Space의 페이지를 볼 수 있지만, 편집은 불가능.",
"Cancel": "취소",
"Change email": "이메일 변경",
"Change password": "비밀번호 변경",
"Change photo": "사진 변경",
"Choose a role": "역할 선택",
"Choose your preferred color scheme.": "선호하는 배경 색을 선택하세요.",
"Choose your preferred interface language.": "선호하는 인터페이스 언어를 선택하세요.",
"Choose your preferred page width.": "선호하는 페이지 너비를 선택하세요.",
"Confirm": "확인",
"Copy link": "링크 복사",
"Create": "생성",
"Create group": "팀 생성",
"Create page": "페이지 생성",
"Create space": "Space 생성",
"Create workspace": "Workspace 생성",
"Current password": "현재 비밀번호",
"Dark": "어두운",
"Date": "날짜",
"Delete": "삭제",
"Delete group": "팀 삭제",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "이 페이지를 삭제하시겠습니까? 하위 페이지와 페이지 기록이 모두 삭제됩니다. 이 작업은 되돌릴 수 없습니다.",
"Description": "설명",
"Details": "세부사항",
"e.g ACME": "예: ACME",
"e.g ACME Inc": "예: ACME Inc",
"e.g Developers": "예: 개발자",
"e.g Group for developers": "예: 개발자를 위한 팀",
"e.g product": "예: 제품",
"e.g Product Team": "예: 제품 팀",
"e.g Sales": "예: 영업",
"e.g Space for product team": "예: 제품 팀을 위한 Space",
"e.g Space for sales team to collaborate": "예: 영업 팀의 Space",
"Edit": "편집",
"Read": "읽기",
"Edit group": "팀 편집",
"Email": "이메일",
"Enter a strong password": "강력한 비밀번호를 입력하세요",
"Enter valid email addresses separated by comma or space max_50": "유효한 이메일 주소를 쉼표나 공백으로 구분하여 입력하세요 [최대: 50]",
"enter valid emails addresses": "유효한 이메일 주소를 입력하세요",
"Enter your current password": "기존 비밀번호를 입력하세요",
"enter your full name": "전체 이름을 입력하세요",
"Enter your new password": "새 비밀번호를 입력하세요",
"Enter your new preferred email": "새로운 이메일을 입력하세요",
"Enter your password": "비밀번호를 입력하세요",
"Error fetching page data.": "페이지 데이터 불러오기 오류.",
"Error loading page history.": "페이지 기록 불러오기 오류.",
"Export": "내보내기",
"Failed to create page": "페이지 생성 실패",
"Failed to delete page": "페이지 삭제 실패",
"Failed to fetch recent pages": "최근 페이지 불러오기 실패",
"Failed to import pages": "페이지 가져오기 실패",
"Failed to load page. An error occurred.": "페이지 불러오기 실패. 오류가 발생했습니다.",
"Failed to update data": "데이터 갱신 실패",
"Full access": "전체 권한",
"Full page width": "전체 페이지 너비",
"Full width": "전체 너비",
"General": "일반",
"Group": "팀",
"Group description": "팀 설명",
"Group name": "팀 이름",
"Groups": "팀",
"Has full access to space settings and pages.": "Space 설정과 페이지에 대한 전체 접근 권한이 있습니다.",
"Home": "홈",
"Import pages": "페이지 가져오기",
"Import pages & space settings": "페이지 및 Space 설정 가져오기",
"Importing pages": "페이지 가져오는 중",
"invalid invitation link": "유효하지 않은 초대 링크",
"Invitation signup": "초대 가입",
"Invite by email": "이메일로 초대",
"Invite members": "사용자 초대",
"Invite new members": "새 사용자 초대",
"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에 대한 접근 권한을 받게 됩니다",
"Join the workspace": "Workspace 참여",
"Language": "언어",
"Light": "밝은",
"Link copied": "링크 복사됨",
"Login": "로그인",
"Logout": "로그아웃",
"Manage Group": "팀 관리",
"Manage members": "사용자 관리",
"member": "사용자",
"Member": "사용자",
"members": "사용자들",
"Members": "사용자들",
"My preferences": "내 설정",
"My Profile": "내 프로필",
"My profile": "내 프로필",
"Name": "이름",
"New email": "새 이메일",
"New page": "새 페이지",
"New password": "새 비밀번호",
"No group found": "팀을 찾을 수 없음",
"No page history saved yet.": "아직 저장된 페이지 기록이 없습니다.",
"No pages yet": "아직 페이지가 없습니다",
"No results found...": "결과를 찾을 수 없습니다...",
"No user found": "사용자를 찾을 수 없음",
"Overview": "개요",
"Owner": "소유자",
"page": "페이지",
"Page deleted successfully": "페이지 삭제 완료",
"Page history": "페이지 기록",
"Page import is in progress. Please do not close this tab.": "페이지 가져오기가 진행 중입니다. 이 탭을 닫지 마세요.",
"Pages": "페이지",
"pages": "페이지",
"Password": "비밀번호",
"Password changed successfully": "비밀번호 변경 완료",
"Pending": "대기 중",
"Please confirm your action": "작업을 확인해 주세요",
"Preferences": "설정",
"Print PDF": "PDF로 인쇄",
"Profile": "프로필",
"Recently updated": "최근 업데이트",
"Remove": "제거",
"Remove group member": "팀에서 사용자 제거",
"Remove space member": "Space에서 사용자 제거",
"Restore": "복원",
"Role": "역할",
"Save": "저장",
"Search": "검색",
"Search for groups": "팀 검색",
"Search for users": "사용자 검색",
"Search for users and groups": "사용자 및 팀 검색",
"Search...": "검색...",
"Select language": "언어 선택",
"Select role": "역할 선택",
"Select role to assign to all invited members": "초대된 모든 사용자에게 할당할 역할 선택",
"Select theme": "배경 선택",
"Send invitation": "초대 보내기",
"Invitation sent": "초대 발송 완료",
"Settings": "설정",
"Setup workspace": "Workspace 설정",
"Sign In": "로그인",
"Sign Up": "회원 가입",
"Slug": "고유 경로",
"Space": "Space",
"Space description": "Space 설명",
"Space menu": "Space 메뉴",
"Space name": "Space 이름",
"Space settings": "Space 설정",
"Space slug": "Space의 고유 경로",
"Spaces": "Space",
"Spaces you belong to": "소속된 Space",
"No space found": "Space을 찾을 수 없음",
"Search for spaces": "Space 검색",
"Start typing to search...": "검색하려면 입력을 시작하세요...",
"Status": "상태",
"Successfully imported": "가져오기 완료",
"Successfully restored": "복원 완료",
"System settings": "시스템 설정",
"Theme": "배경",
"To change your email, you have to enter your password and new email.": "이메일을 변경하려면 기존 비밀번호와 새 이메일을 입력해야 합니다.",
"Toggle full page width": "전체 페이지 너비 전환",
"Unable to import pages. Please try again.": "페이지를 가져올 수 없습니다. 다시 시도해주세요.",
"untitled": "제목 없음",
"Untitled": "제목 없음",
"Updated successfully": "업데이트 완료",
"User": "사용자",
"Workspace": "Workspace",
"Workspace Name": "Workspce 이름",
"Workspace settings": "Workspace 설정",
"You can change your password here.": "여기서 비밀번호를 변경할 수 있습니다.",
"Your Email": "이메일",
"Your import is complete.": "가져오기가 완료되었습니다.",
"Your name": "이름",
"Your Name": "이름",
"Your password": "비밀번호",
"Your password must be a minimum of 8 characters.": "비밀번호는 최소 8자 이상이어야 합니다.",
"Sidebar toggle": "사이드바 전환",
"Comments": "댓글",
"404 page not found": "404 페이지를 찾을 수 없음",
"Sorry, we can't find the page you are looking for.": "죄송합니다. 페이지를 찾을 수 없습니다.",
"Take me back to homepage": "홈페이지로 돌아가기",
"Forgot password": "비밀번호 찾기",
"Forgot your password?": "비밀번호를 잊으셨나요?",
"A password reset link has been sent to your email. Please check your inbox.": "비밀번호 재설정 링크가 이메일로 전송되었습니다. 받은 편지함을 확인해주세요.",
"Send reset link": "재설정 링크 보내기",
"Password reset": "비밀번호 재설정",
"Your new password": "새 비밀번호",
"Set password": "비밀번호 설정",
"Write a comment": "댓글 작성",
"Reply...": "답글...",
"Error loading comments.": "댓글 불러오기 오류.",
"No comments yet.": "아직 댓글이 없습니다.",
"Edit comment": "댓글 수정",
"Delete comment": "댓글 삭제",
"Are you sure you want to delete this comment?": "이 댓글을 삭제하시겠습니까?",
"Comment created successfully": "댓글 생성 완료",
"Error creating comment": "댓글 생성 오류",
"Comment updated successfully": "댓글 업데이트 완료",
"Failed to update comment": "댓글 업데이트 실패",
"Comment deleted successfully": "댓글 삭제 완료",
"Failed to delete comment": "댓글 삭제 실패",
"Comment resolved successfully": "댓글 처리 완료",
"Comment re-opened successfully": "댓글이 성공적으로 다시 열렸습니다",
"Comment unresolved successfully": "댓글 미해결로 변경 완료",
"Failed to resolve comment": "댓글 처리 실패",
"Resolve comment": "댓글 해결하기",
"Unresolve comment": "댓글 미해결로 변경하기",
"Resolve 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 unresolve this comment thread?": "이 댓글 스레드를 미해결로 변경하시겠습니까?",
"Resolved": "해결됨",
"No active comments.": "활성 댓글이 없습니다.",
"No resolved comments.": "해결된 댓글이 없습니다.",
"Revoke invitation": "초대 취소",
"Revoke": "취소",
"Don't": "하지 않음",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "이 초대를 취소하시겠습니까? 사용자가 Workspace에 참여할 수 없게 됩니다.",
"Resend invitation": "초대 재전송",
"Anyone with this link can join this workspace.": "이 링크를 가진 모든 사용자가 이 Workspace에 참여할 수 있습니다.",
"Invite link": "초대 링크",
"Copy": "복사",
"Copy to space": "공간에 복사하기",
"Copied": "복사됨",
"Duplicate": "중복",
"Select a user": "사용자 선택",
"Select a group": "팀 선택",
"Export all pages and attachments in this space.": "이 Space의 모든 페이지와 첨부파일을 내보냅니다.",
"Delete space": "Space 삭제",
"Are you sure you want to delete this space?": "이 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의 모든 페이지, 댓글, 첨부파일 및 권한이 영구적으로 삭제됩니다.",
"Confirm space name": "Space 이름 확인",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "작업을 진행하려면 Space 이름 <b>{{spaceName}}</b>을 입력하세요.",
"Format": "형식",
"Include subpages": "하위 페이지 포함",
"Include attachments": "첨부파일 포함",
"Select export format": "내보내기 형식 선택",
"Export failed:": "내보내기 실패:",
"export error": "내보내기 오류",
"Export page": "페이지 내보내기",
"Export space": "Space 내보내기",
"Export {{type}}": "{{type}} 내보내기",
"File exceeds the {{limit}} attachment limit": "첨부 파일 크기 제한 {{limit}}을 초과했습니다",
"Align left": "왼쪽 정렬",
"Align right": "오른쪽 정렬",
"Align center": "가운데 정렬",
"Justify": "정렬",
"Merge cells": "셀 병합",
"Split cell": "셀 분할",
"Delete column": "열 삭제",
"Delete row": "행 삭제",
"Add left column": "왼쪽 열 추가",
"Add right column": "오른쪽 열 추가",
"Add row above": "위에 행 추가",
"Add row below": "아래에 행 추가",
"Delete table": "테이블 삭제",
"Info": "정보",
"Success": "완료",
"Warning": "주의",
"Danger": "위험",
"Mermaid diagram error:": "Mermaid diagram 오류:",
"Invalid Mermaid diagram": "잘못된 Mermaid diagram",
"Double-click to edit Draw.io diagram": "Draw.io diagram을 편집하려면 더블 클릭하세요",
"Exit": "나가기",
"Save & Exit": "저장 후 나가기",
"Double-click to edit Excalidraw diagram": "Excalidraw diagram을 편집하려면 더블 클릭하세요",
"Paste link": "링크 붙여넣기",
"Edit link": "링크 수정",
"Remove link": "링크 제거",
"Add link": "링크 추가",
"Please enter a valid url": "유효한 URL을 입력하세요",
"Empty equation": "빈 수식",
"Invalid equation": "잘못된 수식",
"Color": "색상",
"Text color": "텍스트 색상",
"Default": "기본값",
"Blue": "파란색",
"Green": "초록색",
"Purple": "보라색",
"Red": "빨간색",
"Yellow": "노란색",
"Orange": "주황색",
"Pink": "분홍색",
"Gray": "회색",
"Embed link": "임베드 링크",
"Invalid {{provider}} embed link": "잘못된 {{provider}} 임베드 링크",
"Embed {{provider}}": "{{provider}} 임베드",
"Enter {{provider}} link to embed": "임베드를 할 {{provider}} 링크 입력",
"Bold": "굵게",
"Italic": "기울임",
"Underline": "밑줄",
"Strike": "취소선",
"Code": "코드",
"Comment": "댓글",
"Text": "텍스트",
"Heading 1": "제목 1",
"Heading 2": "제목 2",
"Heading 3": "제목 3",
"To-do List": "할 일 목록",
"Bullet List": "글머리 표",
"Numbered List": "문단 번호",
"Blockquote": "인용구",
"Just start typing with plain text.": "일반 텍스트로 입력을 시작하세요.",
"Track tasks with a to-do list.": "할 일 목록으로 작업을 정리하세요.",
"Big section heading.": "대제목.",
"Medium section heading.": "중제목.",
"Small section heading.": "소제목.",
"Create a simple bullet list.": "글머리 기호 만들기.",
"Create a list with numbering.": "숫자 목록 만들기.",
"Create block quote.": "인용구 만들기.",
"Insert code snippet.": "코드 블록 삽입.",
"Insert horizontal rule divider": "가로 구분선 삽입",
"Upload any image from your device.": "기기에서 이미지를 업로드하세요.",
"Upload any video from your device.": "기기에서 비디오를 업로드하세요.",
"Upload any file from your device.": "기기에서 파일을 업로드하세요.",
"Table": "테이블",
"Insert a table.": "테이블 삽입.",
"Insert collapsible block.": "접을 수 있는 블록 삽입.",
"Video": "비디오",
"Divider": "구분선",
"Quote": "인용",
"Image": "이미지",
"File attachment": "파일 첨부",
"Toggle block": "블록 토글",
"Callout": "경고 상자",
"Insert callout notice.": "돋보이는 글을 작성하기.",
"Math inline": "수식",
"Insert inline math equation.": "수식 삽입.",
"Math block": "수식 블록",
"Insert math equation": "수식 삽입",
"Mermaid diagram": "Mermaid diagram",
"Insert mermaid diagram": "Mermaid diagram 삽입",
"Insert and design Drawio diagrams": "Drawio diagram 삽입 및 디자인",
"Insert current date": "현재 날짜 삽입",
"Draw and sketch excalidraw diagrams": "Excalidraw diagram 그리기 및 스케치",
"Multiple": "복제",
"Heading {{level}}": "제목 {{level}}",
"Toggle title": "제목 토글",
"Write anything. Enter \"/\" for commands": "아무거나 입력하세요. 명령어를 사용하려면 \"/\"를 입력하세요",
"Names do not match": "이름이 일치하지 않습니다",
"Today, {{time}}": "오늘, {{time}}",
"Yesterday, {{time}}": "어제, {{time}}",
"Space created successfully": "공간 생성 완료",
"Space updated successfully": "공간이 성공적으로 업데이트되었습니다",
"Space deleted successfully": "스페이스 삭제 완료",
"Members added successfully": "회원 추가 완료",
"Member removed successfully": "멤버가 성공적으로 제거되었습니다",
"Member role updated successfully": "회원 역할이 성공적으로 업데이트되었습니다",
"Created by: <b>{{creatorName}}</b>": "작성자: <b>{{creatorName}}</b>",
"Created at: {{time}}": "생성 날짜: {{time}}",
"Edited by {{name}} {{time}}": "{{name}}님이 편집함 {{time}}",
"Word count: {{wordCount}}": "단어 수: {{wordCount}}",
"Character count: {{characterCount}}": "문자 수: {{characterCount}}",
"New update": "새로운 업데이트",
"{{latestVersion}} is available": "{{latestVersion}}이 사용 가능합니다",
"Default page edit mode": "기본 페이지 편집 모드",
"Choose your preferred page edit mode. Avoid accidental edits.": "선호하는 페이지 편집 모드를 선택하세요. 실수로 인한 편집을 방지하세요.",
"Reading": "읽기",
"Delete member": "회원 삭제",
"Member deleted successfully": "멤버가 성공적으로 제거되었습니다",
"Are you sure you want to delete this workspace member? This action is irreversible.": "이 워크스페이스 멤버를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"Move": "이동",
"Move page": "페이지 이동",
"Move page to a different space.": "페이지를 다른 공간으로 이동합니다.",
"Real-time editor connection lost. Retrying...": "실시간 편집기 연결이 끊어졌습니다. 재시도 중...",
"Table of contents": "목차",
"Add headings (H1, H2, H3) to generate a table of contents.": "목차를 생성하려면 제목 (H1, H2, H3)을 추가하세요.",
"Share": "공유",
"Public sharing": "공개 공유",
"Shared by": "공유자",
"Shared at": "공유 시간",
"Inherits public sharing from": "로부터 공개 공유를 상속함",
"Share to web": "웹에 공유",
"Shared to web": "웹에 공유됨",
"Anyone with the link can view this page": "링크가 있는 사람은 이 페이지를 볼 수 있습니다",
"Make this page publicly accessible": "이 페이지를 공개적으로 접근 가능하게 만들기",
"Include sub-pages": "하위 페이지 포함",
"Make sub-pages public too": "하위 페이지도 공개로 설정",
"Allow search engines to index page": "검색 엔진이 페이지를 색인할 수 있도록 허용",
"Open page": "페이지 열기",
"Page": "페이지",
"Delete public share link": "공유 링크 삭제",
"Delete share": "공유 삭제",
"Are you sure you want to delete this shared link?": "이 공유 링크를 삭제하시겠습니까?",
"Publicly shared pages from spaces you are a member of will appear here": "회원인 공간의 공개 공유된 페이지가 여기에 표시됩니다",
"Share deleted successfully": "공유가 성공적으로 삭제되었습니다",
"Share not found": "공유를 찾을 수 없습니다",
"Failed to share page": "페이지 공유에 실패했습니다",
"Copy page": "페이지 복사하기",
"Copy page to a different space.": "다른 공간으로 페이지 복사하기.",
"Page copied successfully": "페이지가 성공적으로 복사되었습니다",
"Page duplicated successfully": "페이지가 성공적으로 복제되었습니다",
"Find": "찾기",
"Not found": "찾을 수 없음",
"Previous Match (Shift+Enter)": "이전 일치 항목 (Shift+Enter)",
"Next match (Enter)": "다음 일치 항목 (Enter)",
"Match case (Alt+C)": "대소문자 구분 (Alt+C)",
"Replace": "교체",
"Close (Escape)": "닫기 (Escape)",
"Replace (Enter)": "교체 (Enter)",
"Replace all (Ctrl+Alt+Enter)": "모두 교체하기 (Ctrl+Alt+Enter)",
"Replace all": "모두 교체하기",
"View all spaces": "모든 공간 보기",
"Error": "오류",
"Failed to disable MFA": "MFA 비활성화 실패",
"Disable two-factor authentication": "이중 인증 비활성화",
"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:": "이중 인증 비활성화를 위해 비밀번호를 입력하세요:",
"Two-factor authentication has been enabled": "이중 인증이 활성화되었습니다",
"Two-factor authentication has been disabled": "이중 인증이 비활성화되었습니다",
"2-step verification": "2단계 인증",
"Protect your account with an additional verification layer when signing in.": "로그인 시 추가 인증 단계를 통해 계정을 보호하세요.",
"Two-factor authentication is active on your account.": "이중 인증이 계정에 활성화되어 있습니다.",
"Add 2FA method": "2FA 방법 추가",
"Backup codes": "백업 코드",
"Disable": "비활성화",
"Invalid verification code": "유효하지 않은 인증 코드",
"New backup codes have been generated": "새 백업 코드가 생성되었습니다",
"Failed to regenerate 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.": "인증 앱에 접근할 수 없게 된 경우, 백업 코드를 사용하여 계정에 접근할 수 있습니다. 각 코드는 한 번만 사용할 수 있습니다.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "언제든지 새 백업 코드를 재생성할 수 있습니다. 이 작업은 기존 모든 코드를 무효화합니다.",
"Confirm password": "비밀번호 확인",
"Generate 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.": "이 코드를 안전한 장소에 저장하세요. 이전 백업 코드는 더 이상 유효하지 않습니다.",
"Your new backup codes": "새 백업 코드",
"I've saved my backup codes": "백업 코드를 저장했습니다",
"Failed to setup MFA": "MFA 설정 실패",
"Setup & Verify": "설정 및 확인",
"Add to authenticator": "인증앱에 추가",
"1. Scan this QR code with your authenticator app": "1. 인증앱으로 이 QR 코드를 스캔하십시오.",
"Can't scan the code?": "코드를 스캔할 수 없습니까?",
"Enter this code manually in your authenticator app:": "이 코드를 인증앱에 수동으로 입력해 주세요:",
"2. Enter the 6-digit code from your authenticator": "2. 인증앱에서 6자리 코드를 입력하십시오",
"Verify and enable": "확인 및 활성화",
"Failed to generate QR code. Please try again.": "QR 코드 생성 실패. 다시 시도해 주세요.",
"Backup": "백업",
"Save 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.": "인증 앱에 대한 접근 권한을 잃은 경우, 이 코드를 사용하여 귀하의 계정에 접근할 수 있습니다. 각 코드는 한 번만 사용할 수 있습니다.",
"Print": "인쇄",
"Two-factor authentication has been set up. Please log in again.": "이중 인증이 설정되었습니다. 다시 로그인해 주세요.",
"Two-Factor authentication required": "이중 인증 필요",
"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.": "워크스페이스 접근을 계속하려면 이중 인증을 설정해야 합니다. 이는 계정에 추가 보안 계층을 추가합니다.",
"Set up two-factor authentication": "이중 인증 설정하기",
"Cancel and logout": "취소 및 로그아웃",
"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.": "인증앱에서 얻은 인증 코드를 요구하여 계정의 보안에 추가적인 계층을 추가합니다.",
"Password is required": "비밀번호가 필요합니다",
"Password must be at least 8 characters": "비밀번호는 최소 8자 이상이어야 합니다",
"Please enter a 6-digit code": "6자리 코드를 입력해 주세요",
"Code must be exactly 6 digits": "코드는 정확히 6자리여야 합니다",
"Enter the 6-digit code found in your authenticator app": "인증앱에서 찾은 6자리 코드를 입력하십시오",
"Need help authenticating?": "인증에 도움이 필요하십니까?",
"MFA QR Code": "MFA QR 코드",
"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 to set up two-factor authentication.": "비밀번호 재설정 성공. 새 비밀번호로 로그인하여 이중 인증을 설정하세요.",
"Password reset was successful. Please log in with your new password.": "비밀번호 재설정이 성공적으로 완료되었습니다. 새 비밀번호로 로그인하세요.",
"Two-factor authentication": "이중 인증",
"Use authenticator app instead": "대신 인증 앱 사용",
"Verify backup code": "백업 코드 확인",
"Use backup code": "백업 코드 사용",
"Enter one of your backup codes": "백업 코드 중 하나를 입력하세요",
"Backup code": "백업 코드",
"Enter one of your backup codes. Each backup code can only be used once.": "백업 코드 중 하나를 입력하세요. 각 백업 코드는 한 번만 사용할 수 있습니다.",
"Verify": "확인",
"Trash": "휴지통",
"Pages in trash will be permanently deleted after 30 days.": "휴지통의 페이지는 30일 후에 영구적으로 삭제됩니다.",
"Deleted": "삭제됨",
"No pages in trash": "휴지통에 페이지가 없습니다",
"Permanently delete page?": "페이지를 영구적으로 삭제하시겠습니까?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "'{{title}}'을(를) 영구적으로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
"Restore '{{title}}' and its sub-pages?": "'{{title}}' 및 하위 페이지를 복구하시겠습니까?",
"Move to trash": "휴지통으로 이동",
"Move this page to trash?": "이 페이지를 휴지통으로 이동하시겠습니까?",
"Restore page": "페이지 복구",
"Page moved to trash": "페이지가 휴지통으로 이동되었습니다",
"Page restored successfully": "페이지가 성공적으로 복구되었습니다",
"Deleted by": "삭제자",
"Deleted at": "삭제 시간",
"Preview": "미리보기",
"Subpages": "하위 페이지",
"Failed to load subpages": "하위 페이지 로드 실패",
"No subpages": "하위 페이지 없음",
"Subpages (Child pages)": "하위 페이지 (자식 페이지)",
"List all subpages of the current page": "현재 페이지의 모든 하위 페이지 목록",
"Attachments": "첨부 파일",
"All spaces": "전체 공간",
"Unknown": "알 수 없음",
"Find a space": "공간 찾기",
"Search in all your spaces": "모든 공간에서 검색",
"Type": "유형",
"Enterprise": "기업",
"Download attachment": "첨부 파일 다운로드",
"Allowed email domains": "허용된 이메일 도메인",
"Only users with email addresses from these domains can signup via SSO.": "이 도메인의 이메일 주소를 가진 사용자만 SSO를 통해 가입할 수 있습니다.",
"Enter valid domain names separated by comma or space": "콤마 또는 공백으로 구분하여 유효한 도메인 이름 입력",
"Enforce two-factor authentication": "이중 인증 시행",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "시행되면 모든 멤버가 작업 공간에 액세스하기 위해 이중 인증을 활성화해야 합니다.",
"Toggle MFA enforcement": "MFA 시행 전환",
"Display name": "표시 이름",
"Allow signup": "가입 허용",
"Enabled": "활성화됨",
"Advanced Settings": "고급 설정",
"Enable TLS/SSL": "TLS\\/SSL 활성화",
"Use secure connection to LDAP server": "LDAP 서버에 안전한 연결 사용",
"Group sync": "그룹 동기화",
"No SSO providers found.": "SSO 제공자를 찾을 수 없습니다.",
"Delete SSO provider": "SSO 제공자 삭제",
"Are you sure you want to delete this SSO provider?": "이 SSO 제공자를 삭제하시겠습니까?",
"Action": "작업",
"{{ssoProviderType}} configuration": "{{ssoProviderType}} 구성"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Account",
"Active": "Actief",
"Add": "Toevoegen",
"Add group members": "Groepsleden toevoegen",
"Add groups": "Groepen Toevoegen",
"Add members": "Leden toevoegen",
"Add to groups": "Toevoegen aan groepen",
"Add space members": "Voeg leden toe ruimte",
"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 page?": "Weet u zeker dat u deze pagina wil verwijderen?",
"Are you sure you want to remove this user from the group? The user 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 remove this user from the space? The user will lose all access to this space.": "Weet u zeker dat u deze gebruiker van de ruimte wilt verwijderen? De gebruiker zal alle toegang tot deze ruimte verliezen.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Weet u zeker dat u deze versie wilt herstellen? Wijzigingen die geen versie hebben zullen verloren gaan.",
"Can become members of groups and spaces in workspace": "Kunnen lid worden van groepen en ruimtes in de werkruimte",
"Can create and edit pages in space.": "Kan pagina's in de ruimte maken en bewerken.",
"Can edit": "Kan bewerken",
"Can manage workspace": "Kan werkruimte beheren",
"Can manage workspace but cannot delete it": "Kan een werkruimte beheren, maar kan deze niet verwijderen",
"Can view": "Kan bekijken",
"Can view pages in space but not edit.": "Kan pagina's in de ruimte bekijken maar niet bewerken.",
"Cancel": "Annuleren",
"Change email": "Wijzig e-mailadres",
"Change password": "Wijzig wachtwoord",
"Change photo": "Wijzig foto",
"Choose a role": "Kies een rol",
"Choose your preferred color scheme.": "Kies uw gewenste kleurenschema.",
"Choose your preferred interface language.": "Kies uw gewenste interfacetaal.",
"Choose your preferred page width.": "Kies uw gewenste paginabreedte.",
"Confirm": "Bevestig",
"Copy link": "Link kopiëren",
"Create": "Aanmaken",
"Create group": "Groep aanmaken",
"Create page": "Pagina aanmaken",
"Create space": "Ruimte aanmaken",
"Create workspace": "Wwerkruimte aanmaken",
"Current password": "Huidig wachtwoord",
"Dark": "Donker",
"Date": "Datum",
"Delete": "Verwijderen",
"Delete group": "Groep verwijderen",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Weet u zeker dat u deze pagina wilt verwijderen? Dit zal de subpagina's en paginageschiedenis verwijderen. Deze actie kan niet ongedaan gemaakt worden.",
"Description": "Beschrijving",
"Details": "Details",
"e.g ACME": "bijv. ACME",
"e.g ACME Inc": "bijv. ACME Inc",
"e.g Developers": "bijv. Ontwikkelaars",
"e.g Group for developers": "bijv. Groep voor ontwikkelaars",
"e.g product": "bijv. product",
"e.g Product Team": "bijv. Product Team",
"e.g Sales": "bijv. Verkopen",
"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",
"Edit": "Bewerken",
"Read": "Lezen",
"Edit group": "Groep bewerken",
"Email": "E-mailadres",
"Enter a strong password": "Voer een sterk wachtwoord in",
"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 your current password": "Voer uw huidige wachtwoord in",
"enter your full name": "voer uw volledige naam in",
"Enter your new password": "Voer uw nieuwe wachtwoord in",
"Enter your new preferred email": "Voer uw nieuwe e-mailadres in",
"Enter your password": "Voer uw wachtwoord in",
"Error fetching page data.": "Fout bij het ophalen van paginagegevens.",
"Error loading page history.": "Fout bij het laden van de paginageschiedenis.",
"Export": "Exporteer",
"Failed to create page": "Pagina aanmaken mislukt",
"Failed to delete page": "Verwijderen van pagina mislukt",
"Failed to fetch recent pages": "Kan recente pagina's niet ophalen",
"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 update data": "Bijwerken van gegevens mislukt",
"Full access": "Volledig toegang",
"Full page width": "Volledige pagina breedte",
"Full width": "Volledige breedte",
"General": "Algemeen",
"Group": "Groep",
"Group description": "Groepsomschrijving",
"Group name": "Groepsnaam",
"Groups": "Groepen",
"Has full access to space settings and pages.": "Heeft volledige toegang tot ruimte instellingen en pagina's.",
"Home": "Startpagina",
"Import pages": "Importeer pagina's",
"Import pages & space settings": "Importeer pagina en ruimte instellingen",
"Importing pages": "Importeer pagina's",
"invalid invitation link": "ongeldige uitnodigingslink",
"Invitation signup": "Uitnodiging aanmelding",
"Invite by email": "Uitnodigen via e-mail",
"Invite members": "Leden uitnodigen",
"Invite new members": "Nieuwe leden uitnodigen",
"Invited members who are yet to accept their invitation will appear here.": "Uigenodigde 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",
"Join the workspace": "Word lid van de werkruimte",
"Language": "Taal",
"Light": "Licht",
"Link copied": "Link gekopieerd",
"Login": "Inloggen",
"Logout": "Uitloggen",
"Manage Group": "Groep beheren",
"Manage members": "Leden beheren",
"member": "lid",
"Member": "Lid",
"members": "leden",
"Members": "Leden",
"My preferences": "Mijn voorkeuren",
"My Profile": "Mijn profiel",
"My profile": "Mijn profiel",
"Name": "Naam",
"New email": "Nieuw e-mail",
"New page": "Nieuwe pagina",
"New password": "Nieuw wachtwoord",
"No group found": "Geen groep gevonden",
"No page history saved yet.": "Er is nog geen pagina geschiedenis opgeslagen.",
"No pages yet": "Nog geen pagina's",
"No results found...": "Geen resultaten gevonden...",
"No user found": "Geen gebruiker gevonden",
"Overview": "Overzicht",
"Owner": "Eigenaar",
"page": "pagina",
"Page deleted successfully": "Pagina succesvol verwijderd",
"Page history": "Pagina geschiedenis",
"Page import is in progress. Please do not close this tab.": "Importeren van pagina's is bezig. Sluit dit tabblad niet.",
"Pages": "Pagina's",
"pages": "pagina's",
"Password": "Wachtwoord",
"Password changed successfully": "Wachtwoord met succes gewijzigd",
"Pending": "Wachtende",
"Please confirm your action": "Bevestig alstublieft uw actie",
"Preferences": "Voorkeuren",
"Print PDF": "PDF afdrukken",
"Profile": "Profiel",
"Recently updated": "Recent bijgewerkt",
"Remove": "Verwijderen",
"Remove group member": "Lid uit groep verwijderd",
"Remove space member": "Lid uit ruimte verwijderd",
"Restore": "Herstellen",
"Role": "Rol",
"Save": "Opslaan",
"Search": "Zoeken",
"Search for groups": "Zoek naar groepen",
"Search for users": "Zoek naar gebruikers",
"Search for users and groups": "Zoek naar gebruikers en groepen",
"Search...": "Zoeken...",
"Select language": "Selecteer taal",
"Select role": "Selecteer rol",
"Select role to assign to all invited members": "Selecteer rol en wijs toe aan alle uitgenodigde leden",
"Select theme": "Selecteer thema",
"Send invitation": "Uitnodiging versturen",
"Invitation sent": "Uitnodiging verzonden",
"Settings": "Instellingen",
"Setup workspace": "Werkruimte instellen",
"Sign In": "Inloggen",
"Sign Up": "Aanmelden",
"Slug": "Afkorting",
"Space": "Ruimte",
"Space description": "Omschrijving van de ruimte",
"Space menu": "Ruimte menu",
"Space name": "Naam ruimte",
"Space settings": "Ruimte instellingen",
"Space slug": "Ruimte afkorting",
"Spaces": "Ruimtes",
"Spaces you belong to": "Ruimtes waar je bij hoort",
"No space found": "Geen ruimte gevonden",
"Search for spaces": "Zoek naar ruimtes",
"Start typing to search...": "Begin met typen om te zoeken...",
"Status": "Status",
"Successfully imported": "Succesvol geïmporteerd",
"Successfully restored": "Succesvol hersteld",
"System settings": "Systeem instellingen",
"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.",
"Toggle full page width": "Schakel volledige pagina breedte in",
"Unable to import pages. Please try again.": "Pagina's importeren is niet gelukt. Probeer het opnieuw.",
"untitled": "naamloos",
"Untitled": "Naamloos",
"Updated successfully": "Succesvol bijgewerkt",
"User": "Gebruiker",
"Workspace": "Werkruimte",
"Workspace Name": "Naam werkruimte",
"Workspace settings": "Instellingen werkruimte",
"You can change your password here.": "U kunt hier uw wachtwoord wijzigen.",
"Your Email": "Uw e-mailadres",
"Your import is complete.": "Uw import is voltooid.",
"Your name": "Uw naam",
"Your Name": "Uw Naam",
"Your password": "Uw wachtwoord",
"Your password must be a minimum of 8 characters.": "Uw wachtwoord moet minimaal 8 tekens bevatten.",
"Sidebar toggle": "Zijbalk toggelen",
"Comments": "Opmerkingen",
"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.",
"Take me back to homepage": "Ga terug naar de homepage",
"Forgot 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.",
"Send reset link": "Verstuur een link om uw wachtwoord te herstellen",
"Password reset": "Wachtwoord opnieuw instellen",
"Your new password": "Uw nieuwe wachtwoord",
"Set password": "Voer wachtwoord in",
"Write a comment": "Schrijf een reactie",
"Reply...": "Antwoord...",
"Error loading comments.": "Fout bij het laden van reacties.",
"No comments yet.": "Nog geen reacties.",
"Edit comment": "Bewerk reactie",
"Delete comment": "Verwijder reactie",
"Are you sure you want to delete this comment?": "Weet je zeker dat je deze reactie wilt verwijderen?",
"Comment created successfully": "Reactie succesvol aangemaakt",
"Error creating comment": "Fout bij het aanmaken van reactie",
"Comment updated successfully": "Opmerking succesvol bijgewerkt",
"Failed to update comment": "Bijwerken van reactie mislukt",
"Comment deleted successfully": "Reactie met succes verwijderd",
"Failed to delete comment": "Verwijderen van reactie mislukt",
"Comment resolved successfully": "Reactie succesvol opgelost",
"Comment re-opened successfully": "Reactie succesvol heropend",
"Comment unresolved successfully": "Reactie succesvol niet-opgelost gemaakt",
"Failed to resolve comment": "Reactie oplossen mislukt",
"Resolve comment": "Reactie oplossen",
"Unresolve comment": "Reactie niet oplossen",
"Resolve Comment Thread": "Reactiedraad oplossen",
"Unresolve Comment Thread": "Reactiedraad niet oplossen",
"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?",
"Resolved": "Opgelost",
"No active comments.": "Geen actieve reacties.",
"No resolved comments.": "Geen opgeloste reacties.",
"Revoke invitation": "Uitnodiging intrekken",
"Revoke": "Intrekken",
"Don't": "Niet doen",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Weet u zeker dat u deze uitnodiging wilt intrekken? De gebruiker kan niet deelnemen aan de werkruimte.",
"Resend invitation": "Uitnodiging opnieuw verzenden",
"Anyone with this link can join this workspace.": "Iedereen met deze link kan zich aansluiten bij deze werkruimte.",
"Invite link": "Uitnodigingslink",
"Copy": "Kopieer",
"Copy to space": "Kopiëren naar ruimte",
"Copied": "Gekopieerd",
"Duplicate": "Dupliceren",
"Select a user": "Selecteer een gebruiker",
"Select a group": "Selecteer een groep",
"Export all pages and attachments in this space.": "Exporteer alle pagina's en bijlagen in deze ruimte.",
"Delete space": "Verwijder ruimte",
"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.",
"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",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Typ de ruimtenaam <b>{{spaceName}}</b> om uw actie te bevestigen.",
"Format": "Formaat",
"Include subpages": "Inclusief onderliggend pagina's",
"Include attachments": "Inclusief bijlages",
"Select export format": "Selecteer export formaat",
"Export failed:": "Exporteren mislukt:",
"export error": "Exporteer fout",
"Export page": "Exporteer pagina",
"Export space": "Exporteer ruimte",
"Export {{type}}": "Exporteer {{type}}",
"File exceeds the {{limit}} attachment limit": "Bestand overschrijdt de bijlagelimiet van {{limit}}",
"Align left": "Links uitlijnen",
"Align right": "Rechts uitlijnen",
"Align center": "Centreren",
"Justify": "Uitvullen",
"Merge cells": "Cellen samenvoegen",
"Split cell": "Cel splitsen",
"Delete column": "Kolom verwijderen",
"Delete row": "Rij verwijderen",
"Add left column": "Linker kolom toevoegen",
"Add right column": "Rechter kolom toevoegen",
"Add row above": "Rij hierboven toevoegen",
"Add row below": "Rij hieronder toevoegen",
"Delete table": "Verwijder tabel",
"Info": "Info",
"Success": "Geslaagd",
"Warning": "Waarschuwing",
"Danger": "Gevaar",
"Mermaid diagram error:": "Mermaid diagram fout:",
"Invalid Mermaid diagram": "Ongeldig Mermaid diagram",
"Double-click to edit Draw.io diagram": "Dubbelklik om Draw.io diagram te bewerken",
"Exit": "Afsluiten",
"Save & Exit": "Opslaan & Afsluiten",
"Double-click to edit Excalidraw diagram": "Dubbelklik om Excalidraw diagram te bewerken",
"Paste link": "Link plakken",
"Edit link": "Link bewerken",
"Remove link": "Link verwijderen",
"Add link": "Link toevoegen",
"Please enter a valid url": "Voer een geldige URL in",
"Empty equation": "Lege vergelijking",
"Invalid equation": "Ongeldige vergelijking",
"Color": "Kleur",
"Text color": "Tekstkleur",
"Default": "Standaard",
"Blue": "Blauw",
"Green": "Groen",
"Purple": "Paars",
"Red": "Rood",
"Yellow": "Geel",
"Orange": "Oranje",
"Pink": "Roze",
"Gray": "Grijs",
"Embed link": "Link insluiten",
"Invalid {{provider}} embed link": "Ongeldige {{provider}} insluitingslink",
"Embed {{provider}}": "Insluiten {{provider}}",
"Enter {{provider}} link to embed": "Voer {{provider}} link in om in te voegen",
"Bold": "Dikgedrukt",
"Italic": "Schuingedrukt",
"Underline": "Onderstrepen",
"Strike": "Doorhalen",
"Code": "Code",
"Comment": "Reactie",
"Text": "Tekst",
"Heading 1": "Kop 1",
"Heading 2": "Kop 2",
"Heading 3": "Kop 3",
"To-do List": "Takenlijst",
"Bullet List": "Opsommingslijst",
"Numbered List": "Genummerde lijst",
"Blockquote": "Blockquote",
"Just start typing with plain text.": "Begin met typen.",
"Track tasks with a to-do list.": "Houd taken bij met een takenlijst.",
"Big section heading.": "Grote sectie kop.",
"Medium section heading.": "Middelgrote sectie kop.",
"Small section heading.": "Kleine sectie kop.",
"Create a simple bullet list.": "Maak een eenvoudige opsommingslijst aan.",
"Create a list with numbering.": "Maak een lijst met nummering.",
"Create block quote.": "Maak een block quote.",
"Insert code snippet.": "Codefragment invoegen.",
"Insert horizontal rule divider": "Horizontale lijn invoegen",
"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 file from your device.": "Upload een bestand vanaf uw apparaat.",
"Table": "Tabel",
"Insert a table.": "Voeg een tabel in.",
"Insert collapsible block.": "Inklapbaar blok invoegen.",
"Video": "Video",
"Divider": "Scheidingslijn",
"Quote": "Quote",
"Image": "Afbeelding",
"File attachment": "Bestand bijlage",
"Toggle block": "Schakel blok in/uit",
"Callout": "Opmerking",
"Insert callout notice.": "Invoegen opmerking.",
"Math inline": "Wiskundige inline",
"Insert inline math equation.": "Wiskundige inline vergelijking invoegen.",
"Math block": "Wiskunde blok",
"Insert math equation": "Wiskundige inline vergelijking invoegen",
"Mermaid diagram": "Mermaid diagram",
"Insert mermaid diagram": "Voeg mermaid diagram in",
"Insert and design Drawio diagrams": "Drawio diagrammen invoegen en ontwerpen",
"Insert current date": "Huidige datum invoeren",
"Draw and sketch excalidraw diagrams": "Teken en schets excalidraw diagrammen",
"Multiple": "Meerdere",
"Heading {{level}}": "Kop {{level}}",
"Toggle title": "Schakel titel in/uit",
"Write anything. Enter \"/\" for commands": "Schrijf iets. Voer \"/\" in voor commando's",
"Names do not match": "Namen komen niet overeen",
"Today, {{time}}": "Vandaag, {{time}}",
"Yesterday, {{time}}": "Gisteren, {{time}}",
"Space created successfully": "Ruimte succesvol aangemaakt",
"Space updated successfully": "Ruimte succesvol bijgewerkt",
"Space deleted successfully": "Ruimte succesvol verwijderd",
"Members added successfully": "Leden succesvol toegevoegd",
"Member removed successfully": "Lid succesvol verwijderd",
"Member role updated successfully": "Lidrol succesvol bijgewerkt",
"Created by: <b>{{creatorName}}</b>": "Gemaakt door: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Aangemaakt op: {{time}}",
"Edited by {{name}} {{time}}": "Bewerkt door {{name}} {{time}}",
"Word count: {{wordCount}}": "Aantal woorden: {{wordCount}}",
"Character count: {{characterCount}}": "Aantal tekens: {{characterCount}}",
"New update": "Nieuwe update",
"{{latestVersion}} is available": "{{latestVersion}} is beschikbaar",
"Default page edit mode": "Standaard pagina bewerkmodus",
"Choose your preferred page edit mode. Avoid accidental edits.": "Kies uw voorkeurs bewerkmodus voor pagina's. Vermijd per ongeluk bewerken.",
"Reading": "Lezen",
"Delete member": "Verwijder lid",
"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.",
"Move": "Verplaatsen",
"Move page": "Pagina verplaatsen",
"Move page to a different space.": "Verplaats pagina naar een andere ruimte.",
"Real-time editor connection lost. Retrying...": "Realtime editorverbinding verloren. Opnieuw proberen...",
"Table of contents": "Inhoudsopgave",
"Add headings (H1, H2, H3) to generate a table of contents.": "Voeg koppen (H1, H2, H3) toe om een inhoudsopgave te genereren.",
"Share": "Delen",
"Public sharing": "Openbaar delen",
"Shared by": "Gedeeld door",
"Shared at": "Gedeeld op",
"Inherits public sharing from": "Erft openbaar delen van",
"Share to web": "Delen naar web",
"Shared to web": "Gedeeld naar web",
"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",
"Include sub-pages": "Inclusief subpagina's",
"Make sub-pages public too": "Maak subpagina's ook openbaar",
"Allow search engines to index page": "Sta zoekmachines toe om pagina te indexeren",
"Open page": "Pagina openen",
"Page": "Pagina",
"Delete public share link": "Verwijder openbare deel-link",
"Delete share": "Verwijder deel",
"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",
"Share deleted successfully": "Delen succesvol verwijderd",
"Share not found": "Delen niet gevonden",
"Failed to share page": "Pagina delen mislukt",
"Copy page": "Pagina kopiëren",
"Copy page to a different space.": "Kopieer pagina naar een andere ruimte.",
"Page copied successfully": "Pagina succesvol gekopieerd",
"Page duplicated successfully": "Pagina succesvol gedupliceerd",
"Find": "Zoeken",
"Not found": "Niet gevonden",
"Previous Match (Shift+Enter)": "Vorige overeenkomst (Shift+Enter)",
"Next match (Enter)": "Volgende overeenkomst (Enter)",
"Match case (Alt+C)": "Hoofdlettergevoeligheid (Alt+C)",
"Replace": "Vervangen",
"Close (Escape)": "Sluiten (Escape)",
"Replace (Enter)": "Vervangen (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Alles vervangen (Ctrl+Alt+Enter)",
"Replace all": "Alles vervangen",
"View all spaces": "Bekijk alle ruimtes",
"Error": "Fout",
"Failed to disable MFA": "MFA uitschakelen mislukt",
"Disable two-factor authentication": "Twee-factor authenticatie 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.",
"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 disabled": "Twee-factor authenticatie is uitgeschakeld",
"2-step verification": "2-staps verificatie",
"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.",
"Add 2FA method": "2FA-methode toevoegen",
"Backup codes": "Back-up codes",
"Disable": "Uitschakelen",
"Invalid verification code": "Ongeldige verificatiecode",
"New backup codes have been generated": "Nieuwe back-up codes zijn gegenereerd",
"Failed to regenerate backup codes": "Back-up codes opnieuw genereren mislukt",
"About backup codes": "Over back-up 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.": "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.",
"Confirm password": "Bevestig wachtwoord",
"Generate new backup codes": "Genereer nieuwe back-up codes",
"Save your new backup codes": "Sla uw nieuwe back-up codes 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.",
"Your new backup codes": "Uw nieuwe back-up codes",
"I've saved my backup codes": "Ik heb mijn back-up codes opgeslagen",
"Failed to setup MFA": "MFA instellen mislukt",
"Setup & Verify": "Instellen & Verifiëren",
"Add to authenticator": "Toevoegen aan de authenticator",
"1. Scan this QR code with your authenticator app": "1. Scan deze QR-code met uw authenticator-app",
"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:",
"2. Enter the 6-digit code from your authenticator": "2. Voer de 6-cijferige code van uw authenticator in",
"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.",
"Backup": "Back-up",
"Save codes": "Codes opslaan",
"Save your backup codes": "Sla uw back-up codes 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.",
"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 required": "Twee-factor authenticatie vereist",
"Your workspace requires two-factor authentication for all users": "Uw werkruimte vereist twee-factor authenticatie 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.",
"Set up two-factor authentication": "Stel twee-factor authenticatie in",
"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.",
"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 must be at least 8 characters": "Wachtwoord moet minimaal 8 tekens zijn",
"Please enter a 6-digit code": "Voer alstublieft een 6-cijferige code in",
"Code must be exactly 6 digits": "Code moet exact 6 cijfers zijn",
"Enter the 6-digit code found in your authenticator app": "Voer de 6-cijferige code in die in uw authenticator-app staat",
"Need help authenticating?": "Hulp nodig bij het authenticeren?",
"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.",
"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 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",
"Use authenticator app instead": "Gebruik in plaats daarvan de authenticator-app",
"Verify backup code": "Back-up code verifiëren",
"Use backup code": "Gebruik back-up code",
"Enter one of your backup codes": "Voer een van uw back-up codes in",
"Backup code": "Back-up code",
"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",
"Trash": "Prullenbak",
"Pages in trash will be permanently deleted after 30 days.": "Pagina's in de prullenbak worden na 30 dagen permanent verwijderd.",
"Deleted": "Verwijderd",
"No pages in trash": "Geen pagina's in de prullenbak",
"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.",
"Restore '{{title}}' and its sub-pages?": "'{{title}}' en zijn subpagina's herstellen?",
"Move to trash": "Naar de prullenbak verplaatsen",
"Move this page to trash?": "Deze pagina naar de prullenbak verplaatsen?",
"Restore page": "Pagina herstellen",
"Page moved to trash": "Pagina verplaatst naar de prullenbak",
"Page restored successfully": "Pagina succesvol hersteld",
"Deleted by": "Verwijderd door",
"Deleted at": "Verwijderd op",
"Preview": "Voorbeeld",
"Subpages": "Subpagina's",
"Failed to load subpages": "Laden van subpagina's mislukt",
"No subpages": "Geen subpagina's",
"Subpages (Child pages)": "Subpagina's (Kindpagina's)",
"List all subpages of the current page": "Lijst van alle subpagina's van de huidige pagina",
"Attachments": "Bijlagen",
"All spaces": "Alle ruimtes",
"Unknown": "Onbekend",
"Find a space": "Vind een ruimte",
"Search in all your spaces": "Zoek in al je ruimtes",
"Type": "Type",
"Enterprise": "Onderneming",
"Download attachment": "Bijlage downloaden",
"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.",
"Enter valid domain names separated by comma or space": "Voer geldige domeinnamen in, gescheiden door komma of spatie",
"Enforce two-factor authentication": "Handhaaf tweefactorauthenticatie",
"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",
"Display name": "Weergavenaam",
"Allow signup": "Aanmelden toestaan",
"Enabled": "Ingeschakeld",
"Advanced Settings": "Geavanceerde instellingen",
"Enable TLS/SSL": "TLS/SSL inschakelen",
"Use secure connection to LDAP server": "Gebruik een beveiligde verbinding met de LDAP-server",
"Group sync": "Groepssynchronisatie",
"No SSO providers found.": "Geen SSO-providers gevonden.",
"Delete SSO provider": "Verwijder SSO-provider",
"Are you sure you want to delete this SSO provider?": "Weet u zeker dat u deze SSO-provider wilt verwijderen?",
"Action": "Actie",
"{{ssoProviderType}} configuration": "{{ssoProviderType}} configuratie"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Conta",
"Active": "Ativo",
"Add": "Adicionar",
"Add group members": "Adicionar membros ao grupo",
"Add groups": "Adicionar grupos",
"Add members": "Adicionar membros",
"Add to groups": "Adicionar aos grupos",
"Add space members": "Adicionar membros do espaço",
"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 page?": "Tem certeza de que deseja excluir esta página?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Tem certeza de que deseja remover este usuário do grupo? O usuário perderá acesso aos recursos que este grupo possui.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Tem certeza de que deseja remover este usuário do espaço? O usuário perderá todo acesso a este espaço.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Tem certeza de que deseja restaurar esta versão? Quaisquer alterações não versionadas serão perdidas.",
"Can become members of groups and spaces in workspace": "Pode se tornar membro de grupos e espaços no workspace",
"Can create and edit pages in space.": "Pode criar e editar páginas no espaço.",
"Can edit": "Pode editar",
"Can manage workspace": "Pode gerenciar o workspace",
"Can manage workspace but cannot delete it": "Pode gerenciar o workspace, mas não pode excluí-lo",
"Can view": "Pode visualizar",
"Can view pages in space but not edit.": "Pode visualizar páginas no espaço, mas não editar.",
"Cancel": "Cancelar",
"Change email": "Alterar email",
"Change password": "Alterar senha",
"Change photo": "Alterar foto",
"Choose a role": "Escolha um papel",
"Choose your preferred color scheme.": "Escolha seu esquema de cores preferido.",
"Choose your preferred interface language.": "Escolha o idioma da interface.",
"Choose your preferred page width.": "Escolha a largura preferida da página.",
"Confirm": "Confirmar",
"Copy link": "Copiar link",
"Create": "Criar",
"Create group": "Criar grupo",
"Create page": "Criar página",
"Create space": "Criar espaço",
"Create workspace": "Criar workspace",
"Current password": "Senha atual",
"Dark": "Escuro",
"Date": "Data",
"Delete": "Excluir",
"Delete group": "Excluir grupo",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Você tem certeza que quer deletar essa página? Isso irá deletar todas as páginas filhas e to o histórico. Esta ação é irreversível.",
"Description": "Descrição",
"Details": "Detalhes",
"e.g ACME": "ex.: ACME",
"e.g ACME Inc": "ex.: ACME Inc",
"e.g Developers": "ex.: Desenvolvedores",
"e.g Group for developers": "ex.: Grupo para desenvolvedores",
"e.g product": "ex.: produto",
"e.g Product Team": "ex.: Equipe de Produto",
"e.g Sales": "ex.: Vendas",
"e.g Space for product team": "ex.: Espaço para a equipe de produto",
"e.g Space for sales team to collaborate": "ex.: Espaço para a equipe de vendas colaborar",
"Edit": "Editar",
"Read": "Ler",
"Edit group": "Editar grupo",
"Email": "Email",
"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 emails addresses": "insira endereços de email válidos",
"Enter your current password": "Insira sua senha atual",
"enter your full name": "insira seu nome completo",
"Enter your new password": "Insira sua nova senha",
"Enter your new preferred email": "Insira seu novo email preferido",
"Enter your password": "Insira sua senha",
"Error fetching page data.": "Erro ao buscar dados da página.",
"Error loading page history.": "Erro ao carregar o histórico da página.",
"Export": "Exportar",
"Failed to create page": "Falha ao criar página",
"Failed to delete page": "Falha ao excluir página",
"Failed to fetch recent pages": "Falha ao buscar páginas recentes",
"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 update data": "Falha ao atualizar dados",
"Full access": "Acesso total",
"Full page width": "Usar largura total da página",
"Full width": "Largura total",
"General": "Geral",
"Group": "Grupo",
"Group description": "Descrição do grupo",
"Group name": "Nome do grupo",
"Groups": "Grupos",
"Has full access to space settings and pages.": "Tem acesso total às configurações do espaço e às páginas.",
"Home": "Início",
"Import pages": "Importar páginas",
"Import pages & space settings": "Importar páginas e configurações de espaço",
"Importing pages": "Importando páginas",
"invalid invitation link": "link de convite inválido",
"Invitation signup": "Cadastro por convite",
"Invite by email": "Convidar por email",
"Invite members": "Convidar membros",
"Invite new members": "Convidar novos membros",
"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",
"Join the workspace": "Entrar no workspace",
"Language": "Idioma",
"Light": "Claro",
"Link copied": "Link copiado",
"Login": "Entrar",
"Logout": "Sair",
"Manage Group": "Gerenciar Grupo",
"Manage members": "Gerenciar membros",
"member": "membro",
"Member": "Membro",
"members": "membros",
"Members": "Membros",
"My preferences": "Minhas preferências",
"My Profile": "Meu Perfil",
"My profile": "Meu perfil",
"Name": "Nome",
"New email": "Novo email",
"New page": "Nova página",
"New password": "Nova senha",
"No group found": "Nenhum grupo encontrado",
"No page history saved yet.": "Nenhum histórico de página salvo ainda.",
"No pages yet": "Nenhuma página ainda",
"No results found...": "Nenhum resultado encontrado...",
"No user found": "Nenhum usuário encontrado",
"Overview": "Visão geral",
"Owner": "Proprietário",
"page": "página",
"Page deleted successfully": "Página excluída com sucesso",
"Page history": "Histórico da página",
"Page import is in progress. Please do not close this tab.": "A importação da página está em andamento. Por favor, não feche esta aba.",
"Pages": "Páginas",
"pages": "páginas",
"Password": "Senha",
"Password changed successfully": "Senha alterada com sucesso",
"Pending": "Pendente",
"Please confirm your action": "Por favor, confirme sua ação",
"Preferences": "Preferências",
"Print PDF": "Imprimir PDF",
"Profile": "Perfil",
"Recently updated": "Atualizado recentemente",
"Remove": "Remover",
"Remove group member": "Remover membro do grupo",
"Remove space member": "Remover membro do espaço",
"Restore": "Restaurar",
"Role": "Função",
"Save": "Salvar",
"Search": "Buscar",
"Search for groups": "Buscar grupos",
"Search for users": "Buscar usuários",
"Search for users and groups": "Buscar usuários e grupos",
"Search...": "Buscar...",
"Select language": "Selecionar idioma",
"Select role": "Selecionar função",
"Select role to assign to all invited members": "Selecione a função para atribuir a todos os membros convidados",
"Select theme": "Selecionar tema",
"Send invitation": "Enviar convite",
"Invitation sent": "Convite enviado",
"Settings": "Configurações",
"Setup workspace": "Configurar workspace",
"Sign In": "Entrar",
"Sign Up": "Registrar-se",
"Slug": "Slug",
"Space": "Espaço",
"Space description": "Descrição do espaço",
"Space menu": "Menu do espaço",
"Space name": "Nome do espaço",
"Space settings": "Configurações do espaço",
"Space slug": "Slug do espaço",
"Spaces": "Espaços",
"Spaces you belong to": "Espaços aos quais você pertence",
"No space found": "Nenhum espaço encontrado",
"Search for spaces": "Pesquisar espaços",
"Start typing to search...": "Comece a digitar para buscar...",
"Status": "Estado",
"Successfully imported": "Importado com sucesso",
"Successfully restored": "Restaurado com sucesso",
"System settings": "Configurações do sistema",
"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.",
"Toggle full page width": "Alternar para 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.",
"untitled": "sem título",
"Untitled": "Sem título",
"Updated successfully": "Atualizado com sucesso",
"User": "Usuário",
"Workspace": "Espaço de Trabalho",
"Workspace Name": "Nome do Workspace",
"Workspace settings": "Configurações do workspace",
"You can change your password here.": "Você pode alterar sua senha aqui.",
"Your Email": "Seu email",
"Your import is complete.": "Sua importação está concluída.",
"Your name": "Seu nome",
"Your Name": "Seu Nome",
"Your password": "Sua senha",
"Your password must be a minimum of 8 characters.": "Sua senha deve ter no mínimo 8 caracteres.",
"Sidebar toggle": "Interruptor do painel lateral",
"Comments": "Comentários",
"404 page not found": "Erro 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.",
"Take me back to homepage": "Leve-me de volta para a página inicial",
"Forgot password": "Esqueci a 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.",
"Send reset link": "Enviar link de recuperação",
"Password reset": "Resetar a senha",
"Your new password": "Sua nova senha",
"Set password": "Definir a senha",
"Write a comment": "Escreva um comentário",
"Reply...": "Responder...",
"Error loading comments.": "Erro ao carregar comentários.",
"No comments yet.": "Ainda sem comentários.",
"Edit comment": "Editar 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?",
"Comment created successfully": "Comentário criado com sucesso",
"Error creating comment": "Erro ao criar comentário",
"Comment updated successfully": "Comentário atualizado com sucesso",
"Failed to update comment": "Falha ao atualizar comentário",
"Comment deleted successfully": "Comentário excluído com sucesso",
"Failed to delete comment": "Falha ao excluir comentário",
"Comment resolved successfully": "Comentário resolvido com sucesso",
"Comment re-opened successfully": "Comentário reaberto com sucesso",
"Comment unresolved successfully": "Comentário não resolvido com sucesso",
"Failed to resolve comment": "Falha ao resolver comentário",
"Resolve comment": "Resolver comentário",
"Unresolve comment": "Não resolver comentário",
"Resolve Comment Thread": "Resolver Fio de Comentários",
"Unresolve Comment Thread": "Não resolver Fio de Comentários",
"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?",
"Resolved": "Resolvido",
"No active comments.": "Sem comentários ativos.",
"No resolved comments.": "Sem comentários resolvidos.",
"Revoke invitation": "Cancelar o convite",
"Revoke": "Anular",
"Don't": "Não",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Tem certeza de que deseja revogar este convite? O usuário não poderá participar do espaço de trabalho.",
"Resend invitation": "Reenviar convite",
"Anyone with this link can join this workspace.": "Qualquer um com este link pode participar deste espaço de trabalho.",
"Invite link": "Link do convite",
"Copy": "Copiar",
"Copy to space": "Copiar para o espaço",
"Copied": "Copiado",
"Duplicate": "Duplicar",
"Select a user": "Selecione um usuário",
"Select a group": "Selecione um grupo",
"Export all pages and attachments in this space.": "Exportar todas as páginas e anexos deste espaço.",
"Delete space": "Excluir 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.",
"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",
"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",
"Include subpages": "Incluir subpáginas",
"Include attachments": "Incluir anexos",
"Select export format": "Selecionado o formato para exportação",
"Export failed:": "Falha ao exportar:",
"export error": "erro de exportação",
"Export page": "Exportar página",
"Export space": "Exportar espaço",
"Export {{type}}": "Exportar para {{type}}",
"File exceeds the {{limit}} attachment limit": "O arquivo excede o limite de anexos {{limit}}",
"Align left": "Alinhar à esquerda",
"Align right": "Alinhar à direita",
"Align center": "Alinhar ao centro",
"Justify": "Justificar",
"Merge cells": "Mesclar células",
"Split cell": "Dividir célula",
"Delete column": "Excluir coluna",
"Delete row": "Excluir linha",
"Add left column": "Adicionar coluna à esquerda",
"Add right column": "Adicionar coluna à direita",
"Add row above": "Adicionar linha acima",
"Add row below": "Adicionar linha abaixo",
"Delete table": "Excluir tabela",
"Info": "Informação",
"Success": "Sucesso",
"Warning": "Aviso",
"Danger": "Perigo",
"Mermaid diagram error:": "Erro no diagrama Mermaid:",
"Invalid Mermaid diagram": "Diagrama Mermaid inválido",
"Double-click to edit Draw.io diagram": "Clique duas vezes para editar o diagrama Draw.io",
"Exit": "Sair",
"Save & Exit": "Salvar e Sair",
"Double-click to edit Excalidraw diagram": "Clique duas vezes para editar o diagrama Excalidraw",
"Paste link": "Colar link",
"Edit link": "Editar link",
"Remove link": "Remover link",
"Add link": "Adicionar link",
"Please enter a valid url": "Por favor, insira uma URL válida",
"Empty equation": "Equação vazia",
"Invalid equation": "Equação inválida",
"Color": "Cor",
"Text color": "Cor do texto",
"Default": "Padrão",
"Blue": "Azul",
"Green": "Verde",
"Purple": "Violeta",
"Red": "Vermelho",
"Yellow": "Amarelo",
"Orange": "Laranja",
"Pink": "Rosa",
"Gray": "Cinza",
"Embed link": "Link embutido",
"Invalid {{provider}} embed link": "Link de incorporação {{provider}} inválido",
"Embed {{provider}}": "Incorporar {{provider}}",
"Enter {{provider}} link to embed": "Digite o link do {{provider}} para incorporar",
"Bold": "Negrito",
"Italic": "Itálico",
"Underline": "Sublinhado",
"Strike": "Tracejado",
"Code": "Código",
"Comment": "Comentário",
"Text": "Texto",
"Heading 1": "Título 1",
"Heading 2": "Título 2",
"Heading 3": "Título 3",
"To-do List": "Lista de Tarefas",
"Bullet List": "Lista de Pontos",
"Numbered List": "Lista Numerada",
"Blockquote": "Bloco de Citação",
"Just start typing with plain text.": "Basta começar a digita.",
"Track tasks with a to-do list.": "Acompanhe tarefas com uma lista de tarefas.",
"Big section heading.": "Título de seção grande.",
"Medium section heading.": "Título de seção média.",
"Small section heading.": "Título de seção pequena.",
"Create a simple bullet list.": "Crie uma lista simples com marcadores.",
"Create a list with numbering.": "Crie uma lista com numeração.",
"Create block quote.": "Crie uma citação em bloco.",
"Insert code snippet.": "Insira um trecho de código.",
"Insert horizontal rule divider": "Insira um divisor horizontal",
"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 file from your device.": "Envie qualquer arquivo do seu dispositivo.",
"Table": "Tabela",
"Insert a table.": "Insira uma tabela.",
"Insert collapsible block.": "Insira um bloco colapsável.",
"Video": "Vídeo",
"Divider": "Divisor",
"Quote": "Citação",
"Image": "Imagem",
"File attachment": "Anexo de arquivo",
"Toggle block": "Bloco colapsável",
"Callout": "Aviso",
"Insert callout notice.": "Insira um aviso.",
"Math inline": "Matemática inline",
"Insert inline math equation.": "Insira uma equação matemática inline.",
"Math block": "Bloco de matemática",
"Insert math equation": "Insira uma equação matemática",
"Mermaid diagram": "Diagrama Mermaid",
"Insert mermaid diagram": "Insira um diagrama Mermaid",
"Insert and design Drawio diagrams": "Insira e projete diagramas Drawio",
"Insert current date": "Insira a data atual",
"Draw and sketch excalidraw diagrams": "Desenhe e esboce diagramas Excalidraw",
"Multiple": "Múltiplo",
"Heading {{level}}": "Título {{level}}",
"Toggle title": "Alternar título",
"Write anything. Enter \"/\" for commands": "Escreva qualquer coisa. Digite \"/\" para comandos",
"Names do not match": "Os nomes não coincidem",
"Today, {{time}}": "Hoje, {{time}}",
"Yesterday, {{time}}": "Ontem, {{time}}",
"Space created successfully": "Espaço criado com sucesso",
"Space updated successfully": "Espaço atualizado com sucesso",
"Space deleted successfully": "Espaço excluído com sucesso",
"Members added successfully": "Membros adicionados com sucesso",
"Member removed successfully": "Membro removido com sucesso",
"Member role updated successfully": "Função do membro atualizada com sucesso",
"Created by: <b>{{creatorName}}</b>": "Criado por: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Criado em: {{time}}",
"Edited by {{name}} {{time}}": "Editado por {{name}} {{time}}",
"Word count: {{wordCount}}": "Contagem de palavras: {{wordCount}}",
"Character count: {{characterCount}}": "Contagem de caracteres: {{characterCount}}",
"New update": "Nova atualização",
"{{latestVersion}} is available": "{{latestVersion}} está disponível",
"Default page edit mode": "Modo de edição de página padrão",
"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",
"Delete member": "Excluir membro",
"Member deleted successfully": "Membro removido 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.",
"Move": "Mover",
"Move page": "Mover página",
"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...",
"Table of contents": "Tabela de conteúdos",
"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",
"Public sharing": "Compartilhamento público",
"Shared by": "Compartilhado por",
"Shared at": "Compartilhado em",
"Inherits public sharing from": "Herdado do compartilhamento público de",
"Share to web": "Compartilhar 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",
"Make this page publicly accessible": "Tornar esta página publicamente acessível",
"Include sub-pages": "Incluir sub-páginas",
"Make sub-pages public too": "Tornar as sub-páginas públicas também",
"Allow search engines to index page": "Permitir que mecanismos de busca indexem a página",
"Open page": "Abrir página",
"Page": "Página",
"Delete public share link": "Excluir o link público compartilhado",
"Delete share": "Excluir compartilhamento",
"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",
"Share deleted successfully": "Compartilhamento excluído com sucesso",
"Share not found": "Compartilhamento não encontrado",
"Failed to share page": "Falha ao compartilhar página",
"Copy page": "Copiar página",
"Copy page to a different space.": "Copiar página para um espaço diferente.",
"Page copied successfully": "Página copiada com sucesso",
"Page duplicated successfully": "Página duplicada com sucesso",
"Find": "Encontrar",
"Not found": "Não encontrado",
"Previous Match (Shift+Enter)": "Correspondência anterior (Shift+Enter)",
"Next match (Enter)": "Próxima correspondência (Enter)",
"Match case (Alt+C)": "Diferenciar maiúsculas de minúsculas (Alt+C)",
"Replace": "Substituir",
"Close (Escape)": "Fechar (Escape)",
"Replace (Enter)": "Substituir (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Substituir tudo (Ctrl+Alt+Enter)",
"Replace all": "Substituir tudo",
"View all spaces": "Ver todos os espaços",
"Error": "Erro",
"Failed to disable MFA": "Falha ao desativar a MFA",
"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.",
"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 disabled": "Autenticação de dois fatores foi desativada",
"2-step verification": "Verificação em duas etapas",
"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.",
"Add 2FA method": "Adicionar método de 2FA",
"Backup codes": "Códigos de backup",
"Disable": "Desativar",
"Invalid verification code": "Código de verificação inválido",
"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",
"About backup codes": "Sobre 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.",
"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",
"Generate new backup codes": "Gerar novos códigos de backup",
"Save your new backup codes": "Salvar 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.",
"Your new backup codes": "Seus novos códigos de backup",
"I've saved my backup codes": "Eu salvei meus códigos de backup",
"Failed to setup MFA": "Falha ao configurar a MFA",
"Setup & Verify": "Configurar & Verificar",
"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",
"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:",
"2. Enter the 6-digit code from your authenticator": "2. Digite o código de 6 dígitos do seu autenticador",
"Verify and enable": "Verificar e ativar",
"Failed to generate QR code. Please try again.": "Falha ao gerar código QR. Por favor, tente novamente.",
"Backup": "Backup",
"Save codes": "Salvar códigos",
"Save your backup codes": "Salvar 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.",
"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 required": "Autenticação de dois fatores necessá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",
"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",
"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.",
"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 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",
"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",
"Need help authenticating?": "Precisa de ajuda para autenticar?",
"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.",
"Password reset successful. Please log in with your new password and complete two-factor authentication.": "Redefinição de senha bem-sucedida. Por favor, faça login com sua nova senha e complete 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.",
"Two-factor authentication": "Autenticação de dois fatores",
"Use authenticator app instead": "Use o aplicativo autenticador em vez disso",
"Verify backup code": "Verificar 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",
"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.",
"Verify": "Verificar",
"Trash": "Lixeira",
"Pages in trash will be permanently deleted after 30 days.": "Páginas na lixeira serão excluídas permanentemente após 30 dias.",
"Deleted": "Excluído",
"No pages in trash": "Sem páginas na lixeira",
"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.",
"Restore '{{title}}' and its sub-pages?": "Restaurar '{{title}}' e suas subpáginas?",
"Move to trash": "Mover para a lixeira",
"Move this page to trash?": "Mover esta página para a lixeira?",
"Restore page": "Restaurar página",
"Page moved to trash": "Página movida para a lixeira",
"Page restored successfully": "Página restaurada com sucesso",
"Deleted by": "Excluído por",
"Deleted at": "Excluído em",
"Preview": "Visualização",
"Subpages": "Subpáginas",
"Failed to load subpages": "Falha ao carregar subpáginas",
"No subpages": "Sem subpáginas",
"Subpages (Child pages)": "Subpáginas (Páginas filhas)",
"List all subpages of the current page": "Listar todas as subpáginas da página atual",
"Attachments": "Anexos",
"All spaces": "Todos os espaços",
"Unknown": "Desconhecido",
"Find a space": "Encontrar um espaço",
"Search in all your spaces": "Pesquisar em todos os seus espaços",
"Type": "Tipo",
"Enterprise": "Empresa",
"Download attachment": "Baixar anexo",
"Allowed email domains": "Domínios de email 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.",
"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",
"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",
"Display name": "Nome de exibição",
"Allow signup": "Permitir inscrição",
"Enabled": "Habilitado",
"Advanced Settings": "Configurações Avançadas",
"Enable TLS/SSL": "Habilitar TLS/SSL",
"Use secure connection to LDAP server": "Usar conexão segura com o servidor LDAP",
"Group sync": "Sincronização de grupo",
"No SSO providers found.": "Nenhum provedor de SSO encontrado.",
"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?",
"Action": "Ação",
"{{ssoProviderType}} configuration": "Configuração de {{ssoProviderType}}"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Аккаунт",
"Active": "Активный",
"Add": "Добавить",
"Add group members": "Добавить участников группы",
"Add groups": "Добавить группы",
"Add members": "Добавить участников",
"Add to groups": "Добавить в группы",
"Add space members": "Добавить участников пространства",
"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 page?": "Вы уверены, что хотите удалить эту страницу?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Вы уверены, что хотите удалить этого пользователя из группы? Пользователь потеряет доступ к материалам, к которым у этой группы есть доступ.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Вы уверены, что хотите удалить этого пользователя из пространства? Пользователь потеряет весь доступ к этому пространству.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Вы уверены, что хотите восстановить эту версию? Все не зафиксированные изменения будут потеряны.",
"Can become members of groups and spaces in workspace": "Могут становиться участниками групп и пространств в рабочей области",
"Can create and edit pages in space.": "Может создавать и редактировать страницы в пространстве.",
"Can edit": "Может изменять",
"Can manage workspace": "Может управлять рабочей областью",
"Can manage workspace but cannot delete it": "Может управлять рабочей областью, но не может ее удалить",
"Can view": "Может просматривать",
"Can view pages in space but not edit.": "Может просматривать страницы в пространстве, но не может их редактировать.",
"Cancel": "Отменить",
"Change email": "Изменить электронную почту",
"Change password": "Изменить пароль",
"Change photo": "Изменить фото",
"Choose a role": "Выберите роль",
"Choose your preferred color scheme.": "Выберите предпочитаемую цветовую схему.",
"Choose your preferred interface language.": "Выберите предпочитаемый язык интерфейса.",
"Choose your preferred page width.": "Выберите предпочитаемую ширину страницы.",
"Confirm": "Подтвердить",
"Copy link": "Копировать ссылку",
"Create": "Создать",
"Create group": "Создать группу",
"Create page": "Создать страницу",
"Create space": "Создать пространство",
"Create workspace": "Создать рабочую область",
"Current password": "Текущий пароль",
"Dark": "Темная",
"Date": "Дата",
"Delete": "Удалить",
"Delete group": "Удалить группу",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Вы уверены, что хотите удалить эту страницу? Это удалит её дочерние страницы, а также историю страницы. Это действие необратимо.",
"Description": "Описание",
"Details": "Подробности",
"e.g ACME": "например, ACME",
"e.g ACME Inc": "например, ACME Inc",
"e.g Developers": "например, Разработчики",
"e.g Group for developers": "например, Группа для разработчиков",
"e.g product": "например, продукт",
"e.g Product Team": "например, Продуктовая команда",
"e.g Sales": "например, Продажи",
"e.g Space for product team": "например, Пространство для продуктовой команды",
"e.g Space for sales team to collaborate": "например, Пространство для совместной работы команды продаж",
"Edit": "Редактировать",
"Read": "Читать",
"Edit group": "Редактировать группу",
"Email": "Электронная почта",
"Enter a strong password": "Введите надёжный пароль",
"Enter valid email addresses separated by comma or space max_50": "Введите действительные адреса электронной почты, разделенные запятой или пробелом [макс: 50]",
"enter valid emails addresses": "введите действительные адреса электронной почты",
"Enter your current password": "Введите ваш текущий пароль",
"enter your full name": "введите ваше полное имя",
"Enter your new password": "Введите ваш новый пароль",
"Enter your new preferred email": "Введите ваш новый предпочтительный адрес электронной почты",
"Enter your password": "Введите ваш пароль",
"Error fetching page data.": "Ошибка при загрузке данных страницы.",
"Error loading page history.": "Ошибка при загрузке истории страницы.",
"Export": "Экспорт",
"Failed to create page": "Не удалось создать страницу",
"Failed to delete page": "Не удалось удалить страницу",
"Failed to fetch recent pages": "Не удалось получить недавние страницы",
"Failed to import pages": "Не удалось импортировать страницы",
"Failed to load page. An error occurred.": "Не удалось загрузить страницу. Произошла ошибка.",
"Failed to update data": "Не удалось обновить данные",
"Full access": "Полный доступ",
"Full page width": "Ширина на всю страницу",
"Full width": "Во всю ширину",
"General": "Основные",
"Group": "Группа",
"Group description": "Описание группы",
"Group name": "Название группы",
"Groups": "Группы",
"Has full access to space settings and pages.": "Имеет полный доступ к настройкам пространства и страницам.",
"Home": "Главная",
"Import pages": "Импорт страниц",
"Import pages & space settings": "Импорт страниц и настройки пространства",
"Importing pages": "Импортирование страниц",
"invalid invitation link": "ссылка на приглашение недействительна",
"Invitation signup": "Регистрация по приглашению",
"Invite by email": "Пригласить по электронной почте",
"Invite members": "Пригласить участников",
"Invite new members": "Пригласить новых участников",
"Invited members who are yet to accept their invitation will appear here.": "Приглашённые участники, которые ещё не приняли приглашение, появятся здесь.",
"Invited members will be granted access to spaces the groups can access": "Приглашённые участники получат доступ к пространствам, доступ к которым есть у группы",
"Join the workspace": "Присоединиться к рабочей области",
"Language": "Язык",
"Light": "Светлая",
"Link copied": "Ссылка скопирована",
"Login": "Войти",
"Logout": "Выйти",
"Manage Group": "Управление группой",
"Manage members": "Управление участниками",
"member": "участник",
"Member": "Участник",
"members": "участники",
"Members": "Участники",
"My preferences": "Мои настройки",
"My Profile": "Мой Профиль",
"My profile": "Мой профиль",
"Name": "Имя",
"New email": "Новый электронный адрес",
"New page": "Новая страница",
"New password": "Новый пароль",
"No group found": "Группа не найдена",
"No page history saved yet.": "История страниц ещё не сохранена.",
"No pages yet": "Страниц пока нет",
"No results found...": "Результаты не найдены...",
"No user found": "Пользователь не найден",
"Overview": "Обзор",
"Owner": "Владелец",
"page": "страница",
"Page deleted successfully": "Страница успешно удалена",
"Page history": "История страницы",
"Page import is in progress. Please do not close this tab.": "Импорт страницы в процессе. Пожалуйста, не закрывайте эту вкладку.",
"Pages": "Страницы",
"pages": "страницы",
"Password": "Пароль",
"Password changed successfully": "Пароль успешно изменён",
"Pending": "В ожидании",
"Please confirm your action": "Пожалуйста, подтвердите ваше действие",
"Preferences": "Настройки",
"Print PDF": "Печать PDF",
"Profile": "Профиль",
"Recently updated": "Обновлено недавно",
"Remove": "Удалить",
"Remove group member": "Удалить участника группы",
"Remove space member": "Удалить участника пространства",
"Restore": "Восстановить",
"Role": "Роль",
"Save": "Сохранить",
"Search": "Поиск",
"Search for groups": "Поиск групп",
"Search for users": "Поиск пользователей",
"Search for users and groups": "Поиск пользователей и групп",
"Search...": "Поиск...",
"Select language": "Выберите язык",
"Select role": "Выберите роль",
"Select role to assign to all invited members": "Выберите роль для всех приглашённых участников",
"Select theme": "Выберите тему",
"Send invitation": "Отправить приглашение",
"Invitation sent": "Приглашение отправлено",
"Settings": "Настройки",
"Setup workspace": "Настроить рабочую область",
"Sign In": "Вход",
"Sign Up": "Регистрация",
"Slug": "Slug",
"Space": "Пространство",
"Space description": "Описание пространства",
"Space menu": "Меню пространства",
"Space name": "Название пространства",
"Space settings": "Настройки пространства",
"Space slug": "Slug пространства",
"Spaces": "Пространства",
"Spaces you belong to": "Пространства, к которым вы принадлежите",
"No space found": "Пространства не найдены",
"Search for spaces": "Поиск пространств",
"Start typing to search...": "Начните вводить для поиска...",
"Status": "Статус",
"Successfully imported": "Успешно импортировано",
"Successfully restored": "Успешно восстановлено",
"System settings": "Системные настройки",
"Theme": "Тема",
"To change your email, you have to enter your password and new email.": "Чтобы изменить электронную почту, вам нужно ввести пароль и новый адрес.",
"Toggle full page width": "Переключить ширину на всю страницу",
"Unable to import pages. Please try again.": "Не удалось импортировать страницы. Пожалуйста, попробуйте ещё раз.",
"untitled": "без названия",
"Untitled": "Без названия",
"Updated successfully": "Обновлено успешно",
"User": "Пользователь",
"Workspace": "Рабочая область",
"Workspace Name": "Имя рабочей области",
"Workspace settings": "Настройки рабочей области",
"You can change your password here.": "Вы можете изменить свой пароль здесь.",
"Your Email": "Ваш адрес электронной почты",
"Your import is complete.": "Ваш импорт завершен.",
"Your name": "Ваше имя",
"Your Name": "Ваше Имя",
"Your password": "Ваш пароль",
"Your password must be a minimum of 8 characters.": "Ваш пароль должен содержать минимум 8 символов.",
"Sidebar toggle": "Переключить боковую панель",
"Comments": "Комментарии",
"404 page not found": "404 страница не найдена",
"Sorry, we can't find the page you are looking for.": "К сожалению, мы не можем найти страницу, которую вы ищете.",
"Take me back to homepage": "Вернуться на главную страницу",
"Forgot password": "Забыли пароль",
"Forgot your password?": "Забыли пароль?",
"A password reset link has been sent to your email. Please check your inbox.": "Ссылка для сброса пароля была отправлена на ваш электронный адрес. Пожалуйста, проверьте входящие сообщения.",
"Send reset link": "Отправить ссылку для сброса",
"Password reset": "Сброс пароля",
"Your new password": "Ваш новый пароль",
"Set password": "Установить пароль",
"Write a comment": "Написать комментарий",
"Reply...": "Ответить...",
"Error loading comments.": "Ошибка при загрузке комментариев.",
"No comments yet.": "Комментариев пока нет.",
"Edit comment": "Редактировать комментарий",
"Delete comment": "Удалить комментарий",
"Are you sure you want to delete this comment?": "Вы уверены, что хотите удалить этот комментарий?",
"Comment created successfully": "Комментарий успешно создан",
"Error creating comment": "Ошибка при создании комментария",
"Comment updated successfully": "Комментарий успешно обновлён",
"Failed to update comment": "Не удалось обновить комментарий",
"Comment deleted successfully": "Комментарий успешно удалён",
"Failed to delete comment": "Не удалось удалить комментарий",
"Comment resolved successfully": "Комментарий успешно разрешён",
"Comment re-opened successfully": "Комментарий успешно открыт заново",
"Comment unresolved successfully": "Комментарий успешно размечен как нерешённый",
"Failed to resolve comment": "Не удалось разрешить комментарий",
"Resolve comment": "Разрешить комментарий",
"Unresolve comment": "Отметить комментарий как нерешённый",
"Resolve 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 unresolve this comment thread?": "Вы уверены, что хотите отметить эту цепочку комментариев как нерешённую?",
"Resolved": "Решено",
"No active comments.": "Нет активных комментариев.",
"No resolved comments.": "Нет решённых комментариев.",
"Revoke invitation": "Отозвать приглашение",
"Revoke": "Отозвать",
"Don't": "Нет",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Вы уверены, что хотите отозвать это приглашение? Пользователь не сможет присоединиться к рабочей области.",
"Resend invitation": "Отправить приглашение повторно",
"Anyone with this link can join this workspace.": "Любой, у кого есть данная ссылка, может присоединиться к этой рабочей области.",
"Invite link": "Ссылка для приглашения",
"Copy": "Копировать",
"Copy to space": "Копировать в пространство",
"Copied": "Скопировано",
"Duplicate": "Дублировать",
"Select a user": "Выберите пользователя",
"Select a group": "Выберите группу",
"Export all pages and attachments in this space.": "Экспортировать все страницы и вложения в этом пространстве.",
"Delete space": "Удалить пространство",
"Are you sure you want to delete this space?": "Вы уверены, что хотите удалить это пространство?",
"Delete this space with all its pages and data.": "Удалить это пространство со всеми его страницами и данными.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Все страницы, комментарии, вложения и разрешения в этом пространстве будут удалены безвозвратно.",
"Confirm space name": "Подтвердите название пространства",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Введите название пространства <b>{{spaceName}}</b>, чтобы подтвердить ваше действие.",
"Format": "Формат",
"Include subpages": "Включить вложенные страницы",
"Include attachments": "Включить вложения",
"Select export format": "Выберите формат экспорта",
"Export failed:": "Экспортирование не удалось:",
"export error": "ошибка экспорта",
"Export page": "Экспорт страницы",
"Export space": "Экспорт пространства",
"Export {{type}}": "Экспорт {{type}}",
"File exceeds the {{limit}} attachment limit": "Файл превышает лимит вложений {{limit}}",
"Align left": "По левому краю",
"Align right": "По правому краю",
"Align center": "По центру",
"Justify": "По ширине",
"Merge cells": "Объединить ячейки",
"Split cell": "Разделить ячейку",
"Delete column": "Удалить столбец",
"Delete row": "Удалить строку",
"Add left column": "Добавить столбец слева",
"Add right column": "Добавить столбец справа",
"Add row above": "Добавить строку выше",
"Add row below": "Добавить строку ниже",
"Delete table": "Удалить таблицу",
"Info": "Информация",
"Success": "Успешно",
"Warning": "Предупреждение",
"Danger": "Важно",
"Mermaid diagram error:": "Ошибка диаграммы Mermaid:",
"Invalid Mermaid diagram": "Недопустимая диаграмма Mermaid",
"Double-click to edit Draw.io diagram": "Кликните дважды для редактирования диаграммы Draw.io",
"Exit": "Выйти",
"Save & Exit": "Сохранить и выйти",
"Double-click to edit Excalidraw diagram": "Кликните дважды для редактирования диаграммы Excalidraw",
"Paste link": "Вставить ссылку",
"Edit link": "Редактировать ссылку",
"Remove link": "Удалить ссылку",
"Add link": "Добавить ссылку",
"Please enter a valid url": "Пожалуйста, введите корректный url",
"Empty equation": "Пустое выражение",
"Invalid equation": "Недопустимое уравнение",
"Color": "Цвет",
"Text color": "Цвет текста",
"Default": "По умолчанию",
"Blue": "Синий",
"Green": "Зелёный",
"Purple": "Фиолетовый",
"Red": "Красный",
"Yellow": "Жёлтый",
"Orange": "Оранжевый",
"Pink": "Розовый",
"Gray": "Серый",
"Embed link": "Встроенная ссылка",
"Invalid {{provider}} embed link": "Неверная ссылка для встраивания {{provider}}",
"Embed {{provider}}": "Встроить {{provider}}",
"Enter {{provider}} link to embed": "Введите ссылку для встраивания {{provider}}",
"Bold": "Жирный",
"Italic": "Курсив",
"Underline": "Подчёркнутый",
"Strike": "Перечёркнутый",
"Code": "Код",
"Comment": "Комментарий",
"Text": "Текст",
"Heading 1": "Заголовок 1",
"Heading 2": "Заголовок 2",
"Heading 3": "Заголовок 3",
"To-do List": "Список дел",
"Bullet List": "Маркированный список",
"Numbered List": "Нумерованный список",
"Blockquote": "Блок цитирования",
"Just start typing with plain text.": "Просто начните печатать обычный текст.",
"Track tasks with a to-do list.": "Отследить задачи с помощью списка дел.",
"Big section heading.": "Большой заголовок раздела.",
"Medium section heading.": "Средний заголовок раздела.",
"Small section heading.": "Маленький заголовок раздела.",
"Create a simple bullet list.": "Создать простой маркированный список.",
"Create a list with numbering.": "Создать нумерованный список.",
"Create block quote.": "Создать блок цитирования.",
"Insert code snippet.": "Вставить фрагмент кода.",
"Insert horizontal rule divider": "Вставить горизонтальный разделитель",
"Upload any image from your device.": "Загрузить любое изображение с вашего устройства.",
"Upload any video from your device.": "Загрузить любое видео с вашего устройства.",
"Upload any file from your device.": "Загрузить любой файл с вашего устройства.",
"Table": "Таблица",
"Insert a table.": "Вставить таблицу.",
"Insert collapsible block.": "Вставить сворачиваемый блок.",
"Video": "Видео",
"Divider": "Разделитель",
"Quote": "Цитата",
"Image": "Изображение",
"File attachment": "Прикрепленный файл",
"Toggle block": "Сворачиваемый блок",
"Callout": "Выноска",
"Insert callout notice.": "Вставить выноску с сообщением.",
"Math inline": "Формула",
"Insert inline math equation.": "Вставить математическое выражение в строку.",
"Math block": "Блок формул",
"Insert math equation": "Вставить математическое выражение",
"Mermaid diagram": "Диаграмма Mermaid",
"Insert mermaid diagram": "Вставить диаграмму Mermaid",
"Insert and design Drawio diagrams": "Вставить и рисовать диаграммы Draw.io",
"Insert current date": "Вставить текущую дату",
"Draw and sketch excalidraw diagrams": "Вставить и рисовать диаграммы Excalidraw",
"Multiple": "Несколько",
"Heading {{level}}": "Заголовок {{level}}",
"Toggle title": "Переключить заголовок",
"Write anything. Enter \"/\" for commands": "Начните писать. Введите \"/\" для списка команд",
"Names do not match": "Названия не совпадают",
"Today, {{time}}": "Сегодня, {{time}}",
"Yesterday, {{time}}": "Вчера, {{time}}",
"Space created successfully": "Пространство успешно создано",
"Space updated successfully": "Пространство успешно обновлено",
"Space deleted successfully": "Пространство успешно удалено",
"Members added successfully": "Участники успешно добавлены",
"Member removed successfully": "Участник успешно удален",
"Member role updated successfully": "Роль участника успешно обновлена",
"Created by: <b>{{creatorName}}</b>": "Автор: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Дата создания: {{time}}",
"Edited by {{name}} {{time}}": "Изменено {{name}} {{time}}",
"Word count: {{wordCount}}": "Количество слов: {{wordCount}}",
"Character count: {{characterCount}}": "Количество символов: {{characterCount}}",
"New update": "Новое обновление",
"{{latestVersion}} is available": "Доступна новая версия {{latestVersion}}",
"Default page edit mode": "Режим редактирования страницы по умолчанию",
"Choose your preferred page edit mode. Avoid accidental edits.": "Выберите предпочитаемый режим редактирования страницы. Избегайте случайных изменений.",
"Reading": "Чтение",
"Delete member": "Удалить участника",
"Member deleted successfully": "Участник успешно удален",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Вы уверены, что хотите удалить этого участника рабочей области? Это действие необратимо.",
"Move": "Переместить",
"Move page": "Переместить страницу",
"Move page to a different space.": "Переместите страницу в другое пространство.",
"Real-time editor connection lost. Retrying...": "Соединение с редактором в реальном времени потеряно. Повторная попытка...",
"Table of contents": "Содержание",
"Add headings (H1, H2, H3) to generate a table of contents.": "Добавьте заголовки (H1, H2, H3), чтобы создать оглавление.",
"Share": "Поделиться",
"Public sharing": "Общий доступ",
"Shared by": "Поделился",
"Shared at": "Поделился в",
"Inherits public sharing from": "Наследует общий доступ от",
"Share to web": "Поделиться в интернете",
"Shared to web": "Размещено в интернете",
"Anyone with the link can view this page": "Любой, у кого есть ссылка, может просмотреть эту страницу",
"Make this page publicly accessible": "Сделать эту страницу общедоступной",
"Include sub-pages": "Включить подстраницы",
"Make sub-pages public too": "Сделать подстраницы также общедоступными",
"Allow search engines to index page": "Разрешить поисковым системам индексировать страницу",
"Open page": "Открыть страницу",
"Page": "Страница",
"Delete public share link": "Удалить ссылку на общий доступ",
"Delete share": "Удалить общий доступ",
"Are you sure you want to delete this shared link?": "Вы уверены, что хотите удалить эту ссылку общего доступа?",
"Publicly shared pages from spaces you are a member of will appear here": "Общие страницы из пространств, участником которых вы являетесь, появятся здесь",
"Share deleted successfully": "Общий доступ успешно удален",
"Share not found": "Общий доступ не найден",
"Failed to share page": "Не удалось поделиться страницей",
"Copy page": "Копировать страницу",
"Copy page to a different space.": "Копировать страницу в другое пространство.",
"Page copied successfully": "Страница успешно скопирована",
"Page duplicated successfully": "Страница успешно дублирована",
"Find": "Найти",
"Not found": "Не найдено",
"Previous Match (Shift+Enter)": "Предыдущее совпадение (Shift+Enter)",
"Next match (Enter)": "Следующее совпадение (Enter)",
"Match case (Alt+C)": "Учитывать регистр (Alt+C)",
"Replace": "Заменить",
"Close (Escape)": "Закрыть (Escape)",
"Replace (Enter)": "Заменить (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Заменить все (Ctrl+Alt+Enter)",
"Replace all": "Заменить все",
"View all spaces": "Просмотреть все пространства",
"Error": "Ошибка",
"Failed to disable MFA": "Не удалось отключить двухфакторную аутентификацию",
"Disable two-factor authentication": "Отключить двухфакторную аутентификацию",
"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:": "Пожалуйста, введите ваш пароль, чтобы отключить двухфакторную аутентификацию:",
"Two-factor authentication has been enabled": "Двухфакторная аутентификация включена",
"Two-factor authentication has been disabled": "Двухфакторная аутентификация отключена",
"2-step verification": "Двухэтапная проверка",
"Protect your account with an additional verification layer when signing in.": "Защитите свою учетную запись дополнительным уровнем проверки при входе.",
"Two-factor authentication is active on your account.": "Двухфакторная аутентификация активна на вашей учетной записи.",
"Add 2FA method": "Добавить метод 2FA",
"Backup codes": "Резервные коды",
"Disable": "Отключить",
"Invalid verification code": "Неверный код проверки",
"New backup codes have been generated": "Созданы новые резервные коды",
"Failed to regenerate 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.": "Резервные коды можно использовать для доступа к вашей учетной записи, если вы потеряли доступ к приложению-аутентификатору. Каждый код можно использовать только один раз.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Вы можете создать новые резервные коды в любое время. Это аннулирует все существующие коды.",
"Confirm password": "Подтвердите пароль",
"Generate 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.": "Убедитесь, что сохранили эти коды в безопасном месте. Ваши старые резервные коды больше недействительны.",
"Your new backup codes": "Ваши новые резервные коды",
"I've saved my backup codes": "Я сохранил(а) свои резервные коды",
"Failed to setup MFA": "Не удалось настроить многофакторную аутентификацию",
"Setup & Verify": "Настроить и проверить",
"Add to authenticator": "Добавить в аутентификатор",
"1. Scan this QR code with your authenticator app": "1. Отсканируйте этот QR-код с помощью вашего приложения-аутентификатора",
"Can't scan the code?": "Не удается сканировать код?",
"Enter this code manually in your authenticator app:": "Введите этот код вручную в приложении-аутентификаторе:",
"2. Enter the 6-digit code from your authenticator": "2. Введите 6-значный код из вашего аутентификатора",
"Verify and enable": "Проверить и включить",
"Failed to generate QR code. Please try again.": "Не удалось создать QR-код. Пожалуйста, попробуйте снова.",
"Backup": "Резервное копирование",
"Save 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.": "Эти коды можно использовать для доступа к вашей учетной записи, если вы потеряли доступ к приложению-аутентификатору. Каждый код можно использовать только один раз.",
"Print": "Печать",
"Two-factor authentication has been set up. Please log in again.": "Двухфакторная аутентификация настроена. Пожалуйста, войдите снова.",
"Two-Factor authentication required": "Требуется двухфакторная аутентификация",
"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.": "Чтобы продолжать доступ к вашему рабочему пространству, вы должны настроить двухфакторную аутентификацию. Это добавляет дополнительный уровень безопасности к вашей учетной записи.",
"Set up two-factor authentication": "Настройте двухфакторную аутентификацию",
"Cancel and logout": "Отменить и выйти",
"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.": "Это добавляет дополнительный уровень безопасности к вашей учетной записи, требуя код проверки из вашего приложения-аутентификатора.",
"Password is required": "Требуется пароль",
"Password must be at least 8 characters": "Пароль должен содержать как минимум 8 символов",
"Please enter a 6-digit code": "Пожалуйста, введите 6-значный код",
"Code must be exactly 6 digits": "Код должен содержать ровно 6 цифр",
"Enter the 6-digit code found in your authenticator app": "Введите 6-значный код из вашего приложения-аутентификатора",
"Need help authenticating?": "Нужна помощь с аутентификацией?",
"MFA QR Code": "QR-код двухфакторной аутентификации",
"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 to set up two-factor authentication.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем, чтобы настроить двухфакторную аутентификацию.",
"Password reset was successful. Please log in with your new password.": "Сброс пароля выполнен успешно. Пожалуйста, войдите с вашим новым паролем.",
"Two-factor authentication": "Двухфакторная аутентификация",
"Use authenticator app instead": "Используйте приложение-аутентификатор вместо этого",
"Verify backup code": "Проверка резервного кода",
"Use backup code": "Использовать резервный код",
"Enter one of your backup codes": "Введите один из ваших резервных кодов",
"Backup code": "Резервный код",
"Enter one of your backup codes. Each backup code can only be used once.": "Введите один из ваших резервных кодов. Каждый резервный код можно использовать только один раз.",
"Verify": "Проверить",
"Trash": "Корзина",
"Pages in trash will be permanently deleted after 30 days.": "Страницы в корзине будут окончательно удалены через 30 дней.",
"Deleted": "Удалено",
"No pages in trash": "В корзине нет страниц",
"Permanently delete page?": "Удалить страницу окончательно?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Вы уверены, что хотите окончательно удалить '{{title}}'? Это действие невозможно отменить.",
"Restore '{{title}}' and its sub-pages?": "Восстановить '{{title}}' и её подстраницы?",
"Move to trash": "Переместить в корзину",
"Move this page to trash?": "Переместить эту страницу в корзину?",
"Restore page": "Восстановить страницу",
"Page moved to trash": "Страница перемещена в корзину",
"Page restored successfully": "Страница успешно восстановлена",
"Deleted by": "Удалено пользователем",
"Deleted at": "Удалено в",
"Preview": "Предпросмотр",
"Subpages": "Подстраницы",
"Failed to load subpages": "Не удалось загрузить подстраницы",
"No subpages": "Нет подстраниц",
"Subpages (Child pages)": "Подстраницы (вложенные страницы)",
"List all subpages of the current page": "Показать все подстраницы текущей страницы",
"Attachments": "Вложения",
"All spaces": "Все пространства",
"Unknown": "Неизвестно",
"Find a space": "Найти пространство",
"Search in all your spaces": "Поиск во всех ваших пространствах",
"Type": "Тип",
"Enterprise": "Предприятие",
"Download attachment": "Скачать вложение",
"Allowed email domains": "Разрешенные домены электронной почты",
"Only users with email addresses from these domains can signup via SSO.": "Только пользователи с электронными адресами из этих доменов могут зарегистрироваться через SSO.",
"Enter valid domain names separated by comma or space": "Введите допустимые доменные имена, разделённые запятыми или пробелами",
"Enforce two-factor authentication": "Обязательная двухфакторная аутентификация",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "После введения обязательности все участники должны будут включить двухфакторную аутентификацию для доступа к рабочему пространству.",
"Toggle MFA enforcement": "Переключить обязательность MFA",
"Display name": "Отображаемое имя",
"Allow signup": "Разрешить регистрацию",
"Enabled": "Включено",
"Advanced Settings": "Расширенные настройки",
"Enable TLS/SSL": "Включить TLS/SSL",
"Use secure connection to LDAP server": "Использовать защищённое соединение с сервером LDAP",
"Group sync": "Синхронизация группы",
"No SSO providers found.": "Поставщики SSO не найдены.",
"Delete SSO provider": "Удалить поставщика SSO",
"Are you sure you want to delete this SSO provider?": "Вы уверены, что хотите удалить этого поставщика SSO?",
"Action": "Действие",
"{{ssoProviderType}} configuration": "Настройка {{ssoProviderType}}"
}

View File

@ -0,0 +1,531 @@
{
"Account": "Обліковий запис",
"Active": "Активний",
"Add": "Додати",
"Add group members": "Додати учасників групи",
"Add groups": "Додати групи",
"Add members": "Додати учасників",
"Add to groups": "Додати до груп",
"Add space members": "Додати учасників простору",
"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 page?": "Ви впевнені, що хочете видалити цю сторінку?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "Ви впевнені, що хочете видалити цього користувача з групи? Користувач втратить доступ до матеріалів, до яких ця група має доступ.",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "Ви впевнені, що хочете видалити цього користувача з простору? Користувач втратить весь доступ до цього простору.",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "Ви впевнені, що хочете відновити цю версію? Усі не збережені зміни будуть втрачені.",
"Can become members of groups and spaces in workspace": "Можуть ставати учасниками груп та просторів у робочій області",
"Can create and edit pages in space.": "Може створювати та редагувати сторінки в просторі.",
"Can edit": "Може редагувати",
"Can manage workspace": "Може керувати робочою областю",
"Can manage workspace but cannot delete it": "Може керувати робочою областю, але не може її видалити",
"Can view": "Може переглядати",
"Can view pages in space but not edit.": "Може переглядати сторінки в просторі, але не може їх редагувати.",
"Cancel": "Скасувати",
"Change email": "Змінити електронну пошту",
"Change password": "Змінити пароль",
"Change photo": "Змінити фото",
"Choose a role": "Оберіть роль",
"Choose your preferred color scheme.": "Оберіть бажану кольорову схему.",
"Choose your preferred interface language.": "Оберіть бажану мову інтерфейсу.",
"Choose your preferred page width.": "Оберіть бажану ширину сторінки.",
"Confirm": "Підтвердити",
"Copy link": "Копіювати посилання",
"Create": "Створити",
"Create group": "Створити групу",
"Create page": "Створити сторінку",
"Create space": "Створити простір",
"Create workspace": "Створити робочу область",
"Current password": "Поточний пароль",
"Dark": "Темна",
"Date": "Дата",
"Delete": "Видалити",
"Delete group": "Видалити групу",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "Ви впевнені, що хочете видалити цю сторінку? Це видалить її дочірні сторінки, а також історію сторінки. Ця дія необоротна.",
"Description": "Опис",
"Details": "Деталі",
"e.g ACME": "наприклад, ACME",
"e.g ACME Inc": "наприклад, ACME Inc",
"e.g Developers": "наприклад, Розробники",
"e.g Group for developers": "наприклад, Група для розробників",
"e.g product": "наприклад, продукт",
"e.g Product Team": "наприклад, Продуктова команда",
"e.g Sales": "наприклад, Продажі",
"e.g Space for product team": "наприклад, Простір для продуктової команди",
"e.g Space for sales team to collaborate": "наприклад, Простір для спільної роботи команди продажів",
"Edit": "Редагувати",
"Read": "Читати",
"Edit group": "Редагувати групу",
"Email": "Електронна пошта",
"Enter a strong password": "Введіть надійний пароль",
"Enter valid email addresses separated by comma or space max_50": "Введіть дійсні адреси електронної пошти, розділені комою або пробілом [макс: 50]",
"enter valid emails addresses": "введіть дійсні адреси електронної пошти",
"Enter your current password": "Введіть ваш поточний пароль",
"enter your full name": "введіть ваше повне ім'я",
"Enter your new password": "Введіть ваш новий пароль",
"Enter your new preferred email": "Введіть вашу нову бажану електронну пошту",
"Enter your password": "Введіть ваш пароль",
"Error fetching page data.": "Помилка при завантаженні даних сторінки.",
"Error loading page history.": "Помилка при завантаженні історії сторінки.",
"Export": "Експорт",
"Failed to create page": "Не вдалося створити сторінку",
"Failed to delete page": "Не вдалося видалити сторінку",
"Failed to fetch recent pages": "Не вдалося отримати нещодавні сторінки",
"Failed to import pages": "Не вдалося імпортувати сторінки",
"Failed to load page. An error occurred.": "Не вдалося завантажити сторінку. Сталася помилка.",
"Failed to update data": "Не вдалося оновити дані",
"Full access": "Повний доступ",
"Full page width": "Ширина на всю сторінку",
"Full width": "На всю ширину",
"General": "Загальні",
"Group": "Група",
"Group description": "Опис групи",
"Group name": "Назва групи",
"Groups": "Групи",
"Has full access to space settings and pages.": "Має повний доступ до налаштувань простору та сторінок.",
"Home": "Головна",
"Import pages": "Імпорт сторінок",
"Import pages & space settings": "Імпорт сторінок і налаштування простору",
"Importing pages": "Імпортування сторінок",
"invalid invitation link": "посилання на запрошення недійсне",
"Invitation signup": "Реєстрація за запрошенням",
"Invite by email": "Запросити електронною поштою",
"Invite members": "Запросити учасників",
"Invite new members": "Запросити нових учасників",
"Invited members who are yet to accept their invitation will appear here.": "Запрошені учасники, які ще не прийняли запрошення, з'являться тут.",
"Invited members will be granted access to spaces the groups can access": "Запрошені учасники отримають доступ до просторів, доступ до яких має група",
"Join the workspace": "Приєднатися до робочої області",
"Language": "Мова",
"Light": "Світла",
"Link copied": "Посилання скопійовано",
"Login": "Увійти",
"Logout": "Вийти",
"Manage Group": "Керування групою",
"Manage members": "Керування учасниками",
"member": "учасник",
"Member": "Учасник",
"members": "учасники",
"Members": "Учасники",
"My preferences": "Мої налаштування",
"My Profile": "Мій профіль",
"My profile": "Мій профіль",
"Name": "Ім'я",
"New email": "Нова електронна адреса",
"New page": "Нова сторінка",
"New password": "Новий пароль",
"No group found": "Групу не знайдено",
"No page history saved yet.": "Історія сторінок ще не збережена.",
"No pages yet": "Сторінок поки немає",
"No results found...": "Результати не знайдено...",
"No user found": "Користувача не знайдено",
"Overview": "Огляд",
"Owner": "Власник",
"page": "сторінка",
"Page deleted successfully": "Сторінку успішно видалено",
"Page history": "Історія сторінки",
"Page import is in progress. Please do not close this tab.": "Імпорт сторінки в процесі. Будь ласка, не закривайте цю вкладку.",
"Pages": "Сторінки",
"pages": "сторінки",
"Password": "Пароль",
"Password changed successfully": "Пароль успішно змінено",
"Pending": "В очікуванні",
"Please confirm your action": "Будь ласка, підтвердіть вашу дію",
"Preferences": "Налаштування",
"Print PDF": "Друк PDF",
"Profile": "Профіль",
"Recently updated": "Нещодавно оновлено",
"Remove": "Видалити",
"Remove group member": "Видалити учасника групи",
"Remove space member": "Видалити учасника простору",
"Restore": "Відновити",
"Role": "Роль",
"Save": "Зберегти",
"Search": "Пошук",
"Search for groups": "Пошук груп",
"Search for users": "Пошук користувачів",
"Search for users and groups": "Пошук користувачів та груп",
"Search...": "Пошук...",
"Select language": "Оберіть мову",
"Select role": "Оберіть роль",
"Select role to assign to all invited members": "Оберіть роль для всіх запрошених учасників",
"Select theme": "Оберіть тему",
"Send invitation": "Надіслати запрошення",
"Invitation sent": "Запрошення надіслано",
"Settings": "Налаштування",
"Setup workspace": "Налаштувати робочу область",
"Sign In": "Вхід",
"Sign Up": "Реєстрація",
"Slug": "Slug",
"Space": "Простір",
"Space description": "Опис простору",
"Space menu": "Меню простору",
"Space name": "Назва простору",
"Space settings": "Налаштування простору",
"Space slug": "Slug простору",
"Spaces": "Простори",
"Spaces you belong to": "Простори, до яких ви належите",
"No space found": "Простори не знайдено",
"Search for spaces": "Пошук просторів",
"Start typing to search...": "Почніть вводити для пошуку...",
"Status": "Статус",
"Successfully imported": "Успішно імпортовано",
"Successfully restored": "Успішно відновлено",
"System settings": "Системні налаштування",
"Theme": "Тема",
"To change your email, you have to enter your password and new email.": "Щоб змінити електронну пошту, вам потрібно ввести пароль і нову адресу.",
"Toggle full page width": "Перемкнути ширину на всю сторінку",
"Unable to import pages. Please try again.": "Не вдалося імпортувати сторінки. Будь ласка, спробуйте ще раз.",
"untitled": "без назви",
"Untitled": "Без назви",
"Updated successfully": "Оновлено успішно",
"User": "Користувач",
"Workspace": "Робоча область",
"Workspace Name": "Ім'я робочої області",
"Workspace settings": "Налаштування робочої області",
"You can change your password here.": "Ви можете змінити свій пароль тут.",
"Your Email": "Ваша електронна пошта",
"Your import is complete.": "Ваш імпорт завершено.",
"Your name": "Ваше ім'я",
"Your Name": "Ваше ім'я",
"Your password": "Ваш пароль",
"Your password must be a minimum of 8 characters.": "Ваш пароль повинен містити мінімум 8 символів.",
"Sidebar toggle": "Перемкнути бічну панель",
"Comments": "Коментарі",
"404 page not found": "404 сторінку не знайдено",
"Sorry, we can't find the page you are looking for.": "На жаль, ми не можемо знайти сторінку, яку ви шукаєте.",
"Take me back to homepage": "Повернутися на головну сторінку",
"Forgot password": "Забули пароль",
"Forgot your password?": "Забули пароль?",
"A password reset link has been sent to your email. Please check your inbox.": "Посилання для скидання пароля було надіслано на вашу електронну адресу. Будь ласка, перевірте вхідні повідомлення.",
"Send reset link": "Надіслати посилання для скидання",
"Password reset": "Скидання пароля",
"Your new password": "Ваш новий пароль",
"Set password": "Встановити пароль",
"Write a comment": "Написати коментар",
"Reply...": "Відповісти...",
"Error loading comments.": "Помилка при завантаженні коментарів.",
"No comments yet.": "Коментарів поки немає.",
"Edit comment": "Редагувати коментар",
"Delete comment": "Видалити коментар",
"Are you sure you want to delete this comment?": "Ви впевнені, що хочете видалити цей коментар?",
"Comment created successfully": "Коментар успішно створено",
"Error creating comment": "Помилка при створенні коментаря",
"Comment updated successfully": "Коментар успішно оновлено",
"Failed to update comment": "Не вдалося оновити коментар",
"Comment deleted successfully": "Коментар успішно видалено",
"Failed to delete comment": "Не вдалося видалити коментар",
"Comment resolved successfully": "Коментар успішно вирішено",
"Comment re-opened successfully": "Коментар успішно відкрито повторно",
"Comment unresolved successfully": "Коментар успішно розв'язано",
"Failed to resolve comment": "Не вдалося вирішити коментар",
"Resolve comment": "Вирішити коментар",
"Unresolve comment": "Розв'язати коментар",
"Resolve 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 unresolve this comment thread?": "Ви впевнені, що хочете розв'язати цей ланцюжок коментарів?",
"Resolved": "Вирішено",
"No active comments.": "Немає активних коментарів.",
"No resolved comments.": "Немає вирішених коментарів.",
"Revoke invitation": "Відкликати запрошення",
"Revoke": "Відкликати",
"Don't": "Ні",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "Ви впевнені, що хочете відкликати це запрошення? Користувач не зможе приєднатися до робочої області.",
"Resend invitation": "Надіслати запрошення повторно",
"Anyone with this link can join this workspace.": "Будь-хто, хто має це посилання, може приєднатися до цієї робочої області.",
"Invite link": "Посилання для запрошення",
"Copy": "Копіювати",
"Copy to space": "Скопіювати в простір",
"Copied": "Скопійовано",
"Duplicate": "Дублювати",
"Select a user": "Оберіть користувача",
"Select a group": "Оберіть групу",
"Export all pages and attachments in this space.": "Експортувати всі сторінки та вкладення в цьому просторі.",
"Delete space": "Видалити простір",
"Are you sure you want to delete this space?": "Ви впевнені, що хочете видалити цей простір?",
"Delete this space with all its pages and data.": "Видалити цей простір з усіма його сторінками та даними.",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "Усі сторінки, коментарі, вкладення та дозволи в цьому просторі будуть видалені безповоротно.",
"Confirm space name": "Підтвердіть назву простору",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "Введіть назву простору <b>{{spaceName}}</b>, щоб підтвердити вашу дію.",
"Format": "Формат",
"Include subpages": "Включити вкладені сторінки",
"Include attachments": "Включити вкладення",
"Select export format": "Виберіть формат експорту",
"Export failed:": "Експортування не вдалося:",
"export error": "помилка експорту",
"Export page": "Експорт сторінки",
"Export space": "Експорт простору",
"Export {{type}}": "Експорт {{type}}",
"File exceeds the {{limit}} attachment limit": "Файл перевищує ліміт вкладень {{limit}}",
"Align left": "По лівому краю",
"Align right": "По правому краю",
"Align center": "По центру",
"Justify": "По ширині",
"Merge cells": "Об'єднати комірки",
"Split cell": "Розділити комірку",
"Delete column": "Видалити стовпець",
"Delete row": "Видалити рядок",
"Add left column": "Додати стовпець ліворуч",
"Add right column": "Додати стовпець праворуч",
"Add row above": "Додати рядок вище",
"Add row below": "Додати рядок нижче",
"Delete table": "Видалити таблицю",
"Info": "Інформація",
"Success": "Успішно",
"Warning": "Попередження",
"Danger": "Важливо",
"Mermaid diagram error:": "Помилка діаграми Mermaid:",
"Invalid Mermaid diagram": "Неприпустима діаграма Mermaid",
"Double-click to edit Draw.io diagram": "Клацніть двічі для редагування діаграми Draw.io",
"Exit": "Вийти",
"Save & Exit": "Зберегти та вийти",
"Double-click to edit Excalidraw diagram": "Клацніть двічі для редагування діаграми Excalidraw",
"Paste link": "Вставити посилання",
"Edit link": "Редагувати посилання",
"Remove link": "Видалити посилання",
"Add link": "Додати посилання",
"Please enter a valid url": "Будь ласка, введіть коректний url",
"Empty equation": "Порожнє рівняння",
"Invalid equation": "Неприпустиме рівняння",
"Color": "Колір",
"Text color": "Колір тексту",
"Default": "За замовчуванням",
"Blue": "Синій",
"Green": "Зелений",
"Purple": "Фіолетовий",
"Red": "Червоний",
"Yellow": "Жовтий",
"Orange": "Помаранчевий",
"Pink": "Рожевий",
"Gray": "Сірий",
"Embed link": "Вбудоване посилання",
"Invalid {{provider}} embed link": "Невірне посилання для вбудовування {{provider}}",
"Embed {{provider}}": "Вбудувати {{provider}}",
"Enter {{provider}} link to embed": "Введіть посилання для вбудовування {{provider}}",
"Bold": "Жирний",
"Italic": "Курсив",
"Underline": "Підкреслений",
"Strike": "Закреслений",
"Code": "Код",
"Comment": "Коментар",
"Text": "Текст",
"Heading 1": "Заголовок 1",
"Heading 2": "Заголовок 2",
"Heading 3": "Заголовок 3",
"To-do List": "Список справ",
"Bullet List": "Маркований список",
"Numbered List": "Нумерований список",
"Blockquote": "Блок цитування",
"Just start typing with plain text.": "Просто почніть друкувати звичайний текст.",
"Track tasks with a to-do list.": "Відстежуйте завдання за допомогою списку справ.",
"Big section heading.": "Великий заголовок розділу.",
"Medium section heading.": "Середній заголовок розділу.",
"Small section heading.": "Малий заголовок розділу.",
"Create a simple bullet list.": "Створити простий маркований список.",
"Create a list with numbering.": "Створити нумерований список.",
"Create block quote.": "Створити блок цитування.",
"Insert code snippet.": "Вставити фрагмент коду.",
"Insert horizontal rule divider": "Вставити горизонтальний роздільник",
"Upload any image from your device.": "Завантажити будь-яке зображення з вашого пристрою.",
"Upload any video from your device.": "Завантажити будь-яке відео з вашого пристрою.",
"Upload any file from your device.": "Завантажити будь-який файл з вашого пристрою.",
"Table": "Таблиця",
"Insert a table.": "Вставити таблицю.",
"Insert collapsible block.": "Вставити блок, що згортається.",
"Video": "Відео",
"Divider": "Роздільник",
"Quote": "Цитата",
"Image": "Зображення",
"File attachment": "Прикріплений файл",
"Toggle block": "Блок, що згортається",
"Callout": "Виноска",
"Insert callout notice.": "Вставити виноску з повідомленням.",
"Math inline": "Формула",
"Insert inline math equation.": "Вставити математичне рівняння в рядок.",
"Math block": "Блок формул",
"Insert math equation": "Вставити математичне рівняння",
"Mermaid diagram": "Діаграма Mermaid",
"Insert mermaid diagram": "Вставити діаграму Mermaid",
"Insert and design Drawio diagrams": "Вставити та розробити діаграми Draw.io",
"Insert current date": "Вставити поточну дату",
"Draw and sketch excalidraw diagrams": "Вставити та малювати діаграми Excalidraw",
"Multiple": "Декілька",
"Heading {{level}}": "Заголовок {{level}}",
"Toggle title": "Перемкнути заголовок",
"Write anything. Enter \"/\" for commands": "Почніть писати. Введіть \"/\" для списку команд",
"Names do not match": "Назви не співпадають",
"Today, {{time}}": "Сьогодні, {{time}}",
"Yesterday, {{time}}": "Вчора, {{time}}",
"Space created successfully": "Простір успішно створено",
"Space updated successfully": "Простір успішно оновлено",
"Space deleted successfully": "Простір успішно видалено",
"Members added successfully": "Учасників успішно додано",
"Member removed successfully": "Учасника успішно видалено",
"Member role updated successfully": "Роль учасника успішно оновлено",
"Created by: <b>{{creatorName}}</b>": "Автор: <b>{{creatorName}}</b>",
"Created at: {{time}}": "Дата створення: {{time}}",
"Edited by {{name}} {{time}}": "Змінено {{name}} {{time}}",
"Word count: {{wordCount}}": "Кількість слів: {{wordCount}}",
"Character count: {{characterCount}}": "Кількість символів: {{characterCount}}",
"New update": "Нове оновлення",
"{{latestVersion}} is available": "Доступна нова версія {{latestVersion}}",
"Default page edit mode": "Режим редагування сторінки за замовчуванням",
"Choose your preferred page edit mode. Avoid accidental edits.": "Виберіть бажаний режим редагування сторінки. Уникайте випадкових редагувань.",
"Reading": "Читання",
"Delete member": "Видалити учасника",
"Member deleted successfully": "Учасника успішно видалено",
"Are you sure you want to delete this workspace member? This action is irreversible.": "Ви впевнені, що хочете видалити цього учасника робочої області? Ця дія незворотна.",
"Move": "Перемістити",
"Move page": "Перемістити сторінку",
"Move page to a different space.": "Перемістити сторінку в інший простір.",
"Real-time editor connection lost. Retrying...": "З'єднання з редактором у реальному часі втрачено. Повторна спроба...",
"Table of contents": "Зміст",
"Add headings (H1, H2, H3) to generate a table of contents.": "Додайте заголовки (H1, H2, H3), щоб створити зміст.",
"Share": "Поділитися",
"Public sharing": "Публічний доступ",
"Shared by": "Поділився",
"Shared at": "Поділився в",
"Inherits public sharing from": "Успадковує публічний доступ від",
"Share to web": "Поділитися в інтернеті",
"Shared to web": "Розміщено в інтернеті",
"Anyone with the link can view this page": "Будь-хто, хто має посилання, може переглянути цю сторінку",
"Make this page publicly accessible": "Зробити цю сторінку загальнодоступною",
"Include sub-pages": "Включити підсторінки",
"Make sub-pages public too": "Зробити підсторінки також загальнодоступними",
"Allow search engines to index page": "Дозволити пошуковим системам індексувати сторінку",
"Open page": "Відкрити сторінку",
"Page": "Сторінка",
"Delete public share link": "Видалити посилання на публічний доступ",
"Delete share": "Видалити спільний доступ",
"Are you sure you want to delete this shared link?": "Ви впевнені, що хочете видалити це посилання спільного доступу?",
"Publicly shared pages from spaces you are a member of will appear here": "Публічні сторінки з просторів, учасником яких ви є, з'являться тут",
"Share deleted successfully": "Спільний доступ успішно видалено",
"Share not found": "Спільний доступ не знайдено",
"Failed to share page": "Не вдалося поділитися сторінкою",
"Copy page": "Копіювати сторінки",
"Copy page to a different space.": "Скопіювати сторінку в інший простір.",
"Page copied successfully": "Сторінку успішно скопійовано",
"Page duplicated successfully": "Сторінку успішно дубльовано",
"Find": "Знайти",
"Not found": "Не знайдено",
"Previous Match (Shift+Enter)": "Попередній збіг (Shift+Enter)",
"Next match (Enter)": "Наступний збіг (Enter)",
"Match case (Alt+C)": "Враховувати регістр (Alt+C)",
"Replace": "Замінити",
"Close (Escape)": "Закрити (Escape)",
"Replace (Enter)": "Замінити (Enter)",
"Replace all (Ctrl+Alt+Enter)": "Замінити все (Ctrl+Alt+Enter)",
"Replace all": "Замінити все",
"View all spaces": "Переглянути всі простори",
"Error": "Помилка",
"Failed to disable MFA": "Не вдалося вимкнути MFA",
"Disable two-factor authentication": "Вимкнути двоетапну аутентифікацію",
"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:": "Будь ласка, введіть свій пароль, щоб вимкнути двоетапну аутентифікацію:",
"Two-factor authentication has been enabled": "Двоетапну аутентифікацію включено",
"Two-factor authentication has been disabled": "Двоетапну аутентифікацію вимкнено",
"2-step verification": "Двоетапна перевірка",
"Protect your account with an additional verification layer when signing in.": "Захистіть свій обліковий запис за допомогою додаткового шару перевірки при вході.",
"Two-factor authentication is active on your account.": "Двоетапну аутентифікацію активовано у вашому обліковому записі.",
"Add 2FA method": "Додати метод 2FA",
"Backup codes": "Резервні коди",
"Disable": "Вимкнути",
"Invalid verification code": "Невірний код перевірки",
"New backup codes have been generated": "Нові резервні коди створено",
"Failed to regenerate 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.": "Резервні коди можуть бути використані для доступу до вашого облікового запису, якщо ви втратите доступ до додатку аутентифікатора. Кожен код можна використовувати лише один раз.",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "Ви можете повторно створити нові резервні коди в будь-який час. Це зробить усі існуючі коди недійсними.",
"Confirm password": "Підтвердити пароль",
"Generate 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.": "Обов'язково збережіть ці коди у безпечному місці. Ваші старі резервні коди більше не дійсні.",
"Your new backup codes": "Ваші нові резервні коди",
"I've saved my backup codes": "Я зберіг резервні коди",
"Failed to setup MFA": "Не вдалося налаштувати MFA",
"Setup & Verify": "Налаштувати та перевірити",
"Add to authenticator": "Додати до аутентифікатора",
"1. Scan this QR code with your authenticator app": "1. Скануйте цей QR-код за допомогою додатку аутентифікатора",
"Can't scan the code?": "Не можете відсканувати код?",
"Enter this code manually in your authenticator app:": "Введіть цей код вручну у додатку аутентифікатора:",
"2. Enter the 6-digit code from your authenticator": "2. Введіть 6-значний код із аутентифікатора",
"Verify and enable": "Перевірити та увімкнути",
"Failed to generate QR code. Please try again.": "Не вдалося створити QR-код. Будь ласка, спробуйте ще раз.",
"Backup": "Резервне копіювання",
"Save 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.": "Ці коди можуть бути використані для доступу до вашого облікового запису, якщо ви втратите доступ до додатку аутентифікатора. Кожен код можна використовувати лише один раз.",
"Print": "Друкувати",
"Two-factor authentication has been set up. Please log in again.": "Двоетапну аутентифікацію налаштовано. Будь ласка, увійдіть знову.",
"Two-Factor authentication required": "Потрібна двоетапна аутентифікація",
"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.": "Щоб продовжити доступ до робочого простору, вам потрібно налаштувати двоетапну аутентифікацію. Це додає додатковий шар захисту до вашого облікового запису.",
"Set up two-factor authentication": "Налаштувати двоетапну аутентифікацію",
"Cancel and logout": "Скасувати та вийти",
"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.": "Це додає додатковий шар захисту до вашого облікового запису, вимагаючи код підтвердження з вашого додатку аутентифікатора.",
"Password is required": "Вимагається пароль",
"Password must be at least 8 characters": "Пароль повинен містити щонайменше 8 символів",
"Please enter a 6-digit code": "Будь ласка, введіть 6-значний код",
"Code must be exactly 6 digits": "Код повинен мати точно 6 цифр",
"Enter the 6-digit code found in your authenticator app": "Введіть 6-значний код з вашого додатку аутентифікатора",
"Need help authenticating?": "Потрібна допомога з аутентифікацією?",
"MFA QR Code": "MFA QR-код",
"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 to set up two-factor authentication.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю, щоб налаштувати двоетапну аутентифікацію.",
"Password reset was successful. Please log in with your new password.": "Скидання паролю успішне. Будь ласка, увійдіть за допомогою нового паролю.",
"Two-factor authentication": "Двоетапна аутентифікація",
"Use authenticator app instead": "Використовуйте додаток аутентифікатора замість цього",
"Verify backup code": "Перевірити резервний код",
"Use backup code": "Використовуйте резервний код",
"Enter one of your backup codes": "Введіть один з ваших резервних кодів",
"Backup code": "Резервний код",
"Enter one of your backup codes. Each backup code can only be used once.": "Введіть один з ваших резервних кодів. Кожен резервний код можна використовувати лише один раз.",
"Verify": "Перевірити",
"Trash": "Кошик",
"Pages in trash will be permanently deleted after 30 days.": "Сторінки у кошику будуть остаточно видалені через 30 днів.",
"Deleted": "Видалено",
"No pages in trash": "Немає сторінок у кошику",
"Permanently delete page?": "Остаточно видалити сторінку?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "Ви впевнені, що хочете остаточно видалити '{{title}}'? Цю дію не можна скасувати.",
"Restore '{{title}}' and its sub-pages?": "Відновити '{{title}}' та її підсторінки?",
"Move to trash": "Перемістити до кошика",
"Move this page to trash?": "Перемістити цю сторінку до кошика?",
"Restore page": "Відновити сторінку",
"Page moved to trash": "Сторінка переміщена до кошика",
"Page restored successfully": "Сторінку успішно відновлено",
"Deleted by": "Видалено",
"Deleted at": "Видалено о",
"Preview": "Попередній перегляд",
"Subpages": "Підсторінки",
"Failed to load subpages": "Не вдалося завантажити підсторінки",
"No subpages": "Немає підсторінок",
"Subpages (Child pages)": "Підсторінки (дочірні сторінки)",
"List all subpages of the current page": "Перелік всіх підсторінок поточної сторінки",
"Attachments": "Вкладення",
"All spaces": "Усі простори",
"Unknown": "Невідомо",
"Find a space": "Знайти простір",
"Search in all your spaces": "Шукати у всіх ваших просторах",
"Type": "Тип",
"Enterprise": "Підприємство",
"Download attachment": "Завантажити вкладення",
"Allowed email domains": "Дозволені домени електронної пошти",
"Only users with email addresses from these domains can signup via SSO.": "Лише користувачі з адресами електронної пошти з цих доменів можуть реєструватися через SSO.",
"Enter valid domain names separated by comma or space": "Введіть дійсні доменні імена, розділені комою або пробілом",
"Enforce two-factor authentication": "Вимагати двофакторну автентифікацію",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "Після увімкнення всі учасники повинні ввімкнути двофакторну автентифікацію для доступу до робочого простору.",
"Toggle MFA enforcement": "Перемикання вимоги MFA",
"Display name": "Відображуване ім'я",
"Allow signup": "Дозволити реєстрацію",
"Enabled": "Увімкнено",
"Advanced Settings": "Розширені налаштування",
"Enable TLS/SSL": "Увімкнути TLS/SSL",
"Use secure connection to LDAP server": "Використовувати захищене з'єднання з сервером LDAP",
"Group sync": "Синхронізація групи",
"No SSO providers found.": "Постачальників SSO не знайдено.",
"Delete SSO provider": "Видалити постачальника SSO",
"Are you sure you want to delete this SSO provider?": "Ви впевнені, що хочете видалити цього постачальника SSO?",
"Action": "Дія",
"{{ssoProviderType}} configuration": "Конфігурація {{ssoProviderType}}"
}

View File

@ -0,0 +1,531 @@
{
"Account": "账户",
"Active": "活跃",
"Add": "添加",
"Add group members": "添加群组成员",
"Add groups": "添加群组",
"Add members": "添加成员",
"Add to groups": "添加到群组",
"Add space members": "添加空间成员",
"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 page?": "您确定要删除这个页面吗?",
"Are you sure you want to remove this user from the group? The user will lose access to resources this group has access to.": "您确定要从群组中移除这个用户吗?该用户将失去对该群组可访问资源的访问权限。",
"Are you sure you want to remove this user from the space? The user will lose all access to this space.": "您确定要从空间中移除这个用户吗?该用户将失去对这个空间的所有访问权限。",
"Are you sure you want to restore this version? Any changes not versioned will be lost.": "您确定要恢复此版本吗?任何未版本化的更改将会丢失。",
"Can become members of groups and spaces in workspace": "可以成为工作区中群组和空间的成员",
"Can create and edit pages in space.": "能够在空间中创建和编辑页面",
"Can edit": "可以编辑",
"Can manage workspace": "可以管理工作区",
"Can manage workspace but cannot delete it": "可以管理工作区但不能删除它",
"Can view": "可以查看",
"Can view pages in space but not edit.": "能够在空间中读取页面,但不允许编辑",
"Cancel": "取消",
"Change email": "更改电子邮箱",
"Change password": "更改密码",
"Change photo": "更改照片",
"Choose a role": "选择一个角色",
"Choose your preferred color scheme.": "选择您喜欢的配色方案。",
"Choose your preferred interface language.": "选择您喜欢的界面语言。",
"Choose your preferred page width.": "选择您喜欢的页面宽度。",
"Confirm": "确认",
"Copy link": "复制链接",
"Create": "创建",
"Create group": "创建群组",
"Create page": "创建页面",
"Create space": "创建空间",
"Create workspace": "创建工作空间",
"Current password": "当前密码",
"Dark": "深色",
"Date": "日期",
"Delete": "删除",
"Delete group": "删除群组",
"Are you sure you want to delete this page? This will delete its children and page history. This action is irreversible.": "您确定要删除这个页面吗?这将删除其子页面和页面历史记录。此操作不可逆。",
"Description": "描述",
"Details": "详情",
"e.g ACME": "例如ACME",
"e.g ACME Inc": "例如ACME Inc",
"e.g Developers": "例如:开发人员",
"e.g Group for developers": "例如:开发人员群组",
"e.g product": "例如product",
"e.g Product Team": "例如:产品团队",
"e.g Sales": "例如:销售",
"e.g Space for product team": "例如:产品团队的空间",
"e.g Space for sales team to collaborate": "例如:销售团队协作的空间",
"Edit": "编辑",
"Read": "阅读",
"Edit group": "编辑群组",
"Email": "电子邮箱",
"Enter a strong password": "输入一个强密码",
"Enter valid email addresses separated by comma or space max_50": "输入有效的电子邮箱地址,用逗号或空格分隔 [最多50个]",
"enter valid emails addresses": "输入有效的电子邮箱地址",
"Enter your current password": "输入您的当前密码",
"enter your full name": "输入您的全名",
"Enter your new password": "输入您的新密码",
"Enter your new preferred email": "输入您新的首选电子邮箱",
"Enter your password": "输入您的密码",
"Error fetching page data.": "获取页面数据时出错。",
"Error loading page history.": "加载页面历史时出错。",
"Export": "导出",
"Failed to create page": "创建页面失败",
"Failed to delete page": "删除页面失败",
"Failed to fetch recent pages": "获取最近页面失败",
"Failed to import pages": "导入页面失败",
"Failed to load page. An error occurred.": "页面加载失败。发生了一个错误。",
"Failed to update data": "数据更新失败",
"Full access": "完全访问",
"Full page width": "全页宽度",
"Full width": "全宽",
"General": "常规",
"Group": "群组",
"Group description": "群组描述",
"Group name": "群组名称",
"Groups": "群组",
"Has full access to space settings and pages.": "能够更改全部空间设置和页面",
"Home": "首页",
"Import pages": "导入页面",
"Import pages & space settings": "导入页面和空间设置",
"Importing pages": "正在导入页面",
"invalid invitation link": "无效的邀请链接",
"Invitation signup": "邀请注册",
"Invite by email": "通过电子邮箱邀请",
"Invite members": "邀请成员",
"Invite new members": "邀请新成员",
"Invited members who are yet to accept their invitation will appear here.": "尚未接受邀请的成员将显示在这里。",
"Invited members will be granted access to spaces the groups can access": "被邀请的成员将被授予访问群组可以访问的空间的权限",
"Join the workspace": "加入工作空间",
"Language": "语言",
"Light": "浅色",
"Link copied": "链接已复制",
"Login": "登录",
"Logout": "退出登录",
"Manage Group": "管理群组",
"Manage members": "管理成员",
"member": "成员",
"Member": "成员",
"members": "成员",
"Members": "成员",
"My preferences": "我的偏好设置",
"My Profile": "我的个人资料",
"My profile": "我的个人资料",
"Name": "名称",
"New email": "新电子邮箱",
"New page": "新建页面",
"New password": "新密码",
"No group found": "未找到群组",
"No page history saved yet.": "尚未保存页面历史。",
"No pages yet": "暂无页面",
"No results found...": "未找到结果...",
"No user found": "未找到用户",
"Overview": "概览",
"Owner": "所有者",
"page": "个页面",
"Page deleted successfully": "页面已成功删除",
"Page history": "页面历史",
"Page import is in progress. Please do not close this tab.": "页面导入正在进行中。请不要关闭此标签页。",
"Pages": "页面",
"pages": "个页面",
"Password": "密码",
"Password changed successfully": "密码更改成功",
"Pending": "待定",
"Please confirm your action": "请确认您的操作",
"Preferences": "偏好设置",
"Print PDF": "打印 PDF",
"Profile": "个人资料",
"Recently updated": "最近更新",
"Remove": "移除",
"Remove group member": "移除群组成员",
"Remove space member": "移除空间成员",
"Restore": "恢复",
"Role": "角色",
"Save": "保存",
"Search": "搜索",
"Search for groups": "搜索群组",
"Search for users": "搜索用户",
"Search for users and groups": "搜索用户和群组",
"Search...": "搜索...",
"Select language": "选择语言",
"Select role": "选择角色",
"Select role to assign to all invited members": "选择要分配给所有被邀请成员的角色",
"Select theme": "选择主题",
"Send invitation": "发送邀请",
"Invitation sent": "邀请邮件已发送",
"Settings": "设置",
"Setup workspace": "设置工作空间",
"Sign In": "登录",
"Sign Up": "注册",
"Slug": "短链接",
"Space": "空间",
"Space description": "空间描述",
"Space menu": "空间菜单",
"Space name": "空间名称",
"Space settings": "空间设置",
"Space slug": "空间短链接",
"Spaces": "空间",
"Spaces you belong to": "您所属的空间",
"No space found": "未找到空间",
"Search for spaces": "搜索空间",
"Start typing to search...": "开始输入以搜索...",
"Status": "状态",
"Successfully imported": "成功导入",
"Successfully restored": "恢复成功",
"System settings": "系统设置",
"Theme": "主题",
"To change your email, you have to enter your password and new email.": "要更改您的电子邮箱,您需要输入密码和新的电子邮箱地址。",
"Toggle full page width": "切换全页宽度",
"Unable to import pages. Please try again.": "无法导入页面。请重试。",
"untitled": "无标题",
"Untitled": "无标题",
"Updated successfully": "更新成功",
"User": "用户",
"Workspace": "工作区",
"Workspace Name": "工作空间名称",
"Workspace settings": "工作区设置",
"You can change your password here.": "您可以在这里更改密码。",
"Your Email": "您的电子邮箱",
"Your import is complete.": "导入已完成。",
"Your name": "您的姓名",
"Your Name": "您的姓名",
"Your password": "您的密码",
"Your password must be a minimum of 8 characters.": "您的密码必须至少包含8个字符。",
"Sidebar toggle": "切换侧边栏",
"Comments": "评论",
"404 page not found": "404 页面未找到",
"Sorry, we can't find the page you are looking for.": "抱歉,我们无法找到你所需要的页面",
"Take me back to homepage": "回到主页",
"Forgot password": "忘记密码",
"Forgot your password?": "忘记密码了吗?",
"A password reset link has been sent to your email. Please check your inbox.": "密码重置链接已经发送到您的邮箱,请检查收件箱",
"Send reset link": "发送重置链接",
"Password reset": "重置密码",
"Your new password": "您的新密码",
"Set password": "设置密码",
"Write a comment": "编写评论",
"Reply...": "回复...",
"Error loading comments.": "加载评论时出错",
"No comments yet.": "目前还没有评论",
"Edit comment": "编辑评论",
"Delete comment": "删除评论",
"Are you sure you want to delete this comment?": "你确定要删除这条评论吗?",
"Comment created successfully": "成功创建评论",
"Error creating comment": "创建评论时出错",
"Comment updated successfully": "评论更新成功",
"Failed to update comment": "更新评论失败",
"Comment deleted successfully": "成功删除评论",
"Failed to delete comment": "删除评论失败",
"Comment resolved successfully": "成功标记评论为解决",
"Comment re-opened successfully": "成功重新打开评论",
"Comment unresolved successfully": "成功标记评论为未解决",
"Failed to resolve comment": "标记评论为解决失败",
"Resolve comment": "解决评论",
"Unresolve comment": "取消解决评论",
"Resolve 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 unresolve this comment thread?": "确定要取消解决此评论线程吗?",
"Resolved": "已解决",
"No active comments.": "没有活跃的评论。",
"No resolved comments.": "没有已解决的评论。",
"Revoke invitation": "撤回邀请",
"Revoke": "撤销",
"Don't": "不要",
"Are you sure you want to revoke this invitation? The user will not be able to join the workspace.": "你确定要撤回这个邀请吗?此用户将不能再加入此工作空间。",
"Resend invitation": "重新发送邀请",
"Anyone with this link can join this workspace.": "任何拥有此连接的人都可以加入此工作区",
"Invite link": "邀请链接",
"Copy": "复制",
"Copy to space": "复制到空间",
"Copied": "已复制",
"Duplicate": "重复",
"Select a user": "选择一个用户",
"Select a group": "选择一个组",
"Export all pages and attachments in this space.": "导出当前空间的所有页面和附件",
"Delete space": "删除空间",
"Are you sure you want to delete this space?": "您确定要删除这个空间吗?",
"Delete this space with all its pages and data.": "删除空间及其所有页面和数据",
"All pages, comments, attachments and permissions in this space will be deleted irreversibly.": "此空间中的所有页面、评论、附件和权限将被不可逆转地删除。",
"Confirm space name": "确认空间名称",
"Type the space name <b>{{spaceName}}</b> to confirm your action.": "输入空间名称<b>{{spaceName}}</b>以确认您的操作。",
"Format": "格式",
"Include subpages": "包括子页面",
"Include attachments": "包括附件",
"Select export format": "选择导出格式",
"Export failed:": "导出失败:",
"export error": "导出出错",
"Export page": "导出页面",
"Export space": "导出空间",
"Export {{type}}": "导出为 {{type}}",
"File exceeds the {{limit}} attachment limit": "文件超出了 {{limit}} 类型附件限制",
"Align left": "靠左对齐",
"Align right": "靠右对齐",
"Align center": "居中对齐",
"Justify": "两端对齐",
"Merge cells": "合并单元格",
"Split cell": "分割单元格",
"Delete column": "删除整列",
"Delete row": "删除整行",
"Add left column": "在左侧添加列",
"Add right column": "在右侧添加列",
"Add row above": "在上方添加行",
"Add row below": "在下方插入行",
"Delete table": "删除表格",
"Info": "信息",
"Success": "成功",
"Warning": "警告",
"Danger": "危险",
"Mermaid diagram error:": "Mermaid 图表错误:",
"Invalid Mermaid diagram": "无效的 Mermaid 图表",
"Double-click to edit Draw.io diagram": "双击以编辑 Draw.io 图表",
"Exit": "退出",
"Save & Exit": "保存并退出",
"Double-click to edit Excalidraw diagram": "双击以编辑 Excalidraw 图表",
"Paste link": "粘贴链接",
"Edit link": "编辑链接",
"Remove link": "移除链接",
"Add link": "添加链接",
"Please enter a valid url": "请输入一个合法的 URL",
"Empty equation": "空白公式",
"Invalid equation": "无效的公式",
"Color": "颜色",
"Text color": "文字颜色",
"Default": "默认",
"Blue": "蓝色",
"Green": "绿色",
"Purple": "紫色",
"Red": "红色",
"Yellow": "黄色",
"Orange": "橙色",
"Pink": "粉色",
"Gray": "灰色",
"Embed link": "嵌入链接",
"Invalid {{provider}} embed link": "无效的 {{provider}} 嵌入链接",
"Embed {{provider}}": "嵌入 {{provider}}",
"Enter {{provider}} link to embed": "输入 {{provider}} 链接来嵌入",
"Bold": "粗体",
"Italic": "斜体",
"Underline": "下划线",
"Strike": "删除线",
"Code": "代码",
"Comment": "评论",
"Text": "文字",
"Heading 1": "1 级标题",
"Heading 2": "2 级标题",
"Heading 3": "3 级标题",
"To-do List": "代办列表",
"Bullet List": "无序列表",
"Numbered List": "有序列表",
"Blockquote": "引用块",
"Just start typing with plain text.": "只需开始键入纯文本",
"Track tasks with a to-do list.": "使用代办列表跟踪任务",
"Big section heading.": "大标题",
"Medium section heading.": "中标题",
"Small section heading.": "小标题",
"Create a simple bullet list.": "创建一个简单的无序列表",
"Create a list with numbering.": "创建一个有序列表",
"Create block quote.": "创建引用块",
"Insert code snippet.": "插入代码片段",
"Insert horizontal rule divider": "插入水平分割线",
"Upload any image from your device.": "从设备上传任何图像",
"Upload any video from your device.": "从设备上传任何视频",
"Upload any file from your device.": "从设备上传任何文件",
"Table": "表格",
"Insert a table.": "插入一个表格",
"Insert collapsible block.": "插入一个折叠块",
"Video": "视频",
"Divider": "分割线",
"Quote": "引用",
"Image": "图像",
"File attachment": "文件附件",
"Toggle block": "切换块",
"Callout": "标注块",
"Insert callout notice.": "插入标注提示块",
"Math inline": "行内公式",
"Insert inline math equation.": "插入行内公式",
"Math block": "公式块",
"Insert math equation": "插入数学公式",
"Mermaid diagram": "Mermaid 图表",
"Insert mermaid diagram": "插入 Mermaid 图表",
"Insert and design Drawio diagrams": "插入并设计 Draw.io 图表",
"Insert current date": "插入当前日期",
"Draw and sketch excalidraw diagrams": "绘制 Excalidraw 图表",
"Multiple": "多个",
"Heading {{level}}": "{{level}} 级标题",
"Toggle title": "切换标题",
"Write anything. Enter \"/\" for commands": "开始编写内容,输入 \"/\" 以使用指令",
"Names do not match": "名称不匹配",
"Today, {{time}}": "今天,{{time}}",
"Yesterday, {{time}}": "昨天,{{time}}",
"Space created successfully": "空间创建成功",
"Space updated successfully": "空间更新成功",
"Space deleted successfully": "空间已成功删除",
"Members added successfully": "成员添加成功",
"Member removed successfully": "成员移除成功",
"Member role updated successfully": "成员角色更新成功",
"Created by: <b>{{creatorName}}</b>": "创建者:<b>{{creatorName}}</b>",
"Created at: {{time}}": "创建于:{{time}}",
"Edited by {{name}} {{time}}": "由{{name}} 编辑于 {{time}}",
"Word count: {{wordCount}}": "字数:{{wordCount}}",
"Character count: {{characterCount}}": "字符数:{{characterCount}}",
"New update": "新更新",
"{{latestVersion}} is available": "{{latestVersion}} 已经可以使用",
"Default page edit mode": "默认页面编辑模式",
"Choose your preferred page edit mode. Avoid accidental edits.": "选择您偏好的页面编辑模式。避免意外编辑。",
"Reading": "阅读",
"Delete member": "删除成员",
"Member deleted successfully": "成员删除成功",
"Are you sure you want to delete this workspace member? This action is irreversible.": "您确定要删除此工作区成员吗?此操作不可逆。",
"Move": "移动",
"Move page": "移动页面",
"Move page to a different space.": "将页面移动到不同的空间。",
"Real-time editor connection lost. Retrying...": "实时编辑器连接丢失。重试中……",
"Table of contents": "目录",
"Add headings (H1, H2, H3) to generate a table of contents.": "添加标题H1H2H3以生成目录。",
"Share": "分享",
"Public sharing": "公开分享",
"Shared by": "分享者",
"Shared at": "分享时间",
"Inherits public sharing from": "继承自的公开分享",
"Share to web": "分享到网页",
"Shared to web": "已分享到网页",
"Anyone with the link can view this page": "任何有链接的人都可以查看此页面",
"Make this page publicly accessible": "使此页面可公开访问",
"Include sub-pages": "包括子页面",
"Make sub-pages public too": "将子页面也设为公开",
"Allow search engines to index page": "允许搜索引擎索引页面",
"Open page": "打开页面",
"Page": "页面",
"Delete public share link": "删除公开分享链接",
"Delete share": "删除分享",
"Are you sure you want to delete this shared link?": "您确定要删除此分享链接吗?",
"Publicly shared pages from spaces you are a member of will appear here": "您所在空间的公开共享页面会显示在此处",
"Share deleted successfully": "分享已成功删除",
"Share not found": "未找到分享",
"Failed to share page": "页面分享失败",
"Copy page": "复制页面",
"Copy page to a different space.": "将页面复制到不同的空间。",
"Page copied successfully": "页面复制成功",
"Page duplicated successfully": "页面复制成功",
"Find": "查找",
"Not found": "未找到",
"Previous Match (Shift+Enter)": "上一个匹配 (Shift+Enter)",
"Next match (Enter)": "下一个匹配 (Enter)",
"Match case (Alt+C)": "区分大小写 (Alt+C)",
"Replace": "替换",
"Close (Escape)": "关闭 (Escape)",
"Replace (Enter)": "替换 (Enter)",
"Replace all (Ctrl+Alt+Enter)": "全部替换 (Ctrl+Alt+Enter)",
"Replace all": "全部替换",
"View all spaces": "查看所有空间",
"Error": "错误",
"Failed to disable MFA": "停用 MFA 失败",
"Disable two-factor authentication": "停用双因素认证",
"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:": "请输入您的密码以停用双因素认证:",
"Two-factor authentication has been enabled": "双因素认证已启用",
"Two-factor authentication has been disabled": "双因素认证已停用",
"2-step verification": "两步验证",
"Protect your account with an additional verification layer when signing in.": "通过额外的验证层保护您的账户安全。",
"Two-factor authentication is active on your account.": "您的账户已激活双因素认证。",
"Add 2FA method": "添加 2FA 方法",
"Backup codes": "备份代码",
"Disable": "停用",
"Invalid verification code": "无效的验证码",
"New backup codes have been generated": "已生成新的备份代码",
"Failed to regenerate 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.": "如果您无法访问身份验证器应用,可使用备份代码访问账户。每个代码仅可使用一次。",
"You can regenerate new backup codes at any time. This will invalidate all existing codes.": "您可以随时重新生成新的备份代码。这将使所有现有代码失效。",
"Confirm password": "确认密码",
"Generate 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.": "请确保将这些代码保存在安全的地方。您的旧备份代码不再有效。",
"Your new backup codes": "您的新备份代码",
"I've saved my backup codes": "我已经保存了我的备份代码",
"Failed to setup MFA": "设置 MFA 失败",
"Setup & Verify": "设置并验证",
"Add to authenticator": "添加到身份验证器",
"1. Scan this QR code with your authenticator app": "1. 用身份验证器应用扫描此二维码",
"Can't scan the code?": "无法扫描代码?",
"Enter this code manually in your authenticator app:": "在您的身份验证器应用中手动输入此代码:",
"2. Enter the 6-digit code from your authenticator": "2. 输入来自身份验证器的6位代码",
"Verify and enable": "验证并启用",
"Failed to generate QR code. Please try again.": "生成二维码失败。请重试。",
"Backup": "备份",
"Save 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.": "如果无法访问身份验证器应用,可以使用这些代码访问账户。每个代码仅可使用一次。",
"Print": "打印",
"Two-factor authentication has been set up. Please log in again.": "双因素认证已设置。请重新登录。",
"Two-Factor authentication required": "需要双因素认证",
"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.": "要继续访问工作区,必须设置双因素认证。此操作为您的账户添加一层额外的安全保障。",
"Set up two-factor authentication": "设置双因素认证",
"Cancel and logout": "取消并退出登录",
"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.": "通过要求您的身份验证器应用提供验证码,此操作为您的账户增加了一层额外的安全保障。",
"Password is required": "需要密码",
"Password must be at least 8 characters": "密码必须至少包含8个字符",
"Please enter a 6-digit code": "请输入6位代码",
"Code must be exactly 6 digits": "代码必须正好是6位",
"Enter the 6-digit code found in your authenticator app": "输入在您的身份验证器应用中找到的6位代码",
"Need help authenticating?": "需要帮助进行身份验证吗?",
"MFA QR Code": "MFA二维码",
"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 to set up two-factor authentication.": "密码重置成功。请使用新密码登录以设置双因素认证。",
"Password reset was successful. Please log in with your new password.": "密码重置成功。请使用新密码登录。",
"Two-factor authentication": "双因素认证",
"Use authenticator app instead": "改用身份验证器应用",
"Verify backup code": "验证备份代码",
"Use backup code": "使用备份代码",
"Enter one of your backup codes": "输入您的一个备份代码",
"Backup code": "备份代码",
"Enter one of your backup codes. Each backup code can only be used once.": "输入您的一个备份代码。每个备份代码只能使用一次。",
"Verify": "验证",
"Trash": "垃圾箱",
"Pages in trash will be permanently deleted after 30 days.": "垃圾箱中的页面将在30天后被永久删除。",
"Deleted": "已删除",
"No pages in trash": "垃圾箱中没有页面",
"Permanently delete page?": "永久删除页面?",
"Are you sure you want to permanently delete '{{title}}'? This action cannot be undone.": "确定要永久删除“{{title}}”吗?此操作无法撤销。",
"Restore '{{title}}' and its sub-pages?": "恢复“{{title}}”及其子页面?",
"Move to trash": "移至垃圾箱",
"Move this page to trash?": "将此页面移至垃圾箱?",
"Restore page": "恢复页面",
"Page moved to trash": "页面已移至垃圾箱",
"Page restored successfully": "页面恢复成功",
"Deleted by": "删除人",
"Deleted at": "删除时间",
"Preview": "预览",
"Subpages": "子页面",
"Failed to load subpages": "加载子页面失败",
"No subpages": "没有子页面",
"Subpages (Child pages)": "子页面(子页面)",
"List all subpages of the current page": "列出当前页面的所有子页面",
"Attachments": "附件",
"All spaces": "所有空间",
"Unknown": "未知",
"Find a space": "查找空间",
"Search in all your spaces": "在您的所有空间中搜索",
"Type": "类型",
"Enterprise": "企业",
"Download attachment": "下载附件",
"Allowed email domains": "允许的电子邮件域",
"Only users with email addresses from these domains can signup via SSO.": "只有来自这些域的电子邮件地址的用户才能通过SSO注册。",
"Enter valid domain names separated by comma or space": "输入用逗号或空格分隔的有效域名",
"Enforce two-factor authentication": "强制实施双因素认证",
"Once enforced, all members must enable two-factor authentication to access the workspace.": "一旦实施,所有成员必须启用双因素认证才能访问工作区。",
"Toggle MFA enforcement": "切换多因素认证实施",
"Display name": "显示名称",
"Allow signup": "允许注册",
"Enabled": "已启用",
"Advanced Settings": "高级设置",
"Enable TLS/SSL": "启用TLS/SSL",
"Use secure connection to LDAP server": "使用安全连接到LDAP服务器",
"Group sync": "组同步",
"No SSO providers found.": "未找到SSO提供商。",
"Delete SSO provider": "删除SSO提供商",
"Are you sure you want to delete this SSO provider?": "您确定要删除此SSO提供商吗",
"Action": "操作",
"{{ssoProviderType}} configuration": "{{ssoProviderType}} 配置"
}

View File

@ -0,0 +1,30 @@
{
"name": "Docmost",
"short_name": "Docmost",
"start_url": "/",
"display": "standalone",
"background_color": "#222",
"theme_color": "#222",
"icons": [
{
"src": "icons/favicon-16x16.png",
"type": "image/png",
"sizes": "16x16"
},
{
"src": "icons/favicon-32x32.png",
"type": "image/png",
"sizes": "32x32"
},
{
"src": "icons/app-icon-192x192.png",
"type": "image/png",
"sizes": "180x180 192x192"
},
{
"src": "icons/app-icon-512x512.png",
"type": "image/png",
"sizes": "512x512"
}
]
}

View File

@ -10,51 +10,38 @@ import Groups from "@/pages/settings/group/groups";
import GroupInfo from "./pages/settings/group/group-info";
import Spaces from "@/pages/settings/space/spaces.tsx";
import { Error404 } from "@/components/ui/error-404.tsx";
import { useQuerySubscription } from "@/features/websocket/use-query-subscription.ts";
import { useAtom, useAtomValue } from "jotai";
import { socketAtom } from "@/features/websocket/atoms/socket-atom.ts";
import { useTreeSocket } from "@/features/websocket/use-tree-socket.ts";
import { useEffect } from "react";
import { io } from "socket.io-client";
import { authTokensAtom } from "@/features/auth/atoms/auth-tokens-atom.ts";
import { SOCKET_URL } from "@/features/websocket/types";
import AccountPreferences from "@/pages/settings/account/account-preferences.tsx";
import SpaceHome from "@/pages/space/space-home.tsx";
import PageRedirect from "@/pages/page/page-redirect.tsx";
import Layout from "@/components/layouts/global/layout.tsx";
import { ErrorBoundary } from "react-error-boundary";
import InviteSignup from "@/pages/auth/invite-signup.tsx";
import ForgotPassword from "@/pages/auth/forgot-password.tsx";
import PasswordReset from "./pages/auth/password-reset";
import Billing from "@/ee/billing/pages/billing.tsx";
import CloudLogin from "@/ee/pages/cloud-login.tsx";
import CreateWorkspace from "@/ee/pages/create-workspace.tsx";
import { isCloud } from "@/lib/config.ts";
import { useTranslation } from "react-i18next";
import Security from "@/ee/security/pages/security.tsx";
import License from "@/ee/licence/pages/license.tsx";
import { useRedirectToCloudSelect } from "@/ee/hooks/use-redirect-to-cloud-select.tsx";
import SharedPage from "@/pages/share/shared-page.tsx";
import Shares from "@/pages/settings/shares/shares.tsx";
import ShareLayout from "@/features/share/components/share-layout.tsx";
import ShareRedirect from "@/pages/share/share-redirect.tsx";
import { useTrackOrigin } from "@/hooks/use-track-origin";
import SpacesPage from "@/pages/spaces/spaces.tsx";
import { MfaChallengePage } from "@/ee/mfa/pages/mfa-challenge-page";
import { MfaSetupRequiredPage } from "@/ee/mfa/pages/mfa-setup-required-page";
import SpaceTrash from "@/pages/space/space-trash.tsx";
import UserApiKeys from "@/ee/api-key/pages/user-api-keys";
import WorkspaceApiKeys from "@/ee/api-key/pages/workspace-api-keys";
export default function App() {
const [, setSocket] = useAtom(socketAtom);
const authToken = useAtomValue(authTokensAtom);
useEffect(() => {
if (!authToken?.accessToken) {
return;
}
const newSocket = io(SOCKET_URL, {
transports: ["websocket"],
auth: {
token: authToken.accessToken,
},
});
// @ts-ignore
setSocket(newSocket);
newSocket.on("connect", () => {
console.log("ws connected");
});
return () => {
console.log("ws disconnected");
newSocket.disconnect();
};
}, [authToken?.accessToken]);
useQuerySubscription();
useTreeSocket();
const { t } = useTranslation();
useRedirectToCloudSelect();
useTrackOrigin();
return (
<>
@ -62,19 +49,43 @@ export default function App() {
<Route index element={<Navigate to="/home" />} />
<Route path={"/login"} element={<LoginPage />} />
<Route path={"/invites/:invitationId"} element={<InviteSignup />} />
<Route path={"/setup/register"} element={<SetupWorkspace />} />
<Route path={"/forgot-password"} element={<ForgotPassword />} />
<Route path={"/password-reset"} element={<PasswordReset />} />
<Route path={"/login/mfa"} element={<MfaChallengePage />} />
<Route path={"/login/mfa/setup"} element={<MfaSetupRequiredPage />} />
{!isCloud() && (
<Route path={"/setup/register"} element={<SetupWorkspace />} />
)}
{isCloud() && (
<>
<Route path={"/create"} element={<CreateWorkspace />} />
<Route path={"/select"} element={<CloudLogin />} />
</>
)}
<Route element={<ShareLayout />}>
<Route
path={"/share/:shareId/p/:pageSlug"}
element={<SharedPage />}
/>
<Route path={"/share/p/:pageSlug"} element={<SharedPage />} />
</Route>
<Route path={"/share/:shareId"} element={<ShareRedirect />} />
<Route path={"/p/:pageSlug"} element={<PageRedirect />} />
<Route element={<Layout />}>
<Route path={"/home"} element={<Home />} />
<Route path={"/spaces"} element={<SpacesPage />} />
<Route path={"/s/:spaceSlug"} element={<SpaceHome />} />
<Route path={"/s/:spaceSlug/trash"} element={<SpaceTrash />} />
<Route
path={"/s/:spaceSlug/p/:pageSlug"}
element={
<ErrorBoundary
fallback={<>Failed to load page. An error occurred.</>}
fallback={<>{t("Failed to load page. An error occurred.")}</>}
>
<Page />
</ErrorBoundary>
@ -87,11 +98,17 @@ export default function App() {
path={"account/preferences"}
element={<AccountPreferences />}
/>
<Route path={"account/api-keys"} element={<UserApiKeys />} />
<Route path={"workspace"} element={<WorkspaceSettings />} />
<Route path={"members"} element={<WorkspaceMembers />} />
<Route path={"api-keys"} element={<WorkspaceApiKeys />} />
<Route path={"groups"} element={<Groups />} />
<Route path={"groups/:groupId"} element={<GroupInfo />} />
<Route path={"spaces"} element={<Spaces />} />
<Route path={"sharing"} element={<Shares />} />
<Route path={"security"} element={<Security />} />
{!isCloud() && <Route path={"license"} element={<License />} />}
{isCloud() && <Route path={"billing"} element={<Billing />} />}
</Route>
</Route>

View File

@ -0,0 +1,165 @@
import React, { useRef } from "react";
import { Menu, Box, Loader } from "@mantine/core";
import { useTranslation } from "react-i18next";
import { IconTrash, IconUpload } from "@tabler/icons-react";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import { AvatarIconType } from "@/features/attachments/types/attachment.types.ts";
import { notifications } from "@mantine/notifications";
interface AvatarUploaderProps {
currentImageUrl?: string | null;
fallbackName?: string;
radius?: string | number;
size?: string | number;
variant?: string;
type: AvatarIconType;
onUpload: (file: File) => Promise<void>;
onRemove: () => Promise<void>;
isLoading?: boolean;
disabled?: boolean;
}
export default function AvatarUploader({
currentImageUrl,
fallbackName,
radius,
variant,
size,
type,
onUpload,
onRemove,
isLoading = false,
disabled = false,
}: AvatarUploaderProps) {
const { t } = useTranslation();
const fileInputRef = useRef<HTMLInputElement>(null);
const handleFileInputChange = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const file = event.target.files?.[0];
if (!file || disabled) {
return;
}
// Validate file size (max 10MB)
const maxSizeInBytes = 10 * 1024 * 1024;
if (file.size > maxSizeInBytes) {
notifications.show({
message: t("Image exceeds 10MB limit."),
color: "red",
});
// Reset the input
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
return;
}
try {
await onUpload(file);
} catch (error) {
console.error(error);
notifications.show({
message: t("Failed to upload image"),
color: "red",
});
}
// Reset the input so the same file can be selected again
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
};
const handleUploadClick = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
} else {
console.error("File input ref is null!");
}
};
const handleRemove = async () => {
if (disabled) return;
try {
await onRemove();
notifications.show({
message: t("Image removed successfully"),
});
} catch (error) {
console.error(error);
notifications.show({
message: t("Failed to remove image"),
color: "red",
});
}
};
return (
<Box>
<input
type="file"
ref={fileInputRef}
onChange={handleFileInputChange}
accept="image/png,image/jpeg,image/jpg"
style={{ display: "none" }}
/>
<Menu shadow="md" width={200} withArrow disabled={disabled || isLoading}>
<Menu.Target>
<Box style={{ position: "relative", display: "inline-block" }}>
<CustomAvatar
component="button"
size={size}
avatarUrl={currentImageUrl}
name={fallbackName}
style={{
cursor: disabled || isLoading ? "default" : "pointer",
opacity: isLoading ? 0.6 : 1,
}}
radius={radius}
variant={variant}
type={type}
/>
{isLoading && (
<Box
style={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
zIndex: 1000,
}}
>
<Loader size="sm" />
</Box>
)}
</Box>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item
leftSection={<IconUpload size={16} />}
disabled={isLoading || disabled}
onClick={handleUploadClick}
>
{t("Upload image")}
</Menu.Item>
{currentImageUrl && (
<Menu.Item
leftSection={<IconTrash size={16} />}
color="red"
onClick={handleRemove}
disabled={isLoading || disabled}
>
{t("Remove image")}
</Menu.Item>
)}
</Menu.Dropdown>
</Menu>
</Box>
);
}

View File

@ -0,0 +1,31 @@
import { ActionIcon, CopyButton, Tooltip } from "@mantine/core";
import { IconCheck, IconCopy } from "@tabler/icons-react";
import React from "react";
import { useTranslation } from "react-i18next";
interface CopyProps {
text: string;
}
export default function CopyTextButton({ text }: CopyProps) {
const { t } = useTranslation();
return (
<CopyButton value={text} timeout={2000}>
{({ copied, copy }) => (
<Tooltip
label={copied ? t("Copied") : t("Copy")}
withArrow
position="right"
>
<ActionIcon
color={copied ? "teal" : "gray"}
variant="subtle"
onClick={copy}
>
{copied ? <IconCheck size={16} /> : <IconCopy size={16} />}
</ActionIcon>
</Tooltip>
)}
</CopyButton>
);
}

View File

@ -0,0 +1,169 @@
import {
Modal,
Button,
Group,
Text,
Select,
Switch,
Divider,
} from "@mantine/core";
import { exportPage } from "@/features/page/services/page-service.ts";
import { useState } from "react";
import { ExportFormat } from "@/features/page/types/page.types.ts";
import { notifications } from "@mantine/notifications";
import { exportSpace } from "@/features/space/services/space-service";
import { useTranslation } from "react-i18next";
interface ExportModalProps {
id: string;
type: "space" | "page";
open: boolean;
onClose: () => void;
}
export default function ExportModal({
id,
type,
open,
onClose,
}: ExportModalProps) {
const [format, setFormat] = useState<ExportFormat>(ExportFormat.Markdown);
const [includeChildren, setIncludeChildren] = useState<boolean>(false);
const [includeAttachments, setIncludeAttachments] = useState<boolean>(false);
const { t } = useTranslation();
const handleExport = async () => {
try {
if (type === "page") {
await exportPage({
pageId: id,
format,
includeChildren,
includeAttachments,
});
}
if (type === "space") {
await exportSpace({ spaceId: id, format, includeAttachments });
}
onClose();
} catch (err) {
notifications.show({
message: "Export failed:" + err.response?.data.message,
color: "red",
});
console.error("export error", err);
}
};
const handleChange = (format: ExportFormat) => {
setFormat(format);
};
return (
<Modal.Root
opened={open}
onClose={onClose}
size={500}
padding="xl"
yOffset="10vh"
xOffset={0}
mah={400}
onClick={(e) => e.stopPropagation()}
>
<Modal.Overlay />
<Modal.Content style={{ overflow: "hidden" }}>
<Modal.Header py={0}>
<Modal.Title fw={500}>{t(`Export ${type}`)}</Modal.Title>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body>
<Group justify="space-between" wrap="nowrap">
<div>
<Text size="md">{t("Format")}</Text>
</div>
<ExportFormatSelection format={format} onChange={handleChange} />
</Group>
{type === "page" && (
<>
<Divider my="sm" />
<Group justify="space-between" wrap="nowrap">
<div>
<Text size="md">{t("Include subpages")}</Text>
</div>
<Switch
onChange={(event) =>
setIncludeChildren(event.currentTarget.checked)
}
checked={includeChildren}
/>
</Group>
<Group justify="space-between" wrap="nowrap" mt="md">
<div>
<Text size="md">{t("Include attachments")}</Text>
</div>
<Switch
onChange={(event) =>
setIncludeAttachments(event.currentTarget.checked)
}
checked={includeAttachments}
/>
</Group>
</>
)}
{type === "space" && (
<>
<Divider my="sm" />
<Group justify="space-between" wrap="nowrap">
<div>
<Text size="md">{t("Include attachments")}</Text>
</div>
<Switch
onChange={(event) =>
setIncludeAttachments(event.currentTarget.checked)
}
checked={includeAttachments}
/>
</Group>
</>
)}
<Group justify="center" mt="md">
<Button onClick={onClose} variant="default">
{t("Cancel")}
</Button>
<Button onClick={handleExport}>{t("Export")}</Button>
</Group>
</Modal.Body>
</Modal.Content>
</Modal.Root>
);
}
interface ExportFormatSelection {
format: ExportFormat;
onChange: (value: string) => void;
}
function ExportFormatSelection({ format, onChange }: ExportFormatSelection) {
const { t } = useTranslation();
return (
<Select
data={[
{ value: "markdown", label: "Markdown" },
{ value: "html", label: "HTML" },
]}
defaultValue={format}
onChange={onChange}
styles={{ wrapper: { maxWidth: 120 } }}
comboboxProps={{ width: "120" }}
allowDeselect={false}
withCheckIcon={false}
aria-label={t("Select export format")}
/>
);
}

View File

@ -0,0 +1,20 @@
import { Table, Text } from "@mantine/core";
import React from "react";
import { useTranslation } from "react-i18next";
interface NoTableResultsProps {
colSpan: number;
text?: string;
}
export default function NoTableResults({ colSpan, text }: NoTableResultsProps) {
const { t } = useTranslation();
return (
<Table.Tr>
<Table.Td colSpan={colSpan}>
<Text fw={500} c="dimmed" ta="center">
{text || t("No results found...")}
</Text>
</Table.Td>
</Table.Tr>
);
}

View File

@ -0,0 +1,44 @@
import { Button, Group } from "@mantine/core";
import { useTranslation } from "react-i18next";
export interface PagePaginationProps {
currentPage: number;
hasPrevPage: boolean;
hasNextPage: boolean;
onPageChange: (newPage: number) => void;
}
export default function Paginate({
currentPage,
hasPrevPage,
hasNextPage,
onPageChange,
}: PagePaginationProps) {
const { t } = useTranslation();
if (!hasPrevPage && !hasNextPage) {
return null;
}
return (
<Group mt="md" justify="flex-end">
<Button
variant="default"
size="compact-sm"
onClick={() => onPageChange(currentPage - 1)}
disabled={!hasPrevPage}
>
{t("Prev")}
</Button>
<Button
variant="default"
size="compact-sm"
onClick={() => onPageChange(currentPage + 1)}
disabled={!hasNextPage}
>
{t("Next")}
</Button>
</Group>
);
}

View File

@ -1,70 +1,86 @@
import { Text, Group, UnstyledButton, Badge, Table } from "@mantine/core";
import { Link } from "react-router-dom";
import PageListSkeleton from "@/components/ui/page-list-skeleton.tsx";
import { buildPageUrl } from "@/features/page/page.utils.ts";
import { formattedDate } from "@/lib/time.ts";
import { useRecentChangesQuery } from "@/features/page/queries/page-query.ts";
import { IconFileDescription } from "@tabler/icons-react";
import { getSpaceUrl } from "@/lib/config.ts";
import {
Text,
Group,
UnstyledButton,
Badge,
Table,
ActionIcon,
} from '@mantine/core';
import {Link} from 'react-router-dom';
import PageListSkeleton from '@/components/ui/page-list-skeleton.tsx';
import { buildPageUrl } from '@/features/page/page.utils.ts';
import { formattedDate } from '@/lib/time.ts';
import { useRecentChangesQuery } from '@/features/page/queries/page-query.ts';
import { IconFileDescription } from '@tabler/icons-react';
import { getSpaceUrl } from '@/lib/config.ts';
import { useTranslation } from "react-i18next";
interface Props {
spaceId?: string;
}
export default function RecentChanges({ spaceId }: Props) {
const { data: pages, isLoading, isError } = useRecentChangesQuery(spaceId);
export default function RecentChanges({spaceId}: Props) {
const { t } = useTranslation();
const {data: pages, isLoading, isError} = useRecentChangesQuery(spaceId);
if (isLoading) {
return <PageListSkeleton />;
return <PageListSkeleton/>;
}
if (isError) {
return <Text>Failed to fetch recent pages</Text>;
return <Text>{t("Failed to fetch recent pages")}</Text>;
}
return pages && pages.items.length > 0 ? (
<Table highlightOnHover verticalSpacing="sm">
<Table.Tbody>
{pages.items.map((page) => (
<Table.Tr key={page.id}>
<Table.Td>
<UnstyledButton
component={Link}
to={buildPageUrl(page?.space.slug, page.slugId, page.title)}
>
<Group wrap="nowrap">
{page.icon || <IconFileDescription size={18} />}
<Text fw={500} size="md" lineClamp={1}>
{page.title || "Untitled"}
</Text>
</Group>
</UnstyledButton>
</Table.Td>
{!spaceId && (
<Table.ScrollContainer minWidth={500}>
<Table highlightOnHover verticalSpacing="sm">
<Table.Tbody>
{pages.items.map((page) => (
<Table.Tr key={page.id}>
<Table.Td>
<Badge
color="blue"
variant="light"
<UnstyledButton
component={Link}
to={getSpaceUrl(page?.space.slug)}
style={{ cursor: "pointer" }}
to={buildPageUrl(page?.space.slug, page.slugId, page.title)}
>
{page?.space.name}
</Badge>
<Group wrap="nowrap">
{page.icon || (
<ActionIcon variant='transparent' color='gray' size={18}>
<IconFileDescription size={18}/>
</ActionIcon>
)}
<Text fw={500} size="md" lineClamp={1}>
{page.title || t("Untitled")}
</Text>
</Group>
</UnstyledButton>
</Table.Td>
)}
<Table.Td>
<Text c="dimmed" size="xs" fw={500}>
{formattedDate(page.updatedAt)}
</Text>
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
{!spaceId && (
<Table.Td>
<Badge
color="blue"
variant="light"
component={Link}
to={getSpaceUrl(page?.space.slug)}
style={{cursor: 'pointer'}}
>
{page?.space.name}
</Badge>
</Table.Td>
)}
<Table.Td>
<Text c="dimmed" style={{whiteSpace: 'nowrap'}} size="xs" fw={500}>
{formattedDate(page.updatedAt)}
</Text>
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</Table.ScrollContainer>
) : (
<Text size="md" ta="center">
No pages yet
{t("No pages yet")}
</Text>
);
}

View File

@ -0,0 +1,37 @@
import React, { useState, useEffect } from "react";
import { TextInput, Group } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { IconSearch } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
export interface SearchInputProps {
placeholder?: string;
debounceDelay?: number;
onSearch: (value: string) => void;
}
export function SearchInput({
placeholder,
debounceDelay = 500,
onSearch,
}: SearchInputProps) {
const { t } = useTranslation();
const [value, setValue] = useState("");
const [debouncedValue] = useDebouncedValue(value, debounceDelay);
useEffect(() => {
onSearch(debouncedValue);
}, [debouncedValue, onSearch]);
return (
<Group mb="sm">
<TextInput
size="sm"
placeholder={placeholder || t("Search...")}
leftSection={<IconSearch size={16} />}
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
/>
</Group>
);
}

View File

@ -0,0 +1,24 @@
import { Group, Text } from "@mantine/core";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import React from "react";
import { IUser } from '@/features/user/types/user.types.ts';
interface UserInfoProps {
user: Partial<IUser>;
size?: string;
}
export function UserInfo({ user, size }: UserInfoProps) {
return (
<Group gap="sm" wrap="nowrap">
<CustomAvatar avatarUrl={user?.avatarUrl} name={user?.name} size={size} />
<div>
<Text fz="sm" fw={500} lineClamp={1}>
{user?.name}
</Text>
<Text fz="xs" c="dimmed">
{user?.email}
</Text>
</div>
</Group>
);
}

View File

@ -0,0 +1,32 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function AirtableIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 256 215"
style={{ width: rem(size), height: rem(size) }}
>
<path
fill="#ffbf00"
d="M114.259 2.701 18.86 42.176c-5.305 2.195-5.25 9.73.089 11.847l95.797 37.989a35.544 35.544 0 0 0 26.208 0l95.799-37.99c5.337-2.115 5.393-9.65.086-11.846L141.442 2.7a35.549 35.549 0 0 0-27.183 0"
/>
<path
fill="#26b5f8"
d="M136.35 112.757v94.902c0 4.514 4.55 7.605 8.746 5.942l106.748-41.435a6.39 6.39 0 0 0 4.035-5.941V71.322c0-4.514-4.551-7.604-8.747-5.941l-106.748 41.434a6.392 6.392 0 0 0-4.035 5.942"
/>
<path
fill="#ed3049"
d="m111.423 117.654-31.68 15.296-3.217 1.555L9.65 166.548C5.411 168.593 0 165.504 0 160.795V71.72c0-1.704.874-3.175 2.046-4.283a7.266 7.266 0 0 1 1.618-1.213c1.598-.959 3.878-1.215 5.816-.448l101.41 40.18c5.155 2.045 5.56 9.268.533 11.697"
/>
<path
fillOpacity={0.25}
d="m111.423 117.654-31.68 15.296L2.045 67.438a7.266 7.266 0 0 1 1.618-1.213c1.598-.959 3.878-1.215 5.816-.448l101.41 40.18c5.155 2.045 5.56 9.268.533 11.697"
/>
</svg>
);
}

View File

@ -0,0 +1,20 @@
import { rem } from "@mantine/core";
interface Props {
size?: number | string;
}
export function ConfluenceIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
style={{ width: rem(size), height: rem(size) }}
>
<path d="M.87 18.257c-.248.382-.53.875-.763 1.245a.764.764 0 0 0 .255 1.04l4.965 3.054a.764.764 0 0 0 1.058-.26c.199-.332.454-.763.733-1.221 1.967-3.247 3.945-2.853 7.508-1.146l4.957 2.337a.764.764 0 0 0 1.028-.382l2.364-5.346a.764.764 0 0 0-.382-1 599.851 599.851 0 0 1-4.965-2.361C10.911 10.97 5.224 11.185.87 18.257zM23.131 5.743c.249-.405.531-.875.764-1.25a.764.764 0 0 0-.256-1.034L18.675.404a.764.764 0 0 0-1.058.26c-.195.335-.451.763-.734 1.225-1.966 3.246-3.945 2.85-7.508 1.146L4.437.694a.764.764 0 0 0-1.027.382L1.046 6.422a.764.764 0 0 0 .382 1c1.039.49 3.105 1.467 4.965 2.361 6.698 3.246 12.392 3.029 16.738-4.04z" />
</svg>
);
}

View File

@ -0,0 +1,23 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function FigmaIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
style={{ width: rem(size), height: rem(size) }}
>
<g fill="none" fillRule="evenodd" transform="translate(4)">
<circle cx={12} cy={12} r={4} fill="#19bcfe" />
<path fill="#09cf83" d="M4 24a4 4 0 0 0 4-4v-4H4a4 4 0 1 0 0 8z" />
<path fill="#a259ff" d="M4 16h4V8H4a4 4 0 1 0 0 8z" />
<path fill="#f24e1e" d="M4 8h4V0H4a4 4 0 1 0 0 8z" />
<path fill="#ff7262" d="M12 8H8V0h4a4 4 0 1 1 0 8z" />
</g>
</svg>
);
}

View File

@ -0,0 +1,17 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function FramerIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
style={{ width: rem(size), height: rem(size) }}
>
<path d="M4 0h16v8h-8zm0 8h8l8 8H4zm0 8h8v8z" />
</svg>
);
}

View File

@ -0,0 +1,24 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function GoogleDriveIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 87.3 78"
style={{ width: rem(size), height: rem(size) }}
>
<path d="m6.6 66.85 3.85 6.65c.8 1.4 1.95 2.5 3.3 3.3l13.75-23.8h-27.5c0 1.55.4 3.1 1.2 4.5z" fill="#0066da" />
<path d="m43.65 25-13.75-23.8c-1.35.8-2.5 1.9-3.3 3.3l-25.4 44a9.06 9.06 0 0 0 -1.2 4.5h27.5z" fill="#00ac47" />
<path d="m73.55 76.8c1.35-.8 2.5-1.9 3.3-3.3l1.6-2.75 7.65-13.25c.8-1.4 1.2-2.95 1.2-4.5h-27.502l5.852 11.5z"
fill="#ea4335" />
<path d="m43.65 25 13.75-23.8c-1.35-.8-2.9-1.2-4.5-1.2h-18.5c-1.6 0-3.15.45-4.5 1.2z" fill="#00832d" />
<path d="m59.8 53h-32.3l-13.75 23.8c1.35.8 2.9 1.2 4.5 1.2h50.8c1.6 0 3.15-.45 4.5-1.2z" fill="#2684fc" />
<path d="m73.4 26.5-12.7-22c-.8-1.4-1.95-2.5-3.3-3.3l-13.75 23.8 16.15 28h27.45c0-1.55-.4-3.1-1.2-4.5z"
fill="#ffba00" />
</svg>
);
}

View File

@ -0,0 +1,33 @@
import { rem } from "@mantine/core";
interface Props {
size?: number | string;
}
export function GoogleIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid"
viewBox="0 0 256 262"
style={{ width: rem(size), height: rem(size) }}
>
<path
fill="#4285F4"
d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"
/>
<path
fill="#34A853"
d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"
/>
<path
fill="#FBBC05"
d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782"
/>
<path
fill="#EB4335"
d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"
/>
</svg>
);
}

View File

@ -0,0 +1,23 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function GoogleSheetsIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
style={{ width: rem(size), height: rem(size) }}
>
<path fill="#43a047" d="M37,45H11c-1.657,0-3-1.343-3-3V6c0-1.657,1.343-3,3-3h19l10,10v29C40,43.657,38.657,45,37,45z"/>
<path fill="#c8e6c9" d="M40 13L30 13 30 3z"/>
<path fill="#2e7d32" d="M30 13L40 23 40 13z"/>
<path
fill="#e8f5e9"
d="M31,23H17h-2v2v2v2v2v2v2v2h18v-2v-2v-2v-2v-2v-2v-2H31z M17,25h4v2h-4V25z M17,29h4v2h-4V29z M17,33h4v2h-4V33z M31,35h-8v-2h8V35z M31,31h-8v-2h8V31z M31,27h-8v-2h8V27z"
/>
</svg>
);
}

View File

@ -0,0 +1,20 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
function IconDrawio({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="#F08705"
style={{ width: rem(size), height: rem(size) }}
>
<path d="M19.69 13.419h-2.527l-2.667-4.555a1.292 1.292 0 001.035-1.28V4.16c0-.725-.576-1.312-1.302-1.312H9.771c-.726 0-1.312.576-1.312 1.301v3.435c0 .619.426 1.152 1.034 1.28l-2.666 4.555H4.309c-.725 0-1.312.576-1.312 1.301v3.435c0 .725.576 1.312 1.302 1.312h4.458c.726 0 1.312-.576 1.312-1.302v-3.434c0-.726-.576-1.312-1.301-1.312h-.437l2.645-4.523h2.059l2.656 4.523h-.438c-.725 0-1.312.576-1.312 1.301v3.435c0 .725.576 1.312 1.302 1.312H19.7c.726 0 1.312-.576 1.312-1.302v-3.434c0-.726-.576-1.312-1.301-1.312zM24 22.976c0 .565-.459 1.024-1.013 1.024H1.024A1.022 1.022 0 010 22.987V1.024C0 .459.459 0 1.013 0h21.963C23.541 0 24 .459 24 1.013z"></path>
</svg>
);
}
export default IconDrawio;

View File

@ -0,0 +1,20 @@
import { rem } from "@mantine/core";
interface Props {
size?: number | string;
}
function IconExcalidraw({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="#6965DB"
viewBox="0 0 24 24"
style={{ width: rem(size), height: rem(size) }}
>
<path d="M23.943 19.806a.196.196 0 00-.168-.034c-1.26-1.855-2.873-3.61-4.419-5.315l-.252-.284c-.001-.073-.067-.12-.134-.15l-.084-.084c-.05-.1-.169-.167-.286-.1-.47.234-.907.585-1.327.919-.554.434-1.109.87-1.63 1.354a5.058 5.058 0 00-.588.618c-.084.117-.017.217.084.267-.37.368-.74.736-1.109 1.12a.19.19 0 00-.05.134c0 .05.033.1.067.117l.655.502v.016c.924.92 2.554 2.173 4.285 3.527.251.201.52.402.773.602.117.134.234.285.335.418.05.066.169.084.236.033.033.034.084.067.118.1a.24.24 0 00.1.034.153.153 0 00.135-.066.237.237 0 00.033-.1c.017 0 .017.016.034.016a.192.192 0 00.134-.05l3.058-3.327c.12-.116.014-.267 0-.267zm-7.628-.134l-1.546-1.17-.15-.1c-.035-.017-.068-.05-.102-.067l-.117-.1c.66-.66 1.33-1.308 2-1.956-.488.484-1.463 1.906-1.261 2.373.002 0 .018.042.067.084l1.11.936zm4.1 3.126l-1.277-.97a26.906 26.906 0 00-1.58-1.504c.69.518 1.277.97 1.361 1.053.673.585.638.485 1.093.87l.554.4c-.074.103-.151.148-.151.151zm.336.25l-.034-.016a.913.913 0 00.152-.117zM.587 3.476c.034.217.085.435.118.636.201 1.103.403 2.106.772 2.858l.152.568c.05.217.134.485.219.552a66.769 66.769 0 003.578 2.942.177.177 0 00.219 0s0 .016.016.016a.153.153 0 00.118.05.191.191 0 00.134-.05c1.798-1.989 3.142-3.627 4.1-4.998.068-.066.084-.167.084-.25.067-.067.118-.151.185-.201.067-.067.067-.184 0-.235l-.017-.016c0-.033-.017-.084-.05-.1-.42-.401-.722-.685-1.042-.986a93.555 93.555 0 01-2.352-2.273c-.017-.017-.034-.034-.067-.034-.336-.117-1.025-.234-1.882-.385-1.277-.216-3.008-.517-4.57-.986 0 0-.101 0-.118.017l-.05.05C.05.714.022.707 0 .718c.017.1.017.167.05.284 0 .033.068.301.068.334zm7.191 4.78l-.033.034a.036.036 0 01.033-.034zM6.553 2.238c.101.1.521.502.622.585-.437-.2-1.529-.702-2.034-.869.505.1 1.194.201 1.412.284zM.79 1.403c.252.434.454 1.939.655 3.41-.118-.469-.201-.936-.302-1.372C.992 2.673.84 1.988.638 1.386c.124 0 .152.021.152.017zm-.286-.369c0-.016 0-.033-.017-.033.085 0 .135.017.202.05 0 .006-.145-.017-.185-.017zm23.17-.217c.017-.066-.336-.367-.219-.384.253-.017.253-.401 0-.401-.335.017-.688.1-1.008.15-.587.117-1.192.234-1.78.367a79.696 79.696 0 00-3.949.937c-.403.117-.857.2-1.243.401-.135.067-.118.2-.05.284-.034.017-.051.017-.085.034-.117.017-.218.034-.335.05-.102.017-.152.1-.135.2 0 .017.017.05.017.067-.706.936-1.496 1.923-2.353 2.976-.84.969-1.73 1.989-2.62 3.042-2.84 3.31-6.05 7.07-9.594 10.38a.161.161 0 000 .234c.016.016.033.033.05.033-.05.05-.101.085-.152.134-.033.034-.05.067-.05.1a.364.364 0 00-.067.084c-.067.067-.067.184.017.234.067.066.185.066.235-.017.017-.017.017-.033.033-.033a.265.265 0 01.37 0c.202.217.404.435.588.618l-.42-.35c-.067-.067-.184-.05-.234.016-.068.066-.051.184.016.234l4.469 3.727c.034.034.067.034.118.034a.15.15 0 00.117-.05l.101-.1c.017.016.05.016.067.016.05 0 .084-.016.118-.05 6.049-6.05 10.922-10.614 16.5-14.693.05-.033.067-.1.067-.15.067 0 .118-.05.15-.117 1.026-3.125 1.228-5.9 1.295-7.27 0-.059.016-.038.016-.068.017-.033.017-.05.017-.05a.978.978 0 00-.067-.619zm-10.82 4.915c.268-.301.537-.619.806-.903-1.73 2.273-4.603 5.766-8.67 9.929 2.773-3.059 5.562-6.218 7.864-9.026zM5.14 23.466c-.016-.017-.016-.017 0-.017zm2.504-2.156c.135-.15.27-.284.42-.434 0 0 0 .016.017.016-.224.198-.433.418-.437.418zm.69-.668c.099-.1.14-.173.284-.318.992-1.02 2.017-2.04 3.059-3.076l.016-.016c.252-.2.555-.418.824-.619a228.063 228.063 0 00-4.184 4.029zM14.852 3.91c-.554.719-1.176 1.671-1.697 2.423-1.646 2.374-6.94 8.174-7.057 8.274a1189.647 1189.647 0 01-4.839 4.597l-.1.1c-.085-.1-.085-.25.016-.334C8.652 11.966 13.19 6.133 15.021 3.576c-.05.116-.084.216-.168.334zm2.906 3.427c-.671-.386-.99-.987-.806-1.572l.05-.2a.775.775 0 01.085-.167 1.9 1.9 0 01.756-.703c.016 0 .033 0 .05-.016-.017-.034-.017-.084-.017-.134.017-.1.085-.167.202-.167.202 0 .824.184 1.059.384.067.05.134.117.202.184.084.1.218.268.285.401.034.017.067.184.118.268.033.134.067.284.05.418-.017.016 0 .116-.017.116a1.605 1.605 0 01-.218.619c-.03.03.006.012-.05.067a1.22 1.22 0 01-.32.334 1.49 1.49 0 01-1.26.234 2.191 2.191 0 00-.169-.066zm4.37 1.403c0 .017-.017.05 0 .067-.034 0-.05.017-.085.034a109.886 109.886 0 00-3.915 3.025c1.11-.986 2.218-1.989 3.378-2.975.336-.301.571-.686.638-1.12l.168-1.003v-.033c.085-.201.404-.118.353.1-.004-.001-.173.795-.537 1.905z"></path>
</svg>
);
}
export default IconExcalidraw;

View File

@ -0,0 +1,20 @@
import { rem } from "@mantine/core";
interface Props {
size?: number | string;
}
function IconMermaid({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="#FF3670"
viewBox="0 0 24 24"
style={{ width: rem(size), height: rem(size) }}
>
<path d="M23.99 2.115A12.223 12.223 0 0012 10.149 12.223 12.223 0 00.01 2.115a12.23 12.23 0 005.32 10.604 6.562 6.562 0 012.845 5.423v3.754h7.65v-3.754a6.561 6.561 0 012.844-5.423 12.223 12.223 0 005.32-10.604z"></path>
</svg>
);
}
export default IconMermaid;

View File

@ -0,0 +1,11 @@
export { AirtableIcon } from "./airtable-icon.tsx";
export { FigmaIcon } from "./figma-icon.tsx";
export { TypeformIcon } from "./typeform-icon.tsx";
export { VimeoIcon } from "./vimeo-icon.tsx";
export { MiroIcon } from "./miro-icon.tsx";
export { GoogleDriveIcon } from "./google-drive-icon.tsx";
export { GoogleSheetsIcon } from "./google-sheets-icon.tsx";
export { FramerIcon } from "./framer-icon.tsx";
export { LoomIcon } from "./loom-icon.tsx";
export { YoutubeIcon } from "./youtube-icon.tsx";

View File

@ -0,0 +1,19 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function LoomIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="#625DF5"
style={{ width: rem(size), height: rem(size) }}
>
<path
d="M24 10.665h-7.018l6.078-3.509-1.335-2.312-6.078 3.509 3.508-6.077L16.843.94l-3.508 6.077V0h-2.67v7.018L7.156.94 4.844 2.275l3.509 6.077-6.078-3.508L.94 7.156l6.078 3.509H0v2.67h7.017L.94 16.844l1.335 2.313 6.077-3.508-3.509 6.077 2.312 1.335 3.509-6.078V24h2.67v-7.017l3.508 6.077 2.312-1.335-3.509-6.078 6.078 3.509 1.335-2.313-6.077-3.508h7.017v-2.67H24zm-12 4.966a3.645 3.645 0 1 1 0-7.29 3.645 3.645 0 0 1 0 7.29z" />
</svg>
);
}

View File

@ -0,0 +1,18 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function MiroIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
style={{ width: rem(size), height: rem(size) }}
>
<path
d="M17.392 0H13.9L17 4.808 10.444 0H6.949l3.102 6.3L3.494 0H0l3.05 8.131L0 24h3.494L10.05 6.985 6.949 24h3.494L17 5.494 13.899 24h3.493L24 3.672 17.392 0z" />
</svg>
);
}

View File

@ -0,0 +1,20 @@
import { rem } from "@mantine/core";
interface Props {
size?: number | string;
}
export function OpenIdIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
style={{ width: rem(size), height: rem(size) }}
>
<path d="M14.54.889l-3.63 1.773v18.17c-4.15-.52-7.27-2.78-7.27-5.5 0-2.58 2.8-4.75 6.63-5.41v-2.31C4.42 8.322 0 11.502 0 15.332c0 3.96 4.74 7.24 10.91 7.78l3.63-1.71V.888m.64 6.724v2.31c1.43.25 2.71.7 3.76 1.31l-1.97 1.11 7.03 1.53-.5-5.21-1.87 1.06c-1.74-1.06-3.96-1.81-6.45-2.11z" />
</svg>
);
}

View File

@ -0,0 +1,18 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function TypeformIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
style={{ width: rem(size), height: rem(size) }}
>
<path
d="M15.502 13.035c-.5 0-.756-.411-.756-.917 0-.505.252-.894.756-.894.513 0 .756.407.756.894-.004.515-.261.917-.756.917Zm-4.888-1.81c.292 0 .414.17.414.317 0 .357-.365.514-1.126.536 0-.442.253-.854.712-.854Zm-3.241 1.81c-.473 0-.67-.384-.67-.917 0-.527.202-.894.67-.894.477 0 .702.38.702.894 0 .537-.234.917-.702.917Zm-3.997-2.334h-.738l1.224 2.808c-.234.519-.36.648-.522.648-.171 0-.333-.138-.45-.259l-.324.43c.22.232.522.366.832.366.387 0 .685-.224.856-.626l1.413-3.371h-.725l-.738 2.012-.828-2.008Zm19.553.523c.36 0 .432.246.432.823v1.516H24v-1.914c0-.689-.473-.988-.91-.988-.386 0-.742.241-.94.688a.901.901 0 0 0-.891-.688c-.365 0-.73.232-.927.666v-.626h-.64v2.857h.64v-1.22c0-.617.324-1.114.765-1.114.36 0 .427.246.427.823v1.516h.64l-.005-1.225c0-.617.329-1.114.77-1.114Zm-5.1-.523h-.324v2.857h.639v-1.095c0-.693.306-1.163.76-1.163.118 0 .217.005.325.05l.099-.676c-.081-.009-.153-.018-.225-.018-.45 0-.774.309-.964.707V10.7h-.31Zm-2.327-.045c-.846 0-1.418.644-1.418 1.458 0 .845.58 1.475 1.418 1.475.85 0 1.431-.648 1.431-1.475-.004-.818-.594-1.458-1.431-1.458Zm-4.852 2.38c-.333 0-.581-.17-.685-.515.847-.036 1.675-.242 1.675-.988 0-.43-.423-.872-1.03-.872-.82 0-1.374.666-1.374 1.457 0 .828.545 1.476 1.36 1.476.567 0 .927-.228 1.21-.559l-.31-.42c-.329.335-.531.42-.846.42Zm-3.151-2.38c-.324 0-.648.188-.774.483v-.438h-.64v3.98h.64v-1.422c.135.205.445.34.72.34.85 0 1.3-.631 1.3-1.48-.004-.841-.445-1.463-1.246-1.463Zm-4.483-1.1H0v.622h1.18v3.38h.67v-3.38h1.166v-.622Zm9.502 1.145h-.383v.572h.383v2.285h.639v-2.285h.621v-.572h-.621v-.447c0-.286.117-.385.382-.385.1 0 .19.027.311.068l.144-.537c-.117-.067-.351-.094-.504-.094-.612 0-.972.367-.972 1.002v.393Z" />
</svg>
);
}

View File

@ -0,0 +1,19 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function VimeoIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="#1AB7EA"
style={{ width: rem(size), height: rem(size) }}
>
<path
d="M23.9765 6.4168c-.105 2.338-1.739 5.5429-4.894 9.6088-3.2679 4.247-6.0258 6.3699-8.2898 6.3699-1.409 0-2.578-1.294-3.553-3.881l-1.9179-7.1138c-.719-2.584-1.488-3.878-2.312-3.878-.179 0-.806.378-1.8809 1.132l-1.129-1.457a315.06 315.06 0 003.501-3.1279c1.579-1.368 2.765-2.085 3.5539-2.159 1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.5069.5389 2.45 1.1309 3.674 1.7759 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.8679 3.434-5.7568 6.7619-5.6368 2.4729.06 3.6279 1.664 3.4929 4.7969z" />
</svg>
);
}

View File

@ -0,0 +1,19 @@
import { rem } from '@mantine/core';
interface Props {
size?: number | string;
}
export function YoutubeIcon({ size }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="#FF0000"
style={{ width: rem(size), height: rem(size) }}
>
<path
d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z" />
</svg>
);
}

View File

@ -1,31 +1,46 @@
import { Group, Text } from "@mantine/core";
import { Badge, Group, Text, Tooltip } from "@mantine/core";
import classes from "./app-header.module.css";
import React from "react";
import TopMenu from "@/components/layouts/global/top-menu.tsx";
import { Link } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route.ts";
import { useAtom } from "jotai/index";
import { useAtom } from "jotai";
import {
desktopSidebarAtom,
mobileSidebarAtom,
} from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
import SidebarToggle from "@/components/ui/sidebar-toggle-button.tsx";
import { useTranslation } from "react-i18next";
import useTrial from "@/ee/hooks/use-trial.tsx";
import { isCloud } from "@/lib/config.ts";
import {
SearchControl,
SearchMobileControl,
} from "@/features/search/components/search-control.tsx";
import {
searchSpotlight,
shareSearchSpotlight,
} from "@/features/search/constants.ts";
const links = [{ link: APP_ROUTE.HOME, label: "Home" }];
export function AppHeader() {
const { t } = useTranslation();
const [mobileOpened] = useAtom(mobileSidebarAtom);
const toggleMobile = useToggleSidebar(mobileSidebarAtom);
const [desktopOpened] = useAtom(desktopSidebarAtom);
const toggleDesktop = useToggleSidebar(desktopSidebarAtom);
const { isTrial, trialDaysLeft } = useTrial();
const isHomeRoute = location.pathname.startsWith("/home");
const isSpacesRoute = location.pathname === "/spaces";
const hideSidebar = isHomeRoute || isSpacesRoute;
const items = links.map((link) => (
<Link key={link.label} to={link.link} className={classes.link}>
{link.label}
{t(link.label)}
</Link>
));
@ -33,23 +48,27 @@ export function AppHeader() {
<>
<Group h="100%" px="md" justify="space-between" wrap={"nowrap"}>
<Group wrap="nowrap">
{!isHomeRoute && (
{!hideSidebar && (
<>
<SidebarToggle
aria-label="sidebar toggle"
opened={mobileOpened}
onClick={toggleMobile}
hiddenFrom="sm"
size="sm"
/>
<Tooltip label={t("Sidebar toggle")}>
<SidebarToggle
aria-label={t("Sidebar toggle")}
opened={mobileOpened}
onClick={toggleMobile}
hiddenFrom="sm"
size="sm"
/>
</Tooltip>
<SidebarToggle
aria-label="sidebar toggle"
opened={desktopOpened}
onClick={toggleDesktop}
visibleFrom="sm"
size="sm"
/>
<Tooltip label={t("Sidebar toggle")}>
<SidebarToggle
aria-label={t("Sidebar toggle")}
opened={desktopOpened}
onClick={toggleDesktop}
visibleFrom="sm"
size="sm"
/>
</Tooltip>
</>
)}
@ -57,6 +76,8 @@ export function AppHeader() {
size="lg"
fw={600}
style={{ cursor: "pointer", userSelect: "none" }}
component={Link}
to="/home"
>
Docmost
</Text>
@ -66,7 +87,29 @@ export function AppHeader() {
</Group>
</Group>
<Group px={"xl"}>
<div>
<Group visibleFrom="sm">
<SearchControl onClick={searchSpotlight.open} />
</Group>
<Group hiddenFrom="sm">
<SearchMobileControl onSearch={searchSpotlight.open} />
</Group>
</div>
<Group px={"xl"} wrap="nowrap">
{isCloud() && isTrial && trialDaysLeft !== 0 && (
<Badge
variant="light"
style={{ cursor: "pointer" }}
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.BILLING}
visibleFrom="xs"
>
{trialDaysLeft === 1
? "1 day left"
: `${trialDaysLeft} days left`}
</Badge>
)}
<TopMenu />
</Group>
</Group>

View File

@ -14,3 +14,18 @@
}
}
.resizeHandle {
width: 3px;
cursor: col-resize;
position: absolute;
right: 0;
top: 0;
bottom: 0;
&:hover, &:active {
width: 5px;
background: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-5))
}
}

View File

@ -1,20 +1,30 @@
import { Box, ScrollArea, Text } from "@mantine/core";
import CommentList from "@/features/comment/components/comment-list.tsx";
import CommentListWithTabs from "@/features/comment/components/comment-list-with-tabs.tsx";
import { useAtom } from "jotai";
import { asideStateAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
import React, { ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { TableOfContents } from "@/features/editor/components/table-of-contents/table-of-contents.tsx";
import { useAtomValue } from "jotai";
import { pageEditorAtom } from "@/features/editor/atoms/editor-atoms.ts";
export default function Aside() {
const [{ tab }] = useAtom(asideStateAtom);
const { t } = useTranslation();
const pageEditor = useAtomValue(pageEditorAtom);
let title: string;
let component: ReactNode;
switch (tab) {
case "comments":
component = <CommentList />;
component = <CommentListWithTabs />;
title = "Comments";
break;
case "toc":
component = <TableOfContents editor={pageEditor} />;
title = "Table of contents";
break;
default:
component = null;
title = null;
@ -25,16 +35,20 @@ export default function Aside() {
{component && (
<>
<Text mb="md" fw={500}>
{title}
{t(title)}
</Text>
<ScrollArea
style={{ height: "85vh" }}
scrollbarSize={5}
type="scroll"
>
<div style={{ paddingBottom: "200px" }}>{component}</div>
</ScrollArea>
{tab === "comments" ? (
<CommentListWithTabs />
) : (
<ScrollArea
style={{ height: "85vh" }}
scrollbarSize={5}
type="scroll"
>
<div style={{ paddingBottom: "200px" }}>{component}</div>
</ScrollArea>
)}
</>
)}
</Box>

View File

@ -1,5 +1,5 @@
import { AppShell, Container } from "@mantine/core";
import React from "react";
import React, { useEffect, useRef, useState } from "react";
import { useLocation } from "react-router-dom";
import SettingsSidebar from "@/components/settings/settings-sidebar.tsx";
import { useAtom } from "jotai";
@ -7,33 +7,82 @@ import {
asideStateAtom,
desktopSidebarAtom,
mobileSidebarAtom,
sidebarWidthAtom,
} from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
import { SpaceSidebar } from "@/features/space/components/sidebar/space-sidebar.tsx";
import { AppHeader } from "@/components/layouts/global/app-header.tsx";
import Aside from "@/components/layouts/global/aside.tsx";
import classes from "./app-shell.module.css";
import { useTrialEndAction } from "@/ee/hooks/use-trial-end-action.tsx";
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
export default function GlobalAppShell({
children,
}: {
children: React.ReactNode;
}) {
useTrialEndAction();
const [mobileOpened] = useAtom(mobileSidebarAtom);
const toggleMobile = useToggleSidebar(mobileSidebarAtom);
const [desktopOpened] = useAtom(desktopSidebarAtom);
const [{ isAsideOpen }] = useAtom(asideStateAtom);
const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom);
const [isResizing, setIsResizing] = useState(false);
const sidebarRef = useRef(null);
const startResizing = React.useCallback((mouseDownEvent) => {
mouseDownEvent.preventDefault();
setIsResizing(true);
}, []);
const stopResizing = React.useCallback(() => {
setIsResizing(false);
}, []);
const resize = React.useCallback(
(mouseMoveEvent) => {
if (isResizing) {
const newWidth =
mouseMoveEvent.clientX -
sidebarRef.current.getBoundingClientRect().left;
if (newWidth < 220) {
setSidebarWidth(220);
return;
}
if (newWidth > 600) {
setSidebarWidth(600);
return;
}
setSidebarWidth(newWidth);
}
},
[isResizing],
);
useEffect(() => {
//https://codesandbox.io/p/sandbox/kz9de
window.addEventListener("mousemove", resize);
window.addEventListener("mouseup", stopResizing);
return () => {
window.removeEventListener("mousemove", resize);
window.removeEventListener("mouseup", stopResizing);
};
}, [resize, stopResizing]);
const location = useLocation();
const isSettingsRoute = location.pathname.startsWith("/settings");
const isSpaceRoute = location.pathname.startsWith("/s/");
const isHomeRoute = location.pathname.startsWith("/home");
const isSpacesRoute = location.pathname === "/spaces";
const isPageRoute = location.pathname.includes("/p/");
const hideSidebar = isHomeRoute || isSpacesRoute;
return (
<AppShell
header={{ height: 45 }}
navbar={
!isHomeRoute && {
width: 300,
!hideSidebar && {
width: isSpaceRoute ? sidebarWidth : 300,
breakpoint: "sm",
collapsed: {
mobile: !mobileOpened,
@ -53,15 +102,20 @@ export default function GlobalAppShell({
<AppShell.Header px="md" className={classes.header}>
<AppHeader />
</AppShell.Header>
{!isHomeRoute && (
<AppShell.Navbar className={classes.navbar} withBorder={false}>
{!hideSidebar && (
<AppShell.Navbar
className={classes.navbar}
withBorder={false}
ref={sidebarRef}
>
<div className={classes.resizeHandle} onMouseDown={startResizing} />
{isSpaceRoute && <SpaceSidebar />}
{isSettingsRoute && <SettingsSidebar />}
</AppShell.Navbar>
)}
<AppShell.Main>
{isSettingsRoute ? (
<Container size={800}>{children}</Container>
<Container size={850}>{children}</Container>
) : (
children
)}

View File

@ -19,3 +19,5 @@ export const asideStateAtom = atom<AsideStateType>({
tab: "",
isAsideOpen: false,
});
export const sidebarWidthAtom = atomWithWebStorage<number>('sidebarWidth', 300);

View File

@ -1,13 +1,23 @@
import { UserProvider } from "@/features/user/user-provider.tsx";
import { Outlet } from "react-router-dom";
import { Outlet, useParams } from "react-router-dom";
import GlobalAppShell from "@/components/layouts/global/global-app-shell.tsx";
import { PosthogUser } from "@/ee/components/posthog-user.tsx";
import { isCloud } from "@/lib/config.ts";
import { SearchSpotlight } from "@/features/search/components/search-spotlight.tsx";
import React from "react";
import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts";
export default function Layout() {
const { spaceSlug } = useParams();
const { data: space } = useGetSpaceBySlugQuery(spaceSlug);
return (
<UserProvider>
<GlobalAppShell>
<Outlet />
</GlobalAppShell>
{isCloud() && <PosthogUser />}
<SearchSpotlight spaceId={space?.id} />
</UserProvider>
);
}

View File

@ -1,8 +1,20 @@
import { Avatar, Group, Menu, rem, UnstyledButton, Text } from "@mantine/core";
import {
Group,
Menu,
Text,
UnstyledButton,
useMantineColorScheme,
} from "@mantine/core";
import {
IconBrightnessFilled,
IconBrush,
IconCheck,
IconChevronDown,
IconDeviceDesktop,
IconLogout,
IconMoon,
IconSettings,
IconSun,
IconUserCircle,
IconUsers,
} from "@tabler/icons-react";
@ -12,10 +24,14 @@ import { Link } from "react-router-dom";
import APP_ROUTE from "@/lib/app-route.ts";
import useAuth from "@/features/auth/hooks/use-auth.ts";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import { useTranslation } from "react-i18next";
import { AvatarIconType } from "@/features/attachments/types/attachment.types.ts";
export default function TopMenu() {
const { t } = useTranslation();
const [currentUser] = useAtom(currentUserAtom);
const { logout } = useAuth();
const { colorScheme, setColorScheme } = useMantineColorScheme();
const user = currentUser?.user;
const workspace = currentUser?.workspace;
@ -30,53 +46,41 @@ export default function TopMenu() {
<UnstyledButton>
<Group gap={7} wrap={"nowrap"}>
<CustomAvatar
avatarUrl={workspace.logo}
name={workspace.name}
avatarUrl={workspace?.logo}
name={workspace?.name}
variant="filled"
size="sm"
type={AvatarIconType.WORKSPACE_ICON}
/>
<Text fw={500} size="sm" lh={1} mr={3}>
{workspace.name}
<Text fw={500} size="sm" lh={1} mr={3} lineClamp={1}>
{workspace?.name}
</Text>
<IconChevronDown
style={{ width: rem(12), height: rem(12) }}
stroke={1.5}
/>
<IconChevronDown size={16} />
</Group>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>Workspace</Menu.Label>
<Menu.Label>{t("Workspace")}</Menu.Label>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.GENERAL}
leftSection={
<IconSettings
style={{ width: rem(16), height: rem(16) }}
stroke={1.5}
/>
}
leftSection={<IconSettings size={16} />}
>
Workspace settings
{t("Workspace settings")}
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.WORKSPACE.MEMBERS}
leftSection={
<IconUsers
style={{ width: rem(16), height: rem(16) }}
stroke={1.5}
/>
}
leftSection={<IconUsers size={16} />}
>
Manage members
{t("Manage members")}
</Menu.Item>
<Menu.Divider />
<Menu.Label>Account</Menu.Label>
<Menu.Label>{t("Account")}</Menu.Label>
<Menu.Item component={Link} to={APP_ROUTE.SETTINGS.ACCOUNT.PROFILE}>
<Group wrap={"nowrap"}>
<CustomAvatar
@ -85,11 +89,11 @@ export default function TopMenu() {
name={user.name}
/>
<div>
<div style={{ width: 190 }}>
<Text size="sm" fw={500} lineClamp={1}>
{user.name}
</Text>
<Text size="xs" c="dimmed">
<Text size="xs" c="dimmed" truncate="end">
{user.email}
</Text>
</div>
@ -98,28 +102,61 @@ export default function TopMenu() {
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.ACCOUNT.PROFILE}
leftSection={
<IconUserCircle
style={{ width: rem(16), height: rem(16) }}
stroke={1.5}
/>
}
leftSection={<IconUserCircle size={16} />}
>
My profile
{t("My profile")}
</Menu.Item>
<Menu.Item
component={Link}
to={APP_ROUTE.SETTINGS.ACCOUNT.PREFERENCES}
leftSection={<IconBrush size={16} />}
>
{t("My preferences")}
</Menu.Item>
<Menu.Sub>
<Menu.Sub.Target>
<Menu.Sub.Item leftSection={<IconBrightnessFilled size={16} />}>
{t("Theme")}
</Menu.Sub.Item>
</Menu.Sub.Target>
<Menu.Sub.Dropdown>
<Menu.Item
onClick={() => setColorScheme("light")}
leftSection={<IconSun size={16} />}
rightSection={
colorScheme === "light" ? <IconCheck size={16} /> : null
}
>
{t("Light")}
</Menu.Item>
<Menu.Item
onClick={() => setColorScheme("dark")}
leftSection={<IconMoon size={16} />}
rightSection={
colorScheme === "dark" ? <IconCheck size={16} /> : null
}
>
{t("Dark")}
</Menu.Item>
<Menu.Item
onClick={() => setColorScheme("auto")}
leftSection={<IconDeviceDesktop size={16} />}
rightSection={
colorScheme === "auto" ? <IconCheck size={16} /> : null
}
>
{t("System settings")}
</Menu.Item>
</Menu.Sub.Dropdown>
</Menu.Sub>
<Menu.Divider />
<Menu.Item
onClick={logout}
leftSection={
<IconLogout
style={{ width: rem(16), height: rem(16) }}
stroke={1.5}
/>
}
>
Logout
<Menu.Item onClick={logout} leftSection={<IconLogout size={16} />}>
{t("Logout")}
</Menu.Item>
</Menu.Dropdown>
</Menu>

View File

@ -0,0 +1,59 @@
import { useAppVersion } from "@/features/workspace/queries/workspace-query.ts";
import { isCloud } from "@/lib/config.ts";
import classes from "@/components/settings/settings.module.css";
import { Indicator, Text, Tooltip } from "@mantine/core";
import React from "react";
import semverGt from "semver/functions/gt";
import { useTranslation } from "react-i18next";
export default function AppVersion() {
const { t } = useTranslation();
const { data: appVersion } = useAppVersion(!isCloud());
let hasUpdate = false;
try {
hasUpdate =
appVersion &&
parseFloat(appVersion.latestVersion) > 0 &&
semverGt(appVersion.latestVersion, appVersion.currentVersion);
} catch (err) {
console.error(err);
}
return (
<div className={classes.text}>
<Tooltip
label={t("{{latestVersion}} is available", {
latestVersion: `v${appVersion?.latestVersion}`,
})}
disabled={!hasUpdate}
>
<Indicator
label={t("New update")}
color="gray"
inline
size={16}
position="middle-end"
style={{ cursor: "pointer" }}
disabled={!hasUpdate}
onClick={() => {
window.open(
"https://github.com/docmost/docmost/releases",
"_blank",
);
}}
>
<Text
size="sm"
c="dimmed"
component="a"
mr={45}
href="https://github.com/docmost/docmost/releases"
target="_blank"
>
{appVersion?.currentVersion && <>v{appVersion?.currentVersion}</>}
</Text>
</Indicator>
</Tooltip>
</div>
);
}

View File

@ -0,0 +1,10 @@
import { atom, WritableAtom } from "jotai";
export const settingsOriginAtom: WritableAtom<string | null, [string | null], void> = atom(
null,
(get, set, newValue) => {
if (get(settingsOriginAtom) !== newValue) {
set(settingsOriginAtom, newValue);
}
}
);

View File

@ -0,0 +1,82 @@
import { queryClient } from "@/main.tsx";
import {
getBilling,
getBillingPlans,
} from "@/ee/billing/services/billing-service.ts";
import { getSpaces } from "@/features/space/services/space-service.ts";
import { getGroups } from "@/features/group/services/group-service.ts";
import { QueryParams } from "@/lib/types.ts";
import { getWorkspaceMembers } from "@/features/workspace/services/workspace-service.ts";
import { getLicenseInfo } from "@/ee/licence/services/license-service.ts";
import { getSsoProviders } from "@/ee/security/services/security-service.ts";
import { getShares } from "@/features/share/services/share-service.ts";
import { getApiKeys } from "@/ee/api-key";
export const prefetchWorkspaceMembers = () => {
const params = { limit: 100, page: 1, query: "" } as QueryParams;
queryClient.prefetchQuery({
queryKey: ["workspaceMembers", params],
queryFn: () => getWorkspaceMembers(params),
});
};
export const prefetchSpaces = () => {
queryClient.prefetchQuery({
queryKey: ["spaces", { page: 1 }],
queryFn: () => getSpaces({ page: 1 }),
});
};
export const prefetchGroups = () => {
queryClient.prefetchQuery({
queryKey: ["groups", { page: 1 }],
queryFn: () => getGroups({ page: 1 }),
});
};
export const prefetchBilling = () => {
queryClient.prefetchQuery({
queryKey: ["billing"],
queryFn: () => getBilling(),
});
queryClient.prefetchQuery({
queryKey: ["billing-plans"],
queryFn: () => getBillingPlans(),
});
};
export const prefetchLicense = () => {
queryClient.prefetchQuery({
queryKey: ["license"],
queryFn: () => getLicenseInfo(),
});
};
export const prefetchSsoProviders = () => {
queryClient.prefetchQuery({
queryKey: ["sso-providers"],
queryFn: () => getSsoProviders(),
});
};
export const prefetchShares = () => {
queryClient.prefetchQuery({
queryKey: ["share-list", { page: 1 }],
queryFn: () => getShares({ page: 1, limit: 100 }),
});
};
export const prefetchApiKeys = () => {
queryClient.prefetchQuery({
queryKey: ["api-key-list", { page: 1 }],
queryFn: () => getApiKeys({ page: 1 }),
});
};
export const prefetchApiKeyManagement = () => {
queryClient.prefetchQuery({
queryKey: ["api-key-list", { page: 1 }],
queryFn: () => getApiKeys({ page: 1, adminView: true }),
});
};

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { Group, Text, ScrollArea, ActionIcon, rem } from "@mantine/core";
import { Group, Text, ScrollArea, ActionIcon, Tooltip } from "@mantine/core";
import {
IconUser,
IconSettings,
@ -8,14 +8,43 @@ import {
IconUsersGroup,
IconSpaces,
IconBrush,
IconCoin,
IconLock,
IconKey,
IconWorld,
} from "@tabler/icons-react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { Link, useLocation } from "react-router-dom";
import classes from "./settings.module.css";
import { useTranslation } from "react-i18next";
import { isCloud } from "@/lib/config.ts";
import useUserRole from "@/hooks/use-user-role.tsx";
import { useAtom } from "jotai/index";
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
import {
prefetchApiKeyManagement,
prefetchApiKeys,
prefetchBilling,
prefetchGroups,
prefetchLicense,
prefetchShares,
prefetchSpaces,
prefetchSsoProviders,
prefetchWorkspaceMembers,
} from "@/components/settings/settings-queries.tsx";
import AppVersion from "@/components/settings/app-version.tsx";
import { mobileSidebarAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
import { useSettingsNavigation } from "@/hooks/use-settings-navigation";
interface DataItem {
label: string;
icon: React.ElementType;
path: string;
isCloud?: boolean;
isEnterprise?: boolean;
isAdmin?: boolean;
isSelfhosted?: boolean;
showDisabledInNonEE?: boolean;
}
interface DataGroup {
@ -33,6 +62,14 @@ const groupedData: DataGroup[] = [
icon: IconBrush,
path: "/settings/account/preferences",
},
{
label: "API keys",
icon: IconKey,
path: "/settings/account/api-keys",
isCloud: true,
isEnterprise: true,
showDisabledInNonEE: true,
},
],
},
{
@ -44,55 +81,231 @@ const groupedData: DataGroup[] = [
icon: IconUsers,
path: "/settings/members",
},
{
label: "Billing",
icon: IconCoin,
path: "/settings/billing",
isCloud: true,
isAdmin: true,
},
{
label: "Security & SSO",
icon: IconLock,
path: "/settings/security",
isCloud: true,
isEnterprise: true,
isAdmin: true,
showDisabledInNonEE: true,
},
{ label: "Groups", icon: IconUsersGroup, path: "/settings/groups" },
{ label: "Spaces", icon: IconSpaces, path: "/settings/spaces" },
{ label: "Public sharing", icon: IconWorld, path: "/settings/sharing" },
{
label: "API management",
icon: IconKey,
path: "/settings/api-keys",
isCloud: true,
isEnterprise: true,
isAdmin: true,
showDisabledInNonEE: true,
},
],
},
{
heading: "System",
items: [
{
label: "License & Edition",
icon: IconKey,
path: "/settings/license",
},
],
},
];
export default function SettingsSidebar() {
const { t } = useTranslation();
const location = useLocation();
const [active, setActive] = useState(location.pathname);
const navigate = useNavigate();
const { goBack } = useSettingsNavigation();
const { isAdmin } = useUserRole();
const [workspace] = useAtom(workspaceAtom);
const [mobileSidebarOpened] = useAtom(mobileSidebarAtom);
const toggleMobileSidebar = useToggleSidebar(mobileSidebarAtom);
useEffect(() => {
setActive(location.pathname);
}, [location.pathname]);
const menuItems = groupedData.map((group) => (
<div key={group.heading}>
<Text c="dimmed" className={classes.linkHeader}>
{group.heading}
</Text>
{group.items.map((item) => (
<Link
className={classes.link}
data-active={active.startsWith(item.path) || undefined}
key={item.label}
to={item.path}
>
<item.icon className={classes.linkIcon} stroke={2} />
<span>{item.label}</span>
</Link>
))}
</div>
));
const canShowItem = (item: DataItem) => {
if (item.showDisabledInNonEE && item.isEnterprise) {
// Check admin permission regardless of license
return item.isAdmin ? isAdmin : true;
}
if (item.isCloud && item.isEnterprise) {
if (!(isCloud() || workspace?.hasLicenseKey)) return false;
return item.isAdmin ? isAdmin : true;
}
if (item.isCloud) {
return isCloud() ? (item.isAdmin ? isAdmin : true) : false;
}
if (item.isSelfhosted) {
return !isCloud() ? (item.isAdmin ? isAdmin : true) : false;
}
if (item.isEnterprise) {
return workspace?.hasLicenseKey ? (item.isAdmin ? isAdmin : true) : false;
}
if (item.isAdmin) {
return isAdmin;
}
return true;
};
const isItemDisabled = (item: DataItem) => {
if (item.showDisabledInNonEE && item.isEnterprise) {
return !(isCloud() || workspace?.hasLicenseKey);
}
return false;
};
const menuItems = groupedData.map((group) => {
if (group.heading === "System" && (!isAdmin || isCloud())) {
return null;
}
return (
<div key={group.heading}>
<Text c="dimmed" className={classes.linkHeader}>
{t(group.heading)}
</Text>
{group.items.map((item) => {
if (!canShowItem(item)) {
return null;
}
let prefetchHandler: any;
switch (item.label) {
case "Members":
prefetchHandler = prefetchWorkspaceMembers;
break;
case "Spaces":
prefetchHandler = prefetchSpaces;
break;
case "Groups":
prefetchHandler = prefetchGroups;
break;
case "Billing":
prefetchHandler = prefetchBilling;
break;
case "License & Edition":
if (workspace?.hasLicenseKey) {
prefetchHandler = prefetchLicense;
}
break;
case "Security & SSO":
prefetchHandler = prefetchSsoProviders;
break;
case "Public sharing":
prefetchHandler = prefetchShares;
break;
case "API keys":
prefetchHandler = prefetchApiKeys;
break;
case "API management":
prefetchHandler = prefetchApiKeyManagement;
break;
default:
break;
}
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) {
return (
<Tooltip
key={item.label}
label={t("Available in enterprise edition")}
position="right"
withArrow
>
{linkElement}
</Tooltip>
);
}
return linkElement;
})}
</div>
);
});
return (
<div className={classes.navbar}>
<Group className={classes.title} justify="flex-start">
<ActionIcon
onClick={() => navigate(-1)}
onClick={() => {
goBack();
if (mobileSidebarOpened) {
toggleMobileSidebar();
}
}}
variant="transparent"
c="gray"
aria-label="Back"
>
<IconArrowLeft stroke={2} />
</ActionIcon>
<Text fw={500}>Settings</Text>
<Text fw={500}>{t("Settings")}</Text>
</Group>
<ScrollArea w="100%">{menuItems}</ScrollArea>
{!isCloud() && <AppVersion />}
{isCloud() && (
<div className={classes.text}>
<Text
size="sm"
c="dimmed"
component="a"
href="mailto:help@docmost.com"
>
help@docmost.com
</Text>
</div>
)}
</div>
);
}

View File

@ -57,3 +57,8 @@
display: flex;
align-items: center;
}
.text {
padding-left: var(--mantine-spacing-xs) ;
padding-top: 10px;
}

View File

@ -0,0 +1,19 @@
.dark {
@mixin dark {
display: none;
}
@mixin light {
display: block;
}
}
.light {
@mixin light {
display: none;
}
@mixin dark {
display: block;
}
}

View File

@ -1,13 +1,28 @@
import { Button, Group, useMantineColorScheme } from '@mantine/core';
import {
ActionIcon,
Tooltip,
useComputedColorScheme,
useMantineColorScheme,
} from "@mantine/core";
import { IconMoon, IconSun } from "@tabler/icons-react";
import classes from "./theme-toggle.module.css";
export function ThemeToggle() {
const { setColorScheme } = useMantineColorScheme();
const { setColorScheme } = useMantineColorScheme();
const computedColorScheme = useComputedColorScheme();
return (
<Group justify="center" mt="xl">
<Button onClick={() => setColorScheme('light')}>Light</Button>
<Button onClick={() => setColorScheme('dark')}>Dark</Button>
<Button onClick={() => setColorScheme('auto')}>Auto</Button>
</Group>
);
return (
<Tooltip label="Toggle Color Scheme">
<ActionIcon
variant="default"
onClick={() => {
setColorScheme(computedColorScheme === "light" ? "dark" : "light");
}}
aria-label="Toggle color scheme"
>
<IconSun className={classes.light} size={18} stroke={1.5} />
<IconMoon className={classes.dark} size={18} stroke={1.5} />
</ActionIcon>
</Tooltip>
);
}

View File

@ -1,6 +1,7 @@
import React from "react";
import { Avatar } from "@mantine/core";
import { getAvatarUrl } from "@/lib/config.ts";
import { AvatarIconType } from "@/features/attachments/types/attachment.types.ts";
interface CustomAvatarProps {
avatarUrl: string;
@ -11,13 +12,15 @@ interface CustomAvatarProps {
variant?: string;
style?: any;
component?: any;
type?: AvatarIconType;
mt?: string | number;
}
export const CustomAvatar = React.forwardRef<
HTMLInputElement,
CustomAvatarProps
>(({ avatarUrl, name, ...props }: CustomAvatarProps, ref) => {
const avatarLink = getAvatarUrl(avatarUrl);
>(({ avatarUrl, name, type, ...props }: CustomAvatarProps, ref) => {
const avatarLink = getAvatarUrl(avatarUrl, type);
return (
<Avatar

View File

@ -1,19 +1,25 @@
import React, { ReactNode } from "react";
import data from "@emoji-mart/data";
import Picker from "@emoji-mart/react";
import React, { ReactNode, useState } from "react";
import {
ActionIcon,
Popover,
Button,
useMantineColorScheme,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { useClickOutside, useDisclosure, useWindowEvent } from "@mantine/hooks";
import { Suspense } from "react";
const Picker = React.lazy(() => import("@emoji-mart/react"));
import { useTranslation } from "react-i18next";
export interface EmojiPickerInterface {
onEmojiSelect: (emoji: any) => void;
icon: ReactNode;
removeEmojiAction: () => void;
readOnly: boolean;
actionIconProps?: {
size?: string;
variant?: string;
c?: string;
};
}
function EmojiPicker({
@ -21,9 +27,28 @@ function EmojiPicker({
icon,
removeEmojiAction,
readOnly,
actionIconProps,
}: EmojiPickerInterface) {
const { t } = useTranslation();
const [opened, handlers] = useDisclosure(false);
const { colorScheme } = useMantineColorScheme();
const [target, setTarget] = useState<HTMLElement | null>(null);
const [dropdown, setDropdown] = useState<HTMLDivElement | null>(null);
useClickOutside(
() => handlers.close(),
["mousedown", "touchstart"],
[dropdown, target],
);
// We need this because the default Mantine popover closeOnEscape does not work
useWindowEvent("keydown", (event) => {
if (opened && event.key === "Escape") {
event.stopPropagation();
event.preventDefault();
handlers.close();
}
});
const handleEmojiSelect = (emoji) => {
onEmojiSelect(emoji);
@ -42,35 +67,43 @@ function EmojiPicker({
width={332}
position="bottom"
disabled={readOnly}
closeOnEscape={true}
>
<Popover.Target>
<ActionIcon c="gray" variant="transparent" onClick={handlers.toggle}>
<Popover.Target ref={setTarget}>
<ActionIcon
c={actionIconProps?.c || "gray"}
variant={actionIconProps?.variant || "transparent"}
size={actionIconProps?.size}
onClick={handlers.toggle}
>
{icon}
</ActionIcon>
</Popover.Target>
<Popover.Dropdown bg="000" style={{ border: "none" }}>
<Picker
data={data}
onEmojiSelect={handleEmojiSelect}
perLine={8}
skinTonePosition="search"
theme={colorScheme}
/>
<Button
variant="default"
c="gray"
size="xs"
style={{
position: "absolute",
zIndex: 2,
bottom: "1rem",
right: "1rem",
}}
onClick={handleRemoveEmoji}
>
Remove
</Button>
</Popover.Dropdown>
<Suspense fallback={null}>
<Popover.Dropdown bg="000" style={{ border: "none" }} ref={setDropdown}>
<Picker
data={async () => (await import("@emoji-mart/data")).default}
onEmojiSelect={handleEmojiSelect}
perLine={8}
skinTonePosition="search"
theme={colorScheme}
/>
<Button
variant="default"
c="gray"
size="xs"
style={{
position: "absolute",
zIndex: 2,
bottom: "1rem",
right: "1rem",
}}
onClick={handleRemoveEmoji}
>
{t("Remove")}
</Button>
</Popover.Dropdown>
</Suspense>
</Popover>
);
}

View File

@ -1,19 +1,28 @@
import { Title, Text, Button, Container, Group } from "@mantine/core";
import classes from "./error-404.module.css";
import { Link } from "react-router-dom";
import { Helmet } from "react-helmet-async";
import { useTranslation } from "react-i18next";
export function Error404() {
const { t } = useTranslation();
return (
<Container className={classes.root}>
<Title className={classes.title}>404 Page Not Found</Title>
<Text c="dimmed" size="lg" ta="center" className={classes.description}>
Sorry, we can't find the page you are looking for.
</Text>
<Group justify="center">
<Button component={Link} to={"/home"} variant="subtle" size="md">
Take me back to homepage
</Button>
</Group>
</Container>
<>
<Helmet>
<title>{t("404 page not found")} - Docmost</title>
</Helmet>
<Container className={classes.root}>
<Title className={classes.title}>{t("404 page not found")}</Title>
<Text c="dimmed" size="lg" ta="center" className={classes.description}>
{t("Sorry, we can't find the page you are looking for.")}
</Text>
<Group justify="center">
<Button component={Link} to={"/home"} variant="subtle" size="md">
{t("Take me back to homepage")}
</Button>
</Group>
</Container>
</>
);
}

View File

@ -0,0 +1,47 @@
import { Box } from "@mantine/core";
import React from "react";
interface ResponsiveSettingsRowProps {
children: React.ReactNode;
}
export function ResponsiveSettingsRow({ children }: ResponsiveSettingsRowProps) {
return (
<Box
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
gap: "1rem",
flexWrap: "wrap",
}}
>
{children}
</Box>
);
}
interface ResponsiveSettingsContentProps {
children: React.ReactNode;
}
export function ResponsiveSettingsContent({ children }: ResponsiveSettingsContentProps) {
return (
<Box style={{ flex: "1 1 300px", minWidth: 0 }}>
{children}
</Box>
);
}
interface ResponsiveSettingsControlProps {
children: React.ReactNode;
}
export function ResponsiveSettingsControl({ children }: ResponsiveSettingsControlProps) {
return (
<Box style={{ flex: "0 0 auto" }}>
{children}
</Box>
);
}

View File

@ -2,6 +2,7 @@ import React, { forwardRef } from "react";
import { IconCheck, IconChevronDown } from "@tabler/icons-react";
import { Group, Text, Menu, Button } from "@mantine/core";
import { IRoleData } from "@/lib/types.ts";
import { useTranslation } from "react-i18next";
interface RoleButtonProps extends React.ComponentPropsWithoutRef<"button"> {
name: string;
@ -23,7 +24,7 @@ const RoleButton = forwardRef<HTMLButtonElement, RoleButtonProps>(
),
);
interface SpaceRoleMenuProps {
interface RoleMenuProps {
roles: IRoleData[];
roleName: string;
onChange?: (value: string) => void;
@ -35,11 +36,13 @@ export default function RoleSelectMenu({
roleName,
onChange,
disabled,
}: SpaceRoleMenuProps) {
}: RoleMenuProps) {
const { t } = useTranslation();
return (
<Menu withArrow>
<Menu.Target>
<RoleButton name={roleName} disabled={disabled} />
<RoleButton name={t(roleName)} disabled={disabled} />
</Menu.Target>
<Menu.Dropdown>
@ -50,9 +53,9 @@ export default function RoleSelectMenu({
>
<Group flex="1" gap="xs">
<div>
<Text size="sm">{item.label}</Text>
<Text size="sm">{t(item.label)}</Text>
<Text size="xs" opacity={0.65}>
{item.description}
{t(item.description)}
</Text>
</div>
{item.label === roleName && <IconCheck size={20} />}

View File

@ -1,15 +1,9 @@
import React from "react";
import {
IconLayoutSidebarRightCollapse,
IconLayoutSidebarRightExpand,
IconLayoutSidebarRightExpand
} from "@tabler/icons-react";
import {
ActionIcon,
BoxProps,
ElementProps,
MantineColor,
MantineSize,
} from "@mantine/core";
import React from "react";
import { ActionIcon, BoxProps, ElementProps, MantineColor, MantineSize } from "@mantine/core";
export interface SidebarToggleProps extends BoxProps, ElementProps<"button"> {
size?: MantineSize | `compact-${MantineSize}` | (string & {});
@ -17,18 +11,18 @@ export interface SidebarToggleProps extends BoxProps, ElementProps<"button"> {
opened?: boolean;
}
export default function SidebarToggle({
opened,
size = "sm",
...others
}: SidebarToggleProps) {
return (
<ActionIcon size={size} {...others} variant="subtle" color="gray">
{opened ? (
<IconLayoutSidebarRightExpand />
) : (
<IconLayoutSidebarRightCollapse />
)}
</ActionIcon>
);
}
const SidebarToggle = React.forwardRef<HTMLButtonElement, SidebarToggleProps>(
({ opened, size = "sm", ...others }, ref) => {
return (
<ActionIcon size={size} {...others} variant="subtle" color="gray" ref={ref}>
{opened ? (
<IconLayoutSidebarRightExpand />
) : (
<IconLayoutSidebarRightCollapse />
)}
</ActionIcon>
);
}
);
export default SidebarToggle;

View File

@ -0,0 +1 @@
Files in this directory are subject to the Docmost Enterprise Edition license.

View File

@ -0,0 +1,72 @@
import {
Modal,
Text,
Stack,
Alert,
Group,
Button,
TextInput,
} from "@mantine/core";
import { IconAlertTriangle } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import { IApiKey } from "@/ee/api-key";
import CopyTextButton from "@/components/common/copy.tsx";
interface ApiKeyCreatedModalProps {
opened: boolean;
onClose: () => void;
apiKey: IApiKey;
}
export function ApiKeyCreatedModal({
opened,
onClose,
apiKey,
}: ApiKeyCreatedModalProps) {
const { t } = useTranslation();
if (!apiKey) return null;
return (
<Modal
opened={opened}
onClose={onClose}
title={t("API key created")}
size="lg"
>
<Stack gap="md">
<Alert
icon={<IconAlertTriangle size={16} />}
title={t("Important")}
color="red"
>
{t(
"Make sure to copy your API key now. You won't be able to see it again!",
)}
</Alert>
<div>
<Text size="sm" fw={500} mb="xs">
{t("API key")}
</Text>
<Group gap="xs" wrap="nowrap">
<TextInput
variant="filled"
style={{
flex: 1,
}}
value={apiKey.token}
readOnly
/>
<CopyTextButton text={apiKey.token} />
</Group>
</div>
<Button fullWidth onClick={onClose} mt="md">
{t("I've saved my API key")}
</Button>
</Stack>
</Modal>
);
}

View File

@ -0,0 +1,143 @@
import { ActionIcon, Group, Menu, Table, Text } from "@mantine/core";
import { IconDots, IconEdit, IconTrash } from "@tabler/icons-react";
import { format } from "date-fns";
import { useTranslation } from "react-i18next";
import { IApiKey } from "@/ee/api-key";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import React from "react";
import NoTableResults from "@/components/common/no-table-results";
interface ApiKeyTableProps {
apiKeys: IApiKey[];
isLoading?: boolean;
showUserColumn?: boolean;
onUpdate?: (apiKey: IApiKey) => void;
onRevoke?: (apiKey: IApiKey) => void;
}
export function ApiKeyTable({
apiKeys,
isLoading,
showUserColumn = false,
onUpdate,
onRevoke,
}: ApiKeyTableProps) {
const { t } = useTranslation();
const formatDate = (date: Date | string | null) => {
if (!date) return t("Never");
return format(new Date(date), "MMM dd, yyyy");
};
const isExpired = (expiresAt: string | null) => {
if (!expiresAt) return false;
return new Date(expiresAt) < new Date();
};
return (
<Table.ScrollContainer minWidth={500}>
<Table highlightOnHover verticalSpacing="sm">
<Table.Thead>
<Table.Tr>
<Table.Th>{t("Name")}</Table.Th>
{showUserColumn && <Table.Th>{t("User")}</Table.Th>}
<Table.Th>{t("Last used")}</Table.Th>
<Table.Th>{t("Expires")}</Table.Th>
<Table.Th>{t("Created")}</Table.Th>
<Table.Th></Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{apiKeys && apiKeys.length > 0 ? (
apiKeys.map((apiKey: IApiKey, index: number) => (
<Table.Tr key={index}>
<Table.Td>
<Text fz="sm" fw={500}>
{apiKey.name}
</Text>
</Table.Td>
{showUserColumn && apiKey.creator && (
<Table.Td>
<Group gap="4" wrap="nowrap">
<CustomAvatar
avatarUrl={apiKey.creator?.avatarUrl}
name={apiKey.creator.name}
size="sm"
/>
<Text fz="sm" lineClamp={1}>
{apiKey.creator.name}
</Text>
</Group>
</Table.Td>
)}
<Table.Td>
<Text fz="sm" style={{ whiteSpace: "nowrap" }}>
{formatDate(apiKey.lastUsedAt)}
</Text>
</Table.Td>
<Table.Td>
{apiKey.expiresAt ? (
isExpired(apiKey.expiresAt) ? (
<Text fz="sm" style={{ whiteSpace: "nowrap" }}>
{t("Expired")}
</Text>
) : (
<Text fz="sm" style={{ whiteSpace: "nowrap" }}>
{formatDate(apiKey.expiresAt)}
</Text>
)
) : (
<Text fz="sm" style={{ whiteSpace: "nowrap" }}>
{t("Never")}
</Text>
)}
</Table.Td>
<Table.Td>
<Text fz="sm" style={{ whiteSpace: "nowrap" }}>
{formatDate(apiKey.createdAt)}
</Text>
</Table.Td>
<Table.Td>
<Menu position="bottom-end" withinPortal>
<Menu.Target>
<ActionIcon variant="subtle" color="gray">
<IconDots size={16} />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
{onUpdate && (
<Menu.Item
leftSection={<IconEdit size={16} />}
onClick={() => onUpdate(apiKey)}
>
{t("Rename")}
</Menu.Item>
)}
{onRevoke && (
<Menu.Item
leftSection={<IconTrash size={16} />}
color="red"
onClick={() => onRevoke(apiKey)}
>
{t("Revoke")}
</Menu.Item>
)}
</Menu.Dropdown>
</Menu>
</Table.Td>
</Table.Tr>
))
) : (
<NoTableResults colSpan={showUserColumn ? 6 : 5} />
)}
</Table.Tbody>
</Table>
</Table.ScrollContainer>
);
}

View File

@ -0,0 +1,153 @@
import { lazy, Suspense, useState } from "react";
import { Modal, TextInput, Button, Group, Stack, Select } from "@mantine/core";
import { useForm } from "@mantine/form";
import { zodResolver } from "mantine-form-zod-resolver";
import { z } from "zod";
import { useTranslation } from "react-i18next";
import { useCreateApiKeyMutation } from "@/ee/api-key/queries/api-key-query";
import { IconCalendar } from "@tabler/icons-react";
import { IApiKey } from "@/ee/api-key";
const DateInput = lazy(() =>
import("@mantine/dates").then((module) => ({
default: module.DateInput,
})),
);
interface CreateApiKeyModalProps {
opened: boolean;
onClose: () => void;
onSuccess: (response: IApiKey) => void;
}
const formSchema = z.object({
name: z.string().min(1, "Name is required"),
expiresAt: z.string().optional(),
});
type FormValues = z.infer<typeof formSchema>;
export function CreateApiKeyModal({
opened,
onClose,
onSuccess,
}: CreateApiKeyModalProps) {
const { t } = useTranslation();
const [expirationOption, setExpirationOption] = useState<string>("30");
const createApiKeyMutation = useCreateApiKeyMutation();
const form = useForm<FormValues>({
validate: zodResolver(formSchema),
initialValues: {
name: "",
expiresAt: "",
},
});
const getExpirationDate = (): string | undefined => {
if (expirationOption === "never") {
return undefined;
}
if (expirationOption === "custom") {
return form.values.expiresAt;
}
const days = parseInt(expirationOption);
const date = new Date();
date.setDate(date.getDate() + days);
return date.toISOString();
};
const getExpirationLabel = (days: number) => {
const date = new Date();
date.setDate(date.getDate() + days);
const formatted = date.toLocaleDateString("en-US", {
month: "short",
day: "2-digit",
year: "numeric",
});
return `${days} days (${formatted})`;
};
const expirationOptions = [
{ value: "30", label: getExpirationLabel(30) },
{ value: "60", label: getExpirationLabel(60) },
{ value: "90", label: getExpirationLabel(90) },
{ value: "365", label: getExpirationLabel(365) },
{ value: "custom", label: t("Custom") },
{ value: "never", label: t("No expiration") },
];
const handleSubmit = async (data: {
name?: string;
expiresAt?: string | Date;
}) => {
const groupData = {
name: data.name,
expiresAt: getExpirationDate(),
};
try {
const createdKey = await createApiKeyMutation.mutateAsync(groupData);
onSuccess(createdKey);
form.reset();
onClose();
} catch (err) {
//
}
};
const handleClose = () => {
form.reset();
setExpirationOption("30");
onClose();
};
return (
<Modal
opened={opened}
onClose={handleClose}
title={t("Create API Key")}
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")}
/>
<Select
label={t("Expiration")}
data={expirationOptions}
value={expirationOption}
onChange={(value) => setExpirationOption(value || "30")}
leftSection={<IconCalendar size={16} />}
allowDeselect={false}
/>
{expirationOption === "custom" && (
<Suspense fallback={null}>
<DateInput
label={t("Custom expiration date")}
placeholder={t("Select expiration date")}
minDate={new Date()}
{...form.getInputProps("expiresAt")}
/>
</Suspense>
)}
<Group justify="flex-end" mt="md">
<Button variant="default" onClick={handleClose}>
{t("Cancel")}
</Button>
<Button type="submit" loading={createApiKeyMutation.isPending}>
{t("Create")}
</Button>
</Group>
</Stack>
</form>
</Modal>
);
}

View File

@ -0,0 +1,62 @@
import { Modal, Text, Button, Group, Stack } from "@mantine/core";
import { useTranslation } from "react-i18next";
import { useRevokeApiKeyMutation } from "@/ee/api-key/queries/api-key-query.ts";
import { IApiKey } from "@/ee/api-key";
interface RevokeApiKeyModalProps {
opened: boolean;
onClose: () => void;
apiKey: IApiKey | null;
}
export function RevokeApiKeyModal({
opened,
onClose,
apiKey,
}: RevokeApiKeyModalProps) {
const { t } = useTranslation();
const revokeApiKeyMutation = useRevokeApiKeyMutation();
const handleRevoke = async () => {
if (!apiKey) return;
await revokeApiKeyMutation.mutateAsync({
apiKeyId: apiKey.id,
});
onClose();
};
return (
<Modal
opened={opened}
onClose={onClose}
title={t("Revoke API key")}
size="md"
>
<Stack gap="md">
<Text>
{t("Are you sure you want to revoke this API key")}{" "}
<strong>{apiKey?.name}</strong>?
</Text>
<Text size="sm" c="dimmed">
{t(
"This action cannot be undone. Any applications using this API key will stop working.",
)}
</Text>
<Group justify="flex-end" mt="md">
<Button variant="default" onClick={onClose}>
{t("Cancel")}
</Button>
<Button
color="red"
onClick={handleRevoke}
loading={revokeApiKeyMutation.isPending}
>
{t("Revoke")}
</Button>
</Group>
</Stack>
</Modal>
);
}

View File

@ -0,0 +1,80 @@
import { Modal, TextInput, Button, Group, Stack } from "@mantine/core";
import { useForm } from "@mantine/form";
import { zodResolver } from "mantine-form-zod-resolver";
import { z } from "zod";
import { useTranslation } from "react-i18next";
import { useUpdateApiKeyMutation } from "@/ee/api-key/queries/api-key-query";
import { IApiKey } from "@/ee/api-key";
import { useEffect } from "react";
const formSchema = z.object({
name: z.string().min(1, "Name is required"),
});
type FormValues = z.infer<typeof formSchema>;
interface UpdateApiKeyModalProps {
opened: boolean;
onClose: () => void;
apiKey: IApiKey | null;
}
export function UpdateApiKeyModal({
opened,
onClose,
apiKey,
}: UpdateApiKeyModalProps) {
const { t } = useTranslation();
const updateApiKeyMutation = useUpdateApiKeyMutation();
const form = useForm<FormValues>({
validate: zodResolver(formSchema),
initialValues: {
name: "",
},
});
useEffect(() => {
if (opened && apiKey) {
form.setValues({ name: apiKey.name });
}
}, [opened, apiKey]);
const handleSubmit = async (data: { name?: string }) => {
const apiKeyData = {
apiKeyId: apiKey.id,
name: data.name,
};
await updateApiKeyMutation.mutateAsync(apiKeyData);
onClose();
};
return (
<Modal
opened={opened}
onClose={onClose}
title={t("Update API key")}
size="md"
>
<form onSubmit={form.onSubmit((values) => handleSubmit(values))}>
<Stack gap="md">
<TextInput
label={t("Name")}
placeholder={t("Enter a descriptive token name")}
required
{...form.getInputProps("name")}
/>
<Group justify="flex-end" mt="md">
<Button variant="default" onClick={onClose}>
{t("Cancel")}
</Button>
<Button type="submit" loading={updateApiKeyMutation.isPending}>
{t("Update")}
</Button>
</Group>
</Stack>
</form>
</Modal>
);
}

View File

@ -0,0 +1,11 @@
export { ApiKeyTable } from "./components/api-key-table";
export { CreateApiKeyModal } from "./components/create-api-key-modal";
export { ApiKeyCreatedModal } from "./components/api-key-created-modal";
export { UpdateApiKeyModal } from "./components/update-api-key-modal";
export { RevokeApiKeyModal } from "./components/revoke-api-key-modal";
// Services
export * from "./services/api-key-service";
// Types
export * from "./types/api-key.types";

View File

@ -0,0 +1,106 @@
import React, { useState } from "react";
import { Button, Group, Space } from "@mantine/core";
import { Helmet } from "react-helmet-async";
import { useTranslation } from "react-i18next";
import SettingsTitle from "@/components/settings/settings-title";
import { getAppName } from "@/lib/config";
import { ApiKeyTable } from "@/ee/api-key/components/api-key-table";
import { CreateApiKeyModal } from "@/ee/api-key/components/create-api-key-modal";
import { ApiKeyCreatedModal } from "@/ee/api-key/components/api-key-created-modal";
import { UpdateApiKeyModal } from "@/ee/api-key/components/update-api-key-modal";
import { RevokeApiKeyModal } from "@/ee/api-key/components/revoke-api-key-modal";
import Paginate from "@/components/common/paginate";
import { usePaginateAndSearch } from "@/hooks/use-paginate-and-search";
import { useGetApiKeysQuery } from "@/ee/api-key/queries/api-key-query.ts";
import { IApiKey } from "@/ee/api-key";
export default function UserApiKeys() {
const { t } = useTranslation();
const { page, setPage } = usePaginateAndSearch();
const [createModalOpened, setCreateModalOpened] = useState(false);
const [createdApiKey, setCreatedApiKey] = useState<IApiKey | null>(null);
const [updateModalOpened, setUpdateModalOpened] = useState(false);
const [revokeModalOpened, setRevokeModalOpened] = useState(false);
const [selectedApiKey, setSelectedApiKey] = useState<IApiKey | null>(null);
const { data, isLoading } = useGetApiKeysQuery({ page });
const handleCreateSuccess = (response: IApiKey) => {
setCreatedApiKey(response);
};
const handleUpdate = (apiKey: IApiKey) => {
setSelectedApiKey(apiKey);
setUpdateModalOpened(true);
};
const handleRevoke = (apiKey: IApiKey) => {
setSelectedApiKey(apiKey);
setRevokeModalOpened(true);
};
return (
<>
<Helmet>
<title>
{t("API keys")} - {getAppName()}
</title>
</Helmet>
<SettingsTitle title={t("API keys")} />
<Group justify="flex-end" mb="md">
<Button onClick={() => setCreateModalOpened(true)}>
{t("Create API Key")}
</Button>
</Group>
<ApiKeyTable
apiKeys={data?.items || []}
isLoading={isLoading}
onUpdate={handleUpdate}
onRevoke={handleRevoke}
/>
<Space h="md" />
{data?.items.length > 0 && (
<Paginate
currentPage={page}
hasPrevPage={data?.meta.hasPrevPage}
hasNextPage={data?.meta.hasNextPage}
onPageChange={setPage}
/>
)}
<CreateApiKeyModal
opened={createModalOpened}
onClose={() => setCreateModalOpened(false)}
onSuccess={handleCreateSuccess}
/>
<ApiKeyCreatedModal
opened={!!createdApiKey}
onClose={() => setCreatedApiKey(null)}
apiKey={createdApiKey}
/>
<UpdateApiKeyModal
opened={updateModalOpened}
onClose={() => {
setUpdateModalOpened(false);
setSelectedApiKey(null);
}}
apiKey={selectedApiKey}
/>
<RevokeApiKeyModal
opened={revokeModalOpened}
onClose={() => {
setRevokeModalOpened(false);
setSelectedApiKey(null);
}}
apiKey={selectedApiKey}
/>
</>
);
}

View File

@ -0,0 +1,117 @@
import React, { useState } from "react";
import { Button, Group, Space, Text } from "@mantine/core";
import { Helmet } from "react-helmet-async";
import { useTranslation } from "react-i18next";
import SettingsTitle from "@/components/settings/settings-title";
import { getAppName } from "@/lib/config";
import { ApiKeyTable } from "@/ee/api-key/components/api-key-table";
import { CreateApiKeyModal } from "@/ee/api-key/components/create-api-key-modal";
import { ApiKeyCreatedModal } from "@/ee/api-key/components/api-key-created-modal";
import { UpdateApiKeyModal } from "@/ee/api-key/components/update-api-key-modal";
import { RevokeApiKeyModal } from "@/ee/api-key/components/revoke-api-key-modal";
import Paginate from "@/components/common/paginate";
import { usePaginateAndSearch } from "@/hooks/use-paginate-and-search";
import { useGetApiKeysQuery } from "@/ee/api-key/queries/api-key-query.ts";
import { IApiKey } from "@/ee/api-key";
import useUserRole from '@/hooks/use-user-role.tsx';
export default function WorkspaceApiKeys() {
const { t } = useTranslation();
const { page, setPage } = usePaginateAndSearch();
const [createModalOpened, setCreateModalOpened] = useState(false);
const [createdApiKey, setCreatedApiKey] = useState<IApiKey | null>(null);
const [updateModalOpened, setUpdateModalOpened] = useState(false);
const [revokeModalOpened, setRevokeModalOpened] = useState(false);
const [selectedApiKey, setSelectedApiKey] = useState<IApiKey | null>(null);
const { data, isLoading } = useGetApiKeysQuery({ page, adminView: true });
const { isAdmin } = useUserRole();
if (!isAdmin) {
return null;
}
const handleCreateSuccess = (response: IApiKey) => {
setCreatedApiKey(response);
};
const handleUpdate = (apiKey: IApiKey) => {
setSelectedApiKey(apiKey);
setUpdateModalOpened(true);
};
const handleRevoke = (apiKey: IApiKey) => {
setSelectedApiKey(apiKey);
setRevokeModalOpened(true);
};
return (
<>
<Helmet>
<title>
{t("API management")} - {getAppName()}
</title>
</Helmet>
<SettingsTitle title={t("API management")} />
<Text size="md" c="dimmed" mb="md">
{t("Manage API keys for all users in the workspace")}
</Text>
<Group justify="flex-end" mb="md">
<Button onClick={() => setCreateModalOpened(true)}>
{t("Create API Key")}
</Button>
</Group>
<ApiKeyTable
apiKeys={data?.items}
isLoading={isLoading}
showUserColumn
onUpdate={handleUpdate}
onRevoke={handleRevoke}
/>
<Space h="md" />
{data?.items.length > 0 && (
<Paginate
currentPage={page}
hasPrevPage={data?.meta.hasPrevPage}
hasNextPage={data?.meta.hasNextPage}
onPageChange={setPage}
/>
)}
<CreateApiKeyModal
opened={createModalOpened}
onClose={() => setCreateModalOpened(false)}
onSuccess={handleCreateSuccess}
/>
<ApiKeyCreatedModal
opened={!!createdApiKey}
onClose={() => setCreatedApiKey(null)}
apiKey={createdApiKey}
/>
<UpdateApiKeyModal
opened={updateModalOpened}
onClose={() => {
setUpdateModalOpened(false);
setSelectedApiKey(null);
}}
apiKey={selectedApiKey}
/>
<RevokeApiKeyModal
opened={revokeModalOpened}
onClose={() => {
setRevokeModalOpened(false);
setSelectedApiKey(null);
}}
apiKey={selectedApiKey}
/>
</>
);
}

View File

@ -0,0 +1,97 @@
import { IPagination, QueryParams } from "@/lib/types.ts";
import {
keepPreviousData,
useMutation,
useQuery,
useQueryClient,
UseQueryResult,
} from "@tanstack/react-query";
import {
createApiKey,
getApiKeys,
IApiKey,
ICreateApiKeyRequest,
IUpdateApiKeyRequest,
revokeApiKey,
updateApiKey,
} from "@/ee/api-key";
import { notifications } from "@mantine/notifications";
import { useTranslation } from "react-i18next";
export function useGetApiKeysQuery(
params?: QueryParams,
): UseQueryResult<IPagination<IApiKey>, Error> {
return useQuery({
queryKey: ["api-key-list", params],
queryFn: () => getApiKeys(params),
staleTime: 0,
gcTime: 0,
placeholderData: keepPreviousData,
});
}
export function useRevokeApiKeyMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<
void,
Error,
{
apiKeyId: string;
}
>({
mutationFn: (data) => revokeApiKey(data),
onSuccess: (data, variables) => {
notifications.show({ message: t("Revoked successfully") });
queryClient.invalidateQueries({
predicate: (item) =>
["api-key-list"].includes(item.queryKey[0] as string),
});
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({ message: errorMessage, color: "red" });
},
});
}
export function useCreateApiKeyMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<IApiKey, Error, ICreateApiKeyRequest>({
mutationFn: (data) => createApiKey(data),
onSuccess: () => {
notifications.show({ message: t("API key created successfully") });
queryClient.invalidateQueries({
predicate: (item) =>
["api-key-list"].includes(item.queryKey[0] as string),
});
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({ message: errorMessage, color: "red" });
},
});
}
export function useUpdateApiKeyMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
return useMutation<IApiKey, Error, IUpdateApiKeyRequest>({
mutationFn: (data) => updateApiKey(data),
onSuccess: (data, variables) => {
notifications.show({ message: t("Updated successfully") });
queryClient.invalidateQueries({
predicate: (item) =>
["api-key-list"].includes(item.queryKey[0] as string),
});
},
onError: (error) => {
const errorMessage = error["response"]?.data?.message;
notifications.show({ message: errorMessage, color: "red" });
},
});
}

View File

@ -0,0 +1,32 @@
import api from "@/lib/api-client";
import {
ICreateApiKeyRequest,
IApiKey,
IUpdateApiKeyRequest,
} from "@/ee/api-key/types/api-key.types";
import { IPagination, QueryParams } from "@/lib/types.ts";
export async function getApiKeys(
params?: QueryParams,
): Promise<IPagination<IApiKey>> {
const req = await api.post("/api-keys", { ...params });
return req.data;
}
export async function createApiKey(
data: ICreateApiKeyRequest,
): Promise<IApiKey> {
const req = await api.post<IApiKey>("/api-keys/create", data);
return req.data;
}
export async function updateApiKey(
data: IUpdateApiKeyRequest,
): Promise<IApiKey> {
const req = await api.post<IApiKey>("/api-keys/update", data);
return req.data;
}
export async function revokeApiKey(data: { apiKeyId: string }): Promise<void> {
await api.post("/api-keys/revoke", data);
}

View File

@ -0,0 +1,23 @@
import { IUser } from "@/features/user/types/user.types.ts";
export interface IApiKey {
id: string;
name: string;
token?: string;
creatorId: string;
workspaceId: string;
expiresAt: string | null;
lastUsedAt: string | null;
createdAt: string;
creator: Partial<IUser>;
}
export interface ICreateApiKeyRequest {
name: string;
expiresAt?: string;
}
export interface IUpdateApiKeyRequest {
apiKeyId: string;
name: string;
}

View File

@ -0,0 +1,171 @@
import {
useBillingPlans,
useBillingQuery,
} from "@/ee/billing/queries/billing-query.ts";
import { Group, Text, SimpleGrid, Paper } from "@mantine/core";
import classes from "./billing.module.css";
import { format } from "date-fns";
import { formatInterval } from "@/ee/billing/utils.ts";
export default function BillingDetails() {
const { data: billing } = useBillingQuery();
const { data: plans } = useBillingPlans();
if (!billing || !plans) {
return null;
}
return (
<div className={classes.root}>
<SimpleGrid cols={{ base: 1, xs: 2, sm: 3 }}>
<Paper p="md" radius="md">
<Group justify="apart">
<div>
<Text
c="dimmed"
tt="uppercase"
fw={700}
fz="xs"
className={classes.label}
>
Plan
</Text>
<Text fw={700} fz="lg" tt="capitalize">
{plans.find(
(plan) => plan.productId === billing.stripeProductId,
)?.name ||
billing.planName ||
"Standard"}
</Text>
</div>
</Group>
</Paper>
<Paper p="md" radius="md">
<Group justify="apart">
<div>
<Text
c="dimmed"
tt="uppercase"
fw={700}
fz="xs"
className={classes.label}
>
Billing Period
</Text>
<Text fw={700} fz="lg" tt="capitalize">
{formatInterval(billing.interval)}
</Text>
</div>
</Group>
</Paper>
<Paper p="md" radius="md">
<Group justify="apart">
<div>
<Text
c="dimmed"
tt="uppercase"
fw={700}
fz="xs"
className={classes.label}
>
{billing.cancelAtPeriodEnd
? "Cancellation date"
: "Renewal date"}
</Text>
<Text fw={700} fz="lg">
{format(billing.periodEndAt, "dd MMM, yyyy")}
</Text>
</div>
</Group>
</Paper>
</SimpleGrid>
<SimpleGrid cols={{ base: 1, xs: 2, sm: 3 }}>
<Paper p="md" radius="md">
<Group justify="apart">
<div>
<Text
c="dimmed"
tt="uppercase"
fw={700}
fz="xs"
className={classes.label}
>
Seat count
</Text>
<Text fw={700} fz="lg">
{billing.quantity}
</Text>
</div>
</Group>
</Paper>
<Paper p="md" radius="md">
<Group justify="apart">
<div>
<Text
c="dimmed"
tt="uppercase"
fw={700}
fz="xs"
className={classes.label}
>
Cost
</Text>
{billing.billingScheme === "tiered" && (
<>
<Text fw={700} fz="lg">
${billing.amount / 100} {billing.currency.toUpperCase()} /{" "}
{billing.interval}
</Text>
<Text c="dimmed" fz="sm">
per {billing.interval}
</Text>
</>
)}
{billing.billingScheme !== "tiered" && (
<>
<Text fw={700} fz="lg">
{(billing.amount / 100) * billing.quantity}{" "}
{billing.currency.toUpperCase()} / {billing.interval}
</Text>
<Text c="dimmed" fz="sm">
${billing.amount / 100} /user/{billing.interval}
</Text>
</>
)}
</div>
</Group>
</Paper>
{billing.billingScheme === "tiered" && billing.tieredUpTo && (
<Paper p="md" radius="md">
<Group justify="apart">
<div>
<Text
c="dimmed"
tt="uppercase"
fw={700}
fz="xs"
className={classes.label}
>
Current Tier
</Text>
<Text fw={700} fz="lg">
For {billing.tieredUpTo} users
</Text>
{/*billing.tieredFlatAmount && (
<Text c="dimmed" fz="sm">
</Text>
)*/}
</div>
</Group>
</Paper>
)}
</SimpleGrid>
</div>
);
}

View File

@ -0,0 +1,13 @@
import { Alert } from "@mantine/core";
import React from "react";
export default function BillingIncomplete() {
return (
<>
<Alert variant="light" color="blue">
Your subscription is in an incomplete state. Please refresh this page if
you recently made your payment.
</Alert>
</>
);
}

View File

@ -0,0 +1,233 @@
import {
Button,
Card,
List,
ThemeIcon,
Title,
Text,
Group,
Select,
Container,
Stack,
Badge,
Flex,
Switch,
Alert,
} from "@mantine/core";
import { useState } from "react";
import { IconCheck, IconInfoCircle } from "@tabler/icons-react";
import { getCheckoutLink } from "@/ee/billing/services/billing-service.ts";
import { useBillingPlans } from "@/ee/billing/queries/billing-query.ts";
import { useAtomValue } from "jotai";
import { workspaceAtom } from "@/features/user/atoms/current-user-atom";
export default function BillingPlans() {
const { data: plans } = useBillingPlans();
const workspace = useAtomValue(workspaceAtom);
const [isAnnual, setIsAnnual] = useState(true);
const [selectedTierValue, setSelectedTierValue] = useState<string | null>(
null,
);
const handleCheckout = async (priceId: string) => {
try {
const checkoutLink = await getCheckoutLink({
priceId: priceId,
});
window.location.href = checkoutLink.url;
} catch (err) {
console.error("Failed to get checkout link", err);
}
};
// TODO: remove by July 30.
// Check if workspace was created between June 28 and July 14, 2025
const showTieredPricingNotice = (() => {
if (!workspace?.createdAt) return false;
const createdDate = new Date(workspace.createdAt);
const startDate = new Date('2025-06-20');
const endDate = new Date('2025-07-14');
return createdDate >= startDate && createdDate <= endDate;
})();
if (!plans || plans.length === 0) {
return null;
}
// Check if any plan is tiered
const hasTieredPlans = plans.some(plan => plan.billingScheme === 'tiered' && plan.pricingTiers?.length > 0);
const firstTieredPlan = plans.find(plan => plan.billingScheme === 'tiered' && plan.pricingTiers?.length > 0);
// Set initial tier value if not set and we have tiered plans
if (hasTieredPlans && !selectedTierValue && firstTieredPlan) {
setSelectedTierValue(firstTieredPlan.pricingTiers[0].upTo.toString());
return null;
}
// For tiered plans, ensure we have a selected tier
if (hasTieredPlans && !selectedTierValue) {
return null;
}
const selectData = firstTieredPlan?.pricingTiers
?.filter((tier) => !tier.custom)
.map((tier, index) => {
const prevMaxUsers =
index > 0 ? firstTieredPlan.pricingTiers[index - 1].upTo : 0;
return {
value: tier.upTo.toString(),
label: `${prevMaxUsers + 1}-${tier.upTo} users`,
};
}) || [];
return (
<Container size="xl" py="xl">
{/* Tiered pricing notice for eligible workspaces */}
{showTieredPricingNotice && !hasTieredPlans && (
<Alert
icon={<IconInfoCircle size={16} />}
title="Want the old tiered pricing?"
color="blue"
mb="lg"
>
Contact support to switch back to our tiered pricing model.
</Alert>
)}
{/* Controls Section */}
<Stack gap="xl" mb="md">
{/* Team Size and Billing Controls */}
<Group justify="center" align="center" gap="sm">
{hasTieredPlans && (
<Select
label="Team size"
description="Select the number of users"
value={selectedTierValue}
onChange={setSelectedTierValue}
data={selectData}
w={250}
size="md"
allowDeselect={false}
/>
)}
<Group justify="center" align="start">
<Flex justify="center" gap="md" align="center">
<Text size="md">Monthly</Text>
<Switch
defaultChecked={isAnnual}
onChange={(event) => setIsAnnual(event.target.checked)}
size="sm"
/>
<Text size="md">
Annually
<Badge component="span" variant="light" color="blue">
15% OFF
</Badge>
</Text>
</Flex>
</Group>
</Group>
</Stack>
{/* Plans Grid */}
<Group justify="center" gap="lg" align="stretch">
{plans.map((plan, index) => {
let price;
let displayPrice;
const priceId = isAnnual ? plan.yearlyId : plan.monthlyId;
if (plan.billingScheme === 'tiered' && plan.pricingTiers?.length > 0) {
// Tiered billing logic
const planSelectedTier =
plan.pricingTiers.find(
(tier) => tier.upTo.toString() === selectedTierValue,
) || plan.pricingTiers[0];
price = isAnnual
? planSelectedTier.yearly
: planSelectedTier.monthly;
displayPrice = isAnnual ? (price / 12).toFixed(0) : price;
} else {
// Per-unit billing logic
const monthlyPrice = parseFloat(plan.price?.monthly || '0');
const yearlyPrice = parseFloat(plan.price?.yearly || '0');
price = isAnnual ? yearlyPrice : monthlyPrice;
displayPrice = isAnnual ? (yearlyPrice / 12).toFixed(0) : monthlyPrice;
}
return (
<Card
key={plan.name}
withBorder
radius="lg"
shadow="sm"
p="xl"
w={350}
miw={300}
style={{
position: "relative",
}}
>
<Stack gap="lg">
{/* Plan Header */}
<Stack gap="xs">
<Title order={3} size="h4">
{plan.name}
</Title>
{plan.description && (
<Text size="sm" c="dimmed">
{plan.description}
</Text>
)}
</Stack>
{/* Pricing */}
<Stack gap="xs">
<Group align="baseline" gap="xs">
<Title order={1} size="h1">
${displayPrice}
</Title>
<Text size="lg" c="dimmed">
{plan.billingScheme === 'per_unit'
? `per user/month`
: `per month`}
</Text>
</Group>
<Text size="sm" c="dimmed">
{isAnnual ? "Billed annually" : "Billed monthly"}
</Text>
{plan.billingScheme === 'tiered' && plan.pricingTiers && (
<Text size="md" fw={500}>
For {plan.pricingTiers.find(tier => tier.upTo.toString() === selectedTierValue)?.upTo || plan.pricingTiers[0].upTo} users
</Text>
)}
</Stack>
{/* CTA Button */}
<Button onClick={() => handleCheckout(priceId)} fullWidth>
Subscribe
</Button>
{/* Features */}
<List
spacing="xs"
size="sm"
icon={
<ThemeIcon size={20} radius="xl">
<IconCheck size={14} />
</ThemeIcon>
}
>
{plan.features.map((feature, featureIndex) => (
<List.Item key={featureIndex}>{feature}</List.Item>
))}
</List>
</Stack>
</Card>
);
})}
</Group>
</Container>
);
}

View File

@ -0,0 +1,32 @@
import { Alert } from "@mantine/core";
import { useBillingQuery } from "@/ee/billing/queries/billing-query.ts";
import useTrial from "@/ee/hooks/use-trial.tsx";
import { getBillingTrialDays } from '@/lib/config.ts';
export default function BillingTrial() {
const { data: billing, isLoading } = useBillingQuery();
const { trialDaysLeft } = useTrial();
if (isLoading) {
return null;
}
return (
<>
{trialDaysLeft > 0 && !billing && (
<Alert title="Your Trial is Active 🎉" color="blue" radius="md">
You have {trialDaysLeft} {trialDaysLeft === 1 ? "day" : "days"} left
in your {getBillingTrialDays()}-day free trial. Please subscribe to a paid plan before your trial
ends.
</Alert>
)}
{trialDaysLeft === 0 && (
<Alert title="Your Trial has ended" color="red" radius="md">
Your {getBillingTrialDays()}-day free trial has come to an end. Please subscribe to a paid plan to
continue using this service.
</Alert>
)}
</>
);
}

View File

@ -0,0 +1,10 @@
.root {
padding-top: var(--mantine-spacing-xs);
padding-bottom: var(--mantine-spacing-xs);
}
.label {
font-family:
Greycliff CF,
var(--mantine-font-family);
}

View File

@ -0,0 +1,34 @@
import { Button, Group, Text } from "@mantine/core";
import React from "react";
import { getBillingPortalLink } from "@/ee/billing/services/billing-service.ts";
export default function ManageBilling() {
const handleBillingPortal = async () => {
try {
const portalLink = await getBillingPortalLink();
window.location.href = portalLink.url;
} catch (err) {
console.error("Failed to get billing portal link", err);
}
};
return (
<>
<Group justify="space-between" wrap="wrap" gap="xl">
<div style={{ flex: 1, minWidth: "200px" }}>
<Text size="md" fw={500}>
Manage subscription
</Text>
<Text size="sm" c="dimmed">
Manage your your subscription, invoices, update payment details, and
more.
</Text>
</div>
<Button style={{ flexShrink: 0 }} onClick={handleBillingPortal}>
Manage
</Button>
</Group>
</>
);
}

View File

@ -0,0 +1,41 @@
import { Helmet } from "react-helmet-async";
import { getAppName } from "@/lib/config.ts";
import SettingsTitle from "@/components/settings/settings-title.tsx";
import BillingPlans from "@/ee/billing/components/billing-plans.tsx";
import BillingTrial from "@/ee/billing/components/billing-trial.tsx";
import ManageBilling from "@/ee/billing/components/manage-billing.tsx";
import { Divider } from "@mantine/core";
import React from "react";
import BillingDetails from "@/ee/billing/components/billing-details.tsx";
import { useBillingQuery } from "@/ee/billing/queries/billing-query.ts";
import useUserRole from "@/hooks/use-user-role.tsx";
export default function Billing() {
const { data: billing, isError: isBillingError } = useBillingQuery();
const { isAdmin } = useUserRole();
if (!isAdmin) {
return null;
}
return (
<>
<Helmet>
<title>Billing - {getAppName()}</title>
</Helmet>
<SettingsTitle title="Billing" />
<BillingTrial />
<BillingDetails />
{isBillingError && <BillingPlans />}
{billing && (
<>
<Divider my="lg" />
<ManageBilling />
</>
)}
</>
);
}

View File

@ -0,0 +1,20 @@
import { useQuery, UseQueryResult } from "@tanstack/react-query";
import {
getBilling,
getBillingPlans,
} from "@/ee/billing/services/billing-service.ts";
import { IBilling, IBillingPlan } from "@/ee/billing/types/billing.types.ts";
export function useBillingQuery(): UseQueryResult<IBilling, Error> {
return useQuery({
queryKey: ["billing"],
queryFn: () => getBilling(),
});
}
export function useBillingPlans(): UseQueryResult<IBillingPlan[], Error> {
return useQuery({
queryKey: ["billing-plans"],
queryFn: () => getBillingPlans(),
});
}

View File

@ -0,0 +1,29 @@
import api from "@/lib/api-client.ts";
import {
IBilling,
IBillingPlan,
IBillingPortal,
ICheckoutLink,
} from "@/ee/billing/types/billing.types.ts";
export async function getBilling(): Promise<IBilling> {
const req = await api.post<IBilling>("/billing/info");
return req.data;
}
export async function getBillingPlans(): Promise<IBillingPlan[]> {
const req = await api.post<IBillingPlan[]>("/billing/plans");
return req.data;
}
export async function getCheckoutLink(data: {
priceId: string;
}): Promise<ICheckoutLink> {
const req = await api.post<ICheckoutLink>("/billing/checkout", data);
return req.data;
}
export async function getBillingPortalLink(): Promise<IBillingPortal> {
const req = await api.post<IBillingPortal>("/billing/portal");
return req.data;
}

View File

@ -0,0 +1,64 @@
export enum BillingPlan {
STANDARD = "standard",
BUSINESS = "business",
}
export interface IBilling {
id: string;
stripeSubscriptionId: string;
stripeCustomerId: string;
status: string;
quantity: number;
amount: number;
interval: string;
currency: string;
metadata: Record<string, any>;
stripePriceId: string;
stripeItemId: string;
stripeProductId: string;
periodStartAt: Date;
periodEndAt: Date;
cancelAtPeriodEnd: boolean;
cancelAt: Date;
canceledAt: Date;
workspaceId: string;
createdAt: Date;
updatedAt: Date;
deletedAt: Date;
billingScheme: string | null;
tieredUpTo: string | null;
tieredFlatAmount: number | null;
tieredUnitAmount: number | null;
planName: string | null;
}
export interface ICheckoutLink {
url: string;
}
export interface IBillingPortal {
url: string;
}
export interface IBillingPlan {
name: string;
description: string;
productId: string;
monthlyId: string;
yearlyId: string;
currency: string;
price?: {
monthly: string;
yearly: string;
};
features: string[];
billingScheme: string | null;
pricingTiers?: PricingTier[];
}
interface PricingTier {
upTo: number;
monthly?: number;
yearly?: number;
custom?: boolean;
}

View File

@ -0,0 +1,17 @@
import { differenceInCalendarDays } from "date-fns";
export function formatInterval(interval: string): string {
if (interval === "month") {
return "monthly";
}
if (interval === "year") {
return "yearly";
}
}
export function getTrialDaysLeft(trialEndAt: Date) {
if (!trialEndAt) return null;
const daysLeft = differenceInCalendarDays(trialEndAt, new Date());
return daysLeft > 0 ? daysLeft : 0;
}

View File

@ -0,0 +1,13 @@
import { useQuery, UseQueryResult } from "@tanstack/react-query";
import { IWorkspace } from "@/features/workspace/types/workspace.types.ts";
import { getJoinedWorkspaces } from "@/ee/cloud/service/cloud-service.ts";
export function useJoinedWorkspacesQuery(): UseQueryResult<
Partial<IWorkspace[]>,
Error
> {
return useQuery({
queryKey: ["joined-workspaces"],
queryFn: () => getJoinedWorkspaces(),
});
}

View File

@ -0,0 +1,7 @@
import { IWorkspace } from "@/features/workspace/types/workspace.types.ts";
import api from "@/lib/api-client.ts";
export async function getJoinedWorkspaces(): Promise<Partial<IWorkspace[]>> {
const req = await api.post<Partial<IWorkspace[]>>("/workspace/joined");
return req.data;
}

View File

@ -0,0 +1,67 @@
import { ActionIcon, Tooltip } from "@mantine/core";
import { IconCircleCheck, IconCircleCheckFilled } from "@tabler/icons-react";
import { useResolveCommentMutation } from "@/ee/comment/queries/comment-query";
import { useTranslation } from "react-i18next";
import { Editor } from "@tiptap/react";
interface ResolveCommentProps {
editor: Editor;
commentId: string;
pageId: string;
resolvedAt?: Date;
}
function ResolveComment({
editor,
commentId,
pageId,
resolvedAt,
}: ResolveCommentProps) {
const { t } = useTranslation();
const resolveCommentMutation = useResolveCommentMutation();
const isResolved = resolvedAt != null;
const iconColor = isResolved ? "green" : "gray";
const handleResolveToggle = async () => {
try {
await resolveCommentMutation.mutateAsync({
commentId,
pageId,
resolved: !isResolved,
});
if (editor) {
editor.commands.setCommentResolved(commentId, !isResolved);
}
//
} catch (error) {
console.error("Failed to toggle resolved state:", error);
}
};
return (
<Tooltip
label={isResolved ? t("Re-Open comment") : t("Resolve comment")}
position="top"
>
<ActionIcon
onClick={handleResolveToggle}
variant="subtle"
color={isResolved ? "green" : "gray"}
size="sm"
loading={resolveCommentMutation.isPending}
disabled={resolveCommentMutation.isPending}
>
{isResolved ? (
<IconCircleCheckFilled size={18} />
) : (
<IconCircleCheck size={18} />
)}
</ActionIcon>
</Tooltip>
);
}
export default ResolveComment;

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