035c49f675
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
96 lines
2.6 KiB
Vue
96 lines
2.6 KiB
Vue
<template>
|
|
<v-card class="fc-danger-zone mt-8" variant="outlined">
|
|
<v-card-title class="d-flex align-center" style="gap: 10px;">
|
|
<v-icon icon="mdi-alert-octagon" color="error" size="small" />
|
|
<span>Danger zone</span>
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<p class="text-body-2 fc-muted mb-4">
|
|
Cascade-delete this artist and every image, source, post, and
|
|
attachment associated with them. This cannot be undone.
|
|
Recoverable only from an FC-3h backup.
|
|
</p>
|
|
<v-btn
|
|
color="error" variant="flat" rounded="pill"
|
|
prepend-icon="mdi-delete-forever"
|
|
:loading="loading"
|
|
@click="onClick"
|
|
>Delete artist & cascade</v-btn>
|
|
|
|
<DestructiveConfirmModal
|
|
v-model="modalOpen"
|
|
action="delete"
|
|
kind="artist"
|
|
:run-id="artistId"
|
|
tier="C"
|
|
:projected-counts="projectedCounts"
|
|
:description="modalDescription"
|
|
@confirm="onConfirm"
|
|
/>
|
|
</v-card-text>
|
|
</v-card>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
|
|
import DestructiveConfirmModal from '../modal/DestructiveConfirmModal.vue'
|
|
import { useAdminStore } from '../../stores/admin.js'
|
|
|
|
const props = defineProps({
|
|
slug: { type: String, required: true },
|
|
artistId: { type: Number, required: true },
|
|
artistName: { type: String, required: true },
|
|
})
|
|
|
|
const router = useRouter()
|
|
const store = useAdminStore()
|
|
const loading = ref(false)
|
|
const modalOpen = ref(false)
|
|
const projected = ref(null)
|
|
|
|
const projectedCounts = computed(() => projected.value?.projected || null)
|
|
|
|
const modalDescription = computed(
|
|
() => projected.value
|
|
? `Artist “${props.artistName}” — `
|
|
+ `${projected.value.projected.images} images, `
|
|
+ `${projected.value.projected.sources} sources, `
|
|
+ `${Math.round(projected.value.projected.bytes_on_disk / 1_048_576)} MiB on disk`
|
|
: '',
|
|
)
|
|
|
|
async function onClick() {
|
|
loading.value = true
|
|
try {
|
|
projected.value = await store.projectArtistCascade(props.slug)
|
|
modalOpen.value = true
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function onConfirm(token) {
|
|
loading.value = true
|
|
try {
|
|
const result = await store.dispatchArtistCascade(props.slug, token)
|
|
const taskId = result.task_id
|
|
router.push('/artists')
|
|
if (taskId) {
|
|
store.pollTaskUntilDone(taskId).catch(() => {})
|
|
}
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.fc-danger-zone {
|
|
border-color: rgb(var(--v-theme-error));
|
|
border-radius: 8px;
|
|
}
|
|
.fc-muted { color: rgb(var(--v-theme-on-surface-variant)); }
|
|
</style>
|