fix: open publish page

This commit is contained in:
Nathan
2025-10-16 00:33:08 +08:00
parent a9c4f6ca82
commit abf967df2d
4 changed files with 87 additions and 79 deletions

View File

@@ -1,18 +1,11 @@
import { IconButton } from '@mui/material';
import { memo, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { memo, useMemo, useState } from 'react';
import { UIVariant, View } from '@/application/types';
import { ReactComponent as RightIcon } from '@/assets/icons/alt_arrow_right.svg';
import { ReactComponent as MoreIcon } from '@/assets/icons/more.svg';
import { ReactComponent as PrivateSpaceIcon } from '@/assets/icons/private-space.svg';
import { ReactComponent as ShareIcon } from '@/assets/icons/share-to.svg';
import { ReactComponent as TeamIcon } from '@/assets/icons/team.svg';
import BreadcrumbItem from '@/components/_shared/breadcrumb/BreadcrumbItem';
import BreadcrumbMoreModal from '@/components/_shared/breadcrumb/BreadcrumbMoreModal';
import { useCurrentWorkspaceId } from '@/components/app/app.hooks';
import { useCurrentUser, useService } from '@/components/main/app.hooks';
import { Progress } from '@/components/ui/progress';
import { getPlatform } from '@/utils/platform';
export interface BreadcrumbProps {
@@ -78,78 +71,30 @@ export function Breadcrumb({ crumbs, toView, variant }: BreadcrumbProps) {
return (
<div
className={`${
isLast ? 'text-text-primary' : 'text-text-secondary'
} flex min-w-0 max-w-[160px] items-center gap-2 truncate`}
className={`${isLast ? 'text-text-primary' : 'text-text-secondary'
} flex min-w-0 max-w-[160px] items-center gap-2 truncate`}
key={key}
>
<BreadcrumbItem variant={variant} toView={toView} crumb={crumb} disableClick={isLast} />
<BreadcrumbItem toView={toView} crumb={crumb} disableClick={isLast} variant={variant} />
{!isLast && <RightIcon className={'h-5 w-5 shrink-0'} />}
</div>
);
});
}, [crumbs, toView, variant]);
const service = useService();
const currentWorkspaceId = useCurrentWorkspaceId();
const currentUser = useCurrentUser();
const { t } = useTranslation();
const [isShared, setIsShared] = useState(false);
const [loading, setLoading] = useState(false);
const isPrivate = crumbs.some((crumb) => crumb.is_private);
useEffect(() => {
if (!service || !currentWorkspaceId || !currentUser) return;
const loadShareDetail = async () => {
const viewId = crumbs[crumbs.length - 1].view_id;
const ancestorViewIds = crumbs.map((crumb) => crumb.view_id);
try {
setLoading(true);
const res = await service.getShareDetail(currentWorkspaceId, viewId, ancestorViewIds);
const shared = res.shared_with.some((item) => item.email !== currentUser.email);
setIsShared(shared);
} catch (error) {
setIsShared(false);
} finally {
setLoading(false);
}
};
void loadShareDetail();
}, [service, currentWorkspaceId, currentUser, crumbs]);
return (
<div
data-testid='breadcrumb-navigation'
className={'relative flex h-full w-full flex-1 items-center gap-2 overflow-hidden'}
>
{renderCrumb}
<BreadcrumbMoreModal open={openMore} onClose={() => setOpenMore(false)} crumbs={crumbs} toView={toView} />
{variant === UIVariant.App && !isPrivate && (
<div className='ml-2 flex items-center gap-1 text-xs font-medium text-text-tertiary'>
<TeamIcon className='h-5 w-5 shrink-0 text-icon-tertiary' />
{t('teamSpace')}
</div>
)}
{variant === UIVariant.App && isPrivate && (
<div className='ml-2 flex items-center gap-1 text-xs font-medium text-text-tertiary'>
{loading && <Progress variant={'primary'} />}
{isShared ? (
<>
<ShareIcon className='h-5 w-5 shrink-0 text-icon-tertiary' />
{t('share')}
</>
) : (
<>
<PrivateSpaceIcon className='h-5 w-5 shrink-0 text-icon-tertiary' />
{t('private')}
</>
)}
</div>
)}
<BreadcrumbMoreModal
open={openMore}
onClose={() => setOpenMore(false)}
crumbs={crumbs}
toView={toView}
variant={variant}
/>
</div>
);
}

View File

@@ -1,4 +1,4 @@
import { View } from '@/application/types';
import { UIVariant, View } from '@/application/types';
import BreadcrumbItem from '@/components/_shared/breadcrumb/BreadcrumbItem';
import { NormalModal } from '@/components/_shared/modal';
import { useMemo } from 'react';
@@ -9,11 +9,13 @@ function BreadcrumbMoreModal({
onClose,
crumbs,
toView,
variant,
}: {
open: boolean;
onClose: () => void;
crumbs: View[];
toView?: (viewId: string) => Promise<void>;
variant?: UIVariant;
}) {
const { t } = useTranslation();
const title = useMemo(() => {
@@ -52,7 +54,7 @@ function BreadcrumbMoreModal({
}}
>
{index !== 0 && <div className={'text-text-secondary'}> {'-'} </div>}
<BreadcrumbItem crumb={crumb} toView={toView} />
<BreadcrumbItem crumb={crumb} toView={toView} variant={variant} />
</div>
))}
</div>

View File

@@ -1,26 +1,87 @@
import { UIVariant } from '@/application/types';
import { BreadcrumbProps } from '@/components/_shared/breadcrumb/Breadcrumb';
import BreadcrumbSkeleton from '@/components/_shared/skeleton/BreadcrumbSkeleton';
import { useAppHandlers, useBreadcrumb } from '@/components/app/app.hooks';
import React from 'react';
import { useAppHandlers, useBreadcrumb, useCurrentWorkspaceId } from '@/components/app/app.hooks';
import { useCurrentUser, useService } from '@/components/main/app.hooks';
import { Progress } from '@/components/ui/progress';
import { ReactComponent as PrivateSpaceIcon } from '@/assets/icons/private-space.svg';
import { ReactComponent as ShareIcon } from '@/assets/icons/share-to.svg';
import { ReactComponent as TeamIcon } from '@/assets/icons/team.svg';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
export function withAppBreadcrumb (Component: React.ComponentType<BreadcrumbProps>) {
return function PublishBreadcrumbComponent () {
return function AppBreadcrumbComponent () {
const isTrash = window.location.pathname === '/app/trash';
const crumbs = useBreadcrumb();
const toView = useAppHandlers().toView;
const service = useService();
const currentWorkspaceId = useCurrentWorkspaceId();
const currentUser = useCurrentUser();
const { t } = useTranslation();
const [isShared, setIsShared] = useState(false);
const [loading, setLoading] = useState(false);
const isPrivate = crumbs?.some((crumb) => crumb.is_private);
useEffect(() => {
if (!service || !currentWorkspaceId || !currentUser || !crumbs || isTrash) return;
const loadShareDetail = async () => {
const viewId = crumbs[crumbs.length - 1].view_id;
const ancestorViewIds = crumbs.map((crumb) => crumb.view_id);
try {
setLoading(true);
const res = await service.getShareDetail(currentWorkspaceId, viewId, ancestorViewIds);
const shared = res.shared_with.some((item) => item.email !== currentUser.email);
setIsShared(shared);
} catch (error) {
setIsShared(false);
} finally {
setLoading(false);
}
};
void loadShareDetail();
}, [service, currentWorkspaceId, currentUser, crumbs, isTrash]);
return (
<div className={'h-full flex-1 overflow-hidden'}>
{!crumbs ? <BreadcrumbSkeleton /> :
!isTrash && <Component
toView={toView}
variant={UIVariant.App}
crumbs={crumbs}
/>
!isTrash && (
<div className={'relative flex h-full w-full flex-1 items-center gap-2 overflow-hidden'}>
<Component
toView={toView}
crumbs={crumbs}
variant={UIVariant.App}
/>
{!isPrivate && (
<div className='ml-2 flex items-center gap-1 text-xs font-medium text-text-tertiary'>
<TeamIcon className='h-5 w-5 shrink-0 text-icon-tertiary' />
{t('teamSpace')}
</div>
)}
{isPrivate && (
<div className='ml-2 flex items-center gap-1 text-xs font-medium text-text-tertiary'>
{loading && <Progress variant={'primary'} />}
{isShared ? (
<>
<ShareIcon className='h-5 w-5 shrink-0 text-icon-tertiary' />
{t('share')}
</>
) : (
<>
<PrivateSpaceIcon className='h-5 w-5 shrink-0 text-icon-tertiary' />
{t('private')}
</>
)}
</div>
)}
</div>
)
}
</div>
);
};
}
}

View File

@@ -21,4 +21,4 @@ export function withPublishBreadcrumb (Component: React.ComponentType<Breadcrumb
</div>
);
};
}
}