ultisuite-client/components/drive/breadcrumb-nav.tsx
R3D347HR4Y 6ec95262af Add OnlyOffice integration and update project configurations
- 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.
2026-06-07 15:49:21 +02:00

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>
</>
)
}