laravel-vue-file-share/resources/js/Pages/RecycleBin.vue
2023-10-17 22:45:04 -07:00

221 lines
8.2 KiB
Vue

<script setup>
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue";
import { router, Link } from "@inertiajs/vue3";
import FileIcon from "@/Components/custom/FileIcon.vue";
import Checkbox from "@/Components/Checkbox.vue";
import { ref, computed } from "vue";
import RestoreButton from "@/Components/custom/RestoreButton.vue";
import DeleteButton from "@/Components/custom/DeleteButton.vue";
import { faRecycle } from "@fortawesome/free-solid-svg-icons";
import MainBreadcrumbButton from "@/Components/custom/MainBreadcrumbButton.vue";
// defines refs
const allSelected = ref(false);
const fileSelectedStatus = ref({});
// defines props
const { files } = defineProps({
files: Object,
folder: Object,
ancestors: Array,
});
// defines computed properties
// gets a formatted array of all currently-selected files
const currentlySelected = computed(() => {
// casts the ref object of currently selected files to array
// { id: bool } becomes [id, bool]
let array = Object.entries(fileSelectedStatus.value);
// filters array for all the id's in [id, bool] where bool === true
array = array.filter((idBool) => idBool[1]);
// maps filtered array from [id, bool] to [id]
array = array.map((idBool) => idBool[0]);
// returns
return array;
});
// selects all files
const selectAll = () => {
files.data.forEach((file) => {
// set each fileSelectedStatus value to the value of allSelected
fileSelectedStatus.value[file.id] = allSelected.value;
});
};
// selects file
const selectFile = (file) => {
// get current value
const currentValue = fileSelectedStatus.value[file.id];
// invert
const newValue = !currentValue;
// set file's value
fileSelectedStatus.value[file.id] = newValue;
// if new value is negative, disable allSelected
if (!newValue) {
allSelected.value = false;
} else {
// else check if this "completes" the selection of all files in folder
let isallSelected = true;
files.data.forEach((entry) => {
// get current value at id
const status = fileSelectedStatus.value[entry.id];
// if the fileSelectedStatus value at id is falsy, set isallSelected to false
if (!status) isallSelected = false;
});
// update allSelected value
allSelected.value = isallSelected;
}
};
// opens folder when clicked
const openFolder = (file) => {
if (!file.is_folder) {
return;
}
router.visit(
route("recycleBin", {
folder: file.id,
})
);
};
</script>
<template>
<AuthenticatedLayout>
<nav class="flex items-center justify-between mb-2">
<ol class="inline-flex items-center">
<MainBreadcrumbButton
:href="route('recycleBin')"
:active="$page.url === '/recycle-bin'"
class="flex items-center justify-center"
>
<font-awesome-icon
:icon="faRecycle"
class="h-5 w-5"
aria-hidden="true"
/>
</MainBreadcrumbButton>
<li
v-if="ancestors"
v-for="(ancestor, index) of ancestors.data"
:key="ancestor.id"
class="inline-flex items-center"
>
<div class="flex items-center" v-if="ancestor.parent_id">
<div class="mx-2">&#x27A4;</div>
<Link
v-if="index == ancestors.data.length - 1"
class="border-sky-600 border px-3 py-2 rounded bg-sky-600"
:href="route('sharedBy', { folder: ancestor.id })"
>
{{ ancestor.name }}
</Link>
<Link
v-else
class="border-gray-700 border px-3 py-2 rounded hover:border-sky-600"
:href="route('sharedBy', { folder: ancestor.id })"
>
{{ ancestor.name }}
</Link>
</div>
</li>
</ol>
<div class="flex gap-4">
<RestoreButton
:restoreall="allSelected"
:selected="currentlySelected"
/>
<DeleteButton
:getall="allSelected"
:selected="currentlySelected"
/>
</div>
</nav>
<div class="overflow-auto h-full w-full" v-if="files.data.length">
<table class="w-full border-separate">
<colgroup>
<col />
<col />
<col />
<col />
</colgroup>
<thead>
<tr class="sticky top-0 z-20">
<th class="p-3 rounded bg-zinc-600 rounded font-medium">
<Checkbox
v-model:checked="allSelected"
@change="selectAll()"
/>
</th>
<th
class="py-3 px-1 rounded bg-zinc-600 rounded font-medium"
>
Name
</th>
<th
class="py-3 px-1 rounded bg-zinc-600 rounded font-medium"
>
Recycled
</th>
<th
class="py-3 px-1 rounded bg-zinc-600 rounded font-medium"
>
Size
</th>
</tr>
</thead>
<tbody>
<tr
v-for="file of files.data"
:key="file.id"
@dblclick="openFolder(file)"
>
<td
class="text-center whitespace-nowrap border-gray-700 border rounded hover:border-sky-600 hover:ring-sky-600 w-12"
@click="selectFile(file)"
>
<Checkbox
:checked="fileSelectedStatus[file.id]"
:v-model="
fileSelectedStatus[file.id] || allSelected
"
/>
</td>
<td
class="py-3 px-1 text-center whitespace-nowrap border-gray-700 border rounded hover:border-sky-600 hover:ring-sky-600 flex items-center justify-center relative"
>
<span
class="absolute left-0 bg-zinc-900 w-11 h-10 pl-1"
>
<FileIcon :file="file" />
</span>
<span class="pl-10 pr-10 overflow-auto">
{{ file.name }}
</span>
</td>
<td
class="py-3 px-1 text-center whitespace-nowrap border-gray-700 border rounded hover:border-sky-600 hover:ring-sky-600"
>
{{ file.deleted_at }}
</td>
<td
class="py-3 px-1 text-center whitespace-nowrap border-gray-700 border rounded hover:border-sky-600 hover:ring-sky-600"
>
{{ file.size }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="h-full" v-else>
<div
class="flex flex-col items-center justify-center h-full text-3xl"
>
This folder is empty
</div>
</div>
</AuthenticatedLayout>
</template>