This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { computed, reactive, ref, watch } from 'vue';
|
||||
|
||||
import ConditionBadge from '@/components/atoms/ConditionBadge.vue';
|
||||
import ImageGallery from '@/components/molecules/ImageGallery.vue';
|
||||
@@ -7,6 +7,7 @@ import StatusBadge from '@/components/atoms/StatusBadge.vue';
|
||||
|
||||
const props = defineProps({
|
||||
images: { type: Array, required: true },
|
||||
disabled: { type: Boolean, default: false },
|
||||
isSaving: { type: Boolean, default: false },
|
||||
});
|
||||
const emit = defineEmits(['upload', 'move', 'primary', 'alt-text', 'retry', 'delete']);
|
||||
@@ -17,16 +18,21 @@ const altTextDrafts = reactive({});
|
||||
const isDragging = ref(false);
|
||||
|
||||
function beginEditAltText(image) {
|
||||
altTextDrafts[image.id] = image.altText ?? '';
|
||||
altTextDrafts[image.id] ??= image.altText ?? '';
|
||||
editingImageId.value = image.id;
|
||||
}
|
||||
|
||||
function saveAltText(imageId) {
|
||||
emit('alt-text', { id: imageId, altText: altTextDrafts[imageId] ?? '' });
|
||||
editingImageId.value = null;
|
||||
}
|
||||
|
||||
watch(() => props.images, (images) => {
|
||||
const edited = images.find((image) => image.id === editingImageId.value);
|
||||
if (edited && edited.altText === altTextDrafts[edited.id]) editingImageId.value = null;
|
||||
});
|
||||
|
||||
function queueUpload(fileList) {
|
||||
if (props.isSaving || props.disabled) return;
|
||||
const files = Array.from(fileList ?? []);
|
||||
if (files.length > 0) emit('upload', files);
|
||||
}
|
||||
@@ -61,15 +67,15 @@ function handleDrop(event) {
|
||||
>
|
||||
<p>Drag and drop images here, or choose files below.</p>
|
||||
<label class="fixture-label" for="admin-image-upload">Add images</label>
|
||||
<input id="admin-image-upload" class="fixture-input" type="file" accept="image/jpeg,image/png,image/webp" multiple :disabled="isSaving" @change="handleFileChange" />
|
||||
<input id="admin-image-upload" class="fixture-input" type="file" accept="image/jpeg,image/png,image/webp" multiple :disabled="isSaving || disabled" @change="handleFileChange" />
|
||||
</div>
|
||||
|
||||
<ImageGallery :images="orderedImages" />
|
||||
|
||||
<p v-if="isSaving" class="state state--loading" role="status">Saving image changes...</p>
|
||||
<p v-else-if="orderedImages.length === 0" class="state" role="status">No images uploaded yet.</p>
|
||||
<p v-if="!isSaving && orderedImages.length === 0" class="state" role="status">No images uploaded yet.</p>
|
||||
|
||||
<ul v-else class="admin-image-manager__list">
|
||||
<ul v-if="orderedImages.length" class="admin-image-manager__list">
|
||||
<li v-for="(image, index) in orderedImages" :key="image.id" class="admin-image-manager__item">
|
||||
<div class="admin-image-manager__row">
|
||||
<ConditionBadge :label="image.altText || `Image ${index + 1}`" :selected="image.isPrimary" />
|
||||
@@ -79,17 +85,17 @@ function handleDrop(event) {
|
||||
|
||||
<div class="admin-image-manager__row">
|
||||
<label class="fixture-label" :for="`admin-alt-text-${image.id}`">Alt text</label>
|
||||
<input :id="`admin-alt-text-${image.id}`" v-model="altTextDrafts[image.id]" class="fixture-input" :disabled="editingImageId !== image.id" />
|
||||
<button v-if="editingImageId !== image.id" class="button button--secondary" type="button" @click="beginEditAltText(image)">Edit alt text</button>
|
||||
<button v-else class="button button--primary" type="button" @click="saveAltText(image.id)">Save alt text</button>
|
||||
<input :id="`admin-alt-text-${image.id}`" v-model="altTextDrafts[image.id]" class="fixture-input" :disabled="isSaving || disabled || editingImageId !== image.id" />
|
||||
<button v-if="editingImageId !== image.id" class="button button--secondary" type="button" :disabled="isSaving || disabled" @click="beginEditAltText(image)">Edit alt text</button>
|
||||
<button v-else class="button button--primary" type="button" :disabled="isSaving || disabled" @click="saveAltText(image.id)">Save alt text</button>
|
||||
</div>
|
||||
|
||||
<div class="admin-image-manager__row">
|
||||
<button class="button button--secondary" type="button" :disabled="image.isPrimary" @click="emit('primary', image.id)">Make primary</button>
|
||||
<button class="button button--secondary" type="button" :disabled="index === 0" @click="emit('move', { id: image.id, direction: 'up' })">Move up</button>
|
||||
<button class="button button--secondary" type="button" :disabled="index === orderedImages.length - 1" @click="emit('move', { id: image.id, direction: 'down' })">Move down</button>
|
||||
<button v-if="image.processingStatus === 'FAILED'" class="button button--secondary" type="button" @click="emit('retry', image.id)">Retry processing</button>
|
||||
<button class="button button--danger" type="button" @click="emit('delete', image.id)">Delete image</button>
|
||||
<button class="button button--secondary" type="button" :disabled="isSaving || disabled || image.isPrimary" @click="emit('primary', image.id)">Make primary</button>
|
||||
<button class="button button--secondary" type="button" :disabled="isSaving || disabled || index === 0" @click="emit('move', { id: image.id, direction: 'up' })">Move up</button>
|
||||
<button class="button button--secondary" type="button" :disabled="isSaving || disabled || index === orderedImages.length - 1" @click="emit('move', { id: image.id, direction: 'down' })">Move down</button>
|
||||
<button v-if="image.processingStatus === 'FAILED'" class="button button--secondary" type="button" :disabled="isSaving || disabled" @click="emit('retry', image.id)">Retry processing</button>
|
||||
<button class="button button--danger" type="button" :disabled="isSaving || disabled" @click="emit('delete', image.id)">Delete image</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user