import { computed, reactive, ref } from 'vue' import { defineStore } from 'pinia' import { io } from 'socket.io-client' import api from '@/services/HttpService' function constructUrl(path: string | string[], append = true) { const arr = Array.isArray(path) ? path : path.split('/').filter(Boolean) const url = import.meta.env.VITE_API_ENDPOINT + arr.reduce((a, v, i) => { switch (String(i)) { case '0': return `cabinet/${v}` case '1': return `${a}/drawer/${v}` case '2': return `${a}/folder/${v}` case '3': return `${a}/subfolder/${v}` default: return a } }, '') return append ? url + ['cabinet', '/drawer', '/folder', '/subfolder'][arr.length] : url } const useStorage = defineStore('storage', async () => { const folderList = ref< Record< string, // path that contains folders { pathname: string name: string }[] > >({}) const fileList = ref< Record< string, // path that contains files { pathname: string path: string fileName: string fileSize: string fileType: string title: string description: string category: string[] keyword: string[] updatedAt: string updatedBy: string createdAt: string createdBy: string }[] > >({}) const tree = computed(() => { type Structure = { pathname: string name: string folder: Structure file: (typeof fileList.value)[string] }[] let structure: Structure = [] // parse list of folder and list of file into tree Object.entries(folderList.value).forEach(([key, value]) => { const arr = key.split('/').filter(Boolean) // init outer tree if (arr.length === 0) { structure = value.map((v) => ({ pathname: v.pathname, name: v.name, folder: [], file: [], })) } else { let current: Structure[number] | undefined // traverse into tree arr.forEach((v, i) => { current = i === 0 ? structure.find((x) => x.name === v) : current?.folder.find((x) => x.name === v) }) // set data in tree (object is references to the same object) if (current) { current.folder = value.map((v) => ({ pathname: v.pathname, name: v.name, folder: [], file: [], })) current.file = fileList.value[key] ?? [] } } }) return structure }) const currentInfo = reactive<{ path: string dept: number }>({ path: '', dept: 0, }) async function getStorage(path: string = '') { const res = await api.get<(typeof folderList.value)[string]>( constructUrl(path), ) if (res.status === 200) folderList.value[path] = res.data.sort((a, b) => a.pathname.localeCompare(b.pathname), ) } async function getStorageFile(path: string = '') { const arr = path.split('/').filter(Boolean) if (arr.length < 3) return const res = await api.get<(typeof fileList.value)[string]>( constructUrl(path, false) + '/file', ) if (res.status === 200) fileList.value[path] = res.data.sort((a, b) => a.pathname.localeCompare(b.pathname), ) } async function goto(path: string) { const arr = path.split('/').filter(Boolean) for (let i = 0; i < arr.length; i++) { const current = arr.slice(0, i - arr.length).join('/') + '/' if (!folderList.value[current]) await getStorage(current) } // only get this path once, after that will get from socket.io-client instead if (!folderList.value[path]) await getStorage(path) if (!fileList.value[path]) await getStorageFile(path) currentInfo.path = path currentInfo.dept = path.split('/').filter(Boolean).length - 1 } async function gotoParent() { const arr = currentInfo.path.split('/').filter(Boolean) await goto([...arr.slice(0, -1), ''].join('/')) } const socket = io('http://localhost:25570') socket.on('connect', () => console.info('Socket.io connected.')) socket.on('disconnect', () => console.info('Socket.io disconnected.')) socket.on('CreateFolder', (data: { pathname: string }) => { const arr = data.pathname.split('/').filter(Boolean) const path = [...arr.slice(0, -1), ''].join('/') if (folderList.value[path]) { folderList.value[path].push({ pathname: data.pathname, name: arr[arr.length - 1], }) folderList.value[path].sort((a, b) => a.pathname.localeCompare(b.pathname), ) } }) socket.on( 'EditFolder', (data: { from: { pathname: string }; to: { pathname: string } }) => { console.log(data) // TODO: Implement }, ) socket.on('DeleteFolder', (data: { pathname: string }) => { if (folderList.value[data.pathname]) { delete folderList.value[data.pathname] } const arr = data.pathname.split('/').filter(Boolean) const path = [...arr.slice(0, -1), ''].join('/') if (folderList.value[path]) { folderList.value[path] = folderList.value[path].filter( (v) => v.pathname !== data.pathname, ) } }) await goto('เอกสารทดสอบระบบ/dev-test/dev-test/') console.log(tree.value) return { // information currentInfo, folderList, fileList, tree, // fetch getStorage, getStorageFile, // traverse goto, gotoParent, } }) export default useStorage