feat: TOC position for publicly shared docs (#7057)
* feat: TOC position for publicly shared docs * remove preferences object * comment * fix: Allow sidebar position preference without public branding switch --------- Co-authored-by: Tom Moor <tom.moor@gmail.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import { RouteComponentProps, useLocation } from "react-router-dom";
|
|||||||
import styled, { ThemeProvider } from "styled-components";
|
import styled, { ThemeProvider } from "styled-components";
|
||||||
import { setCookie } from "tiny-cookie";
|
import { setCookie } from "tiny-cookie";
|
||||||
import { s } from "@shared/styles";
|
import { s } from "@shared/styles";
|
||||||
import { NavigationNode, PublicTeam } from "@shared/types";
|
import { NavigationNode, PublicTeam, TOCPosition } from "@shared/types";
|
||||||
import type { Theme } from "~/stores/UiStore";
|
import type { Theme } from "~/stores/UiStore";
|
||||||
import DocumentModel from "~/models/Document";
|
import DocumentModel from "~/models/Document";
|
||||||
import Error404 from "~/scenes/Error404";
|
import Error404 from "~/scenes/Error404";
|
||||||
@@ -102,6 +102,7 @@ function SharedDocumentScene(props: Props) {
|
|||||||
? (searchParams.get("theme") as Theme)
|
? (searchParams.get("theme") as Theme)
|
||||||
: undefined;
|
: undefined;
|
||||||
const theme = useBuildTheme(response?.team?.customTheme, themeOverride);
|
const theme = useBuildTheme(response?.team?.customTheme, themeOverride);
|
||||||
|
const tocPosition = response?.team?.tocPosition ?? TOCPosition.Left;
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -188,6 +189,7 @@ function SharedDocumentScene(props: Props) {
|
|||||||
document={response.document}
|
document={response.document}
|
||||||
sharedTree={response.sharedTree}
|
sharedTree={response.sharedTree}
|
||||||
shareId={shareId}
|
shareId={shareId}
|
||||||
|
tocPosition={tocPosition}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ type Props = WithTranslation &
|
|||||||
revision?: Revision;
|
revision?: Revision;
|
||||||
readOnly: boolean;
|
readOnly: boolean;
|
||||||
shareId?: string;
|
shareId?: string;
|
||||||
|
tocPosition?: TOCPosition;
|
||||||
onCreateLink?: (title: string, nested?: boolean) => Promise<string>;
|
onCreateLink?: (title: string, nested?: boolean) => Promise<string>;
|
||||||
onSearchLink?: (term: string) => Promise<SearchResult[]>;
|
onSearchLink?: (term: string) => Promise<SearchResult[]>;
|
||||||
};
|
};
|
||||||
@@ -394,8 +395,17 @@ class DocumentScene extends React.Component<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { document, revision, readOnly, abilities, auth, ui, shareId, t } =
|
const {
|
||||||
this.props;
|
document,
|
||||||
|
revision,
|
||||||
|
readOnly,
|
||||||
|
abilities,
|
||||||
|
auth,
|
||||||
|
ui,
|
||||||
|
shareId,
|
||||||
|
tocPosition,
|
||||||
|
t,
|
||||||
|
} = this.props;
|
||||||
const { team, user } = auth;
|
const { team, user } = auth;
|
||||||
const isShare = !!shareId;
|
const isShare = !!shareId;
|
||||||
const embedsDisabled =
|
const embedsDisabled =
|
||||||
@@ -404,9 +414,10 @@ class DocumentScene extends React.Component<Props> {
|
|||||||
const hasHeadings = this.headings.length > 0;
|
const hasHeadings = this.headings.length > 0;
|
||||||
const showContents =
|
const showContents =
|
||||||
ui.tocVisible && ((readOnly && hasHeadings) || !readOnly);
|
ui.tocVisible && ((readOnly && hasHeadings) || !readOnly);
|
||||||
const tocPosition =
|
const tocPos =
|
||||||
(team?.getPreference(TeamPreference.TocPosition) as TOCPosition) ||
|
tocPosition ??
|
||||||
TOCPosition.Left;
|
((team?.getPreference(TeamPreference.TocPosition) as TOCPosition) ||
|
||||||
|
TOCPosition.Left);
|
||||||
const multiplayerEditor =
|
const multiplayerEditor =
|
||||||
!document.isArchived && !document.isDeleted && !revision && !isShare;
|
!document.isArchived && !document.isDeleted && !revision && !isShare;
|
||||||
|
|
||||||
@@ -503,7 +514,7 @@ class DocumentScene extends React.Component<Props> {
|
|||||||
{showContents && (
|
{showContents && (
|
||||||
<ContentsContainer
|
<ContentsContainer
|
||||||
docFullWidth={document.fullWidth}
|
docFullWidth={document.fullWidth}
|
||||||
position={tocPosition}
|
position={tocPos}
|
||||||
>
|
>
|
||||||
<Contents headings={this.headings} />
|
<Contents headings={this.headings} />
|
||||||
</ContentsContainer>
|
</ContentsContainer>
|
||||||
@@ -511,7 +522,7 @@ class DocumentScene extends React.Component<Props> {
|
|||||||
<EditorContainer
|
<EditorContainer
|
||||||
docFullWidth={document.fullWidth}
|
docFullWidth={document.fullWidth}
|
||||||
showContents={showContents}
|
showContents={showContents}
|
||||||
tocPosition={tocPosition}
|
tocPosition={tocPos}
|
||||||
>
|
>
|
||||||
<Editor
|
<Editor
|
||||||
id={document.id}
|
id={document.id}
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
import { TeamPreference } from "@shared/types";
|
import { TOCPosition, TeamPreference } from "@shared/types";
|
||||||
import { Team } from "@server/models";
|
import { Team } from "@server/models";
|
||||||
|
|
||||||
export default function presentPublicTeam(team: Team) {
|
export default function presentPublicTeam(
|
||||||
|
/** The team to present */
|
||||||
|
team: Team,
|
||||||
|
/** Whether the branding is public */
|
||||||
|
isBrandingPublic: boolean
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
name: team.name,
|
...(isBrandingPublic
|
||||||
avatarUrl: team.avatarUrl,
|
? {
|
||||||
customTheme: team.getPreference(TeamPreference.CustomTheme),
|
name: team.name,
|
||||||
|
avatarUrl: team.avatarUrl,
|
||||||
|
customTheme: team.getPreference(TeamPreference.CustomTheme),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
tocPosition: team.getPreference(TeamPreference.TocPosition) as TOCPosition,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -439,8 +439,11 @@ router.post(
|
|||||||
apiVersion >= 2
|
apiVersion >= 2
|
||||||
? {
|
? {
|
||||||
document: serializedDocument,
|
document: serializedDocument,
|
||||||
team: team?.getPreference(TeamPreference.PublicBranding)
|
team: team
|
||||||
? presentPublicTeam(team)
|
? presentPublicTeam(
|
||||||
|
team,
|
||||||
|
!!team?.getPreference(TeamPreference.PublicBranding)
|
||||||
|
)
|
||||||
: undefined,
|
: undefined,
|
||||||
sharedTree:
|
sharedTree:
|
||||||
share && share.includeChildDocuments
|
share && share.includeChildDocuments
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ export type PublicTeam = {
|
|||||||
avatarUrl: string;
|
avatarUrl: string;
|
||||||
name: string;
|
name: string;
|
||||||
customTheme: Partial<CustomTheme>;
|
customTheme: Partial<CustomTheme>;
|
||||||
|
tocPosition: TOCPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum TOCPosition {
|
export enum TOCPosition {
|
||||||
|
|||||||
Reference in New Issue
Block a user