From 5335f9af89cf07bbaa8e494b30f31f92607b4baf Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Sun, 10 Dec 2023 15:00:50 +0700 Subject: [PATCH] feat: implement socket on edit and fews method --- Services/client/src/stores/storage.ts | 137 ++++++++++++++++++-------- 1 file changed, 95 insertions(+), 42 deletions(-) diff --git a/Services/client/src/stores/storage.ts b/Services/client/src/stores/storage.ts index 3533435..a975cc8 100644 --- a/Services/client/src/stores/storage.ts +++ b/Services/client/src/stores/storage.ts @@ -1,8 +1,11 @@ import { computed, reactive, ref } from 'vue' import { defineStore } from 'pinia' import { io } from 'socket.io-client' + import api from '@/services/HttpService' +import { useLoader } from './loader' + function constructUrl(path: string | string[], append = true) { const arr = Array.isArray(path) ? path : path.split('/').filter(Boolean) const url = @@ -26,8 +29,10 @@ function constructUrl(path: string | string[], append = true) { : url } -const useStorage = defineStore('storage', async () => { - const folderList = ref< +const useStorage = defineStore('storageStore', () => { + const loader = useLoader() + const init = ref(false) + const folder = ref< Record< string, // path that contains folders { @@ -36,7 +41,7 @@ const useStorage = defineStore('storage', async () => { }[] > >({}) - const fileList = ref< + const file = ref< Record< string, // path that contains files { @@ -61,17 +66,18 @@ const useStorage = defineStore('storage', async () => { pathname: string name: string folder: Structure - file: (typeof fileList.value)[string] + file: (typeof file.value)[string] }[] let structure: Structure = [] // parse list of folder and list of file into tree - Object.entries(folderList.value).forEach(([key, value]) => { + Object.entries(folder.value).forEach(([key, value]) => { const arr = key.split('/').filter(Boolean) // init outer tree if (arr.length === 0) { + if (!init.value) init.value = true structure = value.map((v) => ({ pathname: v.pathname, name: v.name, @@ -97,7 +103,7 @@ const useStorage = defineStore('storage', async () => { folder: [], file: [], })) - current.file = fileList.value[key] ?? [] + current.file = file.value[key] ?? [] } } }) @@ -109,15 +115,18 @@ const useStorage = defineStore('storage', async () => { dept: number }>({ path: '', - dept: 0, + dept: 1, }) + if (!init.value) goto() 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) => + const arr = path.split('/').filter(Boolean) + + if (arr.length >= 4) return // this system does not have more than 4 level + + const res = await api.get<(typeof folder.value)[string]>(constructUrl(arr)) + if (res.status === 200 && res.data && Array.isArray(res.data)) + folder.value[path] = res.data.sort((a, b) => a.pathname.localeCompare(b.pathname), ) } @@ -125,31 +134,34 @@ const useStorage = defineStore('storage', async () => { async function getStorageFile(path: string = '') { const arr = path.split('/').filter(Boolean) - if (arr.length < 3) return + if (arr.length < 3) return // file in this system only lives in level 3 and 4 - const res = await api.get<(typeof fileList.value)[string]>( - constructUrl(path, false) + '/file', + const res = await api.get<(typeof file.value)[string]>( + constructUrl(arr, false) + '/file', ) - if (res.status === 200) - fileList.value[path] = res.data.sort((a, b) => + if (res.status === 200 && res.data && Array.isArray(res.data)) + file.value[path] = res.data.sort((a, b) => a.pathname.localeCompare(b.pathname), ) } - async function goto(path: string) { + async function goto(path: string = '', force = false) { + loader.show() const arr = path.split('/').filter(Boolean) + // get all parent to the root structure for (let i = 0; i < arr.length; i++) { const current = arr.slice(0, i - arr.length).join('/') + '/' - if (!folderList.value[current]) await getStorage(current) + if (!folder.value[current] || force) 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) + if (!folder.value[path] || force) await getStorage(path) + if (!file.value[path] || force) await getStorageFile(path) currentInfo.path = path - currentInfo.dept = path.split('/').filter(Boolean).length - 1 + currentInfo.dept = path.split('/').filter(Boolean).length + loader.hide() } async function gotoParent() { @@ -157,7 +169,8 @@ const useStorage = defineStore('storage', async () => { await goto([...arr.slice(0, -1), ''].join('/')) } - const socket = io('http://localhost:25570') + // socket.io zone + const socket = io('http://localhost:25565') socket.on('connect', () => console.info('Socket.io connected.')) socket.on('disconnect', () => console.info('Socket.io disconnected.')) @@ -165,45 +178,81 @@ const useStorage = defineStore('storage', async () => { const arr = data.pathname.split('/').filter(Boolean) const path = [...arr.slice(0, -1), ''].join('/') - if (folderList.value[path]) { - folderList.value[path].push({ + if (folder.value[path]) { + folder.value[path].push({ pathname: data.pathname, name: arr[arr.length - 1], }) - folderList.value[path].sort((a, b) => - a.pathname.localeCompare(b.pathname), - ) + folder.value[path].sort((a, b) => a.pathname.localeCompare(b.pathname)) + } + }) + // NOTE: + // API planned to make new endpoint that can move and rename in one go. + // Need to change if api handle move and rename file instead of just edit. + socket.on('EditFolder', (data: { from: string; to: string }) => { + const src = data.from.split('/').filter(Boolean) + const dst = data.to.split('/').filter(Boolean) + const path = [...src.slice(0, -1), ''].join('/') + + if (folder.value[path]) { + const val = folder.value[path].find((v) => v.pathname === data.from) + + if (val) { + val.pathname = data.to + val.name = dst[dst.length - 1] + } + } + + for (let key in folder.value) { + if (key.startsWith(data.from)) { + folder.value[key.replace(data.from, data.to)] = folder.value[key].map( + (v) => { + v.pathname = v.pathname.replace(data.from, data.to) + return v + }, + ) + delete folder.value[key] + } } }) - 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] + for (let key in folder.value) { + if (key.startsWith(data.pathname)) { + delete folder.value[key] + } } 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( + if (folder.value[path]) { + folder.value[path] = folder.value[path].filter( (v) => v.pathname !== data.pathname, ) } }) - await goto('เอกสารทดสอบระบบ/dev-test/dev-test/') - console.log(tree.value) + async function createFolder(name: string, path: string = currentInfo.path) { + loader.show() + await api.post(constructUrl(path, true), { name }) + loader.hide() + } + async function editFolder(name: string, path: string) { + loader.show() + await api.put(constructUrl(path), { name }) + loader.hide() + } + async function deleteFolder(path: string) { + loader.show() + await api.delete(constructUrl(path)) + loader.hide() + } return { // information currentInfo, - folderList, - fileList, + folder, + file, tree, // fetch getStorage, @@ -211,6 +260,10 @@ const useStorage = defineStore('storage', async () => { // traverse goto, gotoParent, + // operation + createFolder, + editFolder, + deleteFolder, } })