Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/components/app/components/AppContextConsumer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Awareness } from 'y-protocols/awareness';
import { AIChatProvider } from '@/components/ai-chat/AIChatProvider';
import { AppOverlayProvider } from '@/components/app/app-overlay/AppOverlayProvider';
import { AppContext, useAppViewId, useCurrentWorkspaceId } from '@/components/app/app.hooks';
import { RequestAccessError } from '@/components/app/hooks/useWorkspaceData';
import RequestAccess from '@/components/app/landing-pages/RequestAccess';
import { useCurrentUser } from '@/components/main/app.hooks';

Expand All @@ -14,7 +15,7 @@ const ViewModal = React.lazy(() => import('@/components/app/ViewModal'));

interface AppContextConsumerProps {
children: React.ReactNode;
requestAccessOpened: boolean;
requestAccessError: RequestAccessError | null;
openModalViewId?: string;
setOpenModalViewId: (id: string | undefined) => void;
awarenessMap: Record<string, Awareness>;
Expand All @@ -23,15 +24,15 @@ interface AppContextConsumerProps {
// Component that consumes all internal contexts and provides the unified AppContext
// This maintains the original AppContext API while using the new layered architecture internally
export const AppContextConsumer: React.FC<AppContextConsumerProps> = memo(
({ children, requestAccessOpened, openModalViewId, setOpenModalViewId, awarenessMap }) => {
({ children, requestAccessError, openModalViewId, setOpenModalViewId, awarenessMap }) => {
// Merge all layer data into the complete AppContextType
const allContextData = useAllContextData(awarenessMap);

return (
<AppContext.Provider value={allContextData}>
<AIChatProvider>
<AppOverlayProvider>
{requestAccessOpened ? <RequestAccess /> : children}
{requestAccessError ? <RequestAccess error={requestAccessError} /> : children}
{
<Suspense>
<ViewModal
Expand Down
26 changes: 21 additions & 5 deletions src/components/app/hooks/useWorkspaceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ import { useNavigate } from 'react-router-dom';
import { validate as uuidValidate } from 'uuid';

import { APP_EVENTS } from '@/application/constants';
import { invalidToken } from '@/application/session/token';
import { DatabaseRelations, MentionablePerson, UIVariant, View, ViewLayout } from '@/application/types';
import { findView, findViewByLayout } from '@/components/_shared/outline/utils';
import { createDeduplicatedNoArgsRequest } from '@/utils/deduplicateRequest';

import { useAuthInternal } from '../contexts/AuthInternalContext';
import { useSyncInternal } from '../contexts/SyncInternalContext';

const USER_NO_ACCESS_CODE = [1024, 1012];
const USER_NO_ACCESS_CODE = 1012;
const USER_UNAUTHORIZED_CODE = 1024;

export interface RequestAccessError {
code: number;
message: string;
}

// Hook for managing workspace data (outline, favorites, recent, trash)
export function useWorkspaceData() {
Expand All @@ -25,7 +32,7 @@ export function useWorkspaceData() {
const [recentViews, setRecentViews] = useState<View[]>();
const [trashList, setTrashList] = useState<View[]>();
const [workspaceDatabases, setWorkspaceDatabases] = useState<DatabaseRelations | undefined>(undefined);
const [requestAccessOpened, setRequestAccessOpened] = useState(false);
const [requestAccessError, setRequestAccessError] = useState<RequestAccessError | null>(null);

const mentionableUsersRef = useRef<MentionablePerson[]>([]);

Expand Down Expand Up @@ -110,8 +117,17 @@ export function useWorkspaceData() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
console.error('App outline not found');
if (USER_NO_ACCESS_CODE.includes(e.code)) {
setRequestAccessOpened(true);
if (e.code === USER_UNAUTHORIZED_CODE) {
invalidToken();
navigate('/login');
return;
}

if (e.code === USER_NO_ACCESS_CODE) {
setRequestAccessError({
code: e.code,
message: e.message,
});
return;
}
}
Expand Down Expand Up @@ -320,7 +336,7 @@ export function useWorkspaceData() {
recentViews,
trashList,
workspaceDatabases,
requestAccessOpened,
requestAccessError,
loadOutline,
loadFavoriteViews,
loadRecentViews,
Expand Down
9 changes: 7 additions & 2 deletions src/components/app/landing-pages/RequestAccess.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ReactComponent as AppFlowyLogo } from '@/assets/icons/appflowy.svg';
import { RequestAccessError } from '@/components/app/hooks/useWorkspaceData';
import { RequestAccessContent } from '@/components/app/share/RequestAccessContent';

function RequestAccess() {
interface RequestAccessProps {
error?: RequestAccessError;
}

function RequestAccess({ error }: RequestAccessProps) {
return (
<div className='flex h-screen w-screen flex-col bg-background-primary'>
<div className='absolute left-0 top-0 flex h-[60px] w-full items-center justify-between gap-[10px] p-4'>
Expand All @@ -15,7 +20,7 @@ function RequestAccess() {
</span>
</div>
<div className='flex w-full flex-1 items-center justify-center'>
<RequestAccessContent />
<RequestAccessContent error={error} />
</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/app/layers/AppBusinessLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const AppBusinessLayer: React.FC<AppBusinessLayerProps> = ({ children })
recentViews,
trashList,
workspaceDatabases,
requestAccessOpened,
requestAccessError,
loadOutline,
loadFavoriteViews,
loadRecentViews,
Expand Down Expand Up @@ -295,7 +295,7 @@ export const AppBusinessLayer: React.FC<AppBusinessLayerProps> = ({ children })
return (
<BusinessInternalContext.Provider value={businessContextValue}>
<AppContextConsumer
requestAccessOpened={requestAccessOpened}
requestAccessError={requestAccessError}
openModalViewId={openModalViewId}
setOpenModalViewId={setOpenModalViewId}
awarenessMap={awarenessMap}
Expand Down
4 changes: 3 additions & 1 deletion src/components/app/share/RequestAccessContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { toast } from 'sonner';
import { ReactComponent as NoAccessLogo } from '@/assets/icons/no_access.svg';
import { ReactComponent as SuccessLogo } from '@/assets/icons/success_logo.svg';
import { useAppViewId, useCurrentWorkspaceId } from '@/components/app/app.hooks';
import { RequestAccessError } from '@/components/app/hooks/useWorkspaceData';
import { useCurrentUser, useService } from '@/components/main/app.hooks';
import { Button } from '@/components/ui/button';
import { Progress } from '@/components/ui/progress';
Expand All @@ -15,9 +16,10 @@ const REPEAT_REQUEST_CODE = 1043;
interface RequestAccessContentProps {
viewId?: string;
workspaceId?: string;
error?: RequestAccessError;
}

export function RequestAccessContent({ viewId: propViewId, workspaceId: propWorkspaceId }: RequestAccessContentProps) {
export function RequestAccessContent({ viewId: propViewId, workspaceId: propWorkspaceId, error: _error }: RequestAccessContentProps) {
const { t } = useTranslation();
const service = useService();
const currentWorkspaceId = useCurrentWorkspaceId();
Expand Down
Loading