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

Improve bucket overview to show more information

#67
parent c93cba1c
No related branches found
No related tags found
2 merge requests!84Remove development branch,!62Resolve "UI improvements"
Pipeline #37918 passed
...@@ -13,6 +13,7 @@ import { computed, onMounted } from "vue"; ...@@ -13,6 +13,7 @@ import { computed, onMounted } from "vue";
import { Tooltip } from "bootstrap"; import { Tooltip } from "bootstrap";
import { useBucketStore } from "@/stores/buckets"; import { useBucketStore } from "@/stores/buckets";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useAuthStore } from "@/stores/users";
const props = defineProps<{ const props = defineProps<{
active: boolean; active: boolean;
...@@ -23,6 +24,7 @@ const props = defineProps<{ ...@@ -23,6 +24,7 @@ const props = defineProps<{
const randomIDSuffix = Math.random().toString(16).substring(2, 8); const randomIDSuffix = Math.random().toString(16).substring(2, 8);
const permissionRepository = useBucketStore(); const permissionRepository = useBucketStore();
const userRepository = useAuthStore();
const router = useRouter(); const router = useRouter();
const permission = computed<BucketPermissionOut | undefined>( const permission = computed<BucketPermissionOut | undefined>(
...@@ -41,6 +43,8 @@ function permissionDeleted(perm: BucketPermissionIn) { ...@@ -41,6 +43,8 @@ function permissionDeleted(perm: BucketPermissionIn) {
onMounted(() => { onMounted(() => {
if (!props.loading) { if (!props.loading) {
new Tooltip("#tooltip-" + randomIDSuffix); new Tooltip("#tooltip-" + randomIDSuffix);
new Tooltip("#ownBucketIcon-" + randomIDSuffix);
new Tooltip("#sharedBucketIcon-" + randomIDSuffix);
} }
}); });
</script> </script>
...@@ -86,8 +90,44 @@ onMounted(() => { ...@@ -86,8 +90,44 @@ onMounted(() => {
params: { bucketName: bucket.name, subFolders: [] }, params: { bucketName: bucket.name, subFolders: [] },
}" }"
> >
<span class="text-truncate" style="width: 80%">{{ bucket.name }}</span> <span class="text-truncate flex-grow-3">
<div> <template v-if="bucket.owner_constraint === 'READ'"
>Upload Bucket</template
>
<template v-else-if="bucket.owner_constraint === 'WRITE'"
>Download Bucket</template
>
<template v-else>{{ bucket.name }}</template>
</span>
<div class="text-nowrap">
<font-awesome-icon
:hidden="bucket.owner !== userRepository.currentUID"
:id="'ownBucketIcon-' + randomIDSuffix"
icon="fa-solid fa-user"
:class="{
'me-2':
props.active ||
permission ||
(
permissionRepository.bucketPermissionsMapping[bucket.name] ??
[]
).length > 0,
}"
data-bs-toogle="tooltip"
data-bs-title="Own Bucket"
/>
<font-awesome-icon
:hidden="
!permission &&
(permissionRepository.bucketPermissionsMapping[bucket.name] ?? [])
.length === 0
"
:id="'sharedBucketIcon-' + randomIDSuffix"
icon="fa-solid fa-users"
:class="{ 'me-2': props.active }"
data-bs-toogle="tooltip"
data-bs-title="Shared Bucket"
/>
<font-awesome-icon <font-awesome-icon
v-if="props.active && !permission && props.deletable" v-if="props.active && !permission && props.deletable"
icon="fa-solid fa-trash" icon="fa-solid fa-trash"
...@@ -111,7 +151,7 @@ onMounted(() => { ...@@ -111,7 +151,7 @@ onMounted(() => {
<table class="table table-sm table-borderless mb-0"> <table class="table table-sm table-borderless mb-0">
<tbody> <tbody>
<tr v-if="permission"> <tr v-if="permission">
<th scope="row" class="fw-bold">Permission</th> <th scope="row" class="fw-bold">Permission:</th>
<td> <td>
<a <a
href="#" href="#"
...@@ -121,6 +161,30 @@ onMounted(() => { ...@@ -121,6 +161,30 @@ onMounted(() => {
> >
</td> </td>
</tr> </tr>
<tr v-if="permission">
<th scope="row" class="fw-bold">Owner:</th>
<td class="text-truncate">
{{ userRepository.userMapping[bucket.owner] }}
</td>
</tr>
<tr
v-if="
(
permissionRepository.bucketPermissionsMapping[bucket.name] ??
[]
).length > 0
"
>
<th scope="row" class="fw-bold">Permissions:</th>
<td>
<a
href="#"
data-bs-toggle="modal"
data-bs-target="#permission-list-modal"
>View</a
>
</td>
</tr>
<tr> <tr>
<th scope="row" class="fw-bold">Created:</th> <th scope="row" class="fw-bold">Created:</th>
<td> <td>
...@@ -156,12 +220,15 @@ onMounted(() => { ...@@ -156,12 +220,15 @@ onMounted(() => {
.delete-icon { .delete-icon {
color: white; color: white;
} }
.delete-icon:hover { .delete-icon:hover {
color: var(--bs-danger) !important; color: var(--bs-danger) !important;
} }
.info-icon { .info-icon {
color: white; color: white;
} }
.info-icon:hover { .info-icon:hover {
color: var(--bs-info) !important; color: var(--bs-info) !important;
} }
......
...@@ -28,7 +28,17 @@ export const useBucketStore = defineStore({ ...@@ -28,7 +28,17 @@ export const useBucketStore = defineStore({
}, },
getters: { getters: {
buckets(): BucketOut[] { buckets(): BucketOut[] {
return Object.values(this.bucketMapping); const tempList = Object.values(this.bucketMapping);
tempList.sort((bucketA, bucketB) => {
if (bucketA.owner_constraint) {
return -1;
}
if (bucketB.owner_constraint) {
return 1;
}
return bucketA.name > bucketB.name ? 1 : -1;
});
return tempList;
}, },
ownBucketsAndFullPermissions(): string[] { ownBucketsAndFullPermissions(): string[] {
const authStore = useAuthStore(); const authStore = useAuthStore();
...@@ -143,6 +153,12 @@ export const useBucketStore = defineStore({ ...@@ -143,6 +153,12 @@ export const useBucketStore = defineStore({
for (const bucket of buckets) { for (const bucket of buckets) {
this.bucketMapping[bucket.name] = bucket; this.bucketMapping[bucket.name] = bucket;
} }
const userRepository = useAuthStore();
userRepository.fetchUsernames(
buckets
.map((bucket) => bucket.owner)
.filter((owner) => owner != userRepository.currentUID),
);
return buckets; return buckets;
}) })
.finally(onFinally); .finally(onFinally);
......
...@@ -103,7 +103,7 @@ onMounted(() => { ...@@ -103,7 +103,7 @@ onMounted(() => {
class="btn btn-light border shadow-sm" class="btn btn-light border shadow-sm"
data-bs-title="Refresh Data Buckets" data-bs-title="Refresh Data Buckets"
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
@click.stop.prevent="refreshBuckets" @click="refreshBuckets"
> >
<font-awesome-icon <font-awesome-icon
icon="fa-solid fa-arrow-rotate-right" icon="fa-solid fa-arrow-rotate-right"
......
...@@ -9,13 +9,8 @@ import { Toast, Tooltip } from "bootstrap"; ...@@ -9,13 +9,8 @@ import { Toast, Tooltip } from "bootstrap";
const authStore = useAuthStore(); const authStore = useAuthStore();
authStore.$onAction(({ name, args }) => {
if (name === "updateUser") {
refreshKeys(args[0].uid);
}
});
let successToast: Toast | null = null; let successToast: Toast | null = null;
let refreshTimeout: NodeJS.Timeout | undefined = undefined;
const keyState = reactive<{ const keyState = reactive<{
keys: S3Key[]; keys: S3Key[];
...@@ -31,8 +26,8 @@ const keyState = reactive<{ ...@@ -31,8 +26,8 @@ const keyState = reactive<{
const allowKeyDeletion = computed<boolean>(() => keyState.keys.length > 1); const allowKeyDeletion = computed<boolean>(() => keyState.keys.length > 1);
function refreshKeys(uid: string) { function fetchKeys() {
S3KeyService.s3KeyGetUserKeys(uid) S3KeyService.s3KeyGetUserKeys(authStore.currentUID)
.then((keys) => { .then((keys) => {
if (keyState.activeKey >= keys.length) { if (keyState.activeKey >= keys.length) {
keyState.activeKey = keys.length - 1; keyState.activeKey = keys.length - 1;
...@@ -40,7 +35,16 @@ function refreshKeys(uid: string) { ...@@ -40,7 +35,16 @@ function refreshKeys(uid: string) {
keyState.keys = keys; keyState.keys = keys;
}) })
.catch((err) => console.error(err)) .catch((err) => console.error(err))
.finally(() => (keyState.initialLoading = false)); .finally(() => {
keyState.initialLoading = false;
});
}
function refreshKeys() {
clearTimeout(refreshTimeout);
refreshTimeout = setTimeout(() => {
fetchKeys();
}, 500);
} }
function deleteKey(accessKey: string) { function deleteKey(accessKey: string) {
...@@ -75,7 +79,7 @@ function createKey() { ...@@ -75,7 +79,7 @@ function createKey() {
onMounted(() => { onMounted(() => {
successToast = new Toast("#successKeyToast"); successToast = new Toast("#successKeyToast");
if (authStore.authenticated) { if (authStore.authenticated) {
refreshKeys(authStore.currentUID); fetchKeys();
} }
new Tooltip("#createS3KeyButton"); new Tooltip("#createS3KeyButton");
new Tooltip("#refreshS3KeysButton"); new Tooltip("#refreshS3KeysButton");
...@@ -118,7 +122,7 @@ onMounted(() => { ...@@ -118,7 +122,7 @@ onMounted(() => {
id="refreshS3KeysButton" id="refreshS3KeysButton"
data-bs-title="Refresh S3 Keys" data-bs-title="Refresh S3 Keys"
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
@click="refreshKeys(authStore.currentUID)" @click="refreshKeys()"
> >
<font-awesome-icon <font-awesome-icon
icon="fa-solid fa-arrow-rotate-right" icon="fa-solid fa-arrow-rotate-right"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment