Skip to content
Snippets Groups Projects
Verified Commit b15eb74b authored by Daniel Göbel's avatar Daniel Göbel
Browse files

Rework visual loading indication of buckets and objects

#5
parent 53cfdf05
No related branches found
No related tags found
1 merge request!4Display buckets and their objects
This commit is part of merge request !4. Comments created here will be created in the context of that merge request.
......@@ -7,6 +7,7 @@ import fileSize from "filesize";
const props = defineProps<{
active: boolean;
bucket: BucketOut;
loading: boolean;
}>();
const emit = defineEmits<{
......@@ -16,49 +17,57 @@ const emit = defineEmits<{
<template>
<div class="mt-2 mb-2">
<router-link
class="list-group-item list-group-item-action text-nowrap d-flex justify-content-between align-items-center"
:class="{
active: props.active,
rounded: !props.active,
'rounded-top': props.active,
}"
:aria-current="props.active"
:to="{
name: 'bucket',
params: { bucket_name: bucket.name, sub_folders: [] },
}"
>
{{ bucket.name }}
<bootstrap-icon
v-if="props.active"
icon="trash-fill"
:width="16"
:height="16"
fill="white"
@click="emit('delete-bucket', bucket.name)"
/>
</router-link>
<div
:hidden="!props.active"
class="ps-2 rounded-bottom bg-light text-bg-light"
v-if="loading"
class="list-group-item list-group-item-action text-nowrap rounded"
>
<table class="table table-sm table-borderless">
<tbody>
<tr>
<th scope="row" class="fw-bold">Created:</th>
<td>{{ dayjs(bucket.created_at).fromNow() }}</td>
</tr>
<tr>
<th scope="row" class="fw-bold">Objects:</th>
<td>0</td>
</tr>
<tr>
<th scope="row" class="fw-bold">Size:</th>
<td>{{ fileSize(0) }}</td>
</tr>
</tbody>
</table>
<span class="placeholder w-75"></span>
</div>
<div v-else>
<router-link
class="list-group-item list-group-item-action text-nowrap d-flex justify-content-between align-items-center"
:class="{
active: props.active,
rounded: !props.active,
'rounded-top': props.active,
}"
:aria-current="props.active"
:to="{
name: 'bucket',
params: { bucket_name: bucket.name, sub_folders: [] },
}"
>
{{ bucket.name }}
<bootstrap-icon
v-if="props.active"
icon="trash-fill"
:width="16"
:height="16"
fill="white"
@click="emit('delete-bucket', bucket.name)"
/>
</router-link>
<div
:hidden="!props.active"
class="ps-2 rounded-bottom bg-light text-bg-light"
>
<table class="table table-sm table-borderless">
<tbody>
<tr>
<th scope="row" class="fw-bold">Created:</th>
<td>{{ dayjs(bucket.created_at).fromNow() }}</td>
</tr>
<tr>
<th scope="row" class="fw-bold">Objects:</th>
<td>0</td>
</tr>
<tr>
<th scope="row" class="fw-bold">Size:</th>
<td>{{ fileSize(0) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
......
......@@ -34,6 +34,10 @@ watch(
);
const sub_folder_in_url = computed(() => route.params.sub_folders.length > 0);
const error_loading_objects = computed(
() =>
objectState.bucket_permission_error || objectState.bucket_not_found_error
);
onMounted(() => {
update_objects(route.params.bucket_name as string);
......@@ -95,49 +99,64 @@ function update_objects(bucket_name: string) {
</li>
</ol>
</nav>
<div v-if="objectState.loading">
<p aria-hidden="true">
<span class="placeholder col-4"></span>
</p>
</div>
<div v-else-if="objectState.bucket_not_found_error">
<p>Bucket not found</p>
</div>
<div v-else-if="objectState.bucket_permission_error">
<p>No permission for this bucket</p>
<div class="input-group mt-2">
<span class="input-group-text" id="objects-search-wrapping"
><bootstrap-icon icon="search" :width="16" :height="16"
/></span>
<input
type="text"
class="form-control"
placeholder="Search Objects"
aria-label="Search Objects"
aria-describedby="objects-search-wrapping"
disabled
/>
</div>
<div v-else>
<div v-if="objectState.objects.length === 0">
<p>No Objects in this Bucket</p>
<button
type="button"
class="btn btn-secondary m-2"
:disabled="error_loading_objects"
>
<bootstrap-icon icon="upload" :width="16" :height="16" fill="white" />
<span class="visually-hidden">Upload Object</span>
</button>
<button
type="button"
class="btn btn-secondary m-2"
:disabled="error_loading_objects"
>
<bootstrap-icon
icon="person-plus-fill"
:width="16"
:height="16"
fill="white"
/>
<span class="visually-hidden">Add Bucket Permission</span>
</button>
<button
type="button"
class="btn btn-secondary m-2"
:disabled="error_loading_objects"
>
<bootstrap-icon icon="plus-lg" :width="16" :height="16" fill="white" />
Folder
<span class="visually-hidden">Add Folder</span>
</button>
<div class="pt-3">
<div v-if="objectState.bucket_not_found_error">
<p>Bucket not found</p>
</div>
<div v-else-if="objectState.bucket_permission_error">
<p>No permission for this bucket</p>
</div>
<div v-else>
<div class="input-group mt-2">
<span class="input-group-text" id="objects-search-wrapping"
><bootstrap-icon icon="search" :width="16" :height="16"
/></span>
<input
type="text"
class="form-control"
placeholder="Search Objects"
aria-label="Search Objects"
aria-describedby="objects-search-wrapping"
disabled
/>
</div>
<button type="button" class="btn btn-secondary">
<bootstrap-icon icon="upload" :width="16" :height="16" fill="white" />
</button>
<button type="button" class="btn btn-secondary ms-1">
<bootstrap-icon icon="plus-lg" :width="16" :height="16" fill="white" />
Folder
</button>
<table
class="table table-dark table-striped table-hover caption-top align-middle"
>
<caption>
Displaying
{{
objectState.objects.length
objectState.loading ? 0 : objectState.objects.length
}}
Objects
</caption>
......@@ -149,7 +168,17 @@ function update_objects(bucket_name: string) {
<th scope="col"></th>
</tr>
</thead>
<tbody class="table-group-divider">
<tbody v-if="objectState.loading">
<tr v-for="n in 5" :key="n" class="placeholder-glow">
<th scope="row">
<span class="placeholder w-100 bg-secondary"></span>
</th>
<td><span class="placeholder w-50 bg-secondary"></span></td>
<td><span class="placeholder w-50 bg-secondary"></span></td>
<td></td>
</tr>
</tbody>
<tbody v-else>
<tr v-for="obj in objectState.objects" :key="obj.key">
<th scope="row" class="text-truncate">{{ obj.key }}</th>
<td>{{ dayjs(obj.last_modified).fromNow() }}</td>
......
......@@ -60,6 +60,7 @@ onMounted(() => {
@click.stop.prevent="fetchBuckets"
>
<bootstrap-icon icon="arrow-clockwise" />
<span class="visually-hidden">Refresh Buckets</span>
</button>
<button
type="button"
......@@ -68,6 +69,7 @@ onMounted(() => {
data-bs-target="#create-bucket-modal"
>
<bootstrap-icon icon="plus-lg" />
<span class="visually-hidden">Create Bucket</span>
</button>
</div>
<create-bucket-component
......@@ -99,15 +101,18 @@ onMounted(() => {
route.params.bucket_name === bucket.name
"
:bucket="bucket"
:loading="false"
@delete-bucket="deleteBucket"
/>
</div>
<div v-else>
<a
v-for="n in 20"
<bucket-list-item
v-for="n in 5"
:key="n"
class="list-group-item list-group-item-action disabled placeholder-lg-glow m-2 rounded bg-dark"
></a>
:active="false"
:loading="true"
:bucket="{ name: '', description: '', created_at: '', owner: '' }"
></bucket-list-item>
</div>
</div>
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment