- 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.
141 lines
4.5 KiB
TypeScript
141 lines
4.5 KiB
TypeScript
/** Nextcloud OCS share types used by Ultidrive. */
|
|
export const NC_SHARE_TYPE = {
|
|
USER: 0,
|
|
GROUP: 1,
|
|
LINK: 3,
|
|
EMAIL: 4,
|
|
} as const
|
|
|
|
export type DriveShareMode = "public" | "internal" | "contact"
|
|
|
|
export type ShareListSection = "links" | "people" | "groups"
|
|
|
|
export function shareListSection(share: { share_type: number }): ShareListSection {
|
|
if (share.share_type === NC_SHARE_TYPE.USER || share.share_type === NC_SHARE_TYPE.EMAIL) {
|
|
return "people"
|
|
}
|
|
if (share.share_type === NC_SHARE_TYPE.GROUP) return "groups"
|
|
return "links"
|
|
}
|
|
|
|
export const SHARE_SECTION_LABELS: Record<ShareListSection, string> = {
|
|
links: "Liens de partage",
|
|
people: "Personnes",
|
|
groups: "Organisations",
|
|
}
|
|
|
|
import { normalizePublicShareURL } from "@/lib/api/public-share"
|
|
|
|
export function shareLinkForCopy(share: {
|
|
url?: string
|
|
internal_url?: string
|
|
token?: string
|
|
}): string | null {
|
|
if (share.url) return normalizePublicShareURL(share.url, share.token)
|
|
if (share.internal_url) return share.internal_url
|
|
if (share.token) return normalizePublicShareURL("", share.token)
|
|
return null
|
|
}
|
|
|
|
export function shareAccessLabel(share: {
|
|
share_type: number
|
|
access_mode?: string
|
|
label?: string
|
|
}): string {
|
|
if (share.access_mode === "internal" || share.label?.toLowerCase() === "internal") {
|
|
return "Lien interne"
|
|
}
|
|
if (share.share_type === NC_SHARE_TYPE.LINK) return "Lien public"
|
|
if (share.share_type === NC_SHARE_TYPE.USER) return "Utilisateur"
|
|
if (share.share_type === NC_SHARE_TYPE.EMAIL) return "Invitation par e-mail"
|
|
if (share.share_type === NC_SHARE_TYPE.GROUP) return "Groupe"
|
|
return "Partage"
|
|
}
|
|
|
|
export function shareRecipientLabel(share: {
|
|
share_type: number
|
|
share_with?: string
|
|
share_with_displayname?: string
|
|
}): string | null {
|
|
const withEmail = share.share_with?.trim()
|
|
const display = share.share_with_displayname?.trim()
|
|
if (share.share_type === NC_SHARE_TYPE.LINK) {
|
|
if (display && display !== "(Shared link)" && display !== "(Lien partagé)") return display
|
|
return null
|
|
}
|
|
if (display && withEmail && display.toLowerCase() !== withEmail.toLowerCase()) {
|
|
return `${display} (${withEmail})`
|
|
}
|
|
if (display && display !== "(Shared link)" && display !== "(Lien partagé)") return display
|
|
if (withEmail) return withEmail
|
|
return null
|
|
}
|
|
|
|
export function shareOwnerLabel(share: {
|
|
owner_displayname?: string
|
|
owner_id?: string
|
|
file_owner_displayname?: string
|
|
file_owner_id?: string
|
|
}): string | null {
|
|
const owner = share.owner_displayname?.trim() || share.owner_id?.trim()
|
|
const fileOwner = share.file_owner_displayname?.trim() || share.file_owner_id?.trim()
|
|
if (owner && fileOwner && owner !== fileOwner) {
|
|
return `${owner} · fichier : ${fileOwner}`
|
|
}
|
|
return owner || fileOwner || null
|
|
}
|
|
|
|
export function sharePermissionsLabel(permissions: number): string {
|
|
const canRead = (permissions & 1) !== 0
|
|
const canUpdate = (permissions & 2) !== 0
|
|
const canCreate = (permissions & 4) !== 0
|
|
const canDelete = (permissions & 8) !== 0
|
|
if (canRead && canUpdate && canCreate && canDelete) return "Éditeur"
|
|
if (canCreate && !canRead) return "Dépôt uniquement"
|
|
if (canRead && !canUpdate && !canCreate && !canDelete) return "Lecteur"
|
|
const parts: string[] = []
|
|
if (canRead) parts.push("lecture")
|
|
if (canCreate) parts.push("ajout")
|
|
if (canUpdate) parts.push("modification")
|
|
if (canDelete) parts.push("suppression")
|
|
return parts.length > 0 ? parts.join(", ") : "Accès limité"
|
|
}
|
|
|
|
export function formatShareDate(iso?: string): string | null {
|
|
if (!iso?.trim()) return null
|
|
const date = new Date(iso)
|
|
if (Number.isNaN(date.getTime())) return null
|
|
return date.toLocaleDateString("fr-FR", {
|
|
day: "numeric",
|
|
month: "short",
|
|
year: "numeric",
|
|
})
|
|
}
|
|
|
|
export function shareMetaLine(share: {
|
|
permissions: number
|
|
created_at?: string
|
|
expires_at?: string
|
|
has_password?: boolean
|
|
}): string {
|
|
const parts: string[] = [sharePermissionsLabel(share.permissions)]
|
|
const created = formatShareDate(share.created_at)
|
|
if (created) parts.push(`créé le ${created}`)
|
|
const expires = formatShareDate(share.expires_at)
|
|
if (expires) parts.push(`expire le ${expires}`)
|
|
if (share.has_password) parts.push("protégé par mot de passe")
|
|
return parts.join(" · ")
|
|
}
|
|
|
|
export function groupSharesBySection<T extends { share_type: number }>(shares: T[]) {
|
|
const sections: Record<ShareListSection, T[]> = {
|
|
links: [],
|
|
people: [],
|
|
groups: [],
|
|
}
|
|
for (const share of shares) {
|
|
sections[shareListSection(share)].push(share)
|
|
}
|
|
return sections
|
|
}
|