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

94 lines
2.3 KiB
Vue

<script setup lang="ts">
import { t } from '@/i18n'
import { computed, ref } from 'vue'
import ConfirmDialog from '@/components/ConfirmDialog.vue'
import type { MediaItem } from '@/composables/useMedia'
import { isValidFilenameStem, splitFilename } from '@/lib/mediaFormat'
const INVALID_FILENAME_MESSAGE = 'Enter a filename.'
const props = defineProps<{
item: MediaItem
action: (stem: string) => Promise<void>
}>()
const emit = defineEmits<{ close: [confirmed: boolean] }>()
const parts = splitFilename(props.item.filename)
const stem = ref(parts.stem)
const touched = ref(false)
const error = computed(() =>
touched.value && !isValidFilenameStem(stem.value) ? t(INVALID_FILENAME_MESSAGE) : undefined,
)
const help = computed(() =>
t('Letters, numbers, dashes and underscores. The {0} ending stays.', [parts.extension]),
)
async function submit() {
touched.value = true
if (!isValidFilenameStem(stem.value)) {
return false
}
await props.action(stem.value.trim())
}
</script>
<template>
<ConfirmDialog
:title="t('Rename image')"
:description="
t(
'Only the filename changes. The URL stays the same, so articles that use this image keep working.',
)
"
:confirm-label="t('Rename')"
:cancel-label="t('Cancel')"
:pending-label="t('Renaming…')"
tone="neutral"
:action="submit"
@close="emit('close', $event)"
>
<template #body="{ pending, confirm }">
<form class="flex flex-col" novalidate @submit.prevent="confirm">
<UFormField
:label="t('Filename')"
name="filename"
:error="error"
:help="help"
:ui="{
error: 'mt-1.5 text-xs/5',
help: 'mt-1.5 text-xs/5',
}"
>
<template v-if="error" #error="{ error: message }">
<span class="flex items-center gap-1.5">
<UIcon
name="i-lucide-circle-alert"
class="size-3.5 shrink-0 text-error"
/>
{{ message }}
</span>
</template>
<UInput
v-model="stem"
autocomplete="off"
:disabled="pending"
class="w-full"
:highlight="!!error"
:ui="{ base: 'h-11 text-lg md:h-10 md:text-base' }"
@blur="touched = true"
>
<template #trailing>
<span class="font-mono text-base text-muted">{{
parts.extension
}}</span>
</template>
</UInput>
</UFormField>
</form>
</template>
</ConfirmDialog>
</template>