ultisuite-client/components/drive/drive-new-sheet.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

172 lines
4.8 KiB
TypeScript

"use client"
import type { InputHTMLAttributes, ReactNode } from "react"
import {
FileSpreadsheet,
FileText,
FolderPlus,
FolderUp,
Presentation,
Upload,
} from "lucide-react"
import { DriveNameDialog } from "@/components/drive/drive-name-dialog"
import { Sheet, SheetContent, SheetDescription, SheetTitle } from "@/components/ui/sheet"
import {
DRIVE_NEW_MENU_ITEM_CLASS,
useDriveNewMenu,
} from "@/lib/hooks/use-drive-new-menu"
import {
DRIVE_SHEET_CONTENT,
DRIVE_SHEET_OVERLAY,
DRIVE_TEXT_TITLE,
DRIVE_DIALOG_DIVIDER,
} from "@/lib/drive/drive-dialog-styles"
import { cn } from "@/lib/utils"
function SheetAction({
icon,
label,
onClick,
className,
}: {
icon: ReactNode
label: string
onClick?: () => void
className?: string
}) {
return (
<button
type="button"
onClick={onClick}
className={cn(
"flex w-full cursor-pointer items-center text-left transition-colors active:bg-accent/80",
DRIVE_NEW_MENU_ITEM_CLASS,
className
)}
>
{icon}
{label}
</button>
)
}
export function DriveNewSheet({
parentPath,
open,
onOpenChange,
}: {
parentPath: string
open: boolean
onOpenChange: (open: boolean) => void
}) {
const {
pendingKind,
pendingMeta,
defaultName,
confirmNew,
uploadFiles,
importFolder,
pickKind,
closeNameDialog,
} = useDriveNewMenu(parentPath)
const closeSheet = () => onOpenChange(false)
const pick = (kind: Parameters<typeof pickKind>[0]) => {
pickKind(kind)
closeSheet()
}
return (
<>
<DriveNameDialog
open={pendingKind !== null}
onOpenChange={(next) => {
if (!next) closeNameDialog()
}}
title={
pendingKind === "folder"
? "Nouveau dossier"
: pendingMeta
? `Nouveau ${pendingMeta.menuLabel.toLowerCase()}`
: "Nouveau"
}
defaultValue={defaultName}
confirmLabel="Créer"
onConfirm={confirmNew}
/>
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent
side="bottom"
hideClose
overlayClassName={DRIVE_SHEET_OVERLAY}
className={cn(DRIVE_SHEET_CONTENT, "max-h-[min(85dvh,520px)]")}
>
<SheetTitle className="sr-only">Nouveau</SheetTitle>
<SheetDescription className="sr-only">
Créer un document, un tableur, une présentation ou un dossier.
</SheetDescription>
<div className={cn("border-b px-4 py-3", DRIVE_DIALOG_DIVIDER)}>
<p className={cn("text-base font-medium", DRIVE_TEXT_TITLE)}>Nouveau</p>
</div>
<div className="flex flex-col p-2">
<SheetAction
icon={<FileText className="text-blue-600" />}
label="Document"
onClick={() => pick("document")}
/>
<SheetAction
icon={<FileSpreadsheet className="text-green-600" />}
label="Tableur"
onClick={() => pick("spreadsheet")}
/>
<SheetAction
icon={<Presentation className="text-amber-600" />}
label="Présentation"
onClick={() => pick("presentation")}
/>
<SheetAction
icon={<FolderPlus className="text-amber-500" />}
label="Dossier"
onClick={() => pick("folder")}
/>
<label className="flex cursor-pointer items-center active:bg-accent/80">
<span className={cn("flex w-full items-center", DRIVE_NEW_MENU_ITEM_CLASS)}>
<Upload className="text-sky-600" />
Importer un fichier
</span>
<input
type="file"
className="hidden"
multiple
onChange={async (e) => {
await uploadFiles(e.target.files)
e.target.value = ""
closeSheet()
}}
/>
</label>
<label className="flex cursor-pointer items-center active:bg-accent/80">
<span className={cn("flex w-full items-center", DRIVE_NEW_MENU_ITEM_CLASS)}>
<FolderUp className="text-violet-600" />
Importer un dossier
</span>
<input
type="file"
className="hidden"
multiple
{...({ webkitdirectory: "", directory: "" } as InputHTMLAttributes<HTMLInputElement>)}
onChange={async (e) => {
await importFolder(e.target.files)
e.target.value = ""
closeSheet()
}}
/>
</label>
</div>
</SheetContent>
</Sheet>
</>
)
}