diff --git a/src/components/BucketView.vue b/src/components/BucketView.vue index 3e5e844f61fd1db7c620edb51d09a52803164881..9444ecac83397a3ce8ab8ea42489c32809f06c49 100644 --- a/src/components/BucketView.vue +++ b/src/components/BucketView.vue @@ -114,16 +114,25 @@ type FolderTree = { // Reactive State // ----------------------------------------------------------------------------- + +const deleteObjectsState = reactive({ + deletedItem: "", + potentialObjectToDelete: "", + deleteFolder: true, +} as { + deletedItem: string; + potentialObjectToDelete: string; + deleteFolder: boolean; +}); + const objectState = reactive({ objects: [], loading: true, + filterString: "", bucketNotFoundError: false, bucketPermissionError: false, createdPermission: undefined, - deletedItem: "", editObjectKey: "", - potentialObjectToDelete: "", - deleteFolder: true, copyObject: { key: "", size: 0, @@ -139,13 +148,11 @@ const objectState = reactive({ } as { objects: S3ObjectMetaInformation[]; loading: boolean; + filterString: string; bucketNotFoundError: boolean; bucketPermissionError: boolean; createdPermission: undefined | BucketPermission; - deletedItem: string; editObjectKey: string; - potentialObjectToDelete: string; - deleteFolder: boolean; copyObject: S3ObjectMetaInformation; viewDetailObject: S3ObjectMetaInformation; }); @@ -164,6 +171,15 @@ watch( // Computed Properties // ----------------------------------------------------------------------------- +const filteredObjects: ComputedRef<(S3ObjectWithFolder | S3PseudoFolder)[]> = + computed(() => { + return objectState.filterString.length > 0 + ? visibleObjects.value.filter((obj) => + obj.key.includes(objectState.filterString) + ) + : visibleObjects.value; + }); + const folderStructure: ComputedRef<FolderTree> = computed(() => { /** * Store the entire folder structure in a bucket in a tree-like data structure @@ -394,8 +410,8 @@ function objectCopied(copiedObject: S3ObjectMetaInformation) { } function deleteObject(key: string) { - objectState.potentialObjectToDelete = key; - objectState.deleteFolder = false; + deleteObjectsState.potentialObjectToDelete = key; + deleteObjectsState.deleteFolder = false; } /** @@ -411,7 +427,7 @@ function confirmedDeleteObject(key: string) { .send(command) .then(() => { const splittedKey = key.split("/"); - objectState.deletedItem = splittedKey[splittedKey.length - 1]; + deleteObjectsState.deletedItem = splittedKey[splittedKey.length - 1]; successToast?.show(); objectState.objects = objectState.objects.filter( (obj) => obj.key !== key @@ -443,8 +459,8 @@ async function downloadObject(key: string, bucket: string) { } function deleteFolder(folderPath: string) { - objectState.potentialObjectToDelete = folderPath; - objectState.deleteFolder = true; + deleteObjectsState.potentialObjectToDelete = folderPath; + deleteObjectsState.deleteFolder = true; } /** @@ -466,7 +482,7 @@ function confirmedDeleteFolder(folderPath: string) { .send(command) .then(() => { const splittedPath = folderPath.split("/"); - objectState.deletedItem = splittedPath[splittedPath.length - 2]; + deleteObjectsState.deletedItem = splittedPath[splittedPath.length - 2]; successToast?.show(); objectState.objects = objectState.objects.filter( (obj) => !obj.key.startsWith(folderPath) @@ -510,7 +526,7 @@ watch( > <div class="d-flex"> <div class="toast-body"> - Successfully deleted {{ objectState.deletedItem }} + Successfully deleted {{ deleteObjectsState.deletedItem }} </div> <button type="button" @@ -524,12 +540,12 @@ watch( <DeleteModal modalID="delete-object-modal" modal-label="some-label" - :object-name-delete="objectState.potentialObjectToDelete" + :object-name-delete="deleteObjectsState.potentialObjectToDelete" :back-modal-id="undefined" @confirm-delete=" - objectState.deleteFolder - ? confirmedDeleteFolder(objectState.potentialObjectToDelete) - : confirmedDeleteObject(objectState.potentialObjectToDelete) + deleteObjectsState.deleteFolder + ? confirmedDeleteFolder(deleteObjectsState.potentialObjectToDelete) + : confirmedDeleteObject(deleteObjectsState.potentialObjectToDelete) " /> <!-- Navbar Breadcrumb --> @@ -581,7 +597,7 @@ watch( placeholder="Search Objects" aria-label="Search Objects" aria-describedby="objects-search-wrapping" - disabled + v-model.trim="objectState.filterString" /> </div> </div> @@ -727,8 +743,8 @@ watch( <td></td> </tr> </tbody> - <!-- Table body when no objects are in the bcuket --> - <tbody v-else-if="visibleObjects.length === 0"> + <!-- Table body when no objects are in the bucket --> + <tbody v-else-if="filteredObjects.length === 0"> <tr> <td colspan="4" class="text-center fst-italic fw-light"> No objects to display @@ -737,7 +753,7 @@ watch( </tbody> <!-- Table body when showing objects --> <tbody v-else> - <tr v-for="obj in visibleObjects" :key="obj.key"> + <tr v-for="obj in filteredObjects" :key="obj.key"> <th scope="row" class="text-truncate"> <!-- Show file name if row is an object --> <div v-if="isS3Object(obj)">{{ obj.pseudoFileName }}</div>