diff --git a/src/components/BucketListItem.vue b/src/components/BucketListItem.vue index a8ba47b02a04ba7b708997a563b9b0aa82757638..dd79c9aeb8c70aa38233fff123ab22041007c102 100644 --- a/src/components/BucketListItem.vue +++ b/src/components/BucketListItem.vue @@ -1,6 +1,7 @@ <script setup lang="ts"> -import type { BucketOut } from "@/client"; +import type { BucketOut, BucketPermission } from "@/client"; import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import PermissionModal from "@/components/PermissionModal.vue"; import dayjs from "dayjs"; import fileSize from "filesize"; import { onMounted } from "vue"; @@ -10,6 +11,7 @@ const props = defineProps<{ active: boolean; bucket: BucketOut; loading: boolean; + permission: BucketPermission | undefined; }>(); const tooltipID = Math.random().toString(16).substr(2, 8); @@ -26,6 +28,16 @@ onMounted(() => { </script> <template> + <permission-modal + v-if="props.permission != null" + :modalID="'view-permission-modal' + tooltipID" + modal-label="view-permission-modal-label" + :bucket-name="props.bucket.name" + :sub-folders="{ subFolders: {}, files: [] }" + :edit-user-permission="props.permission" + :readonly="true" + :editable="false" + /> <div class="mt-2 mb-2"> <div v-if="loading" @@ -49,11 +61,12 @@ onMounted(() => { > {{ bucket.name }} <bootstrap-icon - v-if="props.active" + v-if="props.active && props.permission == null" icon="trash-fill" + class="delete-icon" :width="16" :height="16" - fill="white" + fill="currentColor" @click="emit('delete-bucket', bucket.name)" /> </router-link> @@ -85,6 +98,17 @@ onMounted(() => { <th scope="row" class="fw-bold">Size:</th> <td>{{ fileSize(0) }}</td> </tr> + <tr v-if="props.permission != null"> + <th scope="row" class="fw-bold">Permission</th> + <td> + <a + href="#" + data-bs-toggle="modal" + :data-bs-target="'#view-permission-modal' + tooltipID" + >View</a + > + </td> + </tr> </tbody> </table> </div> @@ -92,4 +116,11 @@ onMounted(() => { </div> </template> -<style scoped></style> +<style scoped> +.delete-icon { + color: white; +} +.delete-icon:hover { + color: var(--bs-danger); +} +</style> diff --git a/src/components/BucketView.vue b/src/components/BucketView.vue index 4e09fa38bc6a2efc5b4b5cb7add31c81df1a0511..21fe2c3b41167d857ea99ae65ee74a922380225c 100644 --- a/src/components/BucketView.vue +++ b/src/components/BucketView.vue @@ -1,7 +1,7 @@ <script setup lang="ts"> import { onMounted, reactive, watch, computed } from "vue"; import type { ComputedRef } from "vue"; -import type { S3ObjectMetaInformation } from "@/client"; +import type { S3ObjectMetaInformation, BucketPermission } from "@/client"; import { ObjectService } from "@/client"; import BootstrapIcon from "@/components/BootstrapIcon.vue"; import fileSize from "filesize"; @@ -15,6 +15,7 @@ import PermissionModal from "@/components/PermissionModal.vue"; const props = defineProps<{ bucketName: string; subFolders: string[] | string; + permission: BucketPermission | undefined; }>(); // Typescript types @@ -340,6 +341,7 @@ watch( </button> <!-- Add bucket permission button --> <button + v-if="props.permission == null" type="button" class="btn btn-secondary m-2" :disabled="errorLoadingObjects" @@ -360,6 +362,7 @@ watch( :bucket-name="props.bucketName" :sub-folders="folderStructure" :edit-user-permission="undefined" + :editable="false" :readonly="false" /> <!-- Add folder button --> diff --git a/src/components/PermissionModal.vue b/src/components/PermissionModal.vue index 56c607cbe7aa738e6ecec50a00e739d5f5f00b59..9adb360302c3b135c8d2d8c055727d2594715a97 100644 --- a/src/components/PermissionModal.vue +++ b/src/components/PermissionModal.vue @@ -34,6 +34,7 @@ const props = defineProps<{ subFolders: FolderTree; editUserPermission: BucketPermission | undefined; readonly: boolean; + editable: boolean; }>(); // Variables @@ -221,6 +222,7 @@ function formSubmit() { onMounted(() => { createPermissionModal = new Modal("#" + props.modalID); successToast = new Toast("#" + "toast-" + toastID, { autohide: true }); + updatePermission(); }); </script> @@ -256,8 +258,14 @@ onMounted(() => { :modal-label="modalLabel" v-on="{ 'hidden.bs.modal': modalClosed }" > - <template v-slot:header> Create new Permission </template> - <template v-slot:extra-button v-if="formState.readonly"> + <template v-slot:header v-if="formState.readonly" + >View Permission + </template> + <template v-slot:header v-else-if="props.editUserPermission != null" + >Edit Permission + </template> + <template v-slot:header v-else> Create new Permission </template> + <template v-slot:extra-button v-if="formState.readonly && props.editable"> <bootstrap-icon icon="pencil-fill" :height="15" diff --git a/src/views/object-storage/BucketsView.vue b/src/views/object-storage/BucketsView.vue index a3ae113cf64b4c0afa37b9f34af27dfcdbe2a98e..ba6c70b883a1c8b15c02c0d217fa42e6ff122c3b 100644 --- a/src/views/object-storage/BucketsView.vue +++ b/src/views/object-storage/BucketsView.vue @@ -1,5 +1,6 @@ <script setup lang="ts"> -import { onMounted, reactive } from "vue"; +import { onMounted, reactive, computed } from "vue"; +import type { ComputedRef } from "vue"; import type { BucketOut, BucketPermission } from "@/client"; import { BucketService, BucketPermissionsService } from "@/client"; import { useRoute, useRouter } from "vue-router"; @@ -43,6 +44,12 @@ function fetchBuckets() { } } +const currentPermission: ComputedRef<BucketPermission | undefined> = computed( + () => { + return bucketsState.permissions[route.params.bucketName as string]; + } +); + function addBucket(bucket: BucketOut) { bucketsState.buckets.push(bucket); } @@ -117,6 +124,7 @@ onMounted(() => { " :bucket="bucket" :loading="false" + :permission="bucketsState.permissions[bucket.name]" @delete-bucket="deleteBucket" /> </div> @@ -126,13 +134,14 @@ onMounted(() => { :key="n" :active="false" :loading="true" + :permission="undefined" :bucket="{ name: '', description: '', created_at: '', owner: '' }" ></bucket-list-item> </div> </div> </div> <div class="col-9"> - <router-view></router-view> + <router-view :permission="currentPermission"></router-view> </div> </div> </template>