- Updated .env.example to include configuration for OnlyOffice Document Server. - Modified the workspace configuration to remove the drive-suite path. - Adjusted TypeScript environment imports for consistency. - Enhanced Next.js configuration to disable canvas in Webpack. - Updated package.json to include new dependencies for OnlyOffice and PDF.js. - Added global styles for OnlyOffice theme integration in the CSS. - Created new layout and page components for the Drive feature, including public sharing and editing functionalities. - Updated metadata handling across various layouts to reflect the new app structure.
120 lines
4.4 KiB
TypeScript
120 lines
4.4 KiB
TypeScript
"use client"
|
|
|
|
import { Fragment, useState } from "react"
|
|
import Link from "next/link"
|
|
import { ChevronRight } from "lucide-react"
|
|
import { BreadcrumbFolderMenu } from "@/components/drive/breadcrumb-folder-menu"
|
|
import type { DriveView } from "@/lib/drive/drive-url"
|
|
import { buildDriveFolderHref, folderPathFromSegments } from "@/lib/drive/drive-url"
|
|
import { displayFileName } from "@/lib/drive/display-file-name"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
/** xs/sm: single line, intermediate crumbs clamp + ellipsis. */
|
|
const MOBILE_INTERMEDIATE_CRUMB_CLASS =
|
|
"max-md:line-clamp-1 max-md:min-w-0 max-md:shrink max-md:overflow-hidden max-md:break-all max-md:[overflow-wrap:anywhere]"
|
|
|
|
/** Shared line box so mixed font sizes stay vertically centered in the chrome row. */
|
|
const CRUMB_LINE_CLASS = "leading-6 md:leading-7"
|
|
|
|
export function BreadcrumbNav({
|
|
view,
|
|
segments,
|
|
writable = true,
|
|
}: {
|
|
view: Extract<DriveView, "files" | "shared">
|
|
segments: string[]
|
|
/** When false, double-click rename is disabled (e.g. read-only share). */
|
|
writable?: boolean
|
|
}) {
|
|
const [renameOpen, setRenameOpen] = useState(false)
|
|
|
|
const rootLabel = view === "shared" ? "Partagés avec moi" : "Mon Drive"
|
|
const rootHref = view === "shared" ? "/drive/shared" : "/drive"
|
|
const folderPath = folderPathFromSegments(segments)
|
|
const canRenameCurrent = writable && segments.length > 0
|
|
|
|
const crumbs = [{ label: rootLabel, href: rootHref, segments: [] as string[] }]
|
|
for (let i = 0; i < segments.length; i++) {
|
|
const slice = segments.slice(0, i + 1)
|
|
crumbs.push({
|
|
label: displayFileName(segments[i]),
|
|
href: buildDriveFolderHref(view, slice),
|
|
segments: slice,
|
|
})
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<nav className="flex min-w-0 flex-nowrap items-center gap-1 overflow-hidden text-[#5f6368] md:gap-2 dark:text-muted-foreground">
|
|
{crumbs.map((c, i) => {
|
|
const isLast = i === crumbs.length - 1
|
|
const isRenamableFolder = isLast && canRenameCurrent
|
|
|
|
return (
|
|
<Fragment key={c.href}>
|
|
{i > 0 && (
|
|
<ChevronRight
|
|
className="size-4 shrink-0 opacity-60 md:size-5"
|
|
aria-hidden
|
|
/>
|
|
)}
|
|
{isLast ? (
|
|
<span className="inline-flex min-w-0 max-w-full shrink items-center gap-0.5">
|
|
<span
|
|
className={cn(
|
|
"min-w-0 max-w-full shrink truncate text-base font-normal tracking-tight text-[#202124] md:text-[1.375rem] dark:text-foreground",
|
|
CRUMB_LINE_CLASS,
|
|
isRenamableFolder &&
|
|
"cursor-text rounded-sm px-0.5 hover:bg-mail-nav-hover"
|
|
)}
|
|
title={
|
|
isRenamableFolder
|
|
? `${c.label} — double-clic pour renommer`
|
|
: c.label
|
|
}
|
|
onDoubleClick={
|
|
isRenamableFolder
|
|
? (e) => {
|
|
e.preventDefault()
|
|
setRenameOpen(true)
|
|
}
|
|
: undefined
|
|
}
|
|
>
|
|
{c.label}
|
|
</span>
|
|
{segments.length > 0 ? (
|
|
<BreadcrumbFolderMenu
|
|
view={view}
|
|
segments={segments}
|
|
folderPath={folderPath}
|
|
writable={writable}
|
|
allowShare={view === "files"}
|
|
renameOpen={renameOpen}
|
|
onRenameOpenChange={setRenameOpen}
|
|
/>
|
|
) : null}
|
|
</span>
|
|
) : (
|
|
<Link
|
|
href={c.href}
|
|
title={c.label}
|
|
className={cn(
|
|
"inline-flex shrink-0 cursor-pointer text-sm hover:text-[#202124] md:text-[1.125rem] dark:hover:text-foreground",
|
|
CRUMB_LINE_CLASS,
|
|
MOBILE_INTERMEDIATE_CRUMB_CLASS,
|
|
i === 0 ? "max-md:max-w-[5.5rem]" : "max-md:max-w-[4.5rem]"
|
|
)}
|
|
>
|
|
{c.label}
|
|
</Link>
|
|
)}
|
|
</Fragment>
|
|
)
|
|
})}
|
|
<span className="sr-only">{folderPath}</span>
|
|
</nav>
|
|
</>
|
|
)
|
|
}
|