From c7860bba47709d8efae0ca7faeb07c28f5260cd1 Mon Sep 17 00:00:00 2001 From: Kilu Date: Tue, 3 Sep 2024 16:41:18 +0800 Subject: [PATCH] feat: support publish outline --- .../src/application/publish/context.tsx | 33 ++++++++- .../services/js-services/http/http_api.ts | 19 ++++- .../application/services/js-services/index.ts | 4 ++ .../src/application/services/services.type.ts | 4 +- .../services/tauri-services/index.ts | 4 ++ .../appflowy_web_app/src/application/types.ts | 24 ++++++- .../appflowy_web_app/src/assets/appflowy.svg | 41 +++++------ .../src/assets/chevron_down.svg | 2 +- .../_shared/popover/RichTooltip.tsx | 9 ++- .../_shared/skeleton/OutlineSkeleton.tsx | 47 ++++++++++++ .../components/_shared/skeleton/skeleton.scss | 13 ++++ .../src/components/publish/PublishView.tsx | 12 +++- .../publish/header/BreadcrumbItem.tsx | 6 +- .../components/publish/header/MoreActions.tsx | 14 +--- .../publish/header/PublishViewHeader.tsx | 30 +++++--- .../components/publish/outline/Outline.tsx | 72 +++++-------------- .../publish/outline/OutlineDrawer.tsx | 22 +++--- .../publish/outline/OutlineItem.tsx | 65 ++++++++++++----- .../publish/outline/OutlinePopover.tsx | 28 +++++--- .../src/pages/AfterPaymentPage.tsx | 10 ++- 20 files changed, 302 insertions(+), 157 deletions(-) create mode 100644 frontend/appflowy_web_app/src/components/_shared/skeleton/OutlineSkeleton.tsx create mode 100644 frontend/appflowy_web_app/src/components/_shared/skeleton/skeleton.scss diff --git a/frontend/appflowy_web_app/src/application/publish/context.tsx b/frontend/appflowy_web_app/src/application/publish/context.tsx index 9e7773624b871..778fe30e81bc1 100644 --- a/frontend/appflowy_web_app/src/application/publish/context.tsx +++ b/frontend/appflowy_web_app/src/application/publish/context.tsx @@ -1,7 +1,9 @@ import { GetViewRowsMap, LoadView, LoadViewMeta } from '@/application/collab.type'; import { db } from '@/application/db'; import { ViewMeta } from '@/application/db/tables/view_metas'; -import { AFConfigContext } from '@/components/app/app.hooks'; +import { View } from '@/application/types'; +import { useService } from '@/components/app/app.hooks'; +import { notify } from '@/components/_shared/notify'; import { useLiveQuery } from 'dexie-react-hooks'; import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -14,8 +16,8 @@ export interface PublishContextType { toView: (viewId: string) => Promise; loadViewMeta: LoadViewMeta; getViewRowsMap?: GetViewRowsMap; - loadView: LoadView; + outline?: View; } export const PublishContext = createContext(null); @@ -36,6 +38,9 @@ export const PublishProvider = ({ return db.view_metas.get(name); }, [namespace, publishName]); + + const [outline, setOutline] = useState(); + const [subscribers, setSubscribers] = useState void>>(new Map()); useEffect(() => { @@ -43,6 +48,7 @@ export const PublishProvider = ({ setSubscribers(new Map()); }; }, []); + useEffect(() => { db.view_metas.hook('creating', (primaryKey, obj) => { const subscriber = subscribers.get(primaryKey); @@ -72,7 +78,8 @@ export const PublishProvider = ({ const prevViewMeta = useRef(viewMeta); - const service = useContext(AFConfigContext)?.service; + const service = useService(); + const navigate = useNavigate(); const toView = useCallback( async (viewId: string) => { @@ -93,6 +100,21 @@ export const PublishProvider = ({ [navigate, service], ); + const loadOutline = useCallback(async () => { + if (!service || !namespace) return; + try { + const res = await service?.getPublishOutline(namespace); + + if (!res) { + throw new Error('Publish outline not found'); + } + + setOutline(res); + } catch (e) { + notify.error('Publish outline not found'); + } + }, [namespace, service]); + const loadViewMeta = useCallback( async (viewId: string, callback?: (meta: ViewMeta) => void) => { try { @@ -188,6 +210,10 @@ export const PublishProvider = ({ prevViewMeta.current = viewMeta; }, [viewMeta]); + useEffect(() => { + void loadOutline(); + }, [loadOutline]); + return ( {children} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/http/http_api.ts b/frontend/appflowy_web_app/src/application/services/js-services/http/http_api.ts index b95a38257850d..cfeda5e915b72 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/http/http_api.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/http/http_api.ts @@ -11,7 +11,7 @@ import { TemplateCreator, TemplateCreatorFormValues, TemplateSummary, UploadTemplatePayload, } from '@/application/template.type'; -import { FolderView, User, Workspace } from '@/application/types'; +import { FolderView, User, View, Workspace } from '@/application/types'; import axios, { AxiosInstance } from 'axios'; import dayjs from 'dayjs'; @@ -233,6 +233,23 @@ export async function getPublishInfoWithViewId (viewId: string) { return Promise.reject(data); } +export async function getPublishOutline (publishNamespace: string) { + const url = `/api/workspace/published-outline/${publishNamespace}`; + const response = await axiosInstance?.get<{ + code: number; + data?: View; + message: string; + }>(url); + + const data = response?.data; + + if (data?.code === 0 && data.data) { + return data.data; + } + + return Promise.reject(data); +} + export async function getPublishViewComments (viewId: string): Promise { const url = `/api/workspace/published-info/${viewId}/comment`; const response = await axiosInstance?.get<{ diff --git a/frontend/appflowy_web_app/src/application/services/js-services/index.ts b/frontend/appflowy_web_app/src/application/services/js-services/index.ts index b8df216c22512..fe75849a7f679 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/index.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/index.ts @@ -164,6 +164,10 @@ export class AFClientService implements AFService { return data; } + async getPublishOutline (namespace: string) { + return APIService.getPublishOutline(namespace); + } + async loginAuth (url: string) { try { console.log('loginAuth', url); diff --git a/frontend/appflowy_web_app/src/application/services/services.type.ts b/frontend/appflowy_web_app/src/application/services/services.type.ts index a346800058f8b..bde0cc4dbe47a 100644 --- a/frontend/appflowy_web_app/src/application/services/services.type.ts +++ b/frontend/appflowy_web_app/src/application/services/services.type.ts @@ -9,7 +9,7 @@ import { UploadTemplatePayload, } from '@/application/template.type'; import * as Y from 'yjs'; -import { DuplicatePublishView, FolderView, User, Workspace } from '@/application/types'; +import { DuplicatePublishView, FolderView, User, View, Workspace } from '@/application/types'; export type AFService = PublishService; @@ -37,6 +37,8 @@ export interface PublishService { destroy: () => void; }>; + getPublishOutline (namespace: string): Promise; + getPublishViewGlobalComments: (viewId: string) => Promise; createCommentOnPublishView: (viewId: string, content: string, replyCommentId?: string) => Promise; deleteCommentOnPublishView: (viewId: string, commentId: string) => Promise; diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts index e6691c473ed32..cfdcda4acbb9c 100644 --- a/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/index.ts @@ -24,6 +24,10 @@ export class AFClientService implements AFService { return Promise.reject('Method not implemented'); } + async getPublishOutline (_namespace: string) { + return Promise.reject('Method not implemented'); + } + async getPublishViewMeta (_namespace: string, _publishName: string) { return Promise.reject('Method not implemented'); } diff --git a/frontend/appflowy_web_app/src/application/types.ts b/frontend/appflowy_web_app/src/application/types.ts index 1549df084bace..d9d89d080ca7a 100644 --- a/frontend/appflowy_web_app/src/application/types.ts +++ b/frontend/appflowy_web_app/src/application/types.ts @@ -1,4 +1,4 @@ -import { CollabType } from '@/application/collab.type'; +import { CollabType, ViewLayout } from '@/application/collab.type'; export interface Workspace { icon: string; @@ -38,3 +38,25 @@ export interface DuplicatePublishView { collabType: CollabType; viewId: string; } + +export interface ViewIcon { + ty: number; + value: string; +} + +export interface ViewExtra { + is_space: boolean; + space_created_at?: number; + space_icon?: string; + space_icon_color?: string; + space_permission?: number; +} + +export interface View { + view_id: string; + name: string; + icon: ViewIcon | null; + layout: ViewLayout; + extra: ViewExtra | null; + children: View[]; +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/appflowy.svg b/frontend/appflowy_web_app/src/assets/appflowy.svg index c282c112e1345..a448b18731c0d 100644 --- a/frontend/appflowy_web_app/src/assets/appflowy.svg +++ b/frontend/appflowy_web_app/src/assets/appflowy.svg @@ -1,25 +1,18 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/frontend/appflowy_web_app/src/assets/chevron_down.svg b/frontend/appflowy_web_app/src/assets/chevron_down.svg index fbf3c9aabd7d6..880c2dde18544 100644 --- a/frontend/appflowy_web_app/src/assets/chevron_down.svg +++ b/frontend/appflowy_web_app/src/assets/chevron_down.svg @@ -1,5 +1,5 @@ - + diff --git a/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx b/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx index bb90b80c4186d..e67b8a388a607 100644 --- a/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx @@ -7,9 +7,13 @@ interface Props { open: boolean; onClose: () => void; placement?: PopperPlacementType; + PaperProps?: { + className?: string; + }; + } -export const RichTooltip = ({ placement = 'top', open, onClose, content, children }: Props) => { +export const RichTooltip = ({ placement = 'top', open, onClose, content, children, PaperProps }: Props) => { const [childNode, setChildNode] = React.useState(null); const [, setTransitioning] = React.useState(false); @@ -48,7 +52,8 @@ export const RichTooltip = ({ placement = 'top', open, onClose, content, childre > - + {content} diff --git a/frontend/appflowy_web_app/src/components/_shared/skeleton/OutlineSkeleton.tsx b/frontend/appflowy_web_app/src/components/_shared/skeleton/OutlineSkeleton.tsx new file mode 100644 index 0000000000000..dcf0f19e8bd59 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/_shared/skeleton/OutlineSkeleton.tsx @@ -0,0 +1,47 @@ +import { Box, Skeleton } from '@mui/material'; +import './skeleton.scss'; + +export const DirectoryStructure = () => { + return ( + +
+ + +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+ + ); +}; \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/components/_shared/skeleton/skeleton.scss b/frontend/appflowy_web_app/src/components/_shared/skeleton/skeleton.scss new file mode 100644 index 0000000000000..82de17d2adcf9 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/_shared/skeleton/skeleton.scss @@ -0,0 +1,13 @@ +.directory-item { + display: flex; + align-items: center; + margin-bottom: 8px; +} + +.directory-item .MuiSkeleton-root { + margin-right: 8px; +} + +.nested { + margin-left: 24px; +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/components/publish/PublishView.tsx b/frontend/appflowy_web_app/src/components/publish/PublishView.tsx index 9c1246da998a6..508c43959435e 100644 --- a/frontend/appflowy_web_app/src/components/publish/PublishView.tsx +++ b/frontend/appflowy_web_app/src/components/publish/PublishView.tsx @@ -42,13 +42,19 @@ export function PublishView ({ namespace, publishName }: PublishViewProps) { void openPublishView(); }, [openPublishView]); - const [open, setOpen] = useState(false); + const [open, setOpen] = useState(() => { + return localStorage.getItem('publish_outline_open') === 'true'; + }); const [search] = useSearchParams(); const isTemplate = search.get('template') === 'true'; const isTemplateThumb = isTemplate && search.get('thumbnail') === 'true'; + useEffect(() => { + localStorage.setItem('publish_outline_open', open ? 'true' : 'false'); + }, [open]); + useEffect(() => { if (!isTemplateThumb) return; document.documentElement.setAttribute('thumbnail', 'true'); @@ -83,6 +89,10 @@ export function PublishView ({ namespace, publishName }: PublishViewProps) { onOpenDrawer={() => { setOpen(true); }} + drawerWidth={drawerWidth} + onCloseDrawer={() => { + setOpen(false); + }} openDrawer={open} />} diff --git a/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx b/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx index 2e3c5d2e48b33..14d6e01cdb020 100644 --- a/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx +++ b/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx @@ -42,7 +42,7 @@ function BreadcrumbItem ({ crumb, disableClick = false }: { crumb: Crumb; disabl return (
{ if (disableClick) return; try { @@ -54,10 +54,10 @@ function BreadcrumbItem ({ crumb, disableClick = false }: { crumb: Crumb; disabl > {extraObj && extraObj.is_space ? ( diff --git a/frontend/appflowy_web_app/src/components/publish/header/MoreActions.tsx b/frontend/appflowy_web_app/src/components/publish/header/MoreActions.tsx index 8d7eec6eb14af..f24ff60473a86 100644 --- a/frontend/appflowy_web_app/src/components/publish/header/MoreActions.tsx +++ b/frontend/appflowy_web_app/src/components/publish/header/MoreActions.tsx @@ -109,19 +109,7 @@ function MoreActions () { {action.label} ))} - -
{ - window.open('https://appflowy.io', '_blank'); - }} - className={ - 'flex w-full cursor-pointer items-center justify-center py-2 text-sm text-text-title opacity-50' - } - > - Powered by - - -
+
)} diff --git a/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx b/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx index 16e0e71f7235e..26941123a2ac0 100644 --- a/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx +++ b/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx @@ -15,7 +15,14 @@ import { Duplicate } from './duplicate'; export const HEADER_HEIGHT = 48; -export function PublishViewHeader({ onOpenDrawer, openDrawer }: { onOpenDrawer: () => void; openDrawer: boolean }) { +export function PublishViewHeader ({ + drawerWidth, onOpenDrawer, openDrawer, onCloseDrawer, +}: { + onOpenDrawer: () => void; + drawerWidth: number; + openDrawer: boolean; + onCloseDrawer: () => void +}) { const { t } = useTranslation(); const viewMeta = usePublishContext()?.viewMeta; const crumbs = useMemo(() => { @@ -28,7 +35,7 @@ export function PublishViewHeader({ onOpenDrawer, openDrawer }: { onOpenDrawer: const extra = ancestor?.extra ? JSON.parse(ancestor.extra) : {}; icon = extra.icon?.value || ancestor.icon?.value; - } catch(e) { + } catch (e) { // ignore } @@ -50,15 +57,20 @@ export function PublishViewHeader({ onOpenDrawer, openDrawer }: { onOpenDrawer: }, []); const onKeyDown = useCallback((e: KeyboardEvent) => { - switch(true) { + switch (true) { case createHotkey(HOT_KEY_NAME.TOGGLE_SIDEBAR)(e): e.preventDefault(); - // setOpen((prev) => !prev); + if (openDrawer) { + onCloseDrawer(); + } else { + onOpenDrawer(); + } + break; default: break; } - }, []); + }, [onCloseDrawer, onOpenDrawer, openDrawer]); useEffect(() => { window.addEventListener('keydown', onKeyDown); @@ -69,7 +81,7 @@ export function PublishViewHeader({ onOpenDrawer, openDrawer }: { onOpenDrawer: const handleOpenPopover = useCallback(() => { debounceClosePopover.cancel(); - if(openDrawer) { + if (openDrawer) { return; } @@ -89,16 +101,16 @@ export function PublishViewHeader({ onOpenDrawer, openDrawer }: { onOpenDrawer: }} className={'appflowy-top-bar sticky top-0 z-10 flex px-5'} > -
- {!openDrawer && openPopover && ( +
+ {!openDrawer && ( { setOpenPopover(false); onOpenDrawer(); diff --git a/frontend/appflowy_web_app/src/components/publish/outline/Outline.tsx b/frontend/appflowy_web_app/src/components/publish/outline/Outline.tsx index 69ac61158a624..c9b2ce928caab 100644 --- a/frontend/appflowy_web_app/src/components/publish/outline/Outline.tsx +++ b/frontend/appflowy_web_app/src/components/publish/outline/Outline.tsx @@ -1,62 +1,26 @@ -import { PublishViewInfo, ViewLayout } from '@/application/collab.type'; +import { usePublishContext } from '@/application/publish'; +import emptyImageSrc from '@/assets/images/empty.png'; +import { DirectoryStructure } from '@/components/_shared/skeleton/OutlineSkeleton'; import OutlineItem from '@/components/publish/outline/OutlineItem'; -import SearchInput from '@/components/publish/outline/SearchInput'; -import { filterViews } from '@/components/publish/outline/utils'; -import { CircularProgress } from '@mui/material'; -import React, { useCallback, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; +import React from 'react'; -function Outline({ viewMeta, width }: { viewMeta?: PublishViewInfo; width: number }) { - const hasChildren = Boolean(viewMeta?.child_views?.length); - const { t } = useTranslation(); - const [children, setChildren] = React.useState([]); +function Outline ({ width }: { width: number }) { + const outline = usePublishContext()?.outline; - useEffect(() => { - if (viewMeta) { - setChildren(viewMeta.child_views || []); - } - }, [viewMeta]); - - const handleSearch = useCallback( - (val: string) => { - if (!val) { - return setChildren(viewMeta?.child_views || []); - } - - setChildren(filterViews(viewMeta?.child_views || [], val)); - }, - [viewMeta] - ); - - if (!viewMeta) { - return ; - } + const isEmpty = outline && outline.children.length === 0; return ( -
-
- -
- - {hasChildren ? ( -
- {children - .filter((view) => view.layout === ViewLayout.Document) - .map((view: PublishViewInfo) => ( - - ))} -
- ) : ( -
{t('noPagesInside')}
- )} +
+ {isEmpty && {'No} + {!outline ? : + outline.children.map((view) => + , + ) + }
); } diff --git a/frontend/appflowy_web_app/src/components/publish/outline/OutlineDrawer.tsx b/frontend/appflowy_web_app/src/components/publish/outline/OutlineDrawer.tsx index c25a447f14cb3..783207f130f06 100644 --- a/frontend/appflowy_web_app/src/components/publish/outline/OutlineDrawer.tsx +++ b/frontend/appflowy_web_app/src/components/publish/outline/OutlineDrawer.tsx @@ -1,15 +1,13 @@ -import { usePublishContext } from '@/application/publish'; -import { ReactComponent as AppflowyLogo } from '@/assets/appflowy.svg'; -import { ReactComponent as Logo } from '@/assets/logo.svg'; +import { ReactComponent as AppFlowyLogo } from '@/assets/appflowy.svg'; import { ReactComponent as SideOutlined } from '@/assets/side_outlined.svg'; +import { AFScroller } from '@/components/_shared/scroller'; import Outline from '@/components/publish/outline/Outline'; import { createHotKeyLabel, HOT_KEY_NAME } from '@/utils/hotkeys'; import { Drawer, IconButton, Tooltip } from '@mui/material'; import { useTranslation } from 'react-i18next'; -export function OutlineDrawer({ open, width, onClose }: { open: boolean; width: number; onClose: () => void }) { +export function OutlineDrawer ({ open, width, onClose }: { open: boolean; width: number; onClose: () => void }) { const { t } = useTranslation(); - const viewMeta = usePublishContext()?.viewMeta; return ( - - +
-
- +
+ + +
+
); diff --git a/frontend/appflowy_web_app/src/components/publish/outline/OutlineItem.tsx b/frontend/appflowy_web_app/src/components/publish/outline/OutlineItem.tsx index 63e92afea52c4..96c55228f3c1d 100644 --- a/frontend/appflowy_web_app/src/components/publish/outline/OutlineItem.tsx +++ b/frontend/appflowy_web_app/src/components/publish/outline/OutlineItem.tsx @@ -1,13 +1,24 @@ -import { PublishViewInfo, ViewLayout } from '@/application/collab.type'; -import { PublishContext } from '@/application/publish'; +import { PublishContext, usePublishContext } from '@/application/publish'; +import { View } from '@/application/types'; import { notify } from '@/components/_shared/notify'; import { ViewIcon } from '@/components/_shared/view-icon'; -import React, { useCallback, useContext } from 'react'; +import SpaceIcon from '@/components/publish/header/SpaceIcon'; +import { renderColor } from '@/utils/color'; +import { isFlagEmoji } from '@/utils/emoji'; +import React, { useCallback, useContext, useEffect } from 'react'; import { ReactComponent as ChevronDownIcon } from '@/assets/chevron_down.svg'; import { useTranslation } from 'react-i18next'; -function OutlineItem({ view, level = 0, width }: { view: PublishViewInfo; width: number; level?: number }) { - const [isExpanded, setIsExpanded] = React.useState(false); +function OutlineItem ({ view, level = 0, width }: { view: View; width: number; level?: number }) { + const [isExpanded, setIsExpanded] = React.useState(() => { + return localStorage.getItem('publish_outline_expanded_' + view.view_id) === 'true'; + }); + + useEffect(() => { + localStorage.setItem('publish_outline_expanded_' + view.view_id, isExpanded ? 'true' : 'false'); + }, [isExpanded, view.view_id]); + + const selected = usePublishContext()?.viewMeta?.view_id === view.view_id; const getIcon = useCallback(() => { if (isExpanded) { return ( @@ -18,6 +29,7 @@ function OutlineItem({ view, level = 0, width }: { view: PublishViewInfo; width: onClick={() => { setIsExpanded(false); }} + className={'opacity-50 hover:opacity-100'} > @@ -29,6 +41,7 @@ function OutlineItem({ view, level = 0, width }: { view: PublishViewInfo; width: style={{ paddingLeft: 1.125 * level + 'rem', }} + className={'opacity-50 hover:opacity-100'} onClick={() => { setIsExpanded(true); }} @@ -40,34 +53,53 @@ function OutlineItem({ view, level = 0, width }: { view: PublishViewInfo; width: const { t } = useTranslation(); const navigateToView = useContext(PublishContext)?.toView; - const renderItem = (item: PublishViewInfo) => { - const { icon, layout, name, view_id } = item; + const renderItem = (item: View) => { + const { icon, layout, name, view_id, extra } = item; + + const isSpace = extra?.is_space; return ( -
+
- {item.child_views?.length ? getIcon() : null} + {item.children?.length ? getIcon() : null}
{ try { await navigateToView?.(view_id); } catch (e) { - notify.error(t('publish.hasNotBeenPublished')); + notify.default(t('publish.hasNotBeenPublished')); } }} style={{ - paddingLeft: item.child_views?.length ? 0 : 1.125 * (level + 1) + 'rem', + paddingLeft: item.children?.length ? 0 : 1.125 * (level + 1) + 'rem', }} className={'flex flex-1 cursor-pointer items-center gap-1.5 overflow-hidden'} > -
{icon?.value || }
+ {isSpace && extra ? + + : +
+ {icon?.value || } +
+ } +
{name}
@@ -75,10 +107,10 @@ function OutlineItem({ view, level = 0, width }: { view: PublishViewInfo; width: ); }; - const children = view.child_views || []; + const children = view.children || []; return ( -
+
{renderItem(view)}
{children - .filter((view) => view.layout === ViewLayout.Document) .map((item, index) => ( ))} diff --git a/frontend/appflowy_web_app/src/components/publish/outline/OutlinePopover.tsx b/frontend/appflowy_web_app/src/components/publish/outline/OutlinePopover.tsx index b876d857e2626..ddb1a9fde4b2e 100644 --- a/frontend/appflowy_web_app/src/components/publish/outline/OutlinePopover.tsx +++ b/frontend/appflowy_web_app/src/components/publish/outline/OutlinePopover.tsx @@ -3,16 +3,16 @@ import Outline from '@/components/publish/outline/Outline'; import { Divider, PopperPlacementType } from '@mui/material'; import React, { ReactElement, useMemo } from 'react'; import { RichTooltip } from '@/components/_shared/popover'; -import { ReactComponent as Logo } from '@/assets/logo.svg'; -import { ReactComponent as AppflowyLogo } from '@/assets/appflowy.svg'; +import { ReactComponent as AppFlowyLogo } from '@/assets/appflowy.svg'; -export function OutlinePopover({ +export function OutlinePopover ({ children, open, onClose, placement, onMouseEnter, onMouseLeave, + drawerWidth, }: { open: boolean; onClose: () => void; @@ -20,6 +20,7 @@ export function OutlinePopover({ placement?: PopperPlacementType; onMouseEnter?: () => void; onMouseLeave?: () => void; + drawerWidth: number; }) { const viewMeta = usePublishContext()?.viewMeta; @@ -28,9 +29,11 @@ export function OutlinePopover({
- + +
{ window.open('https://appflowy.io', '_blank'); }} - className={'flex w-full cursor-pointer items-center justify-center text-sm text-text-title opacity-50'} + className={ + 'flex w-full cursor-pointer gap-2 items-center justify-center py-2 text-sm text-text-title opacity-50' + } > - - + Powered by +
); - }, [onMouseEnter, onMouseLeave, viewMeta]); + }, [onMouseEnter, onMouseLeave, viewMeta, drawerWidth]); return ( - + {children} ); diff --git a/frontend/appflowy_web_app/src/pages/AfterPaymentPage.tsx b/frontend/appflowy_web_app/src/pages/AfterPaymentPage.tsx index beece2661c976..de5999a4b8ec1 100644 --- a/frontend/appflowy_web_app/src/pages/AfterPaymentPage.tsx +++ b/frontend/appflowy_web_app/src/pages/AfterPaymentPage.tsx @@ -1,9 +1,8 @@ import { Button, Typography } from '@mui/material'; import React, { useCallback, useEffect } from 'react'; -import { ReactComponent as Logo } from '@/assets/logo.svg'; import { ReactComponent as AppflowyLogo } from '@/assets/appflowy.svg'; -function AfterPaymentPage() { +function AfterPaymentPage () { const openAppFlowy = useCallback(() => { window.open(`appflowy-flutter://payment-success/${window.location.search || ''}`, '_self'); }, []); @@ -14,9 +13,8 @@ function AfterPaymentPage() { return (
- + <> - @@ -31,8 +29,8 @@ function AfterPaymentPage() {