191 lines
5.9 KiB
TypeScript
191 lines
5.9 KiB
TypeScript
import type { Document } from '@/repositories/Document';
|
|
import { fetchFile } from '@/repositories/Document'
|
|
import { formatSize, formatUnixDate } from '@/utils';
|
|
import { defineStore } from 'pinia';
|
|
import { localeIncludes } from 'locale-includes'
|
|
|
|
type FileData = { id: string, mtime: number, size: number, dir: DirectoryData};
|
|
type DirectoryData = {
|
|
[filename: string]: FileData;
|
|
};
|
|
export type FileStructure = {id: string, mtime: number, size: number, dir: DirectoryData};
|
|
type User = {
|
|
isOpenLoginModal: boolean,
|
|
isLoggedIn : boolean,
|
|
}
|
|
|
|
export type DocumentStore = {
|
|
root: FileStructure,
|
|
document: Document[],
|
|
loading: boolean,
|
|
uploadingDocuments: Array<{key: number, name: string, progress: number}>,
|
|
uploadCount: number,
|
|
wsWatch: WebSocket | undefined,
|
|
wsUpload: WebSocket | undefined,
|
|
selectedDocuments: Document[],
|
|
user: User,
|
|
error: string,
|
|
}
|
|
|
|
export const useDocumentStore = defineStore({
|
|
id: 'documents',
|
|
state: (): DocumentStore => ({
|
|
root: {} as FileStructure,
|
|
document: [] as Document[],
|
|
loading: true as boolean,
|
|
uploadingDocuments: [],
|
|
uploadCount: 0 as number,
|
|
wsWatch: undefined,
|
|
wsUpload: undefined,
|
|
selectedDocuments: [] as Document[],
|
|
error: '' as string,
|
|
user: { isLoggedIn: false, isOpenLoginModal: false } as User
|
|
}),
|
|
|
|
actions: {
|
|
updateTable(matched: DirectoryData) {
|
|
// Transform data
|
|
const dataMapped = []
|
|
for (const [name, attr] of Object.entries(matched)) {
|
|
const {id, size, mtime, dir} = attr
|
|
const element: Document = {
|
|
name,
|
|
key: id,
|
|
size,
|
|
sizedisp: formatSize(size),
|
|
mtime,
|
|
modified: formatUnixDate(mtime),
|
|
type: dir === undefined ? 'folder-file' : 'folder',
|
|
}
|
|
dataMapped.push(element)
|
|
}
|
|
// Pre sort directory entries folders first then files, names in natural ordering
|
|
dataMapped.sort((a, b) => a.type === b.type ? a.name.localeCompare(b.name) : a.type === "folder" ? -1 : 1)
|
|
this.document = dataMapped
|
|
this.loading = false;
|
|
},
|
|
setFilter(filter: string){
|
|
function traverseDir(data: FileStructure, path: string){
|
|
if (data.dir === undefined) return
|
|
for (const [name, attr] of Object.entries(data.dir)) {
|
|
const fullname = `${path}/${name}`
|
|
if (localeIncludes(name, filter, {usage: "search", sensitivity: "base"})) {
|
|
matched[fullname.slice(1)] = attr // No initial slash on name
|
|
}
|
|
traverseDir(attr, fullname)
|
|
}
|
|
}
|
|
this.loading = true
|
|
const matched = {}
|
|
traverseDir(this.root, "")
|
|
this.updateTable(matched)
|
|
},
|
|
setActualDocument(location: string){
|
|
location = decodeURIComponent(location)
|
|
this.loading = true
|
|
let data = this.root
|
|
const actualDirArr = []
|
|
try {
|
|
// Navigate to target folder
|
|
for (const dirname of location.split('/').slice(1)) {
|
|
if (!dirname) continue
|
|
actualDirArr.push(dirname)
|
|
data = data.dir[dirname]
|
|
}
|
|
} catch (error) {
|
|
console.error("Cannot show requested folder", location, actualDirArr.join('/'), error)
|
|
}
|
|
if (data.dir === undefined) {
|
|
// Target folder not available
|
|
this.document = []
|
|
this.loading = false // ???
|
|
return
|
|
}
|
|
this.updateTable(data.dir)
|
|
},
|
|
async setActualDocumentFile(path: string){
|
|
this.loading = true;
|
|
const file = await fetchFile(path)
|
|
this.document = [file];
|
|
this.loading = false;
|
|
},
|
|
setSelectedDocuments(document: Document[]){
|
|
this.selectedDocuments = document
|
|
},
|
|
deleteDocument(document: Document){
|
|
this.document = this.document.filter(e => document.key !== e.key)
|
|
this.selectedDocuments = this.selectedDocuments.filter(e => document.key !== e.key)
|
|
},
|
|
updateUploadingDocuments(key: number, progress: number){
|
|
for (const d of this.uploadingDocuments) {
|
|
if(d.key === key) d.progress = progress
|
|
}
|
|
},
|
|
pushUploadingDocuments(name: string){
|
|
this.uploadCount++;
|
|
const document = {
|
|
key: this.uploadCount,
|
|
name: name,
|
|
progress: 0
|
|
}
|
|
this.uploadingDocuments.push(document)
|
|
return document
|
|
},
|
|
deleteUploadingDocument(key: number){
|
|
this.uploadingDocuments = this.uploadingDocuments.filter((e)=> e.key !== key)
|
|
},
|
|
getNextDocumentInRoute(direction: number, path: string){
|
|
const locations = path.split('/').slice(1)
|
|
locations.pop()
|
|
let data = this.root
|
|
const actualDirArr = []
|
|
// Get data target location
|
|
locations.forEach(location => {
|
|
// location = decodeURIComponent(location)
|
|
if(data && data.dir){
|
|
for (const key in data.dir) {
|
|
if(key === location) data = data.dir[key]
|
|
}
|
|
}
|
|
})
|
|
//Store in a temporary array
|
|
for (const key in data.dir) {
|
|
actualDirArr.push({
|
|
name: key,
|
|
content: data.dir[key]
|
|
})
|
|
}
|
|
const actualFileName = decodeURIComponent(this.mainDocument[0].name).split('/').pop()
|
|
let index = actualDirArr.findIndex(e => e.name === actualFileName)
|
|
|
|
if(index < 1 && direction === -1 ){
|
|
index = actualDirArr.length -1
|
|
}else if(index >= actualDirArr.length - 1 && direction === 1){
|
|
index = 0
|
|
}else {
|
|
index = index + direction
|
|
}
|
|
return actualDirArr[index].name
|
|
},
|
|
updateModified() {
|
|
for (const d of this.document) {
|
|
if ("mtime" in d) d.modified = formatUnixDate(d.mtime)
|
|
}
|
|
},
|
|
},
|
|
getters: {
|
|
mainDocument(): Document[] {
|
|
return this.document;
|
|
},
|
|
rootSize(): number | undefined {
|
|
if(this.root) return this.root.size
|
|
},
|
|
rootMain(): DirectoryData | undefined {
|
|
if(this.root) return this.root.dir
|
|
},
|
|
isUserLogged(): boolean{
|
|
return this.user.isLoggedIn
|
|
}
|
|
},
|
|
});
|