d6f742a3c1
UAT: 14/15 passed. Bug fixed: folders/rootFolders array alias in fetchFolders caused duplicate folder row on creation (rootFolders = [...list] breaks the shared reference). Sidebar: Folders section now has a collapse/expand chevron, collapsed by default. State: Phase 4 complete, Phase 5 (Cloud Storage Backends) is next. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
105 lines
3.1 KiB
JavaScript
105 lines
3.1 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import * as api from '../api/client.js'
|
|
|
|
export const useFoldersStore = defineStore('folders', () => {
|
|
const folders = ref([])
|
|
const rootFolders = ref([]) // root-level folders for sidebar tree and folder pickers
|
|
const currentFolderId = ref(null)
|
|
const breadcrumb = ref([])
|
|
const loading = ref(false)
|
|
const error = ref(null)
|
|
const treeVersion = ref(0) // bumped on any mutation so sidebar tree can react
|
|
|
|
async function fetchFolders(parentId = null) {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const data = await api.listFolders(parentId)
|
|
const list = data.items ?? data
|
|
folders.value = list
|
|
if (parentId === null) rootFolders.value = [...list]
|
|
} catch (e) {
|
|
error.value = e.message || 'Failed to load folders'
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function fetchRootFolders() {
|
|
try {
|
|
const data = await api.listFolders(null)
|
|
rootFolders.value = data.items ?? data
|
|
} catch {}
|
|
}
|
|
|
|
async function createFolder(name, parentId = null) {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const folder = await api.createFolder(name, parentId)
|
|
folders.value.push(folder)
|
|
if (parentId === null) rootFolders.value.push(folder)
|
|
treeVersion.value++
|
|
return folder
|
|
} catch (e) {
|
|
error.value = e.message || 'Failed to create folder'
|
|
throw e
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function renameFolder(folderId, name) {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const updated = await api.renameFolder(folderId, name)
|
|
const idx = folders.value.findIndex(f => f.id === folderId)
|
|
if (idx !== -1) folders.value[idx] = updated
|
|
const rootIdx = rootFolders.value.findIndex(f => f.id === folderId)
|
|
if (rootIdx !== -1) rootFolders.value[rootIdx] = updated
|
|
treeVersion.value++
|
|
return updated
|
|
} catch (e) {
|
|
error.value = e.message || 'Failed to rename folder'
|
|
throw e
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function deleteFolder(folderId) {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
await api.deleteFolder(folderId)
|
|
folders.value = folders.value.filter(f => f.id !== folderId)
|
|
rootFolders.value = rootFolders.value.filter(f => f.id !== folderId)
|
|
treeVersion.value++
|
|
} catch (e) {
|
|
error.value = e.message || 'Failed to delete folder'
|
|
throw e
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function navigateTo(folderId) {
|
|
currentFolderId.value = folderId
|
|
if (folderId != null) {
|
|
try {
|
|
const data = await api.getFolder(folderId)
|
|
breadcrumb.value = data.breadcrumb || []
|
|
} catch (e) {
|
|
breadcrumb.value = []
|
|
}
|
|
} else {
|
|
breadcrumb.value = []
|
|
folders.value = [] // clear stale subfolder list when returning to home
|
|
}
|
|
}
|
|
|
|
return { folders, rootFolders, currentFolderId, breadcrumb, loading, error, treeVersion, fetchFolders, fetchRootFolders, createFolder, renameFolder, deleteFolder, navigateTo }
|
|
})
|