Skip to content

Commit d2d1fa0

Browse files
committed
chore(storage): add delete action & files preview
1 parent 4fe0349 commit d2d1fa0

File tree

1 file changed

+66
-14
lines changed

1 file changed

+66
-14
lines changed

pages/storage.vue

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,37 @@ function onFileSelect (e) {
5757
const files = [...(target.files || [])]
5858
if (files.length) {
5959
newFileValue.value = files[0]
60-
if (!newFileKey.value.trim()) {
61-
newFileKey.value = files[0].name
62-
}
60+
newFileKey.value = files[0].name
6361
}
6462
6563
// Clear the input value so that the same file can be uploaded again
66-
// target.value = ''
64+
target.value = ''
6765
}
6866
67+
async function deleteFile (key) {
68+
try {
69+
await useFetch(`/api/storage/${key}`, { method: 'DELETE' })
70+
storage.value = storage.value.filter(t => t.key !== key)
71+
toast.add({ title: `File "${key}" deleted.` })
72+
} catch (err) {
73+
if (err.data?.data?.issues) {
74+
const title = err.data.data.issues.map(issue => issue.message).join('\n')
75+
toast.add({ title, color: 'red' })
76+
}
77+
}
78+
}
79+
80+
onMounted(async () => {
81+
// FIXME
82+
// storage.value = await Promise.all(storage.value.map(async (file) => {
83+
// const { data: { body } } = await useFetch(`/api/storage/${file.key}`, { params: { populate: true } })
84+
// return {
85+
// ...file,
86+
// body
87+
// }
88+
// }))
89+
})
90+
6991
const items = [[{
7092
label: 'Logout',
7193
icon: 'i-heroicons-arrow-left-on-rectangle',
@@ -102,28 +124,58 @@ const items = [[{
102124
autofocus
103125
:ui="{ wrapper: 'flex-1' }"
104126
/>
127+
<UInput
128+
:model-value="newFileValue?.name"
129+
name="fileValue"
130+
disabled
131+
class="flex-1"
132+
autocomplete="off"
133+
:ui="{ wrapper: 'flex-1' }"
134+
/>
105135
<input
106136
ref="uploadRef"
107137
tabindex="-1"
108138
accept="jpeg, png"
109139
type="file"
110140
name="file"
111-
class="flex-1"
141+
class="hidden"
112142
@change="onFileSelect"
113143
>
114144
145+
<UButton
146+
label="Select file"
147+
@click="uploadRef.click()"
148+
/>
149+
115150
<UButton type="submit" icon="i-heroicons-plus-20-solid" :loading="loading" :disabled="false" />
116151
</div>
117152
118-
<ul class="divide-y divide-gray-200 dark:divide-gray-800">
119-
<li
120-
v-for="(file, index) of storage"
121-
:key="index"
122-
class="flex items-center gap-4 py-2"
153+
<div class="grid grid-cols-1 md:grid-cols-3 gap-2">
154+
<UCard
155+
v-for="file of storage"
156+
:key="file.key"
157+
:ui="{
158+
body: {
159+
base: 'space-y-0',
160+
padding: ''
161+
}
162+
}"
163+
class="overflow-hidden relative"
123164
>
124-
<span class="flex-1 font-medium">{{ file.key }}</span>
125-
<span class="flex-1 font-medium">{{ file.httpMetadata?.contentType || '-' }}</span>
126-
</li>
127-
</ul>
165+
<img v-if="file.httpMetadata?.contentType?.startsWith('image/') && file.body" :src="`data:${file.httpMetadata.contentType};base64,${(file.body)}`" class="h-36 w-full object-cover">
166+
<div v-else class="h-36 w-full flex items-center justify-center">
167+
{{ file.key }}
168+
</div>
169+
<div class="flex flex-col gap-1 p-2 border-t border-gray-200 dark:border-gray-800">
170+
<span class="text-sm font-medium">{{ file.key }}</span>
171+
<div class="flex items-center justify-between">
172+
<span class="text-xs">{{ file.httpMetadata?.contentType || '-' }}</span>
173+
<span class="text-xs">{{ file.size ? `${Math.round(file.size / Math.pow(1024, 2) * 100) / 100}MB` : '-' }}</span>
174+
</div>
175+
</div>
176+
177+
<UButton icon="i-heroicons-x-mark" variant="link" color="primary" class="absolute top-0 right-0" @click="deleteFile(file.key)" />
178+
</UCard>
179+
</div>
128180
</UCard>
129181
</template>

0 commit comments

Comments
 (0)