zip file (errors)
This commit is contained in:
@ -1,165 +1,206 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full w-full border">
|
||||
<!-- ... -->
|
||||
<div class="overflow-y-auto">
|
||||
<div v-for="(file, index) in sortedFiles" :key="file.fullPath" class="flex flex-col">
|
||||
<div
|
||||
class="flex items-center pl-4 cursor-pointer"
|
||||
@click="toggleFolder(file)"
|
||||
v-if="file.isDirectory"
|
||||
draggable="true"
|
||||
@dragstart="onDragStart(file, $event)"
|
||||
>
|
||||
<div class="w-5/6 flex items-center px-4 py-2 truncate">
|
||||
<span class="mr-2">{{ folderMap[file.fullPath] ? '-' : '+' }}</span>
|
||||
{{ file.fullPath }}
|
||||
</div>
|
||||
<div class="w-1/6 px-4 py-2">-</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center pl-4"
|
||||
v-else
|
||||
draggable="true"
|
||||
@dragstart="onDragStart(file, $event)"
|
||||
>
|
||||
<div class="w-5/6 flex items-center px-4 py-2 truncate">
|
||||
{{ file.fullPath }}
|
||||
</div>
|
||||
<div class="w-1/6 px-4 py-2">
|
||||
{{ formatFileSize(file.size) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSZip from 'jszip';
|
||||
|
||||
export default {
|
||||
name: 'WebContentViewer',
|
||||
data() {
|
||||
return {
|
||||
zipContent: [],
|
||||
pathTable: [],
|
||||
folderMap: {}, // Map to track folder open/close state
|
||||
};
|
||||
},
|
||||
props: {
|
||||
zipUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
sortedFiles() {
|
||||
const flattenAndSort = (files, parentPath = '') => {
|
||||
const flatList = [];
|
||||
files.forEach(file => {
|
||||
const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
|
||||
|
||||
// Toujours ajouter le dossier parent
|
||||
flatList.push({
|
||||
...file,
|
||||
fullPath,
|
||||
parentPath,
|
||||
});
|
||||
|
||||
// Ajouter les enfants uniquement si le dossier est ouvert
|
||||
if (file.isDirectory && this.folderMap[fullPath] && file.children) {
|
||||
flatList.push(...flattenAndSort(file.children, fullPath));
|
||||
}
|
||||
});
|
||||
|
||||
return flatList.sort((a, b) => a.fullPath.localeCompare(b.fullPath));
|
||||
};
|
||||
|
||||
|
||||
return flattenAndSort(this.zipContent);
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
await this.loadZipContent();
|
||||
const webTransferDiv = document.getElementById('archiveInfos');
|
||||
if (webTransferDiv) {
|
||||
this.archiveUrl = webTransferDiv.dataset.archiveUrl;
|
||||
this.token = webTransferDiv.dataset.token;
|
||||
} else {
|
||||
console.error('Pas d\'informations pour recuperer l\'archive');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadZipContent() {
|
||||
try {
|
||||
const response = await fetch(this.zipUrl);
|
||||
const zipData = await response.blob();
|
||||
const zip = await JSZip.loadAsync(zipData);
|
||||
|
||||
const files = [];
|
||||
zip.forEach((relativePath, file) => {
|
||||
const pathParts = relativePath.split('/').filter(Boolean);
|
||||
|
||||
let currentLevel = files;
|
||||
for (let i = 0; i < pathParts.length; i++) {
|
||||
const partName = pathParts[i];
|
||||
const isDirectory = i < pathParts.length - 1 || file.dir;
|
||||
let existing = currentLevel.find(f => f.name === partName && f.isDirectory === isDirectory);
|
||||
|
||||
if (!existing) {
|
||||
existing = {
|
||||
name: partName,
|
||||
isDirectory,
|
||||
size: isDirectory ? 0 : file._data.uncompressedSize,
|
||||
children: isDirectory ? [] : null,
|
||||
file: file,
|
||||
};
|
||||
currentLevel.push(existing);
|
||||
}
|
||||
|
||||
if (isDirectory) {
|
||||
currentLevel = existing.children;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.zipContent = files;
|
||||
|
||||
// Initialize folderMap
|
||||
const initializeFolderMap = (files, parentPath = '') => {
|
||||
files.forEach(file => {
|
||||
const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
|
||||
this.$set(this.folderMap, fullPath, false);
|
||||
if (file.isDirectory && file.children) {
|
||||
initializeFolderMap(file.children, fullPath);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
initializeFolderMap(this.zipContent);
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du chargement du contenu du ZIP :', error);
|
||||
}
|
||||
},
|
||||
formatFileSize(size) {
|
||||
if (size < 1024) return `${size} B`;
|
||||
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
|
||||
if (size < 1024 * 1024 * 1024) return `${(size / 1024 / 1024).toFixed(2)} MB`;
|
||||
return `${(size / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
||||
},
|
||||
toggleFolder(file) {
|
||||
if (!file.isDirectory) return;
|
||||
const currentState = this.folderMap[file.fullPath];
|
||||
this.$set(this.folderMap, file.fullPath, !currentState);
|
||||
},
|
||||
onDragStart(file, event) {
|
||||
// Sauvegarder l'objet du fichier dans l'événement
|
||||
event.dataTransfer.setData('file', JSON.stringify(file.file));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Ajoutez ici des styles si nécessaire */
|
||||
</style>
|
||||
<template>
|
||||
<div class="flex flex-col h-full w-full border">
|
||||
<div class="flex h-12 items-center border-b border-gray-300">
|
||||
<div class="w-4/6 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">Nom</div>
|
||||
<div class="w-2/6 px-4 py-2 text-gray-500 font-semibold">Taille</div>
|
||||
</div>
|
||||
<div class="overflow-y-auto">
|
||||
<div v-for="(file, index) in sortedFiles" :key="file.fullPath" class="flex flex-col">
|
||||
|
||||
<div
|
||||
class="flex h-16 hover:bg-NcGray items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300"
|
||||
@click="toggleFolder(file)"
|
||||
v-if="file.isDirectory"
|
||||
draggable="true"
|
||||
@dragstart="onDragStart(file, $event)"
|
||||
>
|
||||
<div class="w-4/6 flex items-center py-2 border-r border-gray-300 cursor-pointer">
|
||||
<div class="w-12 h-12 flex items-center justify-center cursor-pointer">
|
||||
<template>
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" class="text-NcBlue w-10 h-10 ">
|
||||
<path
|
||||
d="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z">
|
||||
</path>
|
||||
</svg>
|
||||
</template>
|
||||
</div>
|
||||
<div class="w-4/6 flex items-center py-2 border-r border-gray-300 cursor-pointer">
|
||||
<!-- Icône dynamique pour plié/déplié -->
|
||||
<div class="w-12 h-12 flex items-center justify-center cursor-pointer">
|
||||
<component
|
||||
:is="folderMap[file.fullPath] ? ChevronDownIcon : ChevronRightIcon"
|
||||
class="text-NcBlue w-6 h-6"
|
||||
/>
|
||||
</div>
|
||||
<span class="ml-2 truncate cursor-pointer">{{ file.fullPath }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/6 px-4 py-2 cursor-pointer">-</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex h-16 hover:bg-NcGray items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300"
|
||||
v-else
|
||||
draggable="true"
|
||||
@dragstart="onDragStart(file, $event)"
|
||||
>
|
||||
<template>
|
||||
<div class="flex items-center justify-center cursor-pointer">
|
||||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
|
||||
class="w-10 h-10"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
|
||||
<path
|
||||
d="M6 22c-.55 0-1.021-.196-1.412-.587A1.927 1.927 0 0 1 4 20V4c0-.55.196-1.021.588-1.413A1.926 1.926 0 0 1 6 2h8l6 6v12a1.93 1.93 0 0 1-.587 1.413A1.93 1.93 0 0 1 18 22H6Z"
|
||||
style="fill:#969696;fill-rule:nonzero" transform="matrix(.7 0 0 .7 -.43 -.388)" />
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-4/6 flex items-center px-4 py-2 truncate cursor-pointer">
|
||||
{{ file.fullPath }}
|
||||
</div>
|
||||
<div class="w-2/6 py-2 cursor-pointer">
|
||||
{{ formatFileSize(file.size) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSZip from 'jszip';
|
||||
import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue';
|
||||
import ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'WebContentViewer',
|
||||
data() {
|
||||
return {
|
||||
zipContent: [],
|
||||
pathTable: [],
|
||||
folderMap: {}, // Map to track folder open/close state
|
||||
archiveUrl: '',
|
||||
token: '',
|
||||
ChevronRightIcon,
|
||||
ChevronDownIcon,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
zipUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
sortedFiles() {
|
||||
const flattenAndSort = (files, parentPath = '') => {
|
||||
const flatList = [];
|
||||
files.forEach(file => {
|
||||
const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
|
||||
|
||||
// Toujours ajouter le dossier parent
|
||||
flatList.push({
|
||||
...file,
|
||||
fullPath,
|
||||
parentPath,
|
||||
});
|
||||
|
||||
// Ajouter les enfants uniquement si le dossier est ouvert
|
||||
if (file.isDirectory && this.folderMap[fullPath] && file.children) {
|
||||
flatList.push(...flattenAndSort(file.children, fullPath));
|
||||
}
|
||||
});
|
||||
|
||||
return flatList.sort((a, b) => a.fullPath.localeCompare(b.fullPath));
|
||||
};
|
||||
|
||||
|
||||
return flattenAndSort(this.zipContent);
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
await this.loadZipContent();
|
||||
const webTransferDiv = document.getElementById('archiveInfos');
|
||||
if (webTransferDiv) {
|
||||
this.archiveUrl = webTransferDiv.dataset.archiveUrl;
|
||||
this.token = webTransferDiv.dataset.token;
|
||||
} else {
|
||||
console.error('Pas d\'informations pour recuperer l\'archive');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadZipContent() {
|
||||
try {
|
||||
const response = await fetch(this.zipUrl);
|
||||
const zipData = await response.blob();
|
||||
const zip = await JSZip.loadAsync(zipData);
|
||||
|
||||
const files = [];
|
||||
zip.forEach((relativePath, file) => {
|
||||
const pathParts = relativePath.split('/').filter(Boolean);
|
||||
|
||||
let currentLevel = files;
|
||||
for (let i = 0; i < pathParts.length; i++) {
|
||||
const partName = pathParts[i];
|
||||
const isDirectory = i < pathParts.length - 1 || file.dir;
|
||||
let existing = currentLevel.find(f => f.name === partName && f.isDirectory === isDirectory);
|
||||
|
||||
if (!existing) {
|
||||
existing = {
|
||||
name: partName,
|
||||
isDirectory,
|
||||
size: isDirectory ? 0 : file._data.uncompressedSize,
|
||||
children: isDirectory ? [] : null,
|
||||
file: file,
|
||||
};
|
||||
currentLevel.push(existing);
|
||||
}
|
||||
|
||||
if (isDirectory) {
|
||||
currentLevel = existing.children;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.zipContent = files;
|
||||
|
||||
// Initialize folderMap
|
||||
const initializeFolderMap = (files, parentPath = '') => {
|
||||
files.forEach(file => {
|
||||
const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
|
||||
this.$set(this.folderMap, fullPath, false);
|
||||
if (file.isDirectory && file.children) {
|
||||
initializeFolderMap(file.children, fullPath);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
initializeFolderMap(this.zipContent);
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du chargement du contenu du ZIP :', error);
|
||||
}
|
||||
},
|
||||
formatFileSize(size) {
|
||||
if (size < 1024) return `${size} B`;
|
||||
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
|
||||
if (size < 1024 * 1024 * 1024) return `${(size / 1024 / 1024).toFixed(2)} MB`;
|
||||
return `${(size / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
||||
},
|
||||
toggleFolder(file) {
|
||||
if (!file.isDirectory) return;
|
||||
const currentState = this.folderMap[file.fullPath];
|
||||
this.$set(this.folderMap, file.fullPath, !currentState);
|
||||
},
|
||||
onDragStart(file, event) {
|
||||
// Sauvegarder l'objet du fichier dans l'événement
|
||||
event.dataTransfer.setData('file', JSON.stringify(file.file));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Ajoutez ici des styles si nécessaire */
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user