Skip to content

Commit

Permalink
feat(assets): tree view for list mode (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
arashsheyda authored Jul 19, 2023
1 parent 92dfd21 commit 57b9ca5
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 16 deletions.
61 changes: 46 additions & 15 deletions packages/devtools/client/components/AssetListItem.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,63 @@
<script setup lang="ts">
import type { AssetInfo } from '~/../src/types'
const props = defineProps<{
asset: AssetInfo
}>()
const props = withDefaults(defineProps<{
item: any
index?: number
modelValue: AssetInfo | undefined
}>(), {
index: 0,
})
const emit = defineEmits<{ (...args: any): void }>()
const model = useVModel(props, 'modelValue', emit, { passive: true })
const isCollection = computed(() => props.item?.children?.length)
const open = ref(true)
const icon = computed(() => {
if (props.asset.type === 'image')
if (isCollection.value)
return 'i-carbon-folder'
if (props.item.type === 'image')
return 'i-carbon-image'
if (props.asset.type === 'video')
if (props.item.type === 'video')
return 'i-carbon-video'
if (props.asset.type === 'audio')
if (props.item.type === 'audio')
return 'i-carbon-volume-up'
if (props.asset.type === 'font')
if (props.item.type === 'font')
return 'i-carbon-text-small-caps'
if (props.asset.type === 'text')
if (props.item.type === 'text')
return 'i-carbon-document'
if (props.asset.type === 'json')
if (props.item.type === 'json')
return 'i-carbon-json'
return 'i-carbon-document-blank'
})
</script>

<template>
<button flex="~ gap-1" w-full items-center hover="bg-active" rounded px4 py2>
<div :class="icon" />
<div of-hidden truncate ws-nowrap text-center>
{{ asset.path }}
</div>
</button>
<div>
<button
flex="~ gap-2" w-full items-center hover="bg-active" px4 py1
:style="{ paddingLeft: `calc(1rem + ${index * 1.5}em)` }"
:class="{ 'bg-active': !isCollection && model?.filePath === item?.filePath }"
@click="isCollection ? open = !open : model = item"
>
<div :class="icon" />
<span :class="{ 'flex items-center': isCollection }" flex-auto text-start text-sm font-mono>
{{ item.path }}
</span>
<NIcon v-if="isCollection" icon="carbon:chevron-right" :transform-rotate="open ? 90 : 0" transition />
</button>
<div x-divider />
<slot v-if="open">
<AssetListItem
v-for="subItem in item?.children"
:key="subItem.filepath"
v-model="model"
:item="subItem"
:index="index + 1"
/>
</slot>
</div>
</template>
32 changes: 31 additions & 1 deletion packages/devtools/client/pages/modules/assets.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,32 @@ const byFolders = computed(() => {
return Object.entries(result).sort(([a], [b]) => a.localeCompare(b))
})
const byTree = computed(() => {
const root = { path: 'public', children: [] }
const addToTree = (node: any, pathParts: any, file: AssetInfo) => {
const [currentPart, ...remainingParts] = pathParts
let child = node.children.find((child: any) => child.path === currentPart)
if (!child) {
child = { ...file, path: currentPart, children: [] }
node.children.push(child)
}
if (remainingParts.length > 1)
addToTree(child, remainingParts, file)
else if (remainingParts.length === 1)
child.children.push({ ...file, path: remainingParts[0] })
}
filtered.value.forEach((file) => {
const pathParts = file.path.split('/').filter(part => part !== '')
addToTree(root, pathParts, file)
})
return root.children
})
const selected = ref<AssetInfo>()
const view = ref<'list' | 'grid'>('grid')
Expand Down Expand Up @@ -95,7 +121,11 @@ function refreshAssets() {}
</div>
</template>
<div v-else>
<AssetListItem v-for="a of filtered" :key="a.path" :asset="a" @click="selected = a" />
<AssetListItem
v-for="item, key of byTree" :key="key"
v-model="selected"
:item="item"
/>
</div>
<DrawerRight
:model-value="!!selected"
Expand Down

0 comments on commit 57b9ca5

Please sign in to comment.