Files
RenewCMS/web/src/components/BulkDeleteMediaDialog.vue
T

85 lines
2.6 KiB
Vue

<script setup lang="ts">
import { t } from '@/i18n'
import { computed } from 'vue'
import ConfirmDialog from '@/components/ConfirmDialog.vue'
import MediaBadge from '@/components/MediaBadge.vue'
import type { MediaItem } from '@/composables/useMedia'
import { pluralArticles } from '@/lib/mediaFormat'
const BROKEN_IMAGE = 'which will show a broken image.'
const FINAL_WARNING = "This can't be undone."
const props = defineProps<{
items: MediaItem[]
action: () => Promise<void | boolean>
}>()
const emit = defineEmits<{ close: [confirmed: boolean] }>()
const total = computed(() => props.items.length)
const imageLabel = computed(() => t(total.value === 1 ? '{0} image' : '{0} images', [total.value]))
const inUse = computed(() => props.items.filter((item) => item.used_in > 0))
const articleCount = computed(() => inUse.value.reduce((sum, item) => sum + item.used_in, 0))
const description = computed(() => {
const usedCount = inUse.value.length
const unusedCount = total.value - usedCount
const articles = pluralArticles(articleCount.value)
if (usedCount === 0) {
return total.value === 1
? t("It isn't used in any article. {0}", [t(FINAL_WARNING)])
: t('None of them are used in any article. {0}', [t(FINAL_WARNING)])
}
if (unusedCount === 0) {
const subject = total.value === 1 ? t("It's") : t('All {0} are', [total.value])
return t('{0} used in {1}, {2} {3}', [subject, articles, t(BROKEN_IMAGE), t(FINAL_WARNING)])
}
const rest =
unusedCount === 1
? t("The other one isn't used anywhere.")
: t("The other {0} aren't used anywhere.", [unusedCount])
return t('{0} of them are used in {1}, {2} {3} {4}', [
usedCount,
articles,
t(BROKEN_IMAGE),
rest,
t(FINAL_WARNING),
])
})
</script>
<template>
<ConfirmDialog
:title="t('Delete {0}?', [imageLabel])"
:description="description"
:confirm-label="t('Delete {0}', [imageLabel])"
:cancel-label="t('Cancel')"
:pending-label="t('Deleting…')"
tone="danger"
:action="action"
@close="emit('close', $event)"
>
<template #body>
<ul class="border border-default">
<li
v-for="(item, index) in items"
:key="item.id"
data-testid="bulk-delete-row"
class="flex min-h-9 items-center gap-2 px-3"
:class="{ 'border-t border-muted': index > 0 }"
>
<span class="min-w-0 flex-1 truncate text-highlighted">{{
item.filename
}}</span>
<MediaBadge
v-if="item.used_in > 0"
kind="used"
:label="t('Used in {0}', [item.used_in])"
/>
<MediaBadge v-else kind="unused" :label="t('Unused')" />
</li>
</ul>
</template>
</ConfirmDialog>
</template>