Skip to content

Commit

Permalink
format bucket name
Browse files Browse the repository at this point in the history
  • Loading branch information
TimCsaky committed Dec 15, 2023
1 parent 914fce7 commit 07c1988
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 97 deletions.
1 change: 0 additions & 1 deletion frontend/src/components/bucket/BucketConfigForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ const onSubmit = async (values: any) => {
await bucketStore.fetchBuckets({ userId: getUserId.value, objectPerms: true });
// trim trailing "//", if present
// (modifying getBucketPath() instead seems to break nested bucket display [PR-146])
const currBucketPath = getBucketPath(initialValues as Bucket).endsWith('//')
? getBucketPath(initialValues as Bucket).slice(0, -1)
: getBucketPath(initialValues as Bucket);
Expand Down
148 changes: 72 additions & 76 deletions frontend/src/components/bucket/BucketTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,92 +144,88 @@ function createDummyNodes(neighbour: BucketTreeNode, node: BucketTreeNode) {
return current;
}
watch(
getBuckets,
() => {
// Make sure everything is clear for a rebuild
endpointMap.clear();
bucketTreeNodeMap.clear();
expandedKeys.value = {};
// Split buckets into arrays based on endpoint
for (const bucket of getBuckets.value) {
if (!endpointMap.has(`${bucket.endpoint}/${bucket.bucket}`)) {
endpointMap.set(`${bucket.endpoint}/${bucket.bucket}`, new Array<Bucket>());
}
endpointMap.get(`${bucket.endpoint}/${bucket.bucket}`)?.push(bucket);
watch(getBuckets, () => {
// Make sure everything is clear for a rebuild
endpointMap.clear();
bucketTreeNodeMap.clear();
expandedKeys.value = {};
// Split buckets into arrays based on endpoint
for (const bucket of getBuckets.value) {
if (!endpointMap.has(`${bucket.endpoint}/${bucket.bucket}`)) {
endpointMap.set(`${bucket.endpoint}/${bucket.bucket}`, new Array<Bucket>());
}
endpointMap.get(`${bucket.endpoint}/${bucket.bucket}`)?.push(bucket);
}
// Sort arrays by path
for (const i of endpointMap) {
i[1].sort((a: Bucket, b: Bucket) => getBucketPath(a).localeCompare(getBucketPath(b)));
}
// Sort arrays by path
for (const i of endpointMap) {
i[1].sort((a: Bucket, b: Bucket) => getBucketPath(a).localeCompare(getBucketPath(b)));
}
// Build the tree for each endpoint
// First looks for a direct parent node
// If not found it looks for the nearest neighbour to build 'dummy' nodes to mimic a folder hierarchy
// If that somehow fails it adds the node to the root to ensure its still visible
const tree: Array<BucketTreeNode> = [];
for (const col of endpointMap) {
for (const row of col[1]) {
const path = getBucketPath(row);
const parentPath = path.substring(0, path.lastIndexOf('/'));
const parent = bucketTreeNodeMap.get(parentPath);
const node: BucketTreeNode = {
key: getBucketPath(row),
data: { ...row, dummy: false },
children: new Array(),
isRoot: false
};
if (parent) {
parent.children.push(node);
// Build the tree for each endpoint
// First looks for a direct parent node
// If not found it looks for the nearest neighbour to build 'dummy' nodes to mimic a folder hierarchy
// If that somehow fails it adds the node to the root to ensure its still visible
const tree: Array<BucketTreeNode> = [];
for (const col of endpointMap) {
for (const row of col[1]) {
const path = getBucketPath(row);
const parentPath = path.substring(0, path.lastIndexOf('/'));
const parent = bucketTreeNodeMap.get(parentPath);
const node: BucketTreeNode = {
key: getBucketPath(row),
data: { ...row, dummy: false },
children: new Array(),
isRoot: false
};
if (parent) {
parent.children.push(node);
} else {
const neighbour = findNearestNeighbour(node);
if (neighbour) {
createDummyNodes(neighbour, node).children.push(node);
} else {
const neighbour = findNearestNeighbour(node);
if (neighbour) {
createDummyNodes(neighbour, node).children.push(node);
if (node.data.key !== '/') {
// Top level bucket not at root so create dummy hierarchy to reach it
const rootFullPath = `${node.data.endpoint}/${node.data.bucket}//`;
const dummyRootNode: BucketTreeNode = {
key: rootFullPath,
data: {
accessKeyId: '',
active: false,
bucket: node.data.bucket,
bucketId: '',
bucketName: node.data.bucket,
dummy: true,
endpoint: node.data.endpoint,
key: '/',
region: '',
secretAccessKey: ''
},
children: new Array(),
isRoot: true
};
tree.push(dummyRootNode);
bucketTreeNodeMap.set(rootFullPath, dummyRootNode);
createDummyNodes(dummyRootNode, node).children.push(node);
} else {
if (node.data.key !== '/') {
// Top level bucket not at root so create dummy hierarchy to reach it
const rootFullPath = `${node.data.endpoint}/${node.data.bucket}//`;
const dummyRootNode: BucketTreeNode = {
key: rootFullPath,
data: {
accessKeyId: '',
active: false,
bucket: node.data.bucket,
bucketId: '',
bucketName: node.data.bucket,
dummy: true,
endpoint: node.data.endpoint,
key: '/',
region: '',
secretAccessKey: ''
},
children: new Array(),
isRoot: true
};
tree.push(dummyRootNode);
bucketTreeNodeMap.set(rootFullPath, dummyRootNode);
createDummyNodes(dummyRootNode, node).children.push(node);
} else {
node.isRoot = true;
tree.push(node);
}
node.isRoot = true;
tree.push(node);
}
}
bucketTreeNodeMap.set(getBucketPath(node.data), node);
}
bucketTreeNodeMap.set(getBucketPath(node.data), node);
}
}
// Expand all nodes and set tree state
bucketTreeNodeMap.forEach((_v, k) => (expandedKeys.value[k] = true));
treeData.value = tree;
},
{ deep: true }
);
// Expand all nodes and set tree state
bucketTreeNodeMap.forEach((_v, k) => (expandedKeys.value[k] = true));
treeData.value = tree;
});
</script>

<template>
Expand Down
23 changes: 4 additions & 19 deletions frontend/src/components/bucket/BucketTableBucketName.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { RouteNames } from '@/utils/constants';
import { getBucketPath, getLastSegment } from '@/utils/utils';
import type { BucketTreeNode } from '@/types';
Expand All @@ -14,29 +15,13 @@ const props = withDefaults(defineProps<Props>(), {});
<template>
<span v-if="props.node.data.dummy">
{{ props.node.data.bucketName }}
<span
v-if="node.isRoot"
class="bucket-subtext pl-1"
>
{{ node.data.bucket }}
</span>
</span>
<span v-else>
<router-link :to="{ name: RouteNames.LIST_OBJECTS, query: { bucketId: props.node.data.bucketId } }">
{{ node.data.bucketName }}
{{ props.node.data.bucketName }}
</router-link>
<span
v-if="node.isRoot"
class="bucket-subtext pl-2"
>
{{ node.data.bucket }}
<span class="bucket-subtext pl-2 text-xs">
{{ getLastSegment(getBucketPath(props.node.data)) }}
</span>
</span>
</template>

<style scoped lang="scss">
.bucket-subtext {
font-size: small;
color: gray;
}
</style>
1 change: 0 additions & 1 deletion frontend/src/store/bucketStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export const useBucketStore = defineStore('bucket', () => {
appStore.beginIndeterminateLoading();
return await bucketService.createBucketChild(parentBucketId, subKey, bucketName);
} finally {
state.buckets.value.push();
appStore.endIndeterminateLoading();
}
}
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,14 @@ export function setDispositionHeader(filename: string) {
export function getBucketPath(bucket: Bucket): string {
return `${bucket.endpoint}/${bucket.bucket}/${bucket.key}`;
}

/**
* @function getLastSegment
* Returns the last segment of a path, ignoring trailing slashes
* @param {string} path full path (eg: http://abc.com/bucket/)
* @returns {string} last segment of a path (eg: bucket)
*/
export function getLastSegment(path: string) {
const p = path.replace(/\/+$/, '');
return p.slice(p.lastIndexOf('/') + 1);
}

0 comments on commit 07c1988

Please sign in to comment.