mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
@@ -120,7 +120,7 @@ const DefaultCollectionInputSelect = observer(
|
||||
value={defaultCollectionId ?? "home"}
|
||||
onChange={onSelectCollection}
|
||||
label={t("Start view")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
short
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -39,7 +39,7 @@ export default function InputMemberPermissionSelect(
|
||||
value={value || EmptySelectValue}
|
||||
onChange={onChange}
|
||||
label={t("Permissions")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
nude
|
||||
{...rest}
|
||||
/>
|
||||
|
||||
@@ -60,7 +60,7 @@ type Props = Omit<React.HTMLAttributes<HTMLButtonElement>, "onChange"> & {
|
||||
/* Label for the select menu. */
|
||||
label: string;
|
||||
/* When true, label is hidden in an accessible manner. */
|
||||
hideLabel?: boolean;
|
||||
labelHidden?: boolean;
|
||||
/* When true, menu is disabled. */
|
||||
disabled?: boolean;
|
||||
/* When true, width of the menu trigger is restricted. Otherwise, takes up the full width of parent. */
|
||||
@@ -76,7 +76,7 @@ export const InputSelect = React.forwardRef<HTMLButtonElement, Props>(
|
||||
value,
|
||||
onChange,
|
||||
label,
|
||||
hideLabel,
|
||||
labelHidden,
|
||||
short,
|
||||
help,
|
||||
...triggerProps
|
||||
@@ -149,7 +149,7 @@ export const InputSelect = React.forwardRef<HTMLButtonElement, Props>(
|
||||
|
||||
return (
|
||||
<Wrapper short={short}>
|
||||
<Label text={label} hidden={hideLabel ?? false} help={help} />
|
||||
<Label text={label} hidden={labelHidden ?? false} help={help} />
|
||||
<InputSelectRoot
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
@@ -188,7 +188,7 @@ const MobileSelect = React.forwardRef<HTMLButtonElement, MobileSelectProps>(
|
||||
value,
|
||||
onChange,
|
||||
label,
|
||||
hideLabel,
|
||||
labelHidden,
|
||||
disabled,
|
||||
short,
|
||||
placeholder,
|
||||
@@ -252,7 +252,7 @@ const MobileSelect = React.forwardRef<HTMLButtonElement, MobileSelectProps>(
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Label text={label} hidden={hideLabel ?? false} />
|
||||
<Label text={label} hidden={labelHidden ?? false} />
|
||||
<Drawer open={open} onOpenChange={setOpen}>
|
||||
<DrawerTrigger asChild>
|
||||
<SelectButton
|
||||
|
||||
@@ -11,7 +11,7 @@ type Props = {
|
||||
shrink?: boolean;
|
||||
} & Pick<
|
||||
React.ComponentProps<typeof InputSelect>,
|
||||
"value" | "onChange" | "disabled" | "hideLabel" | "nude" | "help"
|
||||
"value" | "onChange" | "disabled" | "labelHidden" | "nude" | "help"
|
||||
>;
|
||||
|
||||
export const InputSelectPermission = React.forwardRef<HTMLButtonElement, Props>(
|
||||
|
||||
@@ -123,7 +123,7 @@ function Notifications(
|
||||
<HStack>
|
||||
<StyledInputSelect
|
||||
label={t("Filter")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
options={filterOptions}
|
||||
value={filter}
|
||||
onChange={(value) => setFilter(value as NotificationFilter)}
|
||||
|
||||
@@ -125,7 +125,7 @@ export const AccessControlList = observer(
|
||||
}}
|
||||
disabled={!can.update}
|
||||
value={collection?.permission}
|
||||
hideLabel
|
||||
labelHidden
|
||||
nude
|
||||
shrink
|
||||
/>
|
||||
|
||||
@@ -75,7 +75,7 @@ const CommentSortMenu = ({ viewingResolved, onChange }: Props) => {
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
label={t("Sort comments")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
borderOnHover
|
||||
/>
|
||||
);
|
||||
|
||||
+1
-1
@@ -12,11 +12,11 @@ import {
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styled, { css } from "styled-components";
|
||||
import { s } from "@shared/styles";
|
||||
import Text from "@shared/components/Text";
|
||||
import type Document from "~/models/Document";
|
||||
import type Event from "~/models/Event";
|
||||
import Time from "~/components/Time";
|
||||
import Logger from "~/utils/Logger";
|
||||
import Text from "./Text";
|
||||
|
||||
type Props = {
|
||||
document: Document;
|
||||
@@ -0,0 +1,129 @@
|
||||
import { format as formatDate } from "date-fns";
|
||||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import Text from "@shared/components/Text";
|
||||
import { dateLocale } from "@shared/utils/date";
|
||||
import { RevisionHelper } from "@shared/utils/RevisionHelper";
|
||||
import type Document from "~/models/Document";
|
||||
import type Event from "~/models/Event";
|
||||
import Revision from "~/models/Revision";
|
||||
import { InputSelect, type Option } from "~/components/InputSelect";
|
||||
import Switch from "~/components/Switch";
|
||||
import useUserLocale from "~/hooks/useUserLocale";
|
||||
import { revisionCollaboratorText } from "./utils";
|
||||
import { ResizingHeightContainer } from "~/components/ResizingHeightContainer";
|
||||
import Fade from "~/components/Fade";
|
||||
|
||||
export const COMPARE_TO_PREVIOUS = "previous";
|
||||
|
||||
interface Props {
|
||||
showChanges: boolean;
|
||||
onShowChangesToggle: (checked: boolean) => void;
|
||||
items: (Revision | Event<Document>)[];
|
||||
document?: Document;
|
||||
selectedRevisionId?: string;
|
||||
compareTo: string;
|
||||
onCompareToChange: (value: string) => void;
|
||||
}
|
||||
|
||||
export function HighlightChangesControl({
|
||||
showChanges,
|
||||
onShowChangesToggle,
|
||||
items,
|
||||
document,
|
||||
selectedRevisionId,
|
||||
compareTo,
|
||||
onCompareToChange,
|
||||
}: Props) {
|
||||
const { t } = useTranslation();
|
||||
const userLocale = useUserLocale();
|
||||
|
||||
const compareOptions = React.useMemo((): Option[] => {
|
||||
const revisionItems = items.filter(
|
||||
(item): item is Revision => item instanceof Revision
|
||||
);
|
||||
|
||||
const locale = dateLocale(userLocale);
|
||||
const resolvedSelectedId =
|
||||
selectedRevisionId === "latest" && document
|
||||
? RevisionHelper.latestId(document.id)
|
||||
: selectedRevisionId;
|
||||
|
||||
const options: Option[] = [
|
||||
{
|
||||
type: "item",
|
||||
label: t("Previous version"),
|
||||
value: COMPARE_TO_PREVIOUS,
|
||||
},
|
||||
];
|
||||
|
||||
const latestId = document
|
||||
? RevisionHelper.latestId(document.id)
|
||||
: undefined;
|
||||
|
||||
for (const rev of revisionItems) {
|
||||
if (rev.id === resolvedSelectedId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dateLabel = formatDate(new Date(rev.createdAt), "MMM do, h:mm a", {
|
||||
locale,
|
||||
});
|
||||
const collaboratorText = revisionCollaboratorText(rev, t);
|
||||
|
||||
options.push({
|
||||
type: "item",
|
||||
label: rev.name ?? dateLabel,
|
||||
value: rev.id === latestId ? "latest" : rev.id,
|
||||
description: collaboratorText,
|
||||
});
|
||||
}
|
||||
|
||||
return options;
|
||||
}, [items, selectedRevisionId, document, userLocale, t]);
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<ResizingHeightContainer>
|
||||
<Text size="small" as="div" style={{ padding: 4 }}>
|
||||
<Switch
|
||||
label={t("Highlight changes")}
|
||||
checked={showChanges}
|
||||
onChange={onShowChangesToggle}
|
||||
/>
|
||||
</Text>
|
||||
{showChanges && (
|
||||
<Fade as="div">
|
||||
<StyledInputSelect
|
||||
options={compareOptions}
|
||||
value={compareTo}
|
||||
onChange={onCompareToChange}
|
||||
label={t("Compare to")}
|
||||
labelHidden
|
||||
nude
|
||||
short
|
||||
/>
|
||||
</Fade>
|
||||
)}
|
||||
</ResizingHeightContainer>
|
||||
</Content>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledInputSelect = styled(InputSelect)`
|
||||
margin: -4px -9px -1px;
|
||||
width: calc(100% + 18px);
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
position: relative;
|
||||
inset-block-end: -1px;
|
||||
`;
|
||||
|
||||
const Content = styled.div`
|
||||
margin: 0 16px 8px;
|
||||
border: 1px solid ${(props) => props.theme.inputBorder};
|
||||
border-radius: 6px;
|
||||
padding: 8px 8px 0;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
+15
-87
@@ -1,34 +1,29 @@
|
||||
import { format as formatDate } from "date-fns";
|
||||
import isEqual from "fast-deep-equal";
|
||||
import { dateLocale } from "@shared/utils/date";
|
||||
import orderBy from "lodash/orderBy";
|
||||
import { observer } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { Pagination } from "@shared/constants";
|
||||
import { RevisionHelper } from "@shared/utils/RevisionHelper";
|
||||
import Revision from "~/models/Revision";
|
||||
import Empty from "~/components/Empty";
|
||||
import { InputSelect, type Option } from "~/components/InputSelect";
|
||||
import PaginatedEventList from "~/components/PaginatedEventList";
|
||||
import PaginatedEventList from "./PaginatedEventList";
|
||||
import {
|
||||
COMPARE_TO_PREVIOUS,
|
||||
HighlightChangesControl,
|
||||
} from "./HighlightChangesControl";
|
||||
import useKeyDown from "~/hooks/useKeyDown";
|
||||
import { useLocationSidebarContext } from "~/hooks/useLocationSidebarContext";
|
||||
import useQuery from "~/hooks/useQuery";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import useUserLocale from "~/hooks/useUserLocale";
|
||||
import { documentPath, matchDocumentHistory } from "~/utils/routeHelpers";
|
||||
import Sidebar from "./SidebarLayout";
|
||||
import Sidebar from "../SidebarLayout";
|
||||
import useMobile from "~/hooks/useMobile";
|
||||
import Switch from "~/components/Switch";
|
||||
import Text from "@shared/components/Text";
|
||||
import usePersistedState from "~/hooks/usePersistedState";
|
||||
import Scrollable from "~/components/Scrollable";
|
||||
import Flex from "@shared/components/Flex";
|
||||
|
||||
const COMPARE_TO_PREVIOUS = "previous";
|
||||
|
||||
const DocumentEvents = [
|
||||
"documents.publish",
|
||||
"documents.unpublish",
|
||||
@@ -55,7 +50,6 @@ function History() {
|
||||
const [revisionsOffset, setRevisionsOffset] = React.useState(0);
|
||||
const [eventsOffset, setEventsOffset] = React.useState(0);
|
||||
const isMobile = useMobile();
|
||||
const userLocale = useUserLocale();
|
||||
const [compareTo, setCompareTo] = React.useState(
|
||||
() => query.get("compareTo") ?? COMPARE_TO_PREVIOUS
|
||||
);
|
||||
@@ -221,49 +215,6 @@ function History() {
|
||||
return merged;
|
||||
}, [revisions, document, revisionEvents, nonRevisionEvents]);
|
||||
|
||||
const compareOptions = React.useMemo((): Option[] => {
|
||||
const revisionItems = items.filter(
|
||||
(item): item is Revision => item instanceof Revision
|
||||
);
|
||||
|
||||
const locale = dateLocale(userLocale);
|
||||
const resolvedSelectedId =
|
||||
selectedRevisionId === "latest" && document
|
||||
? RevisionHelper.latestId(document.id)
|
||||
: selectedRevisionId;
|
||||
|
||||
const options: Option[] = [
|
||||
{ type: "item", label: t("Previous revision"), value: COMPARE_TO_PREVIOUS },
|
||||
];
|
||||
|
||||
const latestId = document ? RevisionHelper.latestId(document.id) : undefined;
|
||||
|
||||
for (const rev of revisionItems) {
|
||||
if (rev.id === resolvedSelectedId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dateLabel = formatDate(
|
||||
new Date(rev.createdAt),
|
||||
"MMM do, h:mm a",
|
||||
{ locale }
|
||||
);
|
||||
const collaboratorName =
|
||||
rev.collaborators?.[0]?.name ?? rev.createdBy?.name;
|
||||
|
||||
options.push({
|
||||
type: "item",
|
||||
label: dateLabel,
|
||||
value: rev.id === latestId ? "latest" : rev.id,
|
||||
description: collaboratorName
|
||||
? t("{{userName}} edited", { userName: collaboratorName })
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
return options;
|
||||
}, [items, selectedRevisionId, document, userLocale, t]);
|
||||
|
||||
const onCloseHistory = React.useCallback(() => {
|
||||
if (isMobile) {
|
||||
// Allow closing the history drawer on mobile to view revision content
|
||||
@@ -283,26 +234,15 @@ function History() {
|
||||
|
||||
return (
|
||||
<Sidebar title={t("History")} onClose={onCloseHistory} scrollable={false}>
|
||||
<Content>
|
||||
<Text type="secondary" size="small" as="span">
|
||||
<Switch
|
||||
label={t("Highlight changes")}
|
||||
checked={showChanges}
|
||||
onChange={handleShowChangesToggle}
|
||||
/>
|
||||
</Text>
|
||||
{showChanges && (
|
||||
<CompareToWrapper>
|
||||
<InputSelect
|
||||
options={compareOptions}
|
||||
value={compareTo}
|
||||
onChange={handleCompareToChange}
|
||||
label={t("Compare to")}
|
||||
short
|
||||
/>
|
||||
</CompareToWrapper>
|
||||
)}
|
||||
</Content>
|
||||
<HighlightChangesControl
|
||||
showChanges={showChanges}
|
||||
onShowChangesToggle={handleShowChangesToggle}
|
||||
items={items}
|
||||
document={document}
|
||||
selectedRevisionId={selectedRevisionId}
|
||||
compareTo={compareTo}
|
||||
onCompareToChange={handleCompareToChange}
|
||||
/>
|
||||
<Scrollable hiddenScrollbars topShadow>
|
||||
{document ? (
|
||||
<PaginatedEventList
|
||||
@@ -333,16 +273,4 @@ function History() {
|
||||
);
|
||||
}
|
||||
|
||||
const Content = styled.div`
|
||||
margin: 0 16px 8px;
|
||||
border: 1px solid ${(props) => props.theme.inputBorder};
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 0;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const CompareToWrapper = styled.div`
|
||||
padding: 4px 0 8px;
|
||||
`;
|
||||
|
||||
export default observer(History);
|
||||
+31
-28
@@ -4,9 +4,9 @@ import { EditIcon, TrashIcon } from "outline-icons";
|
||||
import { useMemo, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import EventBoundary from "@shared/components/EventBoundary";
|
||||
import { ellipsis, hover } from "@shared/styles";
|
||||
import { ellipsis, hover, s } from "@shared/styles";
|
||||
import { RevisionHelper } from "@shared/utils/RevisionHelper";
|
||||
import type Document from "~/models/Document";
|
||||
import type Revision from "~/models/Revision";
|
||||
@@ -27,8 +27,9 @@ import { useMenuAction } from "~/hooks/useMenuAction";
|
||||
import RevisionMenu from "~/menus/RevisionMenu";
|
||||
import { documentHistoryPath } from "~/utils/routeHelpers";
|
||||
import { EventItem, lineStyle } from "./EventListItem";
|
||||
import Facepile from "./Facepile";
|
||||
import Text from "./Text";
|
||||
import Facepile from "~/components/Facepile";
|
||||
import Text from "~/components/Text";
|
||||
import { revisionCollaboratorText } from "./utils";
|
||||
|
||||
type Props = {
|
||||
document: Document;
|
||||
@@ -70,16 +71,7 @@ const RevisionListItem = ({ item, document, ...rest }: Props) => {
|
||||
} else {
|
||||
icon = <EditIcon size={16} />;
|
||||
|
||||
let collaboratorText: string | undefined;
|
||||
if (item.collaborators && item.collaborators.length === 2) {
|
||||
collaboratorText = `${item.collaborators[0].name} and ${item.collaborators[1].name}`;
|
||||
} else if (item.collaborators && item.collaborators.length > 2) {
|
||||
collaboratorText = t("{{count}} people", {
|
||||
count: item.collaborators.length,
|
||||
});
|
||||
} else {
|
||||
collaboratorText = item.createdBy?.name;
|
||||
}
|
||||
const collaboratorText = revisionCollaboratorText(item, t);
|
||||
|
||||
meta = isLatestRevision ? (
|
||||
<>
|
||||
@@ -101,11 +93,6 @@ const RevisionListItem = ({ item, document, ...rest }: Props) => {
|
||||
};
|
||||
}
|
||||
|
||||
const isActive =
|
||||
typeof to === "string"
|
||||
? location.pathname === to
|
||||
: location.pathname === to?.pathname;
|
||||
|
||||
if (document.isDeleted) {
|
||||
to = undefined;
|
||||
}
|
||||
@@ -157,11 +144,9 @@ const RevisionListItem = ({ item, document, ...rest }: Props) => {
|
||||
}
|
||||
subtitle={<Meta>{meta}</Meta>}
|
||||
actions={
|
||||
isActive ? (
|
||||
<StyledEventBoundary>
|
||||
<RevisionMenu document={document} revisionId={item.id} />
|
||||
</StyledEventBoundary>
|
||||
) : undefined
|
||||
<StyledEventBoundary>
|
||||
<RevisionMenu document={document} revisionId={item.id} />
|
||||
</StyledEventBoundary>
|
||||
}
|
||||
ref={ref}
|
||||
$menuOpen={menuOpen}
|
||||
@@ -192,15 +177,33 @@ const RevisionItem = styled(Item)<{ $menuOpen?: boolean }>`
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
|
||||
${lineStyle}
|
||||
|
||||
${Actions} {
|
||||
opacity: ${(props) => (props.$menuOpen ? 1 : 0.5)};
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&: ${hover} {
|
||||
&:${hover},
|
||||
&:active,
|
||||
&:focus,
|
||||
&:focus-within,
|
||||
&:has([data-state="open"]) {
|
||||
background: ${s("listItemHoverBackground")};
|
||||
|
||||
${Actions} {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
${(props) =>
|
||||
props.$menuOpen &&
|
||||
css`
|
||||
background: ${s("listItemHoverBackground")};
|
||||
|
||||
${Actions} {
|
||||
opacity: 1;
|
||||
}
|
||||
`}
|
||||
|
||||
${lineStyle}
|
||||
`;
|
||||
|
||||
export default observer(RevisionListItem);
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { TFunction } from "i18next";
|
||||
import type Revision from "~/models/Revision";
|
||||
|
||||
/**
|
||||
* Returns a human-readable summary of who collaborated on a revision. Uses the
|
||||
* collaborator list when available, falling back to the creator's name.
|
||||
*
|
||||
* @param revision the revision to summarize.
|
||||
* @param t translation function.
|
||||
* @returns the collaborator text, or undefined if unavailable.
|
||||
*/
|
||||
export function revisionCollaboratorText(
|
||||
revision: Revision,
|
||||
t: TFunction
|
||||
): string | undefined {
|
||||
if (revision.collaborators && revision.collaborators.length === 2) {
|
||||
return `${revision.collaborators[0].name} and ${revision.collaborators[1].name}`;
|
||||
}
|
||||
if (revision.collaborators && revision.collaborators.length > 2) {
|
||||
return t("{{count}} people", { count: revision.collaborators.length });
|
||||
}
|
||||
return revision.createdBy?.name;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ const DocumentComments = lazyWithRetry(
|
||||
() => import("~/scenes/Document/components/Comments/Comments")
|
||||
);
|
||||
const DocumentHistory = lazyWithRetry(
|
||||
() => import("~/scenes/Document/components/History")
|
||||
() => import("~/scenes/Document/components/History/History")
|
||||
);
|
||||
|
||||
interface DocumentSidebarContentProps {
|
||||
|
||||
@@ -187,7 +187,7 @@ const Application = observer(function Application({ oauthClient }: Props) {
|
||||
name="clientType"
|
||||
render={({ field }) => (
|
||||
<InputClientType
|
||||
hideLabel
|
||||
labelHidden
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
ref={field.ref}
|
||||
|
||||
@@ -317,7 +317,7 @@ function Details() {
|
||||
value={tocPosition}
|
||||
onChange={handleTocPositionChange}
|
||||
label={t("Table of contents position")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ function Preferences() {
|
||||
value={user.language}
|
||||
onChange={handleLanguageChange}
|
||||
label={t("Language")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
@@ -201,7 +201,7 @@ function Preferences() {
|
||||
value={ui.theme}
|
||||
onChange={handleThemeChange}
|
||||
label={t("Appearance")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
@@ -293,7 +293,7 @@ function Preferences() {
|
||||
value={user.getPreference(UserPreference.NotificationBadge)}
|
||||
onChange={handleNotificationBadgeChange}
|
||||
label={t("Notification badge")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ function Security() {
|
||||
options={userRoleOptions}
|
||||
onChange={handleDefaultRoleChange}
|
||||
label={t("Default role")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
short
|
||||
/>
|
||||
</SettingRow>
|
||||
@@ -331,7 +331,7 @@ function Security() {
|
||||
options={emailDisplayOptions}
|
||||
onChange={handleEmailDisplayChange}
|
||||
label={t("Email address visibility")}
|
||||
hideLabel
|
||||
labelHidden
|
||||
short
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
@@ -324,15 +324,6 @@
|
||||
"our engineers have been notified": "our engineers have been notified",
|
||||
"Clear cache + reload": "Clear cache + reload",
|
||||
"Show detail": "Show detail",
|
||||
"{{userName}} archived": "{{userName}} archived",
|
||||
"{{userName}} restored": "{{userName}} restored",
|
||||
"{{userName}} deleted": "{{userName}} deleted",
|
||||
"{{userName}} added {{addedUserName}}": "{{userName}} added {{addedUserName}}",
|
||||
"{{userName}} removed {{removedUserName}}": "{{userName}} removed {{removedUserName}}",
|
||||
"{{userName}} moved from trash": "{{userName}} moved from trash",
|
||||
"{{userName}} published": "{{userName}} published",
|
||||
"{{userName}} unpublished": "{{userName}} unpublished",
|
||||
"{{userName}} moved": "{{userName}} moved",
|
||||
"A ZIP file containing the images, and documents in the Markdown format.": "A ZIP file containing the images, and documents in the Markdown format.",
|
||||
"A ZIP file containing the images, and documents as HTML files.": "A ZIP file containing the images, and documents as HTML files.",
|
||||
"Structured data that can be used to transfer data to another compatible {{ appName }} instance.": "Structured data that can be used to transfer data to another compatible {{ appName }} instance.",
|
||||
@@ -424,12 +415,6 @@
|
||||
"{{ hours }}h {{ minutes }}m read": "{{ hours }}h {{ minutes }}m read",
|
||||
"{{ hours }}h read": "{{ hours }}h read",
|
||||
"{{ minutes }}m read": "{{ minutes }}m read",
|
||||
"Revision deleted": "Revision deleted",
|
||||
"{{count}} people": "{{count}} person",
|
||||
"{{count}} people_plural": "{{count}} people",
|
||||
"Current version": "Current version",
|
||||
"{{userName}} edited": "{{userName}} edited",
|
||||
"Revision options": "Revision options",
|
||||
"Manage": "Manage",
|
||||
"All members": "All members",
|
||||
"Everyone in the workspace": "Everyone in the workspace",
|
||||
@@ -725,6 +710,7 @@
|
||||
"Revoking": "Revoking",
|
||||
"Are you sure you want to revoke access?": "Are you sure you want to revoke access?",
|
||||
"Delete app": "Delete app",
|
||||
"Revision options": "Revision options",
|
||||
"Share options": "Share options",
|
||||
"Headings you add to the document will appear here": "Headings you add to the document will appear here",
|
||||
"Contents": "Contents",
|
||||
@@ -832,10 +818,24 @@
|
||||
"Archived": "Archived",
|
||||
"Save draft": "Save draft",
|
||||
"Restore version": "Restore version",
|
||||
"Previous revision": "Previous revision",
|
||||
"{{userName}} archived": "{{userName}} archived",
|
||||
"{{userName}} restored": "{{userName}} restored",
|
||||
"{{userName}} deleted": "{{userName}} deleted",
|
||||
"{{userName}} added {{addedUserName}}": "{{userName}} added {{addedUserName}}",
|
||||
"{{userName}} removed {{removedUserName}}": "{{userName}} removed {{removedUserName}}",
|
||||
"{{userName}} moved from trash": "{{userName}} moved from trash",
|
||||
"{{userName}} published": "{{userName}} published",
|
||||
"{{userName}} unpublished": "{{userName}} unpublished",
|
||||
"{{userName}} moved": "{{userName}} moved",
|
||||
"Previous version": "Previous version",
|
||||
"Highlight changes": "Highlight changes",
|
||||
"Compare to": "Compare to",
|
||||
"No history yet": "No history yet",
|
||||
"Revision deleted": "Revision deleted",
|
||||
"Current version": "Current version",
|
||||
"{{userName}} edited": "{{userName}} edited",
|
||||
"{{count}} people": "{{count}} person",
|
||||
"{{count}} people_plural": "{{count}} people",
|
||||
"Source": "Source",
|
||||
"Created": "Created",
|
||||
"Imported from {{ source }}": "Imported from {{ source }}",
|
||||
|
||||
Reference in New Issue
Block a user