mirror of
https://github.com/colanode/colanode.git
synced 2025-12-29 00:25:03 +01:00
Improve routing
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
import { useMatch, useNavigate } from '@tanstack/react-router';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Account } from '@colanode/client/types';
|
||||
import { AccountContext } from '@colanode/ui/contexts/account';
|
||||
import { useAppMetadata } from '@colanode/ui/contexts/app-metadata';
|
||||
|
||||
const fetchAccountForWorkspace = async (
|
||||
workspaceId?: string
|
||||
): Promise<Account[] | null> => {
|
||||
const accounts = await window.colanode.executeQuery({
|
||||
type: 'account.list',
|
||||
});
|
||||
|
||||
if (accounts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return [accounts[0]!];
|
||||
}
|
||||
|
||||
const accountsForWorkspace: Account[] = [];
|
||||
for (const account of accounts) {
|
||||
const workspaces = await window.colanode.executeQuery({
|
||||
type: 'workspace.list',
|
||||
accountId: account.id,
|
||||
});
|
||||
|
||||
if (workspaces.some((workspace) => workspace.id === workspaceId)) {
|
||||
accountsForWorkspace.push(account);
|
||||
}
|
||||
}
|
||||
|
||||
if (accountsForWorkspace.length === 0) {
|
||||
return [accounts[0]!];
|
||||
}
|
||||
|
||||
return accountsForWorkspace;
|
||||
};
|
||||
|
||||
export const AccountProvider = ({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const appMetadata = useAppMetadata();
|
||||
const navigate = useNavigate();
|
||||
const match = useMatch({ from: '/$workspaceId', shouldThrow: false });
|
||||
const workspaceId = match?.params.workspaceId;
|
||||
const accountId = appMetadata.get('account');
|
||||
|
||||
const [account, setAccount] = useState<Account | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const accounts = await fetchAccountForWorkspace(workspaceId);
|
||||
if (!accounts) {
|
||||
navigate({ to: '/login' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (accounts.length === 1) {
|
||||
if (accountId !== accounts[0]!.id) {
|
||||
appMetadata.set('account', accounts[0]!.id);
|
||||
}
|
||||
|
||||
setAccount(accounts[0]!);
|
||||
return;
|
||||
}
|
||||
|
||||
const account = accounts.find((account) => account.id === accountId);
|
||||
if (account) {
|
||||
setAccount(account);
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: Show account selection
|
||||
setAccount(accounts[0]!);
|
||||
})();
|
||||
}, [workspaceId]);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountContext.Provider value={account}>
|
||||
{children}
|
||||
</AccountContext.Provider>
|
||||
);
|
||||
};
|
||||
28
packages/ui/src/components/accounts/account-screen.tsx
Normal file
28
packages/ui/src/components/accounts/account-screen.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Outlet, useParams } from '@tanstack/react-router';
|
||||
|
||||
import { AccountContext } from '@colanode/ui/contexts/account';
|
||||
import { useLiveQuery } from '@colanode/ui/hooks/use-live-query';
|
||||
|
||||
export const AccountScreen = () => {
|
||||
const { accountId } = useParams({ from: '/acc/$accountId' });
|
||||
|
||||
const accountQuery = useLiveQuery({
|
||||
type: 'account.get',
|
||||
accountId: accountId,
|
||||
});
|
||||
|
||||
if (accountQuery.isPending) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const account = accountQuery.data;
|
||||
if (!account) {
|
||||
return <p>Account not found</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountContext.Provider value={account}>
|
||||
<Outlet />
|
||||
</AccountContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -1,9 +1,11 @@
|
||||
import { useRouter } from '@tanstack/react-router';
|
||||
import { HouseIcon } from 'lucide-react';
|
||||
import { useState, Fragment, useEffect } from 'react';
|
||||
import { useState, Fragment, useEffect, useCallback } from 'react';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { isFeatureSupported } from '@colanode/client/lib';
|
||||
import { Account, ServerDetails } from '@colanode/client/types';
|
||||
import { LoginSuccessOutput } from '@colanode/core';
|
||||
import { EmailLogin } from '@colanode/ui/components/accounts/email-login';
|
||||
import { EmailPasswordResetComplete } from '@colanode/ui/components/accounts/email-password-reset-complete';
|
||||
import { EmailPasswordResetInit } from '@colanode/ui/components/accounts/email-password-reset-init';
|
||||
@@ -12,7 +14,6 @@ import { EmailVerify } from '@colanode/ui/components/accounts/email-verify';
|
||||
import { ServerDropdown } from '@colanode/ui/components/servers/server-dropdown';
|
||||
import { Button } from '@colanode/ui/components/ui/button';
|
||||
import { Separator } from '@colanode/ui/components/ui/separator';
|
||||
import { useApp } from '@colanode/ui/contexts/app';
|
||||
import { ServerContext } from '@colanode/ui/contexts/server';
|
||||
|
||||
interface LoginFormProps {
|
||||
@@ -52,11 +53,12 @@ type PanelState =
|
||||
| PasswordResetCompletePanelState;
|
||||
|
||||
export const LoginForm = ({ accounts, servers }: LoginFormProps) => {
|
||||
const app = useApp();
|
||||
const router = useRouter();
|
||||
|
||||
const [serverDomain, setServerDomain] = useState<string | null>(
|
||||
servers[0]?.domain ?? null
|
||||
);
|
||||
|
||||
const [panel, setPanel] = useState<PanelState>({
|
||||
type: 'login',
|
||||
});
|
||||
@@ -73,6 +75,24 @@ export const LoginForm = ({ accounts, servers }: LoginFormProps) => {
|
||||
? servers.find((s) => s.domain === serverDomain)
|
||||
: null;
|
||||
|
||||
const handleLoginSuccess = useCallback(
|
||||
(output: LoginSuccessOutput) => {
|
||||
const workspace = output.workspaces[0];
|
||||
if (workspace) {
|
||||
router.navigate({
|
||||
to: '/acc/$accountId/$workspaceId',
|
||||
params: { accountId: output.account.id, workspaceId: workspace.id },
|
||||
});
|
||||
} else {
|
||||
router.navigate({
|
||||
to: '/acc/$accountId/create',
|
||||
params: { accountId: output.account.id },
|
||||
});
|
||||
}
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<ServerDropdown
|
||||
@@ -98,7 +118,7 @@ export const LoginForm = ({ accounts, servers }: LoginFormProps) => {
|
||||
<EmailLogin
|
||||
onSuccess={(output) => {
|
||||
if (output.type === 'success') {
|
||||
app.openAccount(output.account.id);
|
||||
handleLoginSuccess(output);
|
||||
} else if (output.type === 'verify') {
|
||||
setPanel({
|
||||
type: 'verify',
|
||||
@@ -123,7 +143,7 @@ export const LoginForm = ({ accounts, servers }: LoginFormProps) => {
|
||||
<EmailRegister
|
||||
onSuccess={(output) => {
|
||||
if (output.type === 'success') {
|
||||
app.openAccount(output.account.id);
|
||||
handleLoginSuccess(output);
|
||||
} else if (output.type === 'verify') {
|
||||
setPanel({
|
||||
type: 'verify',
|
||||
@@ -145,7 +165,7 @@ export const LoginForm = ({ accounts, servers }: LoginFormProps) => {
|
||||
expiresAt={p.expiresAt}
|
||||
onSuccess={(output) => {
|
||||
if (output.type === 'success') {
|
||||
app.openAccount(output.account.id);
|
||||
handleLoginSuccess(output);
|
||||
}
|
||||
}}
|
||||
onBack={() => {
|
||||
@@ -195,7 +215,14 @@ export const LoginForm = ({ accounts, servers }: LoginFormProps) => {
|
||||
className="w-full text-muted-foreground"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
app.closeLogin();
|
||||
if (router.history.canGoBack()) {
|
||||
router.history.back();
|
||||
} else {
|
||||
router.navigate({
|
||||
to: '/acc/$accountId',
|
||||
params: { accountId: accounts[0]!.id },
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<HouseIcon className="mr-1 size-4" />
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { useAccount } from '@colanode/ui/contexts/account';
|
||||
|
||||
export const AppHomeScreen = () => {
|
||||
const navigate = useNavigate();
|
||||
const account = useAccount();
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const workspaces = await window.colanode.executeQuery({
|
||||
type: 'workspace.list',
|
||||
accountId: account.id,
|
||||
const accounts = await window.colanode.executeQuery({
|
||||
type: 'account.list',
|
||||
});
|
||||
|
||||
if (workspaces.length === 0) {
|
||||
navigate({ to: '/create', replace: true });
|
||||
if (accounts.length === 0) {
|
||||
navigate({ to: '/login', replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const workspace = workspaces[0]!;
|
||||
const account = accounts[0]!;
|
||||
navigate({
|
||||
to: '/$workspaceId',
|
||||
params: { workspaceId: workspace.id },
|
||||
to: '/acc/$accountId',
|
||||
params: { accountId: account.id },
|
||||
replace: true,
|
||||
});
|
||||
})();
|
||||
}, [account.id]);
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ export const ChannelCreateDialog = ({
|
||||
onOpenChange,
|
||||
}: ChannelCreateDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -64,9 +64,8 @@ export const ChannelCreateDialog = ({
|
||||
onSuccess(output) {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
to: '/$workspaceId/$nodeId',
|
||||
to: '$nodeId',
|
||||
params: {
|
||||
workspaceId: workspace.id,
|
||||
nodeId: output.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ChannelDeleteDialog = ({
|
||||
onOpenChange,
|
||||
}: ChannelDeleteDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -58,8 +58,7 @@ export const ChannelDeleteDialog = ({
|
||||
onSuccess() {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
to: '/$workspaceId',
|
||||
params: { workspaceId: workspace.id },
|
||||
to: '/',
|
||||
replace: true,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -14,8 +14,8 @@ import { useMutation } from '@colanode/ui/hooks/use-mutation';
|
||||
|
||||
export const ChatCreatePopover = () => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -39,9 +39,8 @@ export const ChatCreatePopover = () => {
|
||||
},
|
||||
onSuccess(output) {
|
||||
navigate({
|
||||
to: '/$workspaceId/$nodeId',
|
||||
to: '$nodeId',
|
||||
params: {
|
||||
workspaceId: workspace.id,
|
||||
nodeId: output.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -35,7 +35,11 @@ export const BoardViewRecordCard = () => {
|
||||
key={record.id}
|
||||
className="animate-fade-in flex cursor-pointer flex-col gap-1 rounded-md border p-2 text-left hover:bg-accent"
|
||||
>
|
||||
<Link from="/$workspaceId" to="$nodeId" params={{ nodeId: record.id }}>
|
||||
<Link
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: record.id }}
|
||||
>
|
||||
<p className={hasName ? '' : 'text-muted-foreground'}>
|
||||
{hasName ? name : 'Unnamed'}
|
||||
</p>
|
||||
|
||||
@@ -33,7 +33,7 @@ export const CalendarViewNoValueList = ({
|
||||
const name = record.attributes.name ?? 'Unnamed';
|
||||
return (
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: record.id }}
|
||||
key={record.id}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const CalendarViewRecordCard = () => {
|
||||
|
||||
return (
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: record.id }}
|
||||
key={record.id}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const DatabaseCreateDialog = ({
|
||||
onOpenChange,
|
||||
}: DatabaseCreateDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -64,9 +64,8 @@ export const DatabaseCreateDialog = ({
|
||||
onSuccess(output) {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
to: '/$workspaceId/$nodeId',
|
||||
to: '$nodeId',
|
||||
params: {
|
||||
workspaceId: workspace.id,
|
||||
nodeId: output.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export const DatabaseDeleteDialog = ({
|
||||
onOpenChange,
|
||||
}: DatabaseDeleteDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -58,8 +58,7 @@ export const DatabaseDeleteDialog = ({
|
||||
onSuccess() {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
to: '/$workspaceId',
|
||||
params: { workspaceId: workspace.id },
|
||||
to: '/',
|
||||
replace: true,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -106,7 +106,7 @@ export const TableViewNameCell = ({ record }: TableViewNameCellProps) => {
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: record.id }}
|
||||
className="absolute right-2 flex h-6 cursor-pointer flex-row items-center gap-1 rounded-md border p-1 text-sm text-muted-foreground opacity-0 hover:bg-accent group-hover:opacity-100"
|
||||
|
||||
@@ -14,7 +14,7 @@ export const ViewFullscreenButton = () => {
|
||||
|
||||
return (
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: database.id }}
|
||||
className="flex cursor-pointer items-center rounded-md p-1.5 hover:bg-accent"
|
||||
|
||||
@@ -34,7 +34,7 @@ interface ViewProps {
|
||||
export const View = ({ view }: ViewProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const database = useDatabase();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
|
||||
const fields: ViewField[] = database.fields
|
||||
.map((field) => {
|
||||
@@ -512,8 +512,8 @@ export const View = ({ view }: ViewProps) => {
|
||||
toast.error(result.error.message);
|
||||
} else {
|
||||
navigate({
|
||||
to: '/$workspaceId/$nodeId',
|
||||
params: { workspaceId: workspace.id, nodeId: result.output.id },
|
||||
to: '$nodeId',
|
||||
params: { nodeId: result.output.id },
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@ export const FileBlock = ({ id }: FileBlockProps) => {
|
||||
if (canPreview) {
|
||||
return (
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: id }}
|
||||
className="flex h-72 max-h-72 max-w-128 w-full cursor-pointer overflow-hidden rounded-md p-2 hover:bg-muted/50"
|
||||
@@ -43,7 +43,7 @@ export const FileBlock = ({ id }: FileBlockProps) => {
|
||||
|
||||
return (
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: id }}
|
||||
className="flex flex-row gap-4 items-center w-full cursor-pointer overflow-hidden rounded-md p-2 pl-0 hover:bg-accent"
|
||||
|
||||
@@ -28,7 +28,7 @@ export const FileContextMenu = ({ id, children }: FileContextMenuProps) => {
|
||||
<ContextMenuItem
|
||||
onSelect={() => {
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
from: '/acc/$accountId/$workspaceId',
|
||||
to: '$nodeId',
|
||||
params: { nodeId: id },
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export const FileDeleteDialog = ({
|
||||
onOpenChange,
|
||||
}: FileDeleteDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -58,7 +58,6 @@ export const FileDeleteDialog = ({
|
||||
onSuccess() {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '/',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -18,7 +18,7 @@ export const FileSaveButton = ({ file }: FileSaveButtonProps) => {
|
||||
const app = useApp();
|
||||
const workspace = useWorkspace();
|
||||
const mutation = useMutation();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
const handleDownloadDesktop = async () => {
|
||||
@@ -40,7 +40,6 @@ export const FileSaveButton = ({ file }: FileSaveButtonProps) => {
|
||||
},
|
||||
onSuccess: () => {
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: 'downloads',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -25,7 +25,7 @@ export const FolderCreateDialog = ({
|
||||
onOpenChange,
|
||||
}: FolderCreateDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -65,8 +65,8 @@ export const FolderCreateDialog = ({
|
||||
onSuccess(output) {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
to: '/$workspaceId/$nodeId',
|
||||
params: { workspaceId: workspace.id, nodeId: output.id },
|
||||
to: '$nodeId',
|
||||
params: { nodeId: output.id },
|
||||
});
|
||||
},
|
||||
onError(error) {
|
||||
|
||||
@@ -27,7 +27,7 @@ export const FolderDeleteDialog = ({
|
||||
onOpenChange,
|
||||
}: FolderDeleteDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -58,7 +58,6 @@ export const FolderDeleteDialog = ({
|
||||
onSuccess() {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '/',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -25,7 +25,7 @@ export const FolderFiles = ({
|
||||
layout: folderLayout,
|
||||
}: FolderFilesProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
|
||||
const [lastPage] = useState<number>(1);
|
||||
const inputs: FileListQueryInput[] = Array.from({
|
||||
@@ -53,7 +53,6 @@ export const FolderFiles = ({
|
||||
},
|
||||
onDoubleClick: (_, id) => {
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '$nodeId',
|
||||
params: { nodeId: id },
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ export const ContainerBreadcrumb = ({
|
||||
{!isFirst && <BreadcrumbSeparator />}
|
||||
<BreadcrumbItem className="cursor-pointer hover:text-foreground">
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: item.id }}
|
||||
>
|
||||
@@ -70,7 +70,7 @@ export const ContainerBreadcrumb = ({
|
||||
return (
|
||||
<DropdownMenuItem key={ellipsisItem.id}>
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: ellipsisItem.id }}
|
||||
>
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import { useRef } from 'react';
|
||||
import { useDrop } from 'react-dnd';
|
||||
|
||||
import { ContainerTab } from '@colanode/client/types';
|
||||
import { ContainerTabContent } from '@colanode/ui/components/layouts/containers/container-tab-content';
|
||||
import { ContainerTabTrigger } from '@colanode/ui/components/layouts/containers/container-tab-trigger';
|
||||
import {
|
||||
ScrollArea,
|
||||
ScrollBar,
|
||||
ScrollViewport,
|
||||
} from '@colanode/ui/components/ui/scroll-area';
|
||||
import { Tabs, TabsList } from '@colanode/ui/components/ui/tabs';
|
||||
import { cn } from '@colanode/ui/lib/utils';
|
||||
|
||||
interface ContainerTabsProps {
|
||||
tabs: ContainerTab[];
|
||||
onTabChange: (value: string) => void;
|
||||
onFocus: () => void;
|
||||
onClose: (value: string) => void;
|
||||
onOpen: (value: string) => void;
|
||||
onMove: (tab: string, before: string | null) => void;
|
||||
}
|
||||
|
||||
export const ContainerTabs = ({
|
||||
tabs,
|
||||
onTabChange,
|
||||
onFocus,
|
||||
onClose,
|
||||
onOpen,
|
||||
onMove,
|
||||
}: ContainerTabsProps) => {
|
||||
const activeTab = tabs.find((t) => t.active)?.path;
|
||||
|
||||
const [dropMonitor, dropRef] = useDrop({
|
||||
accept: 'container-tab',
|
||||
drop: () => ({
|
||||
before: null,
|
||||
}),
|
||||
collect: (monitor) => ({
|
||||
isOver: monitor.isOver(),
|
||||
canDrop: monitor.canDrop(),
|
||||
}),
|
||||
});
|
||||
|
||||
const buttonRef = useRef<HTMLDivElement>(null);
|
||||
const dragDropRef = dropRef(buttonRef);
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
defaultValue={tabs[0]?.path}
|
||||
value={activeTab}
|
||||
onValueChange={onTabChange}
|
||||
onFocus={onFocus}
|
||||
className="h-full min-h-full w-full min-w-full max-h-full max-w-full flex flex-col overflow-hidden"
|
||||
>
|
||||
<ScrollArea className="h-10 min-h-10 w-full">
|
||||
<ScrollViewport>
|
||||
<TabsList className="h-10 w-full justify-start p-0 app-drag-region rounded-none">
|
||||
{tabs.map((tab) => (
|
||||
<ContainerTabTrigger
|
||||
key={tab.path}
|
||||
tab={tab}
|
||||
onClose={() => onClose(tab.path)}
|
||||
onOpen={() => onOpen(tab.path)}
|
||||
onMove={(before) => onMove(tab.path, before)}
|
||||
/>
|
||||
))}
|
||||
<div
|
||||
ref={dragDropRef as React.LegacyRef<HTMLDivElement>}
|
||||
className={cn(
|
||||
'h-full w-10',
|
||||
dropMonitor.isOver &&
|
||||
dropMonitor.canDrop &&
|
||||
'border-l-2 border-blue-300'
|
||||
)}
|
||||
/>
|
||||
</TabsList>
|
||||
<ScrollBar orientation="horizontal" className="z-10" />
|
||||
</ScrollViewport>
|
||||
</ScrollArea>
|
||||
<div className="flex-grow overflow-hidden">
|
||||
{tabs.map((tab) => (
|
||||
<ContainerTabContent key={tab.path} tab={tab} />
|
||||
))}
|
||||
</div>
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Outlet } from '@tanstack/react-router';
|
||||
|
||||
import { AccountProvider } from '@colanode/ui/components/accounts/account-provider';
|
||||
|
||||
export const RootLayout = () => {
|
||||
return (
|
||||
<AccountProvider>
|
||||
<Outlet />
|
||||
</AccountProvider>
|
||||
);
|
||||
};
|
||||
@@ -13,7 +13,9 @@ import { RecordContainer } from '@colanode/ui/components/records/record-containe
|
||||
import { SpaceContainer } from '@colanode/ui/components/spaces/space-container';
|
||||
|
||||
export const NodeScreen = () => {
|
||||
const { nodeId } = useParams({ from: '/$workspaceId/$nodeId' });
|
||||
const { nodeId } = useParams({
|
||||
from: '/acc/$accountId/$workspaceId/$nodeId',
|
||||
});
|
||||
|
||||
return match(getIdType(nodeId))
|
||||
.with(IdType.Space, () => <SpaceContainer spaceId={nodeId} />)
|
||||
|
||||
@@ -25,7 +25,7 @@ export const PageCreateDialog = ({
|
||||
onOpenChange,
|
||||
}: PageCreateDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -65,9 +65,8 @@ export const PageCreateDialog = ({
|
||||
onSuccess(output) {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
to: '/$workspaceId/$nodeId',
|
||||
to: '$nodeId',
|
||||
params: {
|
||||
workspaceId: workspace.id,
|
||||
nodeId: output.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ export const PageDeleteDialog = ({
|
||||
onOpenChange,
|
||||
}: PageDeleteDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -58,7 +58,6 @@ export const PageDeleteDialog = ({
|
||||
onSuccess() {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '/',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -27,7 +27,7 @@ export const RecordDeleteDialog = ({
|
||||
onOpenChange,
|
||||
}: RecordDeleteDialogProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
return (
|
||||
@@ -58,7 +58,6 @@ export const RecordDeleteDialog = ({
|
||||
onSuccess() {
|
||||
onOpenChange(false);
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '/',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@ interface SpaceBodyProps {
|
||||
|
||||
export const SpaceBody = ({ space, role }: SpaceBodyProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
const canEdit = hasNodeRole(role, 'admin');
|
||||
@@ -95,7 +95,6 @@ export const SpaceBody = ({ space, role }: SpaceBodyProps) => {
|
||||
id={space.id}
|
||||
onDeleted={() => {
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '/',
|
||||
});
|
||||
}}
|
||||
|
||||
@@ -29,7 +29,7 @@ interface SpaceSidebarDropdownProps {
|
||||
}
|
||||
|
||||
export const SpaceSidebarDropdown = ({ space }: SpaceSidebarDropdownProps) => {
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
|
||||
const [openCreatePage, setOpenCreatePage] = useState(false);
|
||||
const [openCreateChannel, setOpenCreateChannel] = useState(false);
|
||||
@@ -81,7 +81,6 @@ export const SpaceSidebarDropdown = ({ space }: SpaceSidebarDropdownProps) => {
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '$nodeId',
|
||||
params: { nodeId: space.id },
|
||||
})
|
||||
@@ -94,7 +93,6 @@ export const SpaceSidebarDropdown = ({ space }: SpaceSidebarDropdownProps) => {
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '$nodeId',
|
||||
params: { nodeId: space.id },
|
||||
})
|
||||
|
||||
@@ -105,9 +105,9 @@ export const SpaceSidebarItem = ({ space }: SpaceSidebarItemProps) => {
|
||||
{children.map((child) => (
|
||||
<li key={child.id}>
|
||||
<Link
|
||||
to={'/$workspaceId/$nodeId'}
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{
|
||||
workspaceId: workspace.id,
|
||||
nodeId: child.id,
|
||||
}}
|
||||
className="cursor-pointer select-none"
|
||||
|
||||
@@ -22,7 +22,7 @@ export const WorkspaceDownloadFile = ({
|
||||
download,
|
||||
}: WorkspaceDownloadFileProps) => {
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate();
|
||||
const navigate = useNavigate({ from: '/acc/$accountId/$workspaceId' });
|
||||
|
||||
const fileQuery = useLiveQuery({
|
||||
type: 'node.get',
|
||||
@@ -39,7 +39,6 @@ export const WorkspaceDownloadFile = ({
|
||||
onClick={() => {
|
||||
if (file) {
|
||||
navigate({
|
||||
from: '/$workspaceId',
|
||||
to: '$nodeId',
|
||||
params: { nodeId: file.id },
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export const WorkspaceSidebarChats = () => {
|
||||
{chats.map((item) => (
|
||||
<Link
|
||||
key={item.id}
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: item.id }}
|
||||
className="px-2 flex w-full items-center gap-2 overflow-hidden rounded-md text-left text-sm h-7 cursor-pointer text-foreground hover:bg-muted"
|
||||
|
||||
@@ -78,7 +78,10 @@ export function WorkspaceSidebarMenuFooter() {
|
||||
key={accountItem.id}
|
||||
className="p-0"
|
||||
onClick={() => {
|
||||
app.openAccount(accountItem.id);
|
||||
navigate({
|
||||
to: '/acc/$accountId',
|
||||
params: { accountId: accountItem.id },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<AccountContext.Provider value={accountItem}>
|
||||
|
||||
@@ -75,8 +75,11 @@ export const WorkspaceSidebarMenuHeader = () => {
|
||||
className="p-0 cursor-pointer"
|
||||
onClick={() => {
|
||||
navigate({
|
||||
to: '/$workspaceId',
|
||||
params: { workspaceId: workspaceItem.id },
|
||||
to: '/acc/$accountId/$workspaceId',
|
||||
params: {
|
||||
accountId: workspaceItem.accountId,
|
||||
workspaceId: workspaceItem.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
@@ -106,7 +109,10 @@ export const WorkspaceSidebarMenuHeader = () => {
|
||||
<DropdownMenuItem
|
||||
className="gap-2 p-2 text-muted-foreground hover:text-foreground cursor-pointer"
|
||||
onClick={() => {
|
||||
navigate({ to: '/create' });
|
||||
navigate({
|
||||
to: '/acc/$accountId/create',
|
||||
params: { accountId: account.id },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Plus className="size-4" />
|
||||
|
||||
@@ -35,10 +35,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
<div className="flex flex-col gap-4 h-full px-2 group/sidebar">
|
||||
<div className="flex w-full min-w-0 flex-col gap-1">
|
||||
<WorkspaceSidebarHeader title="Workspace settings" />
|
||||
<Link
|
||||
to="/$workspaceId/settings"
|
||||
params={{ workspaceId: workspace.id }}
|
||||
>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="settings">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="General"
|
||||
@@ -48,7 +45,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
)}
|
||||
</Link>
|
||||
|
||||
<Link to="/$workspaceId/users" params={{ workspaceId: workspace.id }}>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="users">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="Users"
|
||||
@@ -57,7 +54,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
/>
|
||||
)}
|
||||
</Link>
|
||||
<Link to="/$workspaceId/storage" params={{ workspaceId: workspace.id }}>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="storage">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="Storage"
|
||||
@@ -66,7 +63,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
/>
|
||||
)}
|
||||
</Link>
|
||||
<Link to="/$workspaceId/uploads" params={{ workspaceId: workspace.id }}>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="uploads">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="Uploads"
|
||||
@@ -82,10 +79,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
)}
|
||||
</Link>
|
||||
{app.type === 'desktop' && (
|
||||
<Link
|
||||
to="/$workspaceId/downloads"
|
||||
params={{ workspaceId: workspace.id }}
|
||||
>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="downloads">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="Downloads"
|
||||
@@ -98,10 +92,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
</div>
|
||||
<div className="flex w-full min-w-0 flex-col gap-1">
|
||||
<WorkspaceSidebarHeader title="Account settings" />
|
||||
<Link
|
||||
to="/$workspaceId/account/settings"
|
||||
params={{ workspaceId: workspace.id }}
|
||||
>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="account/settings">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="General"
|
||||
@@ -113,10 +104,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
</div>
|
||||
<div className="flex w-full min-w-0 flex-col gap-1">
|
||||
<WorkspaceSidebarHeader title="App settings" />
|
||||
<Link
|
||||
to="/$workspaceId/app/appearance"
|
||||
params={{ workspaceId: workspace.id }}
|
||||
>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="app/appearance">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="Appearance"
|
||||
@@ -128,10 +116,7 @@ export const WorkspaceSidebarSettings = () => {
|
||||
</div>
|
||||
<div className="flex w-full min-w-0 flex-col gap-1">
|
||||
<Separator className="my-2" />
|
||||
<Link
|
||||
to="/$workspaceId/account/logout"
|
||||
params={{ workspaceId: workspace.id }}
|
||||
>
|
||||
<Link from="/acc/$accountId/$workspaceId" to="account/logout">
|
||||
{({ isActive }) => (
|
||||
<WorkspaceSidebarSettingsItem
|
||||
title="Logout"
|
||||
|
||||
@@ -51,7 +51,7 @@ export const WorkspaceUploadFile = ({ upload }: WorkspaceUploadFileProps) => {
|
||||
|
||||
return (
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: file.id }}
|
||||
className="border rounded-lg p-4 bg-card hover:bg-accent/50 transition-colors flex items-center gap-6 cursor-pointer"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCanGoBack, useNavigate, useRouter } from '@tanstack/react-router';
|
||||
import { useRouter } from '@tanstack/react-router';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import { WorkspaceForm } from '@colanode/ui/components/workspaces/workspace-form';
|
||||
@@ -8,11 +8,8 @@ import { useMutation } from '@colanode/ui/hooks/use-mutation';
|
||||
|
||||
export const WorkspaceCreateScreen = () => {
|
||||
const account = useAccount();
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
const canGoBack = useCanGoBack();
|
||||
const router = useRouter();
|
||||
const navigate = useNavigate();
|
||||
const { mutate, isPending } = useMutation();
|
||||
|
||||
const workspacesQuery = useLiveQuery({
|
||||
type: 'workspace.list',
|
||||
@@ -20,13 +17,13 @@ export const WorkspaceCreateScreen = () => {
|
||||
});
|
||||
|
||||
const workspaces = workspacesQuery.data ?? [];
|
||||
const handleCancel = canGoBack
|
||||
const handleCancel = router.history.canGoBack()
|
||||
? () => router.history.back()
|
||||
: workspaces.length > 0
|
||||
? () =>
|
||||
navigate({
|
||||
to: '/$workspaceId',
|
||||
params: { workspaceId: workspaces[0]!.id },
|
||||
router.navigate({
|
||||
to: '/acc/$accountId/$workspaceId',
|
||||
params: { accountId: account.id, workspaceId: workspaces[0]!.id },
|
||||
})
|
||||
: undefined;
|
||||
|
||||
@@ -50,7 +47,10 @@ export const WorkspaceCreateScreen = () => {
|
||||
avatar: values.avatar ?? null,
|
||||
},
|
||||
onSuccess(output) {
|
||||
navigate({ to: `/${output.id}` });
|
||||
router.navigate({
|
||||
to: '/acc/$accountId/$workspaceId',
|
||||
params: { accountId: account.id, workspaceId: output.id },
|
||||
});
|
||||
},
|
||||
onError(error) {
|
||||
toast.error(error.message);
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useLiveQuery } from '@colanode/ui/hooks/use-live-query';
|
||||
|
||||
export const WorkspaceScreen = () => {
|
||||
const account = useAccount();
|
||||
const { workspaceId } = useParams({ from: '/$workspaceId' });
|
||||
const { workspaceId } = useParams({ from: '/acc/$accountId/$workspaceId' });
|
||||
|
||||
const workspaceQuery = useLiveQuery({
|
||||
type: 'workspace.get',
|
||||
|
||||
@@ -49,7 +49,7 @@ export const DatabaseNodeView = ({ node }: NodeViewProps) => {
|
||||
return (
|
||||
<NodeViewWrapper data-id={node.attrs.id}>
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: id }}
|
||||
className="my-0.5 flex h-10 w-full cursor-pointer flex-row items-center gap-1 rounded-md p-1 hover:bg-accent"
|
||||
|
||||
@@ -37,7 +37,7 @@ export const FolderNodeView = ({ node }: NodeViewProps) => {
|
||||
return (
|
||||
<NodeViewWrapper data-id={node.attrs.id}>
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: id }}
|
||||
className="my-0.5 flex h-10 w-full cursor-pointer flex-row items-center gap-1 rounded-md p-1 hover:bg-accent"
|
||||
|
||||
@@ -37,7 +37,7 @@ export const PageNodeView = ({ node }: NodeViewProps) => {
|
||||
return (
|
||||
<NodeViewWrapper data-id={node.attrs.id}>
|
||||
<Link
|
||||
from="/$workspaceId"
|
||||
from="/acc/$accountId/$workspaceId"
|
||||
to="$nodeId"
|
||||
params={{ nodeId: id }}
|
||||
className="my-0.5 flex h-10 w-full cursor-pointer flex-row items-center gap-1 rounded-md p-1 hover:bg-accent"
|
||||
|
||||
@@ -5,11 +5,11 @@ import {
|
||||
} from '@tanstack/react-router';
|
||||
|
||||
import { AccountLogoutScreen } from '@colanode/ui/components/accounts/account-logout-screen';
|
||||
import { AccountScreen } from '@colanode/ui/components/accounts/account-screen';
|
||||
import { AccountSettingsScreen } from '@colanode/ui/components/accounts/account-settings-screen';
|
||||
import { LoginScreen } from '@colanode/ui/components/accounts/login-screen';
|
||||
import { AppAppearanceSettingsScreen } from '@colanode/ui/components/app/app-appearance-settings-screen';
|
||||
import { AppHomeScreen } from '@colanode/ui/components/app/app-home-screen';
|
||||
import { RootLayout } from '@colanode/ui/components/layouts/root-layout';
|
||||
import { NodeScreen } from '@colanode/ui/components/nodes/node-screen';
|
||||
import { WorkspaceDownloadsScreen } from '@colanode/ui/components/workspaces/downloads/workspace-downloads-screen';
|
||||
import { WorkspaceStorageScreen } from '@colanode/ui/components/workspaces/storage/workspace-storage-screen';
|
||||
@@ -20,8 +20,12 @@ import { WorkspaceScreen } from '@colanode/ui/components/workspaces/workspace-sc
|
||||
import { WorkspaceSettingsScreen } from '@colanode/ui/components/workspaces/workspace-settings-screen';
|
||||
import { WorkspaceUsersScreen } from '@colanode/ui/components/workspaces/workspace-users-screen';
|
||||
|
||||
export const rootRoute = createRootRoute({
|
||||
component: RootLayout,
|
||||
export const rootRoute = createRootRoute();
|
||||
|
||||
export const appHomeRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: '/',
|
||||
component: AppHomeScreen,
|
||||
});
|
||||
|
||||
export const loginRoute = createRoute({
|
||||
@@ -30,14 +34,14 @@ export const loginRoute = createRoute({
|
||||
component: LoginScreen,
|
||||
});
|
||||
|
||||
export const appHomeRoute = createRoute({
|
||||
export const accountRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: '/',
|
||||
component: AppHomeScreen,
|
||||
path: '/acc/$accountId',
|
||||
component: AccountScreen,
|
||||
});
|
||||
|
||||
export const workspaceRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
getParentRoute: () => accountRoute,
|
||||
path: '/$workspaceId',
|
||||
component: WorkspaceScreen,
|
||||
});
|
||||
@@ -49,7 +53,7 @@ export const workspaceHomeRoute = createRoute({
|
||||
});
|
||||
|
||||
export const workspaceCreateRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
getParentRoute: () => accountRoute,
|
||||
path: '/create',
|
||||
component: WorkspaceCreateScreen,
|
||||
});
|
||||
@@ -111,18 +115,20 @@ export const appAppearanceRoute = createRoute({
|
||||
export const routeTree = rootRoute.addChildren([
|
||||
appHomeRoute,
|
||||
loginRoute,
|
||||
workspaceCreateRoute,
|
||||
workspaceRoute.addChildren([
|
||||
workspaceHomeRoute,
|
||||
nodeRoute,
|
||||
workspaceDownloadsRoute,
|
||||
workspaceUploadsRoute,
|
||||
workspaceStorageRoute,
|
||||
workspaceUsersRoute,
|
||||
workspaceSettingsRoute,
|
||||
accountSettingsRoute,
|
||||
accountLogoutRoute,
|
||||
appAppearanceRoute,
|
||||
accountRoute.addChildren([
|
||||
workspaceCreateRoute,
|
||||
workspaceRoute.addChildren([
|
||||
workspaceHomeRoute,
|
||||
nodeRoute,
|
||||
workspaceDownloadsRoute,
|
||||
workspaceUploadsRoute,
|
||||
workspaceStorageRoute,
|
||||
workspaceUsersRoute,
|
||||
workspaceSettingsRoute,
|
||||
accountSettingsRoute,
|
||||
accountLogoutRoute,
|
||||
appAppearanceRoute,
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user