mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bee7911bee | |||
| 86714a353f | |||
| fd5391cbb6 | |||
| 6e685ee8d9 | |||
| b595a0d427 | |||
| 1c86119065 | |||
| c629006642 | |||
| 326f733d4c | |||
| d4d683c046 | |||
| 8204ac343f | |||
| cae8de7c7a | |||
| 8efa601967 | |||
| 86c3ea8e9d | |||
| c222782534 | |||
| 19ea7ee52b | |||
| d1de84a07e | |||
| d73b4c55bf | |||
| 9843c4c995 | |||
| 685397b057 | |||
| 13d37d4207 | |||
| 7bedfab301 | |||
| db5850ac0d | |||
| a4c40ce25e | |||
| f5457e79cd | |||
| 73eeeefb25 | |||
| 54f82cac96 | |||
| bb43c24efe | |||
| acf3d7cd08 | |||
| 5245f93642 |
@@ -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:
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>{" "}
|
||||
·{" "}
|
||||
<Link onClick={ui.setLanguagePromptDismissed}>{t("Dismiss")}</Link>
|
||||
<Link onClick={() => ui.set({ languagePromptDismissed: true })}>
|
||||
{t("Dismiss")}
|
||||
</Link>
|
||||
</span>
|
||||
</Flex>
|
||||
</Wrapper>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ function Invite({ onSubmit }: Props) {
|
||||
<Trans>{{ collectionCount }} collections</Trans>
|
||||
</strong>
|
||||
</Tooltip>
|
||||
.
|
||||
.{" "}
|
||||
</span>
|
||||
) : undefined;
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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 |
@@ -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 {
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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(`\`\`\`
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "تصویر پروفایل بهروز شد",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "プロフィール画像の更新に成功しました",
|
||||
|
||||
@@ -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": "프로필 사진이 업데이트 됨",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "Зображення профілю оновлено",
|
||||
|
||||
@@ -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ơ",
|
||||
|
||||
@@ -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": "头像已更新",
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user