PronounsPage/app/components/admin/AdminStorageTree.vue
Valentyne Stigloher 10180aa6a3 (refactor) use #shared alias instead of ~~/shared
the #shared alias used by Nuxt cannot be easily disabled and to prevent breackage with jiti, we make use of it
2025-08-17 18:56:02 +02:00

60 lines
1.6 KiB
Vue

<script setup lang="ts">
import { formatSize } from '#shared/helpers.ts';
type Tree = Map<string, Tree | number>;
const props = defineProps<{
itemKey: string;
tree: Tree;
}>();
const chunk = computed(() => props.itemKey.replace(/^.+:/, ''));
const isOpen = ref(false);
const sumSize = (tree: Tree): number => {
return [...tree.values()].map((node) => {
if (node instanceof Map) {
return sumSize(node);
}
return node;
})
.reduce((sum, size) => sum + size, 0);
};
</script>
<template>
<details @toggle="isOpen = $event.newState === 'open'">
<summary>
<span class="py-1 d-inline-flex justify-content-between">
<code>{{ chunk }}</code>
<span>
<span class="badge text-bg-info">{{ formatSize(sumSize(tree)) }}</span>
</span>
</span>
</summary>
<div v-if="isOpen" class="ps-2 border-start border-secondary">
<template v-for="[childChunk, childNode] of tree.entries()" :key="childChunk">
<AdminStorageTree
v-if="childNode instanceof Map"
:item-key="`${itemKey}:${childChunk}`"
:tree="childNode"
/>
<AdminStorageItem
v-else
:item-key="`${itemKey}:${childChunk}`"
:size="childNode"
/>
</template>
</div>
</details>
</template>
<style scoped lang="scss">
@import 'assets/variables';
summary > span {
width: calc(100% - #{$spacer});
}
</style>