Compare commits

...

29 Commits

Author SHA1 Message Date
Tom Moor bee7911bee Types cleanup 2024-11-20 19:12:43 -05:00
Tom Moor 86714a353f fix: Rare loop of storage events between tabs causing flickering UI 2024-11-20 18:51:58 -05:00
Tom Moor fd5391cbb6 Cache diff generation for email notifications (#7987)
* Cache diff generation, closes #7982

* Handle cannot acquire lock

* Refactor to guard
2024-11-20 14:45:12 -08:00
Hemachandar 6e685ee8d9 store pin location on mount (#7994) 2024-11-20 14:27:16 -08:00
Tom Moor b595a0d427 fix: No-op sending emails in self-hosted if configuration is unavailable rather than retrying
towards #7982
2024-11-19 20:45:32 -05:00
Tom Moor 1c86119065 fix: Cannot sort by role on member settings, closes #7986 2024-11-19 19:22:53 -05:00
Tom Moor c629006642 Add inline resolve action on comment threads (#7977)
* Add inline resolve action on comment threads

* perf refactor
2024-11-18 18:36:44 -08:00
Tom Moor 326f733d4c fix: Further improvements to diacritics matching in CMD+F 2024-11-18 18:04:10 -05:00
Tom Moor d4d683c046 fix: Missing space character in invite modal, related #7968 2024-11-18 17:51:49 -05:00
Tom Moor 8204ac343f chore: Upgrade Sentry/AWS 2024-11-18 17:48:36 -05:00
dependabot[bot] cae8de7c7a chore(deps): bump @octokit/auth-app from 6.1.2 to 6.1.3 (#7974)
Bumps [@octokit/auth-app](https://github.com/octokit/auth-app.js) from 6.1.2 to 6.1.3.
- [Release notes](https://github.com/octokit/auth-app.js/releases)
- [Commits](https://github.com/octokit/auth-app.js/compare/v6.1.2...v6.1.3)

---
updated-dependencies:
- dependency-name: "@octokit/auth-app"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-18 14:41:05 -08:00
dependabot[bot] 8efa601967 chore(deps-dev): bump @relative-ci/agent from 4.2.12 to 4.2.13 (#7975)
Bumps [@relative-ci/agent](https://github.com/relative-ci/agent) from 4.2.12 to 4.2.13.
- [Release notes](https://github.com/relative-ci/agent/releases)
- [Commits](https://github.com/relative-ci/agent/compare/v4.2.12...v4.2.13)

---
updated-dependencies:
- dependency-name: "@relative-ci/agent"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-18 14:40:53 -08:00
Tom Moor 86c3ea8e9d fix: Copy toolbar positioning 2024-11-17 10:00:52 -05:00
Tom Moor c222782534 Upgrade Mermaid script in exported HTML, related #7964 2024-11-17 09:51:46 -05:00
Tom Moor 19ea7ee52b Remove sourcemap generation in bundle size calc (#7966) 2024-11-16 16:57:19 -08:00
Tom Moor d1de84a07e Reduce build time (#7965)
* Test using xlarge

* wip

* wip
2024-11-16 10:45:14 -08:00
Tom Moor d73b4c55bf Mermaid v11 (#7964)
* mermaid-v11

* fix: Various rendering incompatibilities
2024-11-16 08:10:55 -08:00
Hemachandar 9843c4c995 Improvements around templates (#7952)
* hide new-doc-from-template menu item

* change trash path for deleted templates

* conditional show templates in command bar
2024-11-16 07:48:58 -08:00
dependabot[bot] 685397b057 chore(deps): bump cross-spawn from 7.0.3 to 7.0.5 (#7963)
Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.5.
- [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.5)

---
updated-dependencies:
- dependency-name: cross-spawn
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-16 06:43:06 -08:00
Tom Moor 13d37d4207 perf: Fix increase in initial bundle size, prosemirror-transform must be fixed at 1.10.0 until paragraph join is fixed 2024-11-16 09:14:27 -05:00
Tom Moor 7bedfab301 fix: Mermaid diagrams in collapsed headings do not render, closes #7960 2024-11-15 23:43:05 -05:00
Translate-O-Tron db5850ac0d New Crowdin updates (#7898) 2024-11-15 18:15:32 -08:00
Hemachandar a4c40ce25e show resolved view when a resolved comment is opened from notif email (#7959)
* show resolved view when a resolved comment is opened from notif email

* check and replace state
2024-11-15 18:14:30 -08:00
Tom Moor f5457e79cd fix: Mermaid diagram moves up and down when focused in read-only editor 2024-11-14 20:00:55 -05:00
Hemachandar 73eeeefb25 fix: restore workspace templates (#7951) 2024-11-14 16:32:02 -08:00
Hemachandar 54f82cac96 fix: show all templates in the menu (#7950)
* fetch all templates

* websocket events for workspace templates
2024-11-14 16:31:48 -08:00
Tom Moor bb43c24efe fix: Improve handling of unknown errors – closes #7933 2024-11-13 21:22:06 -05:00
Tom Moor acf3d7cd08 fix: Add latex fences as markdown signal 2024-11-13 21:03:44 -05:00
github-actions[bot] 5245f93642 chore: Compressed inefficient images automatically (#7946)
Co-authored-by: tommoor <tommoor@users.noreply.github.com>
2024-11-13 20:47:49 -05:00
60 changed files with 2165 additions and 1261 deletions
+8 -6
View File
@@ -4,12 +4,6 @@ defaults: &defaults
working_directory: ~/outline
docker:
- image: cimg/node:20.10
- image: cimg/redis:5.0
- image: cimg/postgres:14.2
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: circle_test
resource_class: large
environment:
NODE_ENV: test
@@ -78,6 +72,14 @@ jobs:
test-server:
<<: *defaults
parallelism: 3
docker:
- image: cimg/node:20.10
- image: cimg/redis:5.0
- image: cimg/postgres:14.2
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: circle_test
steps:
- checkout
- restore_cache:
+24 -5
View File
@@ -131,11 +131,30 @@ export const createDocumentFromTemplate = createAction({
section: DocumentSection,
icon: <NewDocumentIcon />,
keywords: "create",
visible: ({ currentTeamId, activeDocumentId, stores }) =>
!!currentTeamId &&
!!activeDocumentId &&
!!stores.documents.get(activeDocumentId)?.template &&
stores.policies.abilities(currentTeamId).createDocument,
visible: ({
currentTeamId,
activeCollectionId,
activeDocumentId,
stores,
}) => {
const document = activeDocumentId
? stores.documents.get(activeDocumentId)
: undefined;
if (
!currentTeamId ||
!document?.isTemplate ||
!!document?.isDraft ||
!!document?.isDeleted
) {
return false;
}
if (activeCollectionId) {
return stores.policies.abilities(activeCollectionId).createDocument;
}
return stores.policies.abilities(currentTeamId).createDocument;
},
perform: ({ activeCollectionId, activeDocumentId, sidebarContext }) =>
history.push(
newDocumentPath(activeCollectionId, { templateId: activeDocumentId }),
@@ -2,7 +2,11 @@ import { NewDocumentIcon, ShapesIcon } from "outline-icons";
import * as React from "react";
import Icon from "~/components/Icon";
import { createAction } from "~/actions";
import { DocumentSection } from "~/actions/sections";
import {
ActiveCollectionSection,
DocumentSection,
TeamSection,
} from "~/actions/sections";
import useStores from "~/hooks/useStores";
import history from "~/utils/history";
import { newDocumentPath } from "~/utils/routeHelpers";
@@ -11,26 +15,42 @@ const useTemplatesAction = () => {
const { documents } = useStores();
React.useEffect(() => {
void documents.fetchTemplates();
void documents.fetchAllTemplates();
}, [documents]);
const actions = React.useMemo(
() =>
documents.templatesAlphabetical.map((item) =>
documents.templatesAlphabetical.map((template) =>
createAction({
name: item.titleWithDefault,
name: template.titleWithDefault,
analyticsName: "New document",
section: DocumentSection,
icon: item.icon ? (
<Icon value={item.icon} color={item.color ?? undefined} />
section: template.isWorkspaceTemplate
? TeamSection
: ActiveCollectionSection,
icon: template.icon ? (
<Icon value={template.icon} color={template.color ?? undefined} />
) : (
<NewDocumentIcon />
),
keywords: "create",
visible: ({ currentTeamId, activeCollectionId, stores }) => {
if (activeCollectionId) {
return (
stores.policies.abilities(activeCollectionId).createDocument &&
(template.collectionId === activeCollectionId ||
template.isWorkspaceTemplate)
);
}
return (
!!currentTeamId &&
stores.policies.abilities(currentTeamId).createDocument &&
template.isWorkspaceTemplate
);
},
perform: ({ activeCollectionId, sidebarContext }) =>
history.push(
newDocumentPath(item.collectionId ?? activeCollectionId, {
templateId: item.id,
newDocumentPath(template.collectionId ?? activeCollectionId, {
templateId: template.id,
}),
{
sidebarContext,
@@ -49,9 +69,15 @@ const useTemplatesAction = () => {
placeholder: ({ t }) => t("Choose a template"),
section: DocumentSection,
icon: <ShapesIcon />,
visible: ({ currentTeamId, stores }) =>
!!currentTeamId &&
stores.policies.abilities(currentTeamId).createDocument,
visible: ({ currentTeamId, activeCollectionId, stores }) => {
if (activeCollectionId) {
return stores.policies.abilities(activeCollectionId).createDocument;
}
return (
!!currentTeamId &&
stores.policies.abilities(currentTeamId).createDocument
);
},
children: () => actions,
}),
[actions]
+3 -2
View File
@@ -39,6 +39,7 @@ function DocumentCard(props: Props) {
const { collections } = useStores();
const theme = useTheme();
const { document, pin, canUpdatePin, isDraggable } = props;
const pinnedToHome = React.useRef(!pin?.collectionId).current;
const collection = document.collectionId
? collections.get(document.collectionId)
: undefined;
@@ -122,13 +123,13 @@ function DocumentCard(props: Props) {
<Squircle
color={
collection?.color ??
(!pin?.collectionId ? theme.slateLight : theme.slateDark)
(pinnedToHome ? theme.slateLight : theme.slateDark)
}
>
{collection?.icon &&
collection?.icon !== "letter" &&
collection?.icon !== "collection" &&
!pin?.collectionId ? (
pinnedToHome ? (
<CollectionIcon collection={collection} color="white" />
) : (
<DocumentIcon color="white" />
+4 -2
View File
@@ -47,14 +47,16 @@ export default function LanguagePrompt() {
<br />
<Link
onClick={async () => {
ui.setLanguagePromptDismissed();
ui.set({ languagePromptDismissed: true });
await user.save({ language });
}}
>
{t("Change Language")}
</Link>{" "}
&middot;{" "}
<Link onClick={ui.setLanguagePromptDismissed}>{t("Dismiss")}</Link>
<Link onClick={() => ui.set({ languagePromptDismissed: true })}>
{t("Dismiss")}
</Link>
</span>
</Flex>
</Wrapper>
+16 -13
View File
@@ -2,7 +2,6 @@ import { ReactionIcon } from "outline-icons";
import React from "react";
import { useTranslation } from "react-i18next";
import { PopoverDisclosure, usePopoverState } from "reakit";
import styled from "styled-components";
import EventBoundary from "@shared/components/EventBoundary";
import Flex from "~/components/Flex";
import NudeButton from "~/components/NudeButton";
@@ -11,6 +10,7 @@ import Popover from "~/components/Popover";
import useMobile from "~/hooks/useMobile";
import useOnClickOutside from "~/hooks/useOnClickOutside";
import useWindowSize from "~/hooks/useWindowSize";
import Tooltip from "../Tooltip";
const EmojiPanel = React.lazy(
() => import("~/components/IconPicker/components/EmojiPanel")
@@ -98,15 +98,22 @@ const ReactionPicker: React.FC<Props> = ({
<>
<PopoverDisclosure {...popover}>
{(props) => (
<PopoverButton
{...props}
aria-label={t("Reaction picker")}
className={className}
onClick={handlePopoverButtonClick}
size={size}
<Tooltip
content={t("Add reaction")}
placement="top"
delay={500}
hideOnClick
>
<ReactionIcon size={22} />
</PopoverButton>
<NudeButton
{...props}
aria-label={t("Reaction picker")}
className={className}
onClick={handlePopoverButtonClick}
size={size}
>
<ReactionIcon size={22} />
</NudeButton>
</Tooltip>
)}
</PopoverDisclosure>
<Popover
@@ -151,8 +158,4 @@ const Placeholder = React.memo(
);
Placeholder.displayName = "ReactionPickerPlaceholder";
const PopoverButton = styled(NudeButton)`
border-radius: 50%;
`;
export default ReactionPicker;
+2 -2
View File
@@ -32,13 +32,13 @@ function Right({ children, border, className }: Props) {
Math.min(window.innerWidth - event.pageX, maxWidth),
minWidth
);
ui.setRightSidebarWidth(width);
ui.set({ sidebarRightWidth: width });
},
[minWidth, maxWidth, ui]
);
const handleReset = React.useCallback(() => {
ui.setRightSidebarWidth(theme.sidebarRightWidth);
ui.set({ sidebarRightWidth: theme.sidebarRightWidth });
}, [ui, theme.sidebarRightWidth]);
const handleStopDrag = React.useCallback(() => {
+12 -13
View File
@@ -46,7 +46,6 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(function _Sidebar(
const maxWidth = theme.sidebarMaxWidth;
const minWidth = theme.sidebarMinWidth + 16; // padding
const setWidth = ui.setSidebarWidth;
const [offset, setOffset] = React.useState(0);
const [isHovering, setHovering] = React.useState(false);
const [isAnimating, setAnimating] = React.useState(false);
@@ -62,13 +61,13 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(function _Sidebar(
const width = Math.min(event.pageX - offset, maxWidth);
const isSmallerThanCollapsePoint = width < minWidth / 2;
if (isSmallerThanCollapsePoint) {
setWidth(theme.sidebarCollapsedWidth);
} else {
setWidth(width);
}
ui.set({
sidebarWidth: isSmallerThanCollapsePoint
? theme.sidebarCollapsedWidth
: width,
});
},
[theme, offset, minWidth, maxWidth, setWidth]
[ui, theme, offset, minWidth, maxWidth]
);
const handleStopDrag = React.useCallback(() => {
@@ -86,13 +85,13 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(function _Sidebar(
setCollapsing(true);
ui.collapseSidebar();
} else {
setWidth(minWidth);
ui.set({ sidebarWidth: minWidth });
setAnimating(true);
}
} else {
setWidth(width);
ui.set({ sidebarWidth: width });
}
}, [ui, isSmallerThanMinimum, minWidth, width, setWidth]);
}, [ui, isSmallerThanMinimum, minWidth, width]);
const handleBlur = React.useCallback(() => {
setHovering(false);
@@ -149,11 +148,11 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(function _Sidebar(
React.useEffect(() => {
if (isCollapsing) {
setTimeout(() => {
setWidth(minWidth);
ui.set({ sidebarWidth: minWidth });
setCollapsing(false);
}, ANIMATION_MS);
}
}, [setWidth, minWidth, isCollapsing]);
}, [ui, minWidth, isCollapsing]);
React.useEffect(() => {
if (isResizing) {
@@ -174,7 +173,7 @@ const Sidebar = React.forwardRef<HTMLDivElement, Props>(function _Sidebar(
}, [isResizing, handleDrag, handleBlur, handleStopDrag]);
const handleReset = React.useCallback(() => {
ui.setSidebarWidth(theme.sidebarWidth);
ui.set({ sidebarWidth: theme.sidebarWidth });
}, [ui, theme.sidebarWidth]);
React.useEffect(() => {
+8 -3
View File
@@ -248,14 +248,19 @@ export default class FindAndReplaceExtension extends Extension {
let m;
const search = this.findRegExp;
while ((m = search.exec(deburr(text)))) {
// We construct a string with the text stripped of diacritics plus the original text for
// search allowing to search for diacritics-insensitive matches easily.
while ((m = search.exec(deburr(text) + text))) {
if (m[0] === "") {
break;
}
// Reconstruct the correct match position
const i = m.index > text.length ? m.index - text.length : m.index;
this.results.push({
from: pos + m.index,
to: pos + m.index + m[0].length,
from: pos + i,
to: pos + i + m[0].length,
});
}
} catch (e) {
+2 -1
View File
@@ -254,7 +254,8 @@ export default class Document extends ArchivableModel {
@computed
get path(): string {
const prefix = this.template ? settingsPath("templates") : "/doc";
const prefix =
this.template && !this.isDeleted ? settingsPath("templates") : "/doc";
if (!this.title) {
return `${prefix}/untitled-${this.urlId}`;
@@ -1,6 +1,7 @@
import { differenceInMilliseconds } from "date-fns";
import { action } from "mobx";
import { observer } from "mobx-react";
import { DoneIcon } from "outline-icons";
import { darken } from "polished";
import * as React from "react";
import { useTranslation } from "react-i18next";
@@ -16,10 +17,14 @@ import Comment from "~/models/Comment";
import { Avatar } from "~/components/Avatar";
import ButtonSmall from "~/components/ButtonSmall";
import Flex from "~/components/Flex";
import NudeButton from "~/components/NudeButton";
import ReactionList from "~/components/Reactions/ReactionList";
import ReactionPicker from "~/components/Reactions/ReactionPicker";
import Text from "~/components/Text";
import Time from "~/components/Time";
import Tooltip from "~/components/Tooltip";
import { resolveCommentFactory } from "~/actions/definitions/comments";
import useActionContext from "~/hooks/useActionContext";
import useBoolean from "~/hooks/useBoolean";
import useCurrentUser from "~/hooks/useCurrentUser";
import CommentMenu from "~/menus/CommentMenu";
@@ -242,11 +247,13 @@ function CommentThreadItem({
onRemoveReaction={handleRemoveReaction}
picker={
!comment.isResolved ? (
<StyledReactionPicker
<Action
as={ReactionPicker}
onSelect={handleAddReaction}
onOpen={disableScroll}
onClose={enableScroll}
size={28}
rounded
/>
) : undefined
}
@@ -257,14 +264,20 @@ function CommentThreadItem({
<EventBoundary>
{!isEditing && (
<Actions gap={4} dir={dir}>
{firstOfThread && (
<ResolveButton onUpdate={handleUpdate} comment={comment} />
)}
{!comment.isResolved && (
<StyledReactionPicker
<Action
as={ReactionPicker}
onSelect={handleAddReaction}
onOpen={disableScroll}
onClose={enableScroll}
rounded
/>
)}
<StyledMenu
<Action
as={CommentMenu}
comment={comment}
onEdit={setEditing}
onDelete={handleDelete}
@@ -278,6 +291,38 @@ function CommentThreadItem({
);
}
const ResolveButton = ({
comment,
onUpdate,
}: {
comment: Comment;
onUpdate: (attrs: { resolved: boolean }) => void;
}) => {
const context = useActionContext();
const { t } = useTranslation();
return (
<Tooltip
content={t("Mark as resolved")}
placement="top"
delay={500}
hideOnClick
>
<Action
as={NudeButton}
context={context}
action={resolveCommentFactory({
comment,
onResolve: () => onUpdate({ resolved: true }),
})}
rounded
>
<DoneIcon size={22} outline />
</Action>
</Tooltip>
);
};
const StyledCommentEditor = styled(CommentEditor)`
${(props) =>
!props.readOnly &&
@@ -308,25 +353,13 @@ const Body = styled.form`
border-radius: 2px;
`;
const StyledMenu = styled(CommentMenu)`
color: ${s("textSecondary")};
svg {
fill: currentColor;
opacity: 0.5;
}
&: ${hover}, &[aria-expanded= "true"] {
background: ${s("backgroundQuaternary")};
svg {
opacity: 0.75;
}
}
`;
const StyledReactionPicker = styled(ReactionPicker)`
const Action = styled.span<{ rounded?: boolean }>`
color: ${s("textSecondary")};
${(props) =>
props.rounded &&
css`
border-radius: 50%;
`}
svg {
fill: currentColor;
@@ -352,7 +385,7 @@ const Actions = styled(Flex)<{ dir?: "rtl" | "ltr" }>`
background: ${s("backgroundSecondary")};
padding-left: 4px;
&:has(${StyledReactionPicker}[aria-expanded="true"], ${StyledMenu}[aria-expanded="true"]) {
&:has(${Action}[aria-expanded="true"]) {
opacity: 1;
}
`;
+14 -1
View File
@@ -27,6 +27,7 @@ import useCurrentTeam from "~/hooks/useCurrentTeam";
import useCurrentUser from "~/hooks/useCurrentUser";
import useFocusedComment from "~/hooks/useFocusedComment";
import usePolicy from "~/hooks/usePolicy";
import useQuery from "~/hooks/useQuery";
import useStores from "~/hooks/useStores";
import {
documentHistoryPath,
@@ -81,6 +82,7 @@ function DocumentEditor(props: Props, ref: React.RefObject<any>) {
const user = useCurrentUser({ rejectOnEmpty: false });
const team = useCurrentTeam({ rejectOnEmpty: false });
const history = useHistory();
const params = useQuery();
const {
document,
onChangeTitle,
@@ -103,9 +105,20 @@ function DocumentEditor(props: Props, ref: React.RefObject<any>) {
React.useEffect(() => {
if (focusedComment) {
const viewingResolved = params.get("resolved") === "";
if (
(focusedComment.isResolved && !viewingResolved) ||
(!focusedComment.isResolved && viewingResolved)
) {
history.replace({
search: focusedComment.isResolved ? "resolved=" : "",
pathname: location.pathname,
state: { commentId: focusedComment.id },
});
}
ui.expandComments(document.id);
}
}, [focusedComment, ui, document.id]);
}, [focusedComment, ui, document.id, history, params]);
// Save document when blurring title, but delay so that if clicking on a
// button this is allowed to execute first.
+6 -2
View File
@@ -103,6 +103,10 @@ function DocumentHeader({
});
}, [onSave]);
const handleToggle = React.useCallback(() => {
ui.set({ tocVisible: !ui.tocVisible });
}, [ui]);
const context = useActionContext({
activeDocumentId: document?.id,
});
@@ -129,7 +133,7 @@ function DocumentHeader({
placement="bottom"
>
<Button
onClick={showContents ? ui.hideTableOfContents : ui.showTableOfContents}
onClick={handleToggle}
icon={<TableOfContentsIcon />}
borderOnHover
neutral
@@ -180,7 +184,7 @@ function DocumentHeader({
useKeyDown(
(event) => event.ctrlKey && event.altKey && event.key === "˙",
ui.tocVisible ? ui.hideTableOfContents : ui.showTableOfContents,
handleToggle,
{
allowInInput: true,
}
+1 -1
View File
@@ -127,7 +127,7 @@ function Invite({ onSubmit }: Props) {
<Trans>{{ collectionCount }} collections</Trans>
</strong>
</Tooltip>
.
.{" "}
</span>
) : undefined;
+119 -101
View File
@@ -5,6 +5,124 @@ import { Trans } from "react-i18next";
import Notice from "~/components/Notice";
import useQuery from "~/hooks/useQuery";
function Message({ notice }: { notice: string }) {
switch (notice) {
case "domain-not-allowed":
return (
<Trans>
The domain associated with your email address has not been allowed for
this workspace.
</Trans>
);
case "domain-required":
return (
<Trans>
Unable to sign-in. Please navigate to your workspace's custom URL,
then try to sign-in again.
<hr />
If you were invited to a workspace, you will find a link to it in the
invite email.
</Trans>
);
case "gmail-account-creation":
return (
<Trans>
Sorry, a new account cannot be created with a personal Gmail address.
<hr />
Please use a Google Workspaces account instead.
</Trans>
);
case "pending-deletion":
return (
<Trans>
The workspace associated with your user is scheduled for deletion and
cannot be accessed at this time.
</Trans>
);
case "maximum-reached":
return (
<Trans>
The workspace you authenticated with is not authorized on this
installation. Try another?
</Trans>
);
case "malformed-user-info":
return (
<Trans>
We could not read the user info supplied by your identity provider.
</Trans>
);
case "email-auth-required":
return (
<Trans>
Your account uses email sign-in, please sign-in with email to
continue.
</Trans>
);
case "email-auth-ratelimit":
return (
<Trans>
An email sign-in link was recently sent, please check your inbox or
try again in a few minutes.
</Trans>
);
case "auth-error":
case "state-mismatch":
return (
<Trans>
Authentication failed we were unable to sign you in at this time.
Please try again.
</Trans>
);
case "invalid-authentication":
return (
<Trans>
Authentication failed you do not have permission to access this
workspace.
</Trans>
);
case "expired-token":
return (
<Trans>
Sorry, it looks like that sign-in link is no longer valid, please try
requesting another.
</Trans>
);
case "user-suspended":
return (
<Trans>
Your account has been suspended. To re-activate your account, please
contact a workspace admin.
</Trans>
);
case "team-suspended":
return (
<Trans>
This workspace has been suspended. Please contact support to restore
access.
</Trans>
);
case "authentication-provider-disabled":
return (
<Trans>
Authentication failed this login method was disabled by a team
admin.
</Trans>
);
case "invite-required":
return (
<Trans>
The workspace you are trying to join requires an invite before you can
create an account.
<hr />
Please request an invite from your workspace admin and try again.
</Trans>
);
default:
return <Trans>Sorry, an unknown error occurred.</Trans>;
}
}
export default function Notices() {
const query = useQuery();
const notice = query.get("notice");
@@ -15,107 +133,7 @@ export default function Notices() {
return (
<Notice icon={<WarningIcon color="currentcolor" />}>
{notice === "domain-not-allowed" && (
<Trans>
The domain associated with your email address has not been allowed for
this workspace.
</Trans>
)}
{notice === "domain-required" && (
<Trans>
Unable to sign-in. Please navigate to your workspace's custom URL,
then try to sign-in again.
<hr />
If you were invited to a workspace, you will find a link to it in the
invite email.
</Trans>
)}
{notice === "gmail-account-creation" && (
<Trans>
Sorry, a new account cannot be created with a personal Gmail address.
<hr />
Please use a Google Workspaces account instead.
</Trans>
)}
{notice === "pending-deletion" && (
<Trans>
The workspace associated with your user is scheduled for deletion and
cannot be accessed at this time.
</Trans>
)}
{notice === "maximum-reached" && (
<Trans>
The workspace you authenticated with is not authorized on this
installation. Try another?
</Trans>
)}
{notice === "malformed-user-info" && (
<Trans>
We could not read the user info supplied by your identity provider.
</Trans>
)}
{notice === "email-auth-required" && (
<Trans>
Your account uses email sign-in, please sign-in with email to
continue.
</Trans>
)}
{notice === "email-auth-ratelimit" && (
<Trans>
An email sign-in link was recently sent, please check your inbox or
try again in a few minutes.
</Trans>
)}
{(notice === "auth-error" || notice === "state-mismatch") && (
<Trans>
Authentication failed we were unable to sign you in at this time.
Please try again.
</Trans>
)}
{notice === "invalid-authentication" && (
<Trans>
Authentication failed you do not have permission to access this
workspace.
</Trans>
)}
{notice === "expired-token" && (
<Trans>
Sorry, it looks like that sign-in link is no longer valid, please try
requesting another.
</Trans>
)}
{notice === "user-suspended" && (
<Trans>
Your account has been suspended. To re-activate your account, please
contact a workspace admin.
</Trans>
)}
{notice === "team-suspended" && (
<Trans>
This workspace has been suspended. Please contact support to restore
access.
</Trans>
)}
{notice === "authentication-provider-disabled" && (
<Trans>
Authentication failed this login method was disabled by a team
admin.
</Trans>
)}
{notice === "invite-required" && (
<Trans>
The workspace you are trying to join requires an invite before you can
create an account.
<hr />
Please request an invite from your workspace admin and try again.
</Trans>
)}
{notice === "domain-not-allowed" && (
<Trans>
Sorry, your domain is not allowed. Please try again with an allowed
workspace domain.
</Trans>
)}
<Message notice={notice} />
</Notice>
);
}
@@ -52,7 +52,7 @@ function PeopleTable({ canManage, ...rest }: Props) {
),
},
{
id: "isAdmin",
id: "role",
Header: t("Role"),
accessor: "rank",
Cell: observer(({ row }: { row: { original: User } }) => (
+9 -20
View File
@@ -7,31 +7,19 @@ import { CustomTheme } from "@shared/types";
import Storage from "@shared/utils/Storage";
import { getCookieDomain, parseDomain } from "@shared/utils/domains";
import RootStore from "~/stores/RootStore";
import Policy from "~/models/Policy";
import Team from "~/models/Team";
import User from "~/models/User";
import env from "~/env";
import { setPostLoginPath } from "~/hooks/useLastVisitedPath";
import { PartialExcept } from "~/types";
import { client } from "~/utils/ApiClient";
import Desktop from "~/utils/Desktop";
import Logger from "~/utils/Logger";
import isCloudHosted from "~/utils/isCloudHosted";
import Store from "./base/Store";
type PersistedData = {
user?: PartialExcept<User, "id">;
team?: PartialExcept<Team, "id">;
collaborationToken?: string;
availableTeams?: {
id: string;
name: string;
avatarUrl: string;
url: string;
isSignedIn: boolean;
}[];
policies?: Policy[];
};
type PersistedData = Pick<
AuthStore,
"user" | "team" | "collaborationToken" | "availableTeams" | "policies"
>;
type Provider = {
id: string;
@@ -165,9 +153,10 @@ export default class AuthStore extends Store<Team> {
/** The current team's policies */
@computed
get policies() {
return this.currentTeamId
? [this.rootStore.policies.get(this.currentTeamId)]
: [];
const policy = this.currentTeamId
? this.rootStore.policies.get(this.currentTeamId)
: undefined;
return policy ? [policy] : [];
}
/** Whether the user is signed in */
@@ -177,7 +166,7 @@ export default class AuthStore extends Store<Team> {
}
@computed
get asJson() {
get asJson(): PersistedData {
return {
user: this.user,
team: this.team,
+4
View File
@@ -368,6 +368,10 @@ export default class DocumentsStore extends Store<Document> {
fetchTemplates = async (options?: PaginationParams): Promise<Document[]> =>
this.fetchNamedPage("list", { ...options, template: true });
@action
fetchAllTemplates = async (options?: PaginationParams): Promise<Document[]> =>
this.fetchAll({ ...options, template: true });
@action
fetchAlphabetical = async (options?: PaginationParams): Promise<Document[]> =>
this.fetchNamedPage("list", {
+30 -43
View File
@@ -1,4 +1,4 @@
import { action, autorun, computed, observable } from "mobx";
import { action, computed, observable } from "mobx";
import { flushSync } from "react-dom";
import { light as defaultTheme } from "@shared/styles/theme";
import Storage from "@shared/utils/Storage";
@@ -23,15 +23,16 @@ export enum SystemTheme {
Dark = "dark",
}
type PersistedData = {
languagePromptDismissed: boolean | undefined;
theme: Theme;
sidebarCollapsed: boolean;
sidebarWidth: number;
sidebarRightWidth: number;
tocVisible: boolean | undefined;
commentsExpanded: string[];
};
type PersistedData = Pick<
UiStore,
| "languagePromptDismissed"
| "commentsExpanded"
| "theme"
| "sidebarWidth"
| "sidebarRightWidth"
| "sidebarCollapsed"
| "tocVisible"
>;
class UiStore {
// has the user seen the prompt to change the UI language and actioned it
@@ -134,10 +135,6 @@ class UiStore {
this.tocVisible = newData.tocVisible;
}
});
autorun(() => {
Storage.set(UI_STORE, this.asJson);
});
}
@action
@@ -147,12 +144,7 @@ class UiStore {
this.theme = theme;
});
});
Storage.set("theme", this.theme);
};
@action
setLanguagePromptDismissed = () => {
this.languagePromptDismissed = true;
this.persist();
};
@action
@@ -205,25 +197,24 @@ class UiStore {
this.activeCollectionId = undefined;
};
@action
setSidebarWidth = (width: number): void => {
this.sidebarWidth = width;
};
@action
setRightSidebarWidth = (width: number): void => {
this.sidebarRightWidth = width;
};
@action
collapseSidebar = () => {
this.sidebarCollapsed = true;
this.set({ sidebarCollapsed: true });
};
@action
expandSidebar = () => {
sidebarHidden = false;
this.sidebarCollapsed = false;
this.set({ sidebarCollapsed: false });
};
@action
set = (data: Partial<PersistedData>) => {
for (const key in data) {
// @ts-expect-error doesn't understand PersistedData is subset of keys
this[key] = data[key];
}
this.persist();
};
@action
@@ -231,6 +222,7 @@ class UiStore {
this.commentsExpanded = this.commentsExpanded.filter(
(id) => id !== documentId
);
this.persist();
};
@action
@@ -238,6 +230,7 @@ class UiStore {
if (!this.commentsExpanded.includes(documentId)) {
this.commentsExpanded.push(documentId);
}
this.persist();
};
@action
@@ -252,17 +245,7 @@ class UiStore {
@action
toggleCollapsedSidebar = () => {
sidebarHidden = false;
this.sidebarCollapsed = !this.sidebarCollapsed;
};
@action
showTableOfContents = () => {
this.tocVisible = true;
};
@action
hideTableOfContents = () => {
this.tocVisible = false;
this.set({ sidebarCollapsed: !this.sidebarCollapsed });
};
@action
@@ -324,6 +307,10 @@ class UiStore {
theme: this.theme,
};
}
private persist = () => {
Storage.set(UI_STORE, this.asJson);
};
}
export default UiStore;
+11 -10
View File
@@ -48,11 +48,11 @@
"> 0.25%, not dead"
],
"dependencies": {
"@aws-sdk/client-s3": "3.616.0",
"@aws-sdk/lib-storage": "3.616.0",
"@aws-sdk/s3-presigned-post": "3.616.0",
"@aws-sdk/s3-request-presigner": "3.616.0",
"@aws-sdk/signature-v4-crt": "^3.616.0",
"@aws-sdk/client-s3": "3.693.0",
"@aws-sdk/lib-storage": "3.693.0",
"@aws-sdk/s3-presigned-post": "3.693.0",
"@aws-sdk/s3-request-presigner": "3.693.0",
"@aws-sdk/signature-v4-crt": "^3.693.0",
"@babel/core": "^7.24.7",
"@babel/plugin-proposal-decorators": "^7.24.7",
"@babel/plugin-transform-class-properties": "^7.24.7",
@@ -79,11 +79,11 @@
"@hocuspocus/server": "1.1.2",
"@joplin/turndown-plugin-gfm": "^1.0.49",
"@juggle/resize-observer": "^3.4.0",
"@octokit/auth-app": "^6.1.2",
"@octokit/auth-app": "^6.1.3",
"@outlinewiki/koa-passport": "^4.2.1",
"@outlinewiki/passport-azure-ad-oauth2": "^0.1.0",
"@renderlesskit/react": "^0.11.0",
"@sentry/node": "^7.117.0",
"@sentry/node": "^7.119.0",
"@sentry/react": "^7.119.0",
"@tippyjs/react": "^4.2.6",
"@types/form-data": "^2.5.0",
@@ -150,7 +150,7 @@
"markdown-it": "^13.0.2",
"markdown-it-container": "^3.0.0",
"markdown-it-emoji": "^2.0.0",
"mermaid": "9.3.0",
"mermaid": "11.4.0",
"mime-types": "^2.1.35",
"mobx": "^4.15.4",
"mobx-react": "^6.3.1",
@@ -208,6 +208,7 @@
"react-waypoint": "^10.3.0",
"react-window": "^1.8.10",
"reakit": "^1.3.11",
"redlock": "^5.0.0-beta.2",
"reflect-metadata": "^0.2.2",
"refractor": "^3.6.0",
"request-filtering-agent": "^1.1.2",
@@ -254,7 +255,7 @@
"@babel/cli": "^7.25.9",
"@babel/preset-typescript": "^7.24.1",
"@faker-js/faker": "^8.4.1",
"@relative-ci/agent": "^4.2.12",
"@relative-ci/agent": "^4.2.13",
"@testing-library/react": "^12.0.0",
"@types/addressparser": "^1.0.3",
"@types/body-scroll-lock": "^3.1.2",
@@ -285,7 +286,6 @@
"@types/markdown-it": "^14.1.2",
"@types/markdown-it-container": "^2.0.9",
"@types/markdown-it-emoji": "^2.0.4",
"@types/mermaid": "^9.2.0",
"@types/mime-types": "^2.1.4",
"@types/natural-sort": "^0.0.24",
"@types/node": "20.14.2",
@@ -360,6 +360,7 @@
"yarn-deduplicate": "^6.0.2"
},
"resolutions": {
"prosemirror-transform": "1.10.0",
"body-scroll-lock": "^4.0.0-beta.0",
"d3": "^7.0.0",
"debug": "4.3.4",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+9
View File
@@ -51,6 +51,15 @@ export default abstract class BaseEmail<
* @returns A promise that resolves once the email is placed on the task queue
*/
public schedule(options?: Bull.JobOptions) {
// No-op to schedule emails if SMTP is not configured
if (!env.SMTP_FROM_EMAIL) {
Logger.info(
"email",
`Email ${this.constructor.name} not sent due to missing SMTP configuration`
);
return;
}
const templateName = this.constructor.name;
Metrics.increment("email.scheduled", {
@@ -7,6 +7,7 @@ import HTMLHelper from "@server/models/helpers/HTMLHelper";
import NotificationSettingsHelper from "@server/models/helpers/NotificationSettingsHelper";
import SubscriptionHelper from "@server/models/helpers/SubscriptionHelper";
import { can } from "@server/policies";
import { CacheHelper } from "@server/utils/CacheHelper";
import BaseEmail, { EmailMessageCategory, EmailProps } from "./BaseEmail";
import Body from "./components/Body";
import Button from "./components/Button";
@@ -68,21 +69,28 @@ export default class DocumentPublishedOrUpdatedEmail extends BaseEmail<
let body;
if (revisionId && team?.getPreference(TeamPreference.PreviewsInEmails)) {
// generate the diff html for the email
const revision = await Revision.findByPk(revisionId);
body = await CacheHelper.getDataOrSet<string>(
`diff:${revisionId}`,
async () => {
// generate the diff html for the email
const revision = await Revision.findByPk(revisionId);
if (revision) {
const before = await revision.before();
const content = await DocumentHelper.toEmailDiff(before, revision, {
includeTitle: false,
centered: false,
signedUrls: 4 * Day.seconds,
baseUrl: props.teamUrl,
});
if (revision) {
const before = await revision.before();
const content = await DocumentHelper.toEmailDiff(before, revision, {
includeTitle: false,
centered: false,
signedUrls: 4 * Day.seconds,
baseUrl: props.teamUrl,
});
// inline all css so that it works in as many email providers as possible.
body = content ? await HTMLHelper.inlineCSS(content) : undefined;
}
// inline all css so that it works in as many email providers as possible.
return content ? await HTMLHelper.inlineCSS(content) : undefined;
}
return;
},
30
);
}
return {
+1 -1
View File
@@ -558,7 +558,7 @@ export class ProsemirrorHelper {
// Inject Mermaid script
if (mermaidElements.length) {
element.innerHTML = `
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
mermaid.initialize({
startOnLoad: true,
fontFamily: "inherit",
@@ -852,6 +852,8 @@ export default class WebsocketsProcessor {
channels.push(
...this.getCollectionEventChannels(event, document.collection)
);
} else if (document.isWorkspaceTemplate) {
channels.push(`team-${document.teamId}`);
} else {
channels.push(`collection-${document.collectionId}`);
}
@@ -3036,6 +3036,92 @@ describe("#documents.restore", () => {
expect(body.data.collectionId).toEqual(anotherCollection.id);
});
it("should allow restore of collection templates", async () => {
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const template = await buildDocument({
template: true,
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
await template.delete(user);
const res = await server.post("/api/documents.restore", {
body: {
token: user.getJwtToken(),
id: template.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.deletedAt).toEqual(null);
expect(body.data.collectionId).toEqual(collection.id);
});
it("should allow restore of templates from a deleted collection", async () => {
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const anotherCollection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const template = await buildDocument({
template: true,
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
await template.delete(user);
await collection.destroy({ hooks: false });
const res = await server.post("/api/documents.restore", {
body: {
token: user.getJwtToken(),
id: template.id,
collectionId: anotherCollection.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.deletedAt).toEqual(null);
expect(body.data.collectionId).toEqual(anotherCollection.id);
});
it("should allow restore of workspace templates", async () => {
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const template = await buildDocument({
template: true,
userId: user.id,
teamId: team.id,
collectionId: null,
});
await template.delete(user);
const res = await server.post("/api/documents.restore", {
body: {
token: user.getJwtToken(),
id: template.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.deletedAt).toEqual(null);
expect(body.data.collectionId).toEqual(null);
});
it("should not allow restore of documents to a deleted collection", async () => {
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
+16 -3
View File
@@ -828,13 +828,14 @@ router.post(
}).findByPk(destCollectionId)
: undefined;
if (!destCollection?.isActive) {
// In case of workspace templates, both source and destination collections are undefined.
if (!document.isWorkspaceTemplate && !destCollection?.isActive) {
throw ValidationError(
"Unable to restore, the collection may have been deleted or archived"
);
}
// Skip this for drafts of a deleted collection as they won't have sourceCollectionId
// Skip this for workspace templates and drafts of a deleted collection as they won't have sourceCollectionId.
if (sourceCollectionId && sourceCollectionId !== destCollectionId) {
authorize(user, "updateDocument", srcCollection);
await srcCollection?.removeDocumentInStructure(document, {
@@ -843,7 +844,19 @@ router.post(
});
}
if (document.deletedAt) {
if (document.deletedAt && document.isWorkspaceTemplate) {
authorize(user, "restore", document);
await document.restore({ transaction });
await Event.createFromContext(ctx, {
name: "documents.restore",
documentId: document.id,
collectionId: document.collectionId,
data: {
title: document.title,
},
});
} else if (document.deletedAt) {
authorize(user, "restore", document);
authorize(user, "updateDocument", destCollection);
+49
View File
@@ -1,6 +1,7 @@
import { Day } from "@shared/utils/time";
import Logger from "@server/logging/Logger";
import Redis from "@server/storage/redis";
import { MutexLock } from "./MutexLock";
/**
* A Helper class for server-side cache management
@@ -9,6 +10,54 @@ export class CacheHelper {
// Default expiry time for cache data in seconds
private static defaultDataExpiry = Day.seconds;
/**
* Given a key this method will attempt to get the data from cache store first
* If data is not found, it will call the callback to get the data and save it in cache
* using a distributed lock to prevent multiple writes.
*
* @param key Cache key
* @param callback Callback to get the data if not found in cache
* @param expiry Cache data expiry in seconds
*/
public static async getDataOrSet<T>(
key: string,
callback: () => Promise<T | undefined>,
expiry?: number
): Promise<T | undefined> {
let cache = await this.getData<T>(key);
if (cache) {
return cache;
}
// Nothing in the cache, acquire a lock to prevent multiple writes
let lock;
const lockKey = `lock:${key}`;
try {
try {
lock = await MutexLock.lock.acquire(
[lockKey],
MutexLock.defaultLockTimeout
);
} catch (err) {
Logger.error(`Could not acquire lock for ${key}`, err);
}
cache = await this.getData<T>(key);
if (cache) {
return cache;
}
// Get the data from the callback and save it in cache
const value = await callback();
if (value) {
await this.setData<T>(key, value, expiry);
}
return value;
} finally {
await lock?.release();
}
}
/**
* Given a key, gets the data from cache store
*
+20
View File
@@ -0,0 +1,20 @@
import Redlock from "redlock";
import Redis from "@server/storage/redis";
export class MutexLock {
// Default expiry time for qcuiring lock in milliseconds
public static defaultLockTimeout = 5000;
/**
* Returns the redlock instance
*/
public static get lock(): Redlock {
this.redlock ??= new Redlock([Redis.defaultClient], {
retryJitter: 10,
});
return this.redlock;
}
private static redlock: Redlock;
}
+5 -6
View File
@@ -1300,20 +1300,19 @@ mark {
// Hide code without display none so toolbar can still be positioned against it
&:not(.code-active) {
height: ${props.staticHTML ? "auto" : "0"};
height: ${props.staticHTML || props.readOnly ? "auto" : "0"};
margin: -0.75em 0;
overflow: hidden;
// Allows the margin to collapse correctly by moving div out of the flow
position: ${props.staticHTML ? "relative" : "absolute"};
position: ${props.staticHTML || props.readOnly ? "relative" : "absolute"};
}
}
/* Hide code without display none so toolbar can still be positioned against it */
.ProseMirror[contenteditable="false"] .code-block[data-language=mermaidjs] {
height: ${props.staticHTML ? "auto" : "0"};
margin: -0.5em 0;
overflow: hidden;
height: 0;
overflow: hidden;
margin: -0.5em 0 0 0;
}
.code-block.with-line-numbers {
+28 -13
View File
@@ -1,6 +1,7 @@
import debounce from "lodash/debounce";
import last from "lodash/last";
import sortBy from "lodash/sortBy";
import type MermaidUnsafe from "mermaid";
import { Node } from "prosemirror-model";
import {
Plugin,
@@ -36,7 +37,7 @@ class Cache {
private static data: Map<string, string> = new Map();
}
let mermaid: typeof import("mermaid")["default"];
let mermaid: typeof MermaidUnsafe;
type RendererFunc = (
block: { node: Node; pos: number },
@@ -72,8 +73,16 @@ class MermaidRenderer {
return;
}
// Create a temporary element that will render the diagram off-screen. This is necessary
// as Mermaid will error if the element is not visible, such as if the heading is collapsed
const renderElement = document.createElement("div");
renderElement.style.position = "absolute";
renderElement.style.left = "-9999px";
renderElement.style.top = "-9999px";
document.body.appendChild(renderElement);
try {
mermaid = mermaid ?? (await import("mermaid")).default;
mermaid ??= (await import("mermaid")).default;
mermaid.initialize({
startOnLoad: true,
// TODO: Make dynamic based on the width of the editor or remove in
@@ -84,20 +93,24 @@ class MermaidRenderer {
theme: isDark ? "dark" : "default",
darkMode: isDark,
});
mermaid.render(
const { svg, bindFunctions } = await mermaid.render(
`mermaid-diagram-${this.diagramId}`,
text,
(svgCode, bindFunctions) => {
this.currentTextContent = text;
if (text) {
Cache.set(cacheKey, svgCode);
}
element.classList.remove("parse-error", "empty");
element.innerHTML = svgCode;
bindFunctions?.(element);
},
element
// If the element is not visible we use an off-screen element to render the diagram
element.offsetParent === null ? renderElement : element
);
this.currentTextContent = text;
// Cache the rendered SVG so we won't need to calculate it again in the same session
if (text) {
Cache.set(cacheKey, svg);
}
element.classList.remove("parse-error", "empty");
element.innerHTML = svg;
// Allow the user to interact with the diagram
bindFunctions?.(element);
} catch (error) {
const isEmpty = block.node.textContent.trim().length === 0;
@@ -108,6 +121,8 @@ class MermaidRenderer {
element.innerText = error;
element.classList.add("parse-error");
}
} finally {
renderElement.remove();
}
};
+4
View File
@@ -35,6 +35,10 @@ this is code
).toBe(true);
});
test("returns true for latex fence", () => {
expect(isMarkdown(`\$\$i\$\$`)).toBe(true);
});
test("returns false for non-closed fence", () => {
expect(
isMarkdown(`\`\`\`
+6
View File
@@ -9,6 +9,12 @@ export default function isMarkdown(text: string): boolean {
signals += fences.length;
}
// latex-ish
const latex = text.match(/\$\$/gm);
if (latex && latex.length > 1) {
signals += latex.length;
}
// link-ish
const links = text.match(/\[[^]+\]\(https?:\/\/\S+\)/gm);
if (links) {
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Přehledy",
"Disable viewer insights": "Vypnout analytika nahlížení",
"Enable viewer insights": "Zapnout analytika nahlížení",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Domovská stránka",
"Drafts": "Koncepty",
"Trash": "Koš",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Kdokoli s odkazem má přístup, protože dokument dědí oprávnění po nadřazeném dokumentu <2>{{documentTitle}}</2>",
"Allow anyone with the link to access": "Povolit přístup komukoliv s odkazem",
"Publish to internet": "Zveřejnit na internetu",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Vložené dokumenty nejsou sdíleny na webu. Změnit sdílení pro povolení přístupu (toto bude v budoucnu výchozí chování)",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Tento pracovní prostor byl pozastaven. Prosím kontaktujte podporu pro obnovení přístupu.",
"Authentication failed this login method was disabled by a team admin.": "Ověření se nezdařilo tento způsob přihlášení byl zakázán správcem týmu.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Pracovní prostor, ke kterému se pokoušíte připojit, vyžaduje před vytvořením účtu pozvánku.<1></1> Požádejte správce pracovního prostoru o pozvánku a zkuste to znovu.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Litujeme, vaše doména není povolena. Zkuste to znovu s povolenou doménou pracovního prostoru.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Přihlášení",
"Error": "Chyba",
"Failed to load configuration.": "Nepodařilo se načíst konfiguraci.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Pokud je povoleno, dokumenty mají samostatný režim úprav. Pokud je zakázáno, dokumenty jsou vždy upravitelné, pokud máte oprávnění.",
"Remember previous location": "Zapamatovat předchozí umístění",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automaticky se vracet k dokumentu, který jste si naposledy prohlédli před ukončením aplikace.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Účet můžete kdykoliv odstranit, tento krok je neobnovitelný",
"Profile saved": "Profil uložen",
"Profile picture updated": "Profilový obrázek byl úspěšně aktualizován",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Indsigt",
"Disable viewer insights": "Aktiver seerindsigter",
"Enable viewer insights": "Aktiver seerindsigter",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Hjem",
"Drafts": "Udkast",
"Trash": "Affald",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Publish to internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Login",
"Error": "Error",
"Failed to load configuration.": "Failed to load configuration.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Remember previous location",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatically return to the document you were last viewing when the app is re-opened.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "You may delete your account at any time, note that this is unrecoverable",
"Profile saved": "Profile saved",
"Profile picture updated": "Profile picture updated",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Statistiken",
"Disable viewer insights": "Leser Statistiken deaktivieren",
"Enable viewer insights": "Leser Statistiken aktivieren",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Startseite",
"Drafts": "Entwürfe",
"Trash": "Papierkorb",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Jeder mit diesem Link kann darauf zugreifen, da das übergeordnete Dokument, <2>{{documentTitle}}</2>, geteilt wird",
"Allow anyone with the link to access": "Jedem mit dem Link Zugriff erlauben",
"Publish to internet": "Im Internet veröffentlichen",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Verschachtelte Dokumente werden nicht im Web geteilt. Schalten Sie die Freigabe um, um den Zugriff zu ermöglichen, dies wird das Standardverhalten in Zukunft sein",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Dieser Arbeitsbereich wurde gesperrt. Bitte kontaktiere den Support, um den Zugang wiederherzustellen.",
"Authentication failed this login method was disabled by a team admin.": "Authentifizierung fehlgeschlagen diese Login-Methode wurde von deinem Team-Administrator deaktiviert.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Der Arbeitsbereich, dem du beitreten möchtest, benötigt eine Einladung, bevor du ein Konto erstellen kannst. <1></1>Bitte fordere eine Einladung von deinem Arbeitsbereich-Administrator an und versuche es erneut.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Entschuldige, deine Domain ist nicht erlaubt. Bitte versuche es erneut mit einer zulässigen Arbeitsbereichs-Domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Anmelden",
"Error": "Fehler",
"Failed to load configuration.": "Fehler beim Laden der Konfiguration.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Wenn diese Option aktiviert ist, haben Dokumente einen separaten Bearbeitungsmodus. Wenn sie deaktiviert ist, können Dokumente immer bearbeitet werden, wenn du die Berechtigungen dazu hast.",
"Remember previous location": "Vorherige Position der Oberfläche merken",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatisch zum zuletzt angezeigten Dokument zurückkehren, wenn die App wieder geöffnet wird.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Sie können Ihren Account jederzeit löschen, beachten Sie, dass dies nicht wiederhergestellt werden kann",
"Profile saved": "Profil gespeichert",
"Profile picture updated": "Profilbild wurde aktualisiert",
+2 -1
View File
@@ -308,6 +308,7 @@
"{{ firstUsername }} and {{ secondUsername }} reacted with {{ emoji }}": "{{ firstUsername }} and {{ secondUsername }} reacted with {{ emoji }}",
"{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}": "{{ firstUsername }} and {{ count }} other reacted with {{ emoji }}",
"{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}_plural": "{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}",
"Add reaction": "Add reaction",
"Reaction picker": "Reaction picker",
"Could not load reactions": "Could not load reactions",
"Reaction": "Reaction",
@@ -790,7 +791,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Login",
"Error": "Error",
"Failed to load configuration.": "Failed to load configuration.",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Estadísticas",
"Disable viewer insights": "Deshabilitar estadísticas",
"Enable viewer insights": "Habilitar estadísticas",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Inicio",
"Drafts": "Borradores",
"Trash": "Papelera",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Cualquiera con el enlace puede acceder porque el documento padre, <2>{{documentTitle}}</2>, es compartido",
"Allow anyone with the link to access": "Permitir acceso a cualquiera con el enlace",
"Publish to internet": "Publicar en Internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Los documentos anidados no son compartidos en la web. Cambia las reglas de compartir para habilitar el acceso, este será el comportamiento predeterminado en el futuro",
"{{ userName }} was added to the document": "{{ userName }} ha sido añadido al documento",
"{{ count }} people added to the document": "{{ count }} persona ha sido añadida al documento",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Este espacio de trabajo ha sido suspendido. Ponte en contacto con soporte para restaurar el acceso.",
"Authentication failed this login method was disabled by a team admin.": "Autenticación fallida este método de acceso fue deshabilitado por un administrador del equipo.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "El espacio de trabajo al que estás intentando unirte requiere una invitación antes de que puedas crear una cuenta.<1></1>Por favor, solicita una invitación del administrador de tu espacio de trabajo e inténtalo de nuevo.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Lo sentimos, tu dominio no está permitido. Por favor, inténtelo de nuevo con un dominio permitido en el espacio de trabajo.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Iniciar sesión",
"Error": "Error",
"Failed to load configuration.": "No se pudo cargar la configuración.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Cuando está activada, los documentos tienen un modo de edición separada. Cuando está desactivada, los documentos son siempre editables si tienes permiso de edición.",
"Remember previous location": "Recordar ubicación anterior",
"Automatically return to the document you were last viewing when the app is re-opened.": "Volver automáticamente al documento que estabas viendo cuando la aplicación se vuelva a abrir.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Puedes eliminar tu cuenta en cualquier momento, ten en cuenta que esta es una operación irreversible",
"Profile saved": "Perfil guardado",
"Profile picture updated": "Foto de perfil guardada",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "بینش ها",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "خانه",
"Drafts": "پیش‌نویس‌ها",
"Trash": "زباله‌دان",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "انتشار روی اینترنت",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "ورود",
"Error": "Error",
"Failed to load configuration.": "پیکربندی بارگیری نشد.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Remember previous location",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatically return to the document you were last viewing when the app is re-opened.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "همیشه می‌توانید حساب‌تان را حذف کنید، ولی توجه داشته باشید که این عملیات قابل بازگشت نیست",
"Profile saved": "پروفایل ذخیره شد",
"Profile picture updated": "تصویر پروفایل به‌روز شد",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Analyses",
"Disable viewer insights": "Désactiver le visualisateur d'analyses",
"Enable viewer insights": "Activer le visualisateur d'analyses",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Accueil",
"Drafts": "Brouillons",
"Trash": "Corbeille",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "N'importe qui avec le lien peut accéder car le document parent, <2>{{documentTitle}}</2>, est partagé",
"Allow anyone with the link to access": "Permettre à toute personne ayant le lien d'accéder",
"Publish to internet": "Publier sur Internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Les documents imbriqués ne sont pas partagés sur le web. Activer/désactiver le partage pour activer l'accès, ce sera le comportement par défaut dans le futur",
"{{ userName }} was added to the document": "{{ userName }} a été ajouté au document",
"{{ count }} people added to the document": "{{ count }} personnes ajoutées au document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Cet espace de travail a été suspendu. Veuillez contacter le support afin de le réactiver.",
"Authentication failed this login method was disabled by a team admin.": "Échec de l'authentification - cette méthode de connexion a été désactivée par un administrateur d'équipe.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "L'espace de travail que vous essayez de rejoindre nécessite une invitation avant de pouvoir créer un compte.<1></1> Veuillez demander une invitation à l'administrateur de votre espace de travail et réessayer.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Désolé, votre domaine n'est pas autorisé. Veuillez réessayer avec un domaine d'espace de travail autorisé.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Identification",
"Error": "Erreur",
"Failed to load configuration.": "Échec du chargement de la configuration.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Lorsque cette option est activée, les documents ont un mode d'édition séparé. Lorsqu'elle est désactivée, les documents restent modifiables en permanence si vous en avez la permission.",
"Remember previous location": "Se souvenir de l'emplacement précédent",
"Automatically return to the document you were last viewing when the app is re-opened.": "Revenir automatiquement au document consulté en dernier lors de la réouverture de l'application.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Vous pouvez supprimer votre compte à tout moment, notez que cela est irrécupérable",
"Profile saved": "Profil enregistré",
"Profile picture updated": "Photo de profil sauvegardée",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "תובנות",
"Disable viewer insights": "כיבוי תובנות צופים",
"Enable viewer insights": "הפעלת תובנות צופים",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "בית",
"Drafts": "טיוטות",
"Trash": "אשפה",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Publish to internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Login",
"Error": "Error",
"Failed to load configuration.": "Failed to load configuration.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Remember previous location",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatically return to the document you were last viewing when the app is re-opened.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "You may delete your account at any time, note that this is unrecoverable",
"Profile saved": "Profile saved",
"Profile picture updated": "Profile picture updated",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Részletek",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Kezdőlap",
"Drafts": "Piszkozatok",
"Trash": "Lomtár",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Publikálás interneten",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Login",
"Error": "Error",
"Failed to load configuration.": "Failed to load configuration.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Engedélyezés esetén a dokumentumoknak külön szerkesztési módja van. Kikapcsolt állapotban a dokumentumok mindig szerkeszthetőek, ha rendelkezel jogosultságokkal.",
"Remember previous location": "Remember previous location",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatically return to the document you were last viewing when the app is re-opened.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "You may delete your account at any time, note that this is unrecoverable",
"Profile saved": "Profile saved",
"Profile picture updated": "Profile picture updated",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Wawasan",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Beranda",
"Drafts": "Draf",
"Trash": "Sampah",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Terbitkan ke internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Otentikasi gagal metode masuk ini dinonaktifkan oleh admin tim.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Workspace yang ingin Anda masuki memerlukan undangan sebelum Anda dapat membuat akun.<1></1> Harap minta undangan dari admin workspace Anda dan coba lagi.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Maaf, domain Anda tidak diizinkan. Coba lagi dengan domain workspace yang diizinkan.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Masuk",
"Error": "Kesalahan",
"Failed to load configuration.": "Gagal memuat konfigurasi.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Ingat lokasi sebelumnya",
"Automatically return to the document you were last viewing when the app is re-opened.": "Secara otomatis kembali ke dokumen yang terakhir Anda lihat saat aplikasi dibuka kembali.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Anda dapat menghapus akun Anda kapan saja, namun ingat bahwa ini tidak dapat dibatalkan",
"Profile saved": "Profil disimpan",
"Profile picture updated": "Gambar profil diperbarui",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Statistiche",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Home",
"Drafts": "Bozze",
"Trash": "Cestino",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Pubblica su internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Autenticazione non riuscita: questo metodo di accesso è stato disabilitato da un amministratore del team.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "L'area di lavoro a cui stai tentando di accedere richiede un invito prima di poter creare un account.<1></1>Richiedi un invito all'amministratore dell'area di lavoro e riprova.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Spiacenti, il tuo dominio non è consentito. Riprova con un dominio dell'area di lavoro consentito.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Accedi",
"Error": "Errore",
"Failed to load configuration.": "Impossibile caricare la configurazione.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Ricorda l'ultima posizione",
"Automatically return to the document you were last viewing when the app is re-opened.": "Torna automaticamente all'ultimo documento che stavi visualizzando quando l'app viene riaperta.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Puoi cancellare il tuo account in qualsiasi momento, tieni presente che l'eliminazione non è reversibile",
"Profile saved": "Profilo salvato",
"Profile picture updated": "Immagine del profilo aggiornata",
+15 -8
View File
@@ -25,8 +25,8 @@
"Mark as resolved": "解決済みとしてマーク",
"Thread resolved": "スレッドは解決されました",
"Mark as unresolved": "未解決としてマーク",
"View reactions": "View reactions",
"Reactions": "Reactions",
"View reactions": "リアクションを表示",
"Reactions": "リアクション",
"Copy ID": "ID をコピー",
"Clear IndexedDB cache": "データベースのインデックスを削除する",
"IndexedDB cache cleared": "データベースのインデックスを削除しました",
@@ -94,6 +94,9 @@
"Insights": "分析",
"Disable viewer insights": "ビューアインサイトを無効にする",
"Enable viewer insights": "ビューアインサイトを有効にする",
"Leave document": "ドキュメントから退出する",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "ホーム",
"Drafts": "下書き",
"Trash": "ゴミ箱",
@@ -306,8 +309,8 @@
"{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}": "{{ firstUsername }} and {{ count }} other reacted with {{ emoji }}",
"{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}_plural": "{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}",
"Reaction picker": "Reaction picker",
"Could not load reactions": "Could not load reactions",
"Reaction": "Reaction",
"Could not load reactions": "リアクションを読み込めません",
"Reaction": "リアクション",
"Results": "検索結果",
"No results for {{query}}": "{{query}} に該当する検索結果はありませんでした",
"Manage": "管理者",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "親ドキュメント <2>{{documentTitle}}</2> が共有されているため、リンクを持っている人は誰でもアクセスできます",
"Allow anyone with the link to access": "リンクを持っている誰もがアクセス可能",
"Publish to internet": "インターネットに公開する",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "子ドキュメントは Web で共有されません\nアクセスを有効にするためには共有を切り替えてください\nこれは今後のデフォルトとなります",
"{{ userName }} was added to the document": "{{ userName }} をドキュメントに追加しました",
"{{ count }} people added to the document": "{{ count }} 人をドキュメントに追加しました",
@@ -591,10 +596,10 @@
"Upload image": "画像をアップロード",
"No resolved comments": "解決済みのコメントはありません",
"No comments yet": "コメントはありません",
"New comments": "New comments",
"New comments": "新しいコメント",
"Sort comments": "コメントを並べ替える",
"Most recent": "Most recent",
"Order in doc": "Order in doc",
"Most recent": "最新",
"Order in doc": "ドキュメント内の順序",
"Resolved": "解決済み",
"Error updating comment": "コメントの更新中にエラーが発生しました",
"Document restored": "ドキュメントが復元されました",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "このワークスペースは凍結されています。アクセスを復元するにはサポートにお問い合わせください。",
"Authentication failed this login method was disabled by a team admin.": "認証に失敗しました – このログイン方法はチーム管理者によって無効化されています。",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "アカウントを作成するには、参加しようとしているワークスペースの招待が必要です。 <1></1>ワークスペース管理者に招待をリクエストしてから、もう一度お試しください。",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "あなたのドメインは許可されていません。許可されたワークスペースのドメインでもう一度やり直してください。",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "ログイン",
"Error": "エラー",
"Failed to load configuration.": "構成の読み込みに失敗しました",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "有効にすると、ドキュメントは編集のできない閲覧モードで開かれます。編集をするには、画面上部の編集ボタンを押す必要があります。\n無効にすると、許可がある場合は常に編集できる状態で開かれます。",
"Remember previous location": "前回開いていた場所を記憶する",
"Automatically return to the document you were last viewing when the app is re-opened.": "アプリを再度開いたときに、最後に表示していたドキュメントを自動的に表示します。",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "アカウントはいつでも削除することができます。これは取り返しのつかないことです。",
"Profile saved": "プロフィールを保存しました",
"Profile picture updated": "プロフィール画像の更新に成功しました",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "문서 정보",
"Disable viewer insights": "뷰어 정보 비활성화",
"Enable viewer insights": "뷰어 정보 활성화",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "홈",
"Drafts": "임시 보관함",
"Trash": "휴지통",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "상위 문서인 <2>{{documentTitle}}</2> 이(가) 공유되어 있으므로 링크를 가진 사람은 누구나 접근 가능",
"Allow anyone with the link to access": "링크가 있는 모든 사람에 대해 접근 허용",
"Publish to internet": "인터넷에 게시",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "중첩된 문서들은 웹에 공유되지 않습니다. 공유 버튼을 토글해 액세스를 활성화하면, 미래에도 기본 동작으로 유지됩니다.",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "이 워크스페이스는 정지된 상태입니다. 지원에 연락해 접근 권한을 복구하세요.",
"Authentication failed this login method was disabled by a team admin.": "인증 실패 – 이 로그인 방법은 팀 관리자에 의해 비활성화되었습니다.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "가입하려는 워크스페이스는 계정을 생성하기 전에 초대가 필요합니다.<1></1> 워크스페이스 관리자에게 초대를 요청하고 다시 시도하세요.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "죄송합니다. 귀하의 도메인은 허용되지 않습니다. 허용된 워크스페이스 도메인으로 다시 시도하세요.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "로그인",
"Error": "오류",
"Failed to load configuration.": "구성을 로드하지 못했습니다.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "이 기능을 활성화하면, 문서에서 분할 편집 모드를 사용할 수 있습니다. 활성화하지 않으면 권한이 있을 경우에만 문서를 편집할 수 있습니다.",
"Remember previous location": "이전 위치 기억",
"Automatically return to the document you were last viewing when the app is re-opened.": "앱이 다시 열렸을때 마지막으로 보고 있던 문서로 돌아갑니다.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "계정을 언제든지 삭제할 수 있지만 다시 복구할 수 없습니다",
"Profile saved": "프로필이 저장되었습니다",
"Profile picture updated": "프로필 사진이 업데이트 됨",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Innsikt",
"Disable viewer insights": "Deaktiver leserinnsikt",
"Enable viewer insights": "Aktiver leserinnsikt",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Hjem",
"Drafts": "Utkast",
"Trash": "Søppel",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Alle med koblingen har tilgang fordi det overordnede dokumentet, <2>{{documentTitle}}</2>, deles",
"Allow anyone with the link to access": "Tillat alle med lenken å få tilgang til",
"Publish to internet": "Publiser til internett",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Underdokumenter deles ikke på nettet. Aktiver deling for å tillate tilgang, dette vil være standard oppførsel i fremtiden",
"{{ userName }} was added to the document": "{{ userName }} ble lagt til i dokumentet",
"{{ count }} people added to the document": "{{ count }} person er lagt til i dokumentet",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Dette arbeidsområdet har blitt suspendert. Vennligst kontakt støtte for å gjenopprette tilgangen.",
"Authentication failed this login method was disabled by a team admin.": "Autentisering mislyktes denne innloggingsmetoden ble deaktivert av en teamadministrator.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Arbeidsområdet du prøver å bli med krever en invitasjon før du kan opprette en konto.<1></1>Vennligst be om en invitasjon fra din arbeidsområdeadministrator og prøv igjen.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Beklager, domenet ditt er ikke tillatt. Vennligst prøv igjen med et tillatt arbeidsområdedomene.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Logg inn",
"Error": "Feil",
"Failed to load configuration.": "Kunne ikke laste konfigurasjonen.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Når aktivert, har dokumenter en separat redigeringsmodus. Når deaktivert, er dokumenter alltid redigerbare når du har tillatelse.",
"Remember previous location": "Husk tidligere plassering",
"Automatically return to the document you were last viewing when the app is re-opened.": "Gå automatisk tilbake til dokumentet du sist så på når appen åpnes på nytt.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Du kan slette kontoen din når som helst, merk at dette er uopprettelig",
"Profile saved": "Profil lagret",
"Profile picture updated": "Profilbilde oppdatert",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Inzichten",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Startscherm",
"Drafts": "Concepten",
"Trash": "Prullenbak",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Iedereen met de link heeft toegang, omdat het bovenliggend document <2>{{documentTitle}}</2> wordt gedeeld",
"Allow anyone with the link to access": "Geef iedereen met de link toegang",
"Publish to internet": "Publiceer op internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Geneste documenten worden niet gedeeld op het web, schakel hiervoor delen in. Dit zal in de toekomst de standaardinstelling zijn.",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Toegang tot deze workspace is geblokkeerd. Neem contact op met support om toegang te herstellen.",
"Authentication failed this login method was disabled by a team admin.": "Verificatie mislukt - deze inlogmethode is uitgeschakeld door een teambeheerder.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "De werkruimte die u probeert toe te treden vereist een uitnodiging voordat u een account kunt aanmaken. <1></1>Vraag een uitnodiging aan van uw werkruimte beheerder en probeer het opnieuw.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, uw domein is niet toegestaan. Probeer het opnieuw met een toegestaan werkruimte domein.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Inloggen",
"Error": "Foutmelding",
"Failed to load configuration.": "Laden van configuratiebestand mislukt.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Indien ingeschakeld, hebben documenten een aparte bewerkingsmodus. Indien uitgeschakeld, kunnen documenten altijd worden bewerkt als je daarvoor toestemming hebt.",
"Remember previous location": "Onthoud vorige locatie",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatisch terugkeren naar het document dat je het laatst hebt bekeken als de app opnieuw wordt geopend.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Je kan jouw account op ieder moment verwijderen. Let op: je account kan niet hersteld worden.",
"Profile saved": "Wijzigingen opgeslagen",
"Profile picture updated": "Profielfoto gewijzigd",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Statystyki",
"Disable viewer insights": "Wyłącz spostrzeżenia widzów",
"Enable viewer insights": "Włącz spostrzeżenia widzów",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Strona Główna",
"Drafts": "Kopie robocze",
"Trash": "Kosz",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Każdy, kto posiada link, może uzyskać dostęp, ponieważ nadrzędny dokument, <2>{{documentTitle}}</2>, jest udostępniony",
"Allow anyone with the link to access": "Zezwól każdemu z linkiem na dostęp",
"Publish to internet": "Opublikuj w internecie",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Zagnieżdżone dokumenty nie są udostępniane w sieci. Przełącz udostępnianie, aby umożliwić dostęp, będzie to domyślne zachowanie w przyszłości",
"{{ userName }} was added to the document": "{{ userName }} został dodany do dokumentu",
"{{ count }} people added to the document": "{{ count }} osoba dodanya do dokumentu",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Ten obszar roboczy został zawieszony. Skontaktuj się z wsparciem, aby przywrócić dostęp.",
"Authentication failed this login method was disabled by a team admin.": "Uwierzytelnianie nie powiodło się ta metoda logowania została wyłączona przez administratora zespołu.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Obszar roboczy, do którego próbujesz dołączyć, wymaga zaproszenia przed utworzeniem konta.<1></1> Poproś administratora obszaru roboczego o zaproszenie i spróbuj ponownie.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Przepraszamy, Twoja domena jest niedozwolona. Spróbuj ponownie z dozwoloną domeną obszaru roboczego.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Zaloguj się",
"Error": "Błąd",
"Failed to load configuration.": "Nie udało się załadować konfiguracji.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Gdy włączone, dokumenty mają oddzielny tryb edycji. Gdy wyłączone, dokumenty są zawsze edytowalne, gdy masz uprawnienia.",
"Remember previous location": "Zapamiętaj poprzednią lokalizację",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatycznie wróć do ostatnio oglądanego dokumentu po ponownym otwarciu aplikacji.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Możesz usunąć swoje konto w dowolnym momencie, pamiętaj, że jest to nie do odzyskania",
"Profile saved": "Profil został zapisany",
"Profile picture updated": "Zaktualizowano zdjęcie profilowe",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Estatisticas",
"Disable viewer insights": "Desabilitar Estatísticas de Visualização",
"Enable viewer insights": "Habilitar Estatísticas de Visualização",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Início",
"Drafts": "Rascunhos",
"Trash": "Lixeira",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Qualquer pessoa com o link pode acessar, pois, o documento principal, <2>{{documentTitle}}</2>, está compartilhado",
"Allow anyone with the link to access": "Permitir qualquer pessoa com o link acessar",
"Publish to internet": "Publicar na internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Documentos aninhados não são compartilhados na web. Ative o compartilhamento para ativar o acesso, este será o comportamento padrão no futuro",
"{{ userName }} was added to the document": "{{ userName }} foi adicionado ao documento",
"{{ count }} people added to the document": "{{ count }} pessoas foram adicionadas ao documento",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Este espaço de trabalho foi suspenso. Por favor, contate o suporte para restaurar o acesso.",
"Authentication failed this login method was disabled by a team admin.": "Falha na autenticação este método de login foi desativado por um administrador de equipe.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "O espaço de trabalho que você está tentando entrar requer um convite antes de criar uma conta.<1></1>Solicite um convite do administrador do seu espaço de trabalho e tente novamente.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Desculpe, seu domínio não é permitido. Tente novamente com um domínio permitido no espaço de trabalho.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Iniciar sessão",
"Error": "Erro",
"Failed to load configuration.": "Falha ao carregar configuração.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Quando habilitado, os documentos têm um modo separado de edição. Quando desabilitado, documentos são sempre editáveis quando você possui permissão.",
"Remember previous location": "Lembrar escolha anterior",
"Automatically return to the document you were last viewing when the app is re-opened.": "Retorne automaticamente ao documento que você estava visualizando pela última vez quando o aplicativo for reaberto.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Você pode excluir sua conta a qualquer momento, note que isso não é recuperável",
"Profile saved": "Perfil salvo",
"Profile picture updated": "Imagem do perfil atualizada",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Estatísticas",
"Disable viewer insights": "Desativar estatísticas de visualização",
"Enable viewer insights": "Habilitar estatísticas de visualização",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Página inicial",
"Drafts": "Rascunhos",
"Trash": "Reciclagem",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Qualquer pessoa com a ligação pode aceder porque o documento principal, <2>{{documentTitle}}</2>, está partilhado",
"Allow anyone with the link to access": "Permitir que qualquer um com a ligação aceda",
"Publish to internet": "Publicar na Internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Subdocumentos não são compartilhados. Altere a partilha para ativar o acesso, este será o comportamento por defeito no futuro",
"{{ userName }} was added to the document": "{{ userName }} adicionado ao documento",
"{{ count }} people added to the document": "{{ count }} pessoa adicionada ao documento",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Esta área de trabalho foi suspensa. Por favor, contate o suporte para restaurar o acesso.",
"Authentication failed this login method was disabled by a team admin.": "Falha na autenticação — este método de autenticação foi desativado por um administrador da equipa.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "A área de trabalho em que tenta entrar requer um convite antes de criar uma conta. <1></1>Solicite um convite do administrador da sua área de trabalho e tente novamente.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Desculpe, o seu domínio não é permitido. Tente novamente com um domínio de área de trabalho permitido.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Entrada",
"Error": "Erro",
"Failed to load configuration.": "Falha ao carregar a configuração.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "Quando ativo, documentos têm um modo de edição separado. Quando inativo, documentos serão sempre alteráveis quando tiver permissões.",
"Remember previous location": "Lembrar localização anterior",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automaticamente retornar ao último documento visualizado quando a aplicação for reaberta.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Pode apagar a sua conta a qualquer momento, atenção que isso é irrecuperável",
"Profile saved": "Perfil guardado",
"Profile picture updated": "Foto de perfil foi atualizada",
+12 -5
View File
@@ -25,8 +25,8 @@
"Mark as resolved": "Markera som löst",
"Thread resolved": "Tråd löst",
"Mark as unresolved": "Markera som olöst",
"View reactions": "View reactions",
"Reactions": "Reactions",
"View reactions": "Visa reaktioner",
"Reactions": "Reaktioner",
"Copy ID": "Kopiera ID",
"Clear IndexedDB cache": "Rensa IndexedDB cache",
"IndexedDB cache cleared": "IndexedDB cache rensad",
@@ -94,6 +94,9 @@
"Insights": "Insikter",
"Disable viewer insights": "Inaktivera tittarinsikter",
"Enable viewer insights": "Aktivera tittarinsikter",
"Leave document": "Lämna dokument",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Hem",
"Drafts": "Utkast",
"Trash": "Papperskorg",
@@ -307,7 +310,7 @@
"{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}_plural": "{{ firstUsername }} and {{ count }} others reacted with {{ emoji }}",
"Reaction picker": "Reaction picker",
"Could not load reactions": "Could not load reactions",
"Reaction": "Reaction",
"Reaction": "Reaktion",
"Results": "Resultat",
"No results for {{query}}": "Inga resultat för {{query}}",
"Manage": "Administrera",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Alla med länken kan komma åt eftersom det överordnade dokumentet, <2>{{documentTitle}}</2>, delas",
"Allow anyone with the link to access": "Tillåt vem som helst med länken att komma åt",
"Publish to internet": "Publicera på internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nästlade dokument delas inte på internet. Aktivera delning för att möjliggöra åtkomst, detta kommer att vara standardbeteendet i framtiden",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -591,7 +596,7 @@
"Upload image": "Ladda upp bild",
"No resolved comments": "Inga lösta kommentarer",
"No comments yet": "Inga kommentarer än",
"New comments": "New comments",
"New comments": "Nya kommentarer",
"Sort comments": "Sort comments",
"Most recent": "Most recent",
"Order in doc": "Order in doc",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "Denna arbetsyta har stängts av. Kontakta support för att återställa åtkomst.",
"Authentication failed this login method was disabled by a team admin.": "Autentisering misslyckades denna inloggningsmetod har inaktiverats av en teamadministratör.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Den arbetsyta du försöker ansluta till kräver en inbjudan innan du kan skapa ett konto. <1></1>Vänligen begär en inbjudan från din arbetsyta-administratör och försök igen.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Tyvärr, din domän är inte tillåten. Försök igen med en tillåten arbetsytdomän.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Logga in",
"Error": "Fel",
"Failed to load configuration.": "Det gick inte att ladda konfigurationen.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "När detta är aktiverat har dokument har en separat redigeringsläge. När det är inaktiverat kan dokument alltid redigeras när du har behörighet.",
"Remember previous location": "Kom ihåg tidigare plats",
"Automatically return to the document you were last viewing when the app is re-opened.": "Återvänd automatiskt till det dokument du senast visade när appen öppnas igen.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Du kan när som helst radera ditt konto, notera att detta inte går att återställa",
"Profile saved": "Profilen har sparats",
"Profile picture updated": "Profilbild uppdaterades",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Insights",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "หน้า​แรก​",
"Drafts": "ฉบับร่าง",
"Trash": "ถังขยะ",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Publish to internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Login",
"Error": "Error",
"Failed to load configuration.": "Failed to load configuration.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Remember previous location",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatically return to the document you were last viewing when the app is re-opened.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "You may delete your account at any time, note that this is unrecoverable",
"Profile saved": "Profile saved",
"Profile picture updated": "Profile picture updated",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "İstatistikler",
"Disable viewer insights": "Disable viewer insights",
"Enable viewer insights": "Enable viewer insights",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Anasayfa",
"Drafts": "Taslaklar",
"Trash": "Çöp",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "İnternette yayınla",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Sorry, your domain is not allowed. Please try again with an allowed workspace domain.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Oturum aç",
"Error": "Error",
"Failed to load configuration.": "Konfigürasyon yüklenemedi.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Remember previous location",
"Automatically return to the document you were last viewing when the app is re-opened.": "Automatically return to the document you were last viewing when the app is re-opened.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Hesabınızı istediğiniz zaman silebilirsiniz, bunun kurtarılamaz olduğunu unutmayın",
"Profile saved": "Profil kaydedildi",
"Profile picture updated": "Profil fotoğrafı güncellendi",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Статистика",
"Disable viewer insights": "Вимкнути статистику перегляду",
"Enable viewer insights": "Увімкнути статистику перегляду",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Головна",
"Drafts": "Чернетки",
"Trash": "Кошик",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Опублікувати в інтернеті",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Помилка аутентифікації - цей метод входу був відключений адміністратором команди.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "Робоче середовище, до якого ви намагаєтеся приєднатися, потребує запрошення перед тим, як створити обліковий запис. <1></1>, будь ласка, запитайте запрошення від адміністратора робочого середовища та спробуйте ще раз.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "На жаль, ваш домен не допускається. Будь ласка, спробуйте ще раз із дозволеним робочим доменом.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Логін",
"Error": "Помилка",
"Failed to load configuration.": "Не вдалося завантажити налаштування.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Запам'ятати попереднє місце розташування",
"Automatically return to the document you were last viewing when the app is re-opened.": "Автоматично повертатись до документа, який ви переглядали, коли програма буде знову відкрита.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Ви можете видалити свій обліковий запис у будь-який час, зауважте, що це невиправно",
"Profile saved": "Профіль збережено",
"Profile picture updated": "Зображення профілю оновлено",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "Thông tin chi tiết",
"Disable viewer insights": "Tắt thông tin chi tiết của người xem",
"Enable viewer insights": "Bật thông tin chi tiết về người xem",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "Trang chủ",
"Drafts": "Bản nháp",
"Trash": "Thùng rác",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "Allow anyone with the link to access",
"Publish to internet": "Đăng tải lên internet",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future",
"{{ userName }} was added to the document": "{{ userName }} was added to the document",
"{{ count }} people added to the document": "{{ count }} people added to the document",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "This workspace has been suspended. Please contact support to restore access.",
"Authentication failed this login method was disabled by a team admin.": "Authentication failed this login method was disabled by a team admin.",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "Xin lỗi, tên miền của bạn không được chấp nhận. Hãy thử lại với một tên miền được chấp nhận.",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "Đăng nhập",
"Error": "Lỗi",
"Failed to load configuration.": "Không tải được cấu hình.",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.",
"Remember previous location": "Ghi nhớ vị trí trước đó",
"Automatically return to the document you were last viewing when the app is re-opened.": "Tự động quay lại tài liệu bạn xem lần cuối khi mở lại ứng dụng.",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "Bạn có thể xóa tài khoản của mình bất kỳ lúc nào, lưu ý rằng điều này không thể khôi phục được",
"Profile saved": "Hồ sơ đã lưu",
"Profile picture updated": "Đã cập nhật ảnh hồ sơ",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "统计",
"Disable viewer insights": "禁用浏览者统计",
"Enable viewer insights": "启用浏览者统计",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "主页",
"Drafts": "草稿箱",
"Trash": "回收站",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "知道该链接的任何人都可以访问,因为父级文档 <2>{{documentTitle}}</2> 已共享",
"Allow anyone with the link to access": "允许所有知道链接的人访问",
"Publish to internet": "发布到互联网",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "嵌套文档不会在网页上共享。切换共享以启用访问,这将是未来的默认行为。",
"{{ userName }} was added to the document": "{{ userName }} 已被添加到此文档",
"{{ count }} people added to the document": "{{ count }} 个人被添加到此文档",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "此工作区已暂停。 请联系支持人员以恢复访问权限。",
"Authentication failed this login method was disabled by a team admin.": "身份验证失败 – 此登录方式已被团队管理员禁用。",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "你正在尝试加入的工作区需要邀请才能创建账户。<1></1>请向你的工作区管理员申请邀请并重试。",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "抱歉,你的域不被允许。请使用允许的工作区域重试。",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "登录",
"Error": "加载失败",
"Failed to load configuration.": "配置文件加载失败。",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "启用时,文档为独立编辑模式。禁用时,文档在你拥有权限时始终可编辑。",
"Remember previous location": "记住上一次的位置",
"Automatically return to the document you were last viewing when the app is re-opened.": "重新打开应用程序时自动返回到你上次浏览的文档。",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "你可以随时删除你的帐户,请注意这不可恢复",
"Profile saved": "配置已保存",
"Profile picture updated": "头像已更新",
+8 -1
View File
@@ -94,6 +94,9 @@
"Insights": "洞察分析",
"Disable viewer insights": "停用瀏覽者洞察分析",
"Enable viewer insights": "啟用瀏覽者洞察分析",
"Leave document": "Leave document",
"You have left the shared document": "You have left the shared document",
"Could not leave document": "Could not leave document",
"Home": "首頁",
"Drafts": "草稿",
"Trash": "垃圾桶",
@@ -350,6 +353,8 @@
"Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared": "Anyone with the link can access because the parent document, <2>{{documentTitle}}</2>, is shared",
"Allow anyone with the link to access": "允許任何知道該連結的人訪問",
"Publish to internet": "發佈到互聯網",
"Search engine indexing": "Search engine indexing",
"Disable this setting to discourage search engines from indexing the page": "Disable this setting to discourage search engines from indexing the page",
"Nested documents are not shared on the web. Toggle sharing to enable access, this will be the default behavior in the future": "巢狀文件不會在網路上共用。切換共享以啟用訪問,這會成為未來的預設行為",
"{{ userName }} was added to the document": "{{ userName }} 已新增至此文件",
"{{ count }} people added to the document": "{{ count }} 人已新增至此文件",
@@ -785,7 +790,7 @@
"This workspace has been suspended. Please contact support to restore access.": "這個工作區已被停用。請聯繫支援以回復存取權限。",
"Authentication failed this login method was disabled by a team admin.": "身份驗證失敗 – 此登入方法已被團隊管理員禁用。",
"The workspace you are trying to join requires an invite before you can create an account.<1></1>Please request an invite from your workspace admin and try again.": "您正嘗試加入的工作區需要先得到邀請才能建立帳戶。<1></1>請向工作區管理員獲得邀請後再試一次。",
"Sorry, your domain is not allowed. Please try again with an allowed workspace domain.": "抱歉,您的域名不被允許使用。請使用被允許的工作區域名重試。",
"Sorry, an unknown error occurred.": "Sorry, an unknown error occurred.",
"Login": "登入",
"Error": "發生錯誤",
"Failed to load configuration.": "設定載入失敗",
@@ -961,6 +966,8 @@
"When enabled, documents have a separate editing mode. When disabled, documents are always editable when you have permission.": "啟用時,文件進入獨立的編輯模式。停用時,只要您有足夠權限,始終可對文件進行編輯。",
"Remember previous location": "記住上一次的位置",
"Automatically return to the document you were last viewing when the app is re-opened.": "在打開應用程式時自動開啓上一次檢視的文件。",
"Smart text replacements": "Smart text replacements",
"Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.": "Auto-format text by replacing shortcuts with symbols, dashes, smart quotes, and other typographical elements.",
"You may delete your account at any time, note that this is unrecoverable": "您隨時可以刪除您的使用者帳號,但此為不可回復之動作",
"Profile saved": "個人資料已儲存",
"Profile picture updated": "大頭貼已上傳",
+1 -1
View File
@@ -159,7 +159,7 @@ export default () =>
build: {
outDir: "./build/app",
manifest: true,
sourcemap: true,
sourcemap: process.env.CI ? false : "hidden",
minify: "terser",
// Prevent asset inling as it does not conform to CSP rules
assetsInlineLimit: 0,
+1345 -928
View File
File diff suppressed because it is too large Load Diff