mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
ui changes
This commit is contained in:
@@ -9,7 +9,7 @@ import ActionButton, {
|
||||
} from "~/components/ActionButton";
|
||||
import { undraggableOnDesktop } from "~/styles";
|
||||
|
||||
type RealProps = {
|
||||
export type RealProps = {
|
||||
$fullwidth?: boolean;
|
||||
$borderOnHover?: boolean;
|
||||
$neutral?: boolean;
|
||||
|
||||
@@ -239,6 +239,25 @@ export default class Collection extends ParanoidModel {
|
||||
}
|
||||
};
|
||||
|
||||
get flatDocuments(): Document[] {
|
||||
if (!this?.sortedDocuments) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const flatten = (docs: Document[]): Document[] => {
|
||||
const result: Document[] = [];
|
||||
for (const doc of docs) {
|
||||
result.push(doc);
|
||||
if (doc.children && doc.children.length > 0) {
|
||||
result.push(...flatten(doc.children as Document[]));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
return flatten(this.sortedDocuments as Document[]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the document identified by the given id in the collection in memory.
|
||||
* Does not update the document in the database.
|
||||
|
||||
@@ -34,6 +34,7 @@ import DocumentMeta from "./DocumentMeta";
|
||||
import DocumentTitle from "./DocumentTitle";
|
||||
import first from "lodash/first";
|
||||
import { getLangFor } from "~/utils/language";
|
||||
import NavigationButtons from "./NavigationButtons";
|
||||
|
||||
const extensions = withUIExtensions(withComments(richExtensions));
|
||||
|
||||
@@ -255,6 +256,9 @@ function DocumentEditor(props: Props, ref: React.RefObject<any>) {
|
||||
{...rest}
|
||||
/>
|
||||
<div ref={childRef}>{children}</div>
|
||||
{document.collection?.displayPreferences?.showFooterNavigation && (
|
||||
<NavigationButtons document={document} />
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,49 +3,48 @@ import React, { useMemo } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { css } from "styled-components";
|
||||
import { RealButton } from "~/components/Button";
|
||||
import { RealButton, RealProps } from "~/components/Button";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import Document from "~/models/Document";
|
||||
import breakpoint from "styled-components-breakpoint";
|
||||
import {
|
||||
faChevronLeft,
|
||||
faChevronRight,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
const NavigationButtons = () => {
|
||||
const { collections, documents, ui } = useStores();
|
||||
const activeCollection = collections.active;
|
||||
const activeDocument = documents.active;
|
||||
const NavigationButtons = ({ document }: { document: Document }) => {
|
||||
const { ui } = useStores();
|
||||
const history = useHistory();
|
||||
|
||||
const docs = useMemo(() => {
|
||||
const { collection } = document;
|
||||
let navDocs: Record<string, Document | null> = {
|
||||
prevDoc: null,
|
||||
nextDoc: null,
|
||||
};
|
||||
|
||||
const currentIndex = collections.flatDocuments.findIndex(
|
||||
(doc) => doc.id === activeDocument?.id
|
||||
);
|
||||
if (collection && collection.flatDocuments) {
|
||||
const currentIndex = collection.flatDocuments.findIndex(
|
||||
(doc) => doc.id === document?.id
|
||||
);
|
||||
|
||||
if (
|
||||
currentIndex !== undefined &&
|
||||
currentIndex !== -1 &&
|
||||
activeCollection?.documents
|
||||
) {
|
||||
const nextIdx = currentIndex + 1;
|
||||
if (nextIdx < collections.flatDocuments.length) {
|
||||
navDocs.nextDoc = collections.flatDocuments[nextIdx];
|
||||
}
|
||||
if (currentIndex !== undefined && currentIndex !== -1) {
|
||||
const nextIdx = currentIndex + 1;
|
||||
if (nextIdx < collection.flatDocuments.length) {
|
||||
navDocs.nextDoc = collection.flatDocuments[nextIdx];
|
||||
}
|
||||
|
||||
const prevIdx = currentIndex - 1;
|
||||
if (prevIdx > -1) {
|
||||
navDocs.prevDoc = collections.flatDocuments[prevIdx];
|
||||
const prevIdx = currentIndex - 1;
|
||||
if (prevIdx > -1) {
|
||||
navDocs.prevDoc = collection.flatDocuments[prevIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return navDocs;
|
||||
}, [activeDocument]);
|
||||
}, [document.collection?.sortedDocuments, document.collection]);
|
||||
|
||||
const handleNavigate = (doc: Document | null) => {
|
||||
if (doc) {
|
||||
@@ -53,10 +52,6 @@ const NavigationButtons = () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (!docs.prevDoc && !docs.nextDoc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
fullwidth={!(docs.prevDoc && docs.nextDoc)}
|
||||
@@ -103,42 +98,20 @@ const Wrapper = styled.div<
|
||||
sidebarOpen?: boolean;
|
||||
}
|
||||
>`
|
||||
position: fixed;
|
||||
bottom: 12px;
|
||||
margin-left: 20px;
|
||||
position: sticky;
|
||||
margin-bottom: 100px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
${(props) => css`
|
||||
width: ${props.fullwidth ? "35%" : "45%"};
|
||||
${breakpoint("tablet")`
|
||||
margin: 20px 0;
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.sidebarOpen &&
|
||||
css`
|
||||
@media (max-width: 1100px) {
|
||||
left: 55%;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
left: 65%;
|
||||
}
|
||||
`}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
flex-direction: column;
|
||||
width: 60%;
|
||||
margin-left: 0;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 735px) {
|
||||
width: 90%;
|
||||
left: 50%;
|
||||
}
|
||||
${breakpoint("desktop")`
|
||||
flex-direction: row;
|
||||
`}
|
||||
`;
|
||||
|
||||
const NavButton = styled(RealButton)`
|
||||
@@ -148,22 +121,19 @@ const NavButton = styled(RealButton)`
|
||||
color: ${s("text")};
|
||||
border-radius: 2px;
|
||||
line-height: 18px;
|
||||
width: 60%;
|
||||
background: none;
|
||||
shadow: 0 0 0 0 black;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background: none;
|
||||
}
|
||||
|
||||
${(props) => css`
|
||||
width: ${props.$fullwidth ? "100%" : "50%"};
|
||||
${breakpoint("desktop")`
|
||||
${(props: RealProps) => css`
|
||||
width: ${props.$fullwidth ? "100%" : "50%"};
|
||||
`}
|
||||
`}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const ButtonContent = styled.div`
|
||||
@@ -184,4 +154,4 @@ const ButtonText = styled.div`
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
export default NavigationButtons;
|
||||
export default observer(NavigationButtons);
|
||||
|
||||
@@ -7,7 +7,6 @@ import useStores from "~/hooks/useStores";
|
||||
import DataLoader from "./components/DataLoader";
|
||||
import Document from "./components/Document";
|
||||
import { Footer } from "./components/Footer";
|
||||
import NavigationButtons from "./components/NavigationButtons";
|
||||
|
||||
type Params = {
|
||||
documentSlug: string;
|
||||
@@ -69,8 +68,6 @@ export default function DocumentScene(props: Props) {
|
||||
>
|
||||
{(rest) => (
|
||||
<Document {...rest}>
|
||||
{rest.document.collection?.displayPreferences
|
||||
?.showFooterNavigation && <NavigationButtons />}
|
||||
<Footer document={rest.document} />
|
||||
</Document>
|
||||
)}
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
SubscriptionType,
|
||||
} from "@shared/types";
|
||||
import Collection from "~/models/Collection";
|
||||
import Document from "~/models/Document";
|
||||
import { PaginationParams, Properties } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import RootStore from "./RootStore";
|
||||
@@ -85,25 +84,6 @@ export default class CollectionsStore extends Store<Collection> {
|
||||
);
|
||||
}
|
||||
|
||||
@computed
|
||||
get flatDocuments(): Document[] {
|
||||
const collection = this.active;
|
||||
if (!collection?.sortedDocuments) {return [];}
|
||||
|
||||
const flatten = (docs: Document[]): Document[] => {
|
||||
const result: Document[] = [];
|
||||
for (const doc of docs) {
|
||||
result.push(doc);
|
||||
if (doc.children && doc.children.length > 0) {
|
||||
result.push(...flatten(doc.children as Document[]));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
return flatten(collection.sortedDocuments as Document[]);
|
||||
}
|
||||
|
||||
@action
|
||||
import = async (
|
||||
attachmentId: string,
|
||||
|
||||
Reference in New Issue
Block a user