PHP Classes

File: resources/js/Components/Bucket/FileManager.vue

Recommend this page to a friend!
  Classes of Nyi Nyi Lwin   S3 B2B PHP Amazon S3 File Manager   resources/js/Components/Bucket/FileManager.vue   Download  
File: resources/js/Components/Bucket/FileManager.vue
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: S3 B2B PHP Amazon S3 File Manager
Manage files stored in multiple Amazon S3 buckets
Author: By
Last change:
Date: 9 months ago
Size: 10,060 bytes
 

Contents

Class file image Download
<script setup> import { ref, watch, onMounted } from "vue"; import route from "ziggy-js"; import axios from "axios"; import Folder from "@components/Bucket/Partials/Folder.vue"; import File from "@components/Bucket/Partials/File.vue"; import OptionMenu from "@components/Bucket/Partials/OptionMenu.vue"; import BucketForm from "@components/Bucket/Form/BucketForm.vue"; import SlideOver from "@components/UI/SlideOver.vue"; import DeleteModal from "@components/Bucket/Modals/DeleteModal.vue"; import { DialogTitle } from "@headlessui/vue"; import { ExclamationCircleIcon } from "@heroicons/vue/24/outline/index.js"; import FileUploadModal from "@components/Bucket/Modals/FileUploadModal.vue"; import { CloudArrowUpIcon, HomeIcon, FolderPlusIcon } from "@heroicons/vue/20/solid/index.js"; import NewFolderModal from "@components/Bucket/Modals/NewFolderModal.vue"; const props = defineProps({ bucket: { type: Object, default: () => {} }, folderCols: { type: [Number, String], default: '6', }, fileCols: { type: [Number, String], default: '4', }, hideMenu: { type: Boolean, default: false, }, height: { type: String, default: 'screen', }, }); const emit = defineEmits(['currentFolder', 'deleted']); const storage = ref({ current: { path: '/', name: 'root', }, files: [], folders: [], breadcrumbs: [], }); const loading = ref(false); const showBucketEditForm = ref(false); const openBucketDeleteModal = ref(false); const openFileUploadModal = ref(false); const openNewFolderModal = ref(false); const loadData = async (path = '/') => { loading.value = true; document.body.style.cursor = 'wait'; try { const { data } = await axios.get(route('buckets.files', { bucket: props.bucket.id, path, })); storage.value = data; } catch (error) { console.error(error); } finally { document.body.style.cursor = 'default'; loading.value = false; } emit('currentFolder', storage.value.current); }; watch(() => props.bucket, () => { loadData(); }); const setupWebSocketListeners = () => { const fileEventsChannel = Echo.channel('file-events'); fileEventsChannel.listen('FileMovedEvent', (event) => { loadData(storage.value.current.path); }); }; onMounted(() => { emit('currentFolder', storage.value.current); loadData(); setupWebSocketListeners(); }); </script> <template> <!-- Bucket Edit Form --> <SlideOver v-if="!hideMenu" :show="showBucketEditForm" @close="showBucketEditForm = false" > <BucketForm :url="route('buckets.update', { bucket: props.bucket.id })" :title="$t('buckets.form.edit.title')" :description="$t('buckets.form.edit.description')" :bucket="props.bucket" edit @cancel="showBucketEditForm = false" @saved="showBucketEditForm = false" /> </SlideOver> <!-- Bucket Delete Modal --> <DeleteModal v-if="!hideMenu" :open="openBucketDeleteModal" :delete-url="route('buckets.destroy', { bucket: bucket.id })" @close="openBucketDeleteModal = false" @deleted="emit('deleted')" > <div class="bg-white p-4 "> <div class="text-center sm:text-left"> <DialogTitle as="h3" class="text-base font-semibold leading-6 text-gray-900" > {{ $t('modals.delete_title') }} </DialogTitle> <div class="mt-3"> <p class="text-sm text-gray-500"> {{ $t('modals.delete_bucket') }} </p> </div> <div class="inline-flex gap-2 mt-3"> <ExclamationCircleIcon class="w-5 h-5 text-gray-500" /> <p class="text-sm text-gray-500"> {{ bucket.name }} </p> </div> </div> </div> </DeleteModal> <!-- File Upload Modal --> <FileUploadModal v-if="!loading" :open="openFileUploadModal" :upload-url="route('buckets.files.upload', { bucket: props.bucket.id, path: storage.current.path, })" @uploaded="loadData(storage.current.path)" @close="openFileUploadModal = false" /> <!-- New Folder Modal --> <NewFolderModal v-if="!loading" :open="openNewFolderModal" :current-path="storage.current.path" :create-url="route('buckets.folders.create', { bucket: props.bucket.id, })" @created="loadData(storage.current.path)" @close="openNewFolderModal = false" /> <div class="bg-white relative"> <div class="flex gap-3 items-center justify-between sticky top-0 bg-gray-100 divided-x"> <!-- Breadcrumbs --> <div class="px-5 py-3 overflow-x-auto"> <nav class="flex" aria-label="Breadcrumb" > <ol role="list" class="flex items-center space-x-1" > <li v-if="storage.breadcrumbs.length < 1" @click="loadData('/')" > <div> <span class="text-gray-400 hover:text-gray-500 cursor-pointer"> <HomeIcon class="h-5 w-5 flex-shrink-0" aria-hidden="true" /> <span class="sr-only">Home</span> </span> </div> </li> <li v-for="(breadcrumb, index) in storage.breadcrumbs" v-else :key="index" > <div v-if="breadcrumb.name === 'root'"> <span class="text-gray-400 hover:text-gray-500 cursor-pointer" @click="loadData(breadcrumb.path)" > <HomeIcon class="h-5 w-5 flex-shrink-0" aria-hidden="true" /> <span class="sr-only">Home</span> </span> </div> <div v-else class="flex items-center" > <svg class="h-5 w-5 flex-shrink-0 text-gray-300" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true" > <path d="M5.555 17.776l8-16 .894.448-8 16-.894-.448z" /> </svg> <span class="ml-1 text-sm font-medium text-gray-500 hover:text-gray-700 cursor-pointer" @click="loadData(breadcrumb.path)" > {{ breadcrumb.name }} </span> </div> </li> <li> <div class="flex items-center"> <svg class="h-5 w-5 flex-shrink-0 text-gray-300" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true" > <path d="M5.555 17.776l8-16 .894.448-8 16-.894-.448z" /> </svg> <span v-if="storage.current.path !== '/'" class="ml-1 text-sm font-medium text-gray-500 hover:text-gray-700 cursor-pointer" @click="loadData(storage.current.path)" > {{ storage.current.name }} </span> </div> </li> </ol> </nav> </div> <!-- Menu --> <div v-if="!hideMenu" class="px-5 flex gap-3 items-center divide-x" > <div :class="['text-gray-700', 'flex px-2 py-2 text-sm', 'cursor-pointer']" @click="openNewFolderModal = true" > <FolderPlusIcon class="mr-1.5 h-5 w-5 text-gray-400" aria-hidden="true" /> <span> {{ $t('buttons.new_folder') }} </span> </div> <div :class="['text-gray-700', 'flex px-2 py-2 text-sm', 'cursor-pointer']" @click="openFileUploadModal = true" > <CloudArrowUpIcon class="mr-1.5 h-5 w-5 text-gray-400" aria-hidden="true" /> <span> {{ $t('buttons.upload') }} </span> </div> <OptionMenu class="pt-2" hide-move hide-upload hide-view @edit="showBucketEditForm = true" @delete="openBucketDeleteModal = true" /> </div> </div> <div class="overflow-y-auto px-5 py-3 space-y-5" :class="[`h-${height}`]" > <!-- Folder List --> <div v-if="storage.folders.length" class="space-y-2" > <span class="font-semibold text-md"> {{ $t('file_manager.folders') }} </span> <div :class="['grid gap-2', folderCols]"> <div v-for="(folder, index) in storage.folders" :key="index" @dblclick="loadData(folder.path)" > <Folder :bucket="bucket" :folder="folder" :hide-menu="hideMenu" @deleted="loadData(storage.current.path)" @moved="loadData(storage.current.path)" /> </div> </div> </div> <!-- File List --> <div v-if="storage.files.length" class="space-y-2" > <span class="font-semibold text-md"> {{ $t('file_manager.files') }} </span> <div :class="['grid gap-2', fileCols]"> <div v-for="(file, index) in storage.files" :key="index" class="text-sm text-gray-700" > <File :file="file" :bucket="bucket" :hide-menu="hideMenu" @deleted="loadData(storage.current.path)" @moved="loadData(storage.current.path)" @renamed="loadData(storage.current.path)" /> </div> </div> </div> </div> </div> </template> <style scoped> </style>