slides: fix manager thumbnail 404 under /ops + single-column order list
SlideManager rendered <img :src=slide.url> raw, so the root-relative /api/slides/img/... path 404'd under the /ops subpath mount (the /tv display already wrapped withBase; the manager did not). Wrap the thumbnail in withBase. Also switch the multi-column grid to a single-column list with order numbers so the top-to-bottom play order is clear to arrange.
This commit is contained in:
@@ -32,13 +32,11 @@
|
|||||||
<div v-if="loading" class="muted">Loading...</div>
|
<div v-if="loading" class="muted">Loading...</div>
|
||||||
<div v-else-if="!slides.length" class="muted empty">No slides yet. Upload some images.</div>
|
<div v-else-if="!slides.length" class="muted empty">No slides yet. Upload some images.</div>
|
||||||
|
|
||||||
<div v-else class="slide-grid">
|
<div v-else class="slide-list">
|
||||||
<div v-for="(slide, idx) in slides" :key="slide.slideid" class="slide-tile">
|
<div v-for="(slide, idx) in slides" :key="slide.slideid" class="slide-row">
|
||||||
<label class="pick">
|
<input type="checkbox" class="pick" :value="slide.filename" v-model="selected" />
|
||||||
<input type="checkbox" :value="slide.filename" v-model="selected" />
|
<span class="order-num">{{ idx + 1 }}</span>
|
||||||
</label>
|
<img :src="withBase(slide.url)" :alt="slide.filename" class="thumb" />
|
||||||
<img :src="slide.url" :alt="slide.filename" class="thumb" />
|
|
||||||
<div class="slide-meta">
|
|
||||||
<span class="fname" :title="slide.filename">{{ slide.filename }}</span>
|
<span class="fname" :title="slide.filename">{{ slide.filename }}</span>
|
||||||
<div class="move">
|
<div class="move">
|
||||||
<button class="btn btn-sm btn-secondary" :disabled="idx === 0" @click="move(idx, -1)" title="Move up">↑</button>
|
<button class="btn btn-sm btn-secondary" :disabled="idx === 0" @click="move(idx, -1)" title="Move up">↑</button>
|
||||||
@@ -48,12 +46,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { slidesApi } from '@/api'
|
import { slidesApi } from '@/api'
|
||||||
|
import { withBase } from '@/utils/basePath'
|
||||||
|
|
||||||
const surfaces = [
|
const surfaces = [
|
||||||
{ key: 'lobby', label: 'Lobby Display' },
|
{ key: 'lobby', label: 'Lobby Display' },
|
||||||
@@ -164,42 +162,40 @@ onMounted(load)
|
|||||||
.muted { color: var(--text-light); }
|
.muted { color: var(--text-light); }
|
||||||
.empty { padding: 30px 0; text-align: center; }
|
.empty { padding: 30px 0; text-align: center; }
|
||||||
|
|
||||||
.slide-grid {
|
.slide-list {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
flex-direction: column;
|
||||||
gap: 14px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
.slide-tile {
|
.slide-row {
|
||||||
position: relative;
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
.slide-tile .pick {
|
|
||||||
position: absolute;
|
|
||||||
top: 6px;
|
|
||||||
left: 6px;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 2px 4px;
|
|
||||||
}
|
|
||||||
.thumb {
|
|
||||||
width: 100%;
|
|
||||||
height: 130px;
|
|
||||||
object-fit: cover;
|
|
||||||
display: block;
|
|
||||||
background: #000;
|
|
||||||
}
|
|
||||||
.slide-meta {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
gap: 12px;
|
||||||
gap: 6px;
|
border: 1px solid var(--border);
|
||||||
padding: 6px 8px;
|
border-radius: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: var(--bg);
|
||||||
|
}
|
||||||
|
.slide-row .pick { flex-shrink: 0; }
|
||||||
|
.order-num {
|
||||||
|
width: 1.6rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
.thumb {
|
||||||
|
width: 120px;
|
||||||
|
height: 68px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #000;
|
||||||
}
|
}
|
||||||
.fname {
|
.fname {
|
||||||
font-size: 0.78rem;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
font-size: 0.82rem;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
Reference in New Issue
Block a user