Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced turbopack alias for canvas in next.config.mjs. - Updated package.json scripts for development and branding tasks. - Added new dependencies for Tiptap extensions. - Implemented new demo layouts for agenda, contacts, drive, and mail applications. - Enhanced globals.css for improved theming and splash screen animations. - Added OAuth callback handling for drive mounts. - Updated layout components to integrate new demo shells and improve structure.
164 lines
4.7 KiB
TypeScript
164 lines
4.7 KiB
TypeScript
"use client"
|
|
|
|
import { create } from "zustand"
|
|
import type { DriveFileInfo, DriveListResponse } from "@/lib/api/types"
|
|
import {
|
|
createInitialDemoDriveFiles,
|
|
listDemoDriveFiles,
|
|
listDemoDriveRecent,
|
|
listDemoDriveShared,
|
|
listDemoDriveStarred,
|
|
listDemoDriveTrash,
|
|
searchDemoDriveFiles,
|
|
} from "@/lib/demo/demo-drive-api-data"
|
|
|
|
type DemoDriveStoreState = {
|
|
files: DriveFileInfo[]
|
|
trash: DriveFileInfo[]
|
|
version: number
|
|
}
|
|
|
|
type DemoDriveStoreActions = {
|
|
reset: () => void
|
|
bump: () => void
|
|
listFiles: (path: string, page: number) => DriveListResponse
|
|
listRecent: () => DriveListResponse
|
|
listStarred: (path: string) => DriveListResponse
|
|
listTrash: () => DriveListResponse
|
|
listShared: () => DriveListResponse
|
|
search: (q: string, scope: string, path: string, page: number) => DriveListResponse
|
|
createFolder: (path: string) => void
|
|
deleteFile: (path: string) => void
|
|
rename: (path: string, newName: string) => void
|
|
setFavorite: (path: string, favorite: boolean) => void
|
|
restoreTrash: (name: string) => void
|
|
deleteTrash: (name: string) => void
|
|
emptyTrash: () => void
|
|
}
|
|
|
|
function replacePathPrefix(path: string, oldPrefix: string, newPrefix: string): string {
|
|
if (path === oldPrefix) return newPrefix
|
|
if (path.startsWith(oldPrefix + "/")) {
|
|
return newPrefix + path.slice(oldPrefix.length)
|
|
}
|
|
return path
|
|
}
|
|
|
|
export const useDemoDriveStore = create<DemoDriveStoreState & DemoDriveStoreActions>(
|
|
(set, get) => ({
|
|
files: createInitialDemoDriveFiles(),
|
|
trash: [],
|
|
version: 0,
|
|
|
|
reset: () =>
|
|
set({
|
|
files: createInitialDemoDriveFiles(),
|
|
trash: [],
|
|
version: get().version + 1,
|
|
}),
|
|
|
|
bump: () => set({ version: get().version + 1 }),
|
|
|
|
listFiles: (path, page) => listDemoDriveFiles(get().files, path, page),
|
|
listRecent: () => listDemoDriveRecent(get().files),
|
|
listStarred: (path) => listDemoDriveStarred(get().files, path),
|
|
listTrash: () => listDemoDriveTrash(),
|
|
listShared: () => listDemoDriveShared(),
|
|
search: (q, scope, path, page) =>
|
|
searchDemoDriveFiles(get().files, q, scope, path, page),
|
|
|
|
createFolder: (path) => {
|
|
const normalized = path.startsWith("/") ? path : `/${path}`
|
|
const name = normalized.split("/").pop() ?? "Nouveau dossier"
|
|
set((state) => ({
|
|
files: [
|
|
...state.files,
|
|
{
|
|
path: normalized,
|
|
name,
|
|
type: "directory",
|
|
mime_type: "httpd/unix-directory",
|
|
size: 0,
|
|
last_modified: new Date().toISOString(),
|
|
etag: `"demo-folder-${Date.now()}"`,
|
|
is_favorite: false,
|
|
file_id: Date.now(),
|
|
},
|
|
],
|
|
version: state.version + 1,
|
|
}))
|
|
},
|
|
|
|
deleteFile: (path) => {
|
|
set((state) => {
|
|
const removed = state.files.filter(
|
|
(f) => f.path === path || f.path.startsWith(path + "/")
|
|
)
|
|
const remaining = state.files.filter(
|
|
(f) => f.path !== path && !f.path.startsWith(path + "/")
|
|
)
|
|
return {
|
|
files: remaining,
|
|
trash: [...state.trash, ...removed],
|
|
version: state.version + 1,
|
|
}
|
|
})
|
|
},
|
|
|
|
rename: (path, newName) => {
|
|
set((state) => {
|
|
const parent = path.replace(/\/[^/]+$/, "") || "/"
|
|
const newPath = parent === "/" ? `/${newName}` : `${parent}/${newName}`
|
|
const files = state.files.map((f) => {
|
|
if (f.path === path) {
|
|
return { ...f, path: newPath, name: newName }
|
|
}
|
|
if (f.path.startsWith(path + "/")) {
|
|
return {
|
|
...f,
|
|
path: replacePathPrefix(f.path, path, newPath),
|
|
name: f.path.split("/").pop() ?? f.name,
|
|
}
|
|
}
|
|
return f
|
|
})
|
|
return { files, version: state.version + 1 }
|
|
})
|
|
},
|
|
|
|
setFavorite: (path, favorite) => {
|
|
set((state) => ({
|
|
files: state.files.map((f) =>
|
|
f.path === path || f.path.startsWith(path + "/")
|
|
? { ...f, is_favorite: favorite }
|
|
: f
|
|
),
|
|
version: state.version + 1,
|
|
}))
|
|
},
|
|
|
|
restoreTrash: (name) => {
|
|
set((state) => {
|
|
const entry = state.trash.find((f) => f.name === name)
|
|
if (!entry) return state
|
|
return {
|
|
trash: state.trash.filter((f) => f.name !== name),
|
|
files: [...state.files, entry],
|
|
version: state.version + 1,
|
|
}
|
|
})
|
|
},
|
|
|
|
deleteTrash: (name) => {
|
|
set((state) => ({
|
|
trash: state.trash.filter((f) => f.name !== name),
|
|
version: state.version + 1,
|
|
}))
|
|
},
|
|
|
|
emptyTrash: () => {
|
|
set((state) => ({ trash: [], version: state.version + 1 }))
|
|
},
|
|
})
|
|
)
|