mirror of
https://github.com/get-drexa/drive.git
synced 2025-12-01 05:51:39 +00:00
fix: broken dir path breadcrumb links
This commit is contained in:
@@ -6,14 +6,13 @@ import type {
|
|||||||
import * as Err from "./error"
|
import * as Err from "./error"
|
||||||
import {
|
import {
|
||||||
type DirectoryHandle,
|
type DirectoryHandle,
|
||||||
type FilePath,
|
type DirectoryPath,
|
||||||
type FileSystemItem,
|
type FileSystemItem,
|
||||||
FileType,
|
FileType,
|
||||||
newDirectoryHandle,
|
newDirectoryHandle,
|
||||||
type ReverseFilePath,
|
|
||||||
} from "./filesystem"
|
} from "./filesystem"
|
||||||
|
|
||||||
export type DirectoryInfo = Doc<"directories"> & { path: FilePath }
|
export type DirectoryInfo = Doc<"directories"> & { path: DirectoryPath }
|
||||||
|
|
||||||
export async function fetchRoot(ctx: AuthenticatedQueryCtx) {
|
export async function fetchRoot(ctx: AuthenticatedQueryCtx) {
|
||||||
return await ctx.db
|
return await ctx.db
|
||||||
@@ -50,7 +49,7 @@ export async function fetch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const path: ReverseFilePath = [
|
const path: DirectoryPath = [
|
||||||
{
|
{
|
||||||
handle: newDirectoryHandle(directoryId),
|
handle: newDirectoryHandle(directoryId),
|
||||||
name: directory.name,
|
name: directory.name,
|
||||||
@@ -70,7 +69,7 @@ export async function fetch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...directory, path: path.reverse() as FilePath }
|
return { ...directory, path: path.reverse() as DirectoryPath }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchContent(
|
export async function fetchContent(
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ export type FilePathComponent = {
|
|||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
export type PathComponent = FilePathComponent | DirectoryPathComponent
|
export type PathComponent = FilePathComponent | DirectoryPathComponent
|
||||||
|
export type DirectoryPath = [
|
||||||
|
DirectoryPathComponent,
|
||||||
|
...DirectoryPathComponent[],
|
||||||
|
]
|
||||||
export type FilePath = [...DirectoryPathComponent[], PathComponent]
|
export type FilePath = [...DirectoryPathComponent[], PathComponent]
|
||||||
export type ReverseFilePath = [PathComponent, ...DirectoryPathComponent[]]
|
export type ReverseFilePath = [PathComponent, ...DirectoryPathComponent[]]
|
||||||
|
|
||||||
@@ -154,10 +158,8 @@ export async function restoreItems(
|
|||||||
{ handles }: { handles: FileSystemHandle[] },
|
{ handles }: { handles: FileSystemHandle[] },
|
||||||
) {
|
) {
|
||||||
// Collect all items to restore (including nested items)
|
// Collect all items to restore (including nested items)
|
||||||
const { fileHandles, directoryHandles } = await collectAllHandlesRecursively(
|
const { fileHandles, directoryHandles } =
|
||||||
ctx,
|
await collectAllHandlesRecursively(ctx, { handles })
|
||||||
{ handles },
|
|
||||||
)
|
|
||||||
|
|
||||||
// Restore files and directories by unsetting deletedAt
|
// Restore files and directories by unsetting deletedAt
|
||||||
const [filesResult, directoriesResult] = await Promise.all([
|
const [filesResult, directoriesResult] = await Promise.all([
|
||||||
@@ -183,8 +185,10 @@ export async function deleteItemsPermanently(
|
|||||||
{ handles }: { handles: FileSystemHandle[] },
|
{ handles }: { handles: FileSystemHandle[] },
|
||||||
) {
|
) {
|
||||||
// Collect all items to delete (including nested items)
|
// Collect all items to delete (including nested items)
|
||||||
const { fileHandles: fileHandlesToDelete, directoryHandles: directoryHandlesToDelete } =
|
const {
|
||||||
await collectAllHandlesRecursively(ctx, { handles })
|
fileHandles: fileHandlesToDelete,
|
||||||
|
directoryHandles: directoryHandlesToDelete,
|
||||||
|
} = await collectAllHandlesRecursively(ctx, { handles })
|
||||||
|
|
||||||
// Delete files and directories using their respective models
|
// Delete files and directories using their respective models
|
||||||
const [filesResult, directoriesResult] = await Promise.all([
|
const [filesResult, directoriesResult] = await Promise.all([
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import type { Id } from "@fileone/convex/_generated/dataModel"
|
||||||
import type {
|
import type {
|
||||||
DirectoryHandle,
|
DirectoryHandle,
|
||||||
PathComponent,
|
DirectoryPathComponent,
|
||||||
} from "@fileone/convex/model/filesystem"
|
} from "@fileone/convex/model/filesystem"
|
||||||
import { Link } from "@tanstack/react-router"
|
import { Link } from "@tanstack/react-router"
|
||||||
import { Fragment, useContext } from "react"
|
import { Fragment, useContext } from "react"
|
||||||
@@ -22,7 +23,13 @@ import { cn } from "../../lib/utils"
|
|||||||
import { DirectoryPageContext } from "./context"
|
import { DirectoryPageContext } from "./context"
|
||||||
import { dragInfoAtom } from "./state"
|
import { dragInfoAtom } from "./state"
|
||||||
|
|
||||||
export function FilePathBreadcrumb({ rootLabel }: { rootLabel: string }) {
|
export function FilePathBreadcrumb({
|
||||||
|
rootLabel,
|
||||||
|
directoryUrlFn,
|
||||||
|
}: {
|
||||||
|
rootLabel: string
|
||||||
|
directoryUrlFn: (directory: Id<"directories">) => string
|
||||||
|
}) {
|
||||||
const { rootDirectory, directory } = useContext(DirectoryPageContext)
|
const { rootDirectory, directory } = useContext(DirectoryPageContext)
|
||||||
|
|
||||||
const breadcrumbItems: React.ReactNode[] = []
|
const breadcrumbItems: React.ReactNode[] = []
|
||||||
@@ -33,6 +40,7 @@ export function FilePathBreadcrumb({ rootLabel }: { rootLabel: string }) {
|
|||||||
<FilePathBreadcrumbItem
|
<FilePathBreadcrumbItem
|
||||||
component={directory.path[i]!}
|
component={directory.path[i]!}
|
||||||
rootLabel={rootLabel}
|
rootLabel={rootLabel}
|
||||||
|
directoryUrlFn={directoryUrlFn}
|
||||||
/>
|
/>
|
||||||
</Fragment>,
|
</Fragment>,
|
||||||
)
|
)
|
||||||
@@ -49,6 +57,7 @@ export function FilePathBreadcrumb({ rootLabel }: { rootLabel: string }) {
|
|||||||
<FilePathBreadcrumbItem
|
<FilePathBreadcrumbItem
|
||||||
component={directory.path[0]!}
|
component={directory.path[0]!}
|
||||||
rootLabel={rootLabel}
|
rootLabel={rootLabel}
|
||||||
|
directoryUrlFn={directoryUrlFn}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{breadcrumbItems}
|
{breadcrumbItems}
|
||||||
@@ -64,9 +73,11 @@ export function FilePathBreadcrumb({ rootLabel }: { rootLabel: string }) {
|
|||||||
function FilePathBreadcrumbItem({
|
function FilePathBreadcrumbItem({
|
||||||
component,
|
component,
|
||||||
rootLabel,
|
rootLabel,
|
||||||
|
directoryUrlFn,
|
||||||
}: {
|
}: {
|
||||||
component: PathComponent
|
component: DirectoryPathComponent
|
||||||
rootLabel: string
|
rootLabel: string
|
||||||
|
directoryUrlFn: (directory: Id<"directories">) => string
|
||||||
}) {
|
}) {
|
||||||
const { isDraggedOver, dropHandlers } = useFileDrop({
|
const { isDraggedOver, dropHandlers } = useFileDrop({
|
||||||
destItem: component.handle as DirectoryHandle,
|
destItem: component.handle as DirectoryHandle,
|
||||||
@@ -83,7 +94,7 @@ function FilePathBreadcrumbItem({
|
|||||||
{...dropHandlers}
|
{...dropHandlers}
|
||||||
>
|
>
|
||||||
<BreadcrumbLink asChild>
|
<BreadcrumbLink asChild>
|
||||||
<Link to={`/directories/${component.handle.id}`}>
|
<Link to={directoryUrlFn(component.handle.id)}>
|
||||||
{dirName}
|
{dirName}
|
||||||
</Link>
|
</Link>
|
||||||
</BreadcrumbLink>
|
</BreadcrumbLink>
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ function RouteComponent() {
|
|||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const directoryUrlById = useCallback(
|
||||||
|
(directoryId: Id<"directories">) => `/directories/${directoryId}`,
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
const handleContextMenuRequest = (
|
const handleContextMenuRequest = (
|
||||||
row: Row<FileSystemItem>,
|
row: Row<FileSystemItem>,
|
||||||
table: Table<FileSystemItem>,
|
table: Table<FileSystemItem>,
|
||||||
@@ -126,7 +131,10 @@ function RouteComponent() {
|
|||||||
value={{ rootDirectory, directory, directoryContent }}
|
value={{ rootDirectory, directory, directoryContent }}
|
||||||
>
|
>
|
||||||
<header className="flex py-2 shrink-0 items-center gap-2 border-b px-4 w-full">
|
<header className="flex py-2 shrink-0 items-center gap-2 border-b px-4 w-full">
|
||||||
<FilePathBreadcrumb rootLabel="All Files" />
|
<FilePathBreadcrumb
|
||||||
|
rootLabel="All Files"
|
||||||
|
directoryUrlFn={directoryUrlById}
|
||||||
|
/>
|
||||||
<div className="ml-auto flex flex-row gap-2">
|
<div className="ml-auto flex flex-row gap-2">
|
||||||
<NewDirectoryItemDropdown />
|
<NewDirectoryItemDropdown />
|
||||||
<UploadFileButton />
|
<UploadFileButton />
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
useMutation as useConvexMutation,
|
useMutation as useConvexMutation,
|
||||||
useQuery as useConvexQuery,
|
useQuery as useConvexQuery,
|
||||||
} from "convex/react"
|
} from "convex/react"
|
||||||
import { atom, useAtom, useAtomValue, useSetAtom, useStore } from "jotai"
|
import { atom, useAtom, useSetAtom, useStore } from "jotai"
|
||||||
import { ShredderIcon, TrashIcon, UndoIcon } from "lucide-react"
|
import { ShredderIcon, TrashIcon, UndoIcon } from "lucide-react"
|
||||||
import { useCallback, useEffect } from "react"
|
import { useCallback, useEffect } from "react"
|
||||||
import { toast } from "sonner"
|
import { toast } from "sonner"
|
||||||
@@ -75,6 +75,11 @@ function RouteComponent() {
|
|||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const directoryUrlById = useCallback(
|
||||||
|
(directoryId: Id<"directories">) => `/trash/directories/${directoryId}`,
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
if (!directory || !directoryContent || !rootDirectory) {
|
if (!directory || !directoryContent || !rootDirectory) {
|
||||||
return <DirectoryPageSkeleton />
|
return <DirectoryPageSkeleton />
|
||||||
}
|
}
|
||||||
@@ -97,7 +102,10 @@ function RouteComponent() {
|
|||||||
value={{ rootDirectory, directory, directoryContent }}
|
value={{ rootDirectory, directory, directoryContent }}
|
||||||
>
|
>
|
||||||
<header className="flex py-2 shrink-0 items-center gap-2 border-b px-4 w-full">
|
<header className="flex py-2 shrink-0 items-center gap-2 border-b px-4 w-full">
|
||||||
<FilePathBreadcrumb rootLabel="Trash" />
|
<FilePathBreadcrumb
|
||||||
|
rootLabel="Trash"
|
||||||
|
directoryUrlFn={directoryUrlById}
|
||||||
|
/>
|
||||||
<div className="ml-auto flex flex-row gap-2">
|
<div className="ml-auto flex flex-row gap-2">
|
||||||
<EmptyTrashButton />
|
<EmptyTrashButton />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user