mirror of
https://github.com/knadh/listmonk.git
synced 2025-12-05 16:00:03 +01:00
Refactor media gallery.
This commit is contained in:
@@ -968,6 +968,127 @@ section.analytics {
|
|||||||
.ext {
|
.ext {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb {
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-link {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
|
||||||
|
.item:hover & {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-extension {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-actions {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
|
||||||
|
.media-item:hover & {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filename {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: #363636;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #7a7a7a;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Template form */
|
/* Template form */
|
||||||
|
|||||||
@@ -38,61 +38,64 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="wrap gallery mt-6">
|
<section class="wrap gallery mt-6">
|
||||||
<b-table :data="media.results" :hoverable="true" :loading="loading.media" default-sort="createdAt" :paginated="true"
|
<div class="columns mb-4">
|
||||||
backend-pagination pagination-position="both" @page-change="onPageChange" :current-page="media.page"
|
<div class="column is-6">
|
||||||
:per-page="media.perPage" :total="media.total">
|
<form @submit.prevent="onQueryMedia">
|
||||||
<template #top-left>
|
<div>
|
||||||
<div class="columns">
|
<b-field>
|
||||||
<div class="column is-6">
|
<b-input v-model="queryParams.query" name="query" expanded icon="magnify" ref="query" data-cy="query" />
|
||||||
<form @submit.prevent="onQueryMedia">
|
<p class="controls">
|
||||||
<div>
|
<b-button native-type="submit" type="is-primary" icon-left="magnify" data-cy="btn-query" />
|
||||||
<b-field>
|
</p>
|
||||||
<b-input v-model="queryParams.query" name="query" expanded icon="magnify" ref="query"
|
</b-field>
|
||||||
data-cy="query" />
|
</div>
|
||||||
<p class="controls">
|
</form>
|
||||||
<b-button native-type="submit" type="is-primary" icon-left="magnify" data-cy="btn-query" />
|
</div>
|
||||||
</p>
|
</div>
|
||||||
</b-field>
|
|
||||||
|
<div v-if="loading.media" class="has-text-centered py-6">
|
||||||
|
<b-loading :active="loading.media" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="media.results && media.results.length > 0" class="grid">
|
||||||
|
<div v-for="item in media.results" :key="item.id" class="item">
|
||||||
|
<div class="thumb">
|
||||||
|
<a @click="(e) => onMediaSelect(item, e)" :href="item.url" target="_blank" rel="noopener noreferer"
|
||||||
|
class="thumb-link">
|
||||||
|
<div class="thumb-container">
|
||||||
|
<img v-if="item.thumbUrl" :src="item.thumbUrl" :title="item.filename" alt="" class="thumb-image" />
|
||||||
|
<div v-else class="thumb-placeholder">
|
||||||
|
<span class="file-extension">
|
||||||
|
{{ item.filename.split(".").pop().toUpperCase() }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="actions">
|
||||||
|
<a href="#" @click.prevent="$utils.confirm(null, () => onDeleteMedia(item.id))" data-cy="btn-delete"
|
||||||
|
:aria-label="$t('globals.buttons.delete')" class="delete-btn">
|
||||||
|
<b-tooltip :label="$t('globals.buttons.delete')" type="is-dark">
|
||||||
|
<b-icon icon="trash-can-outline" size="is-small" />
|
||||||
|
</b-tooltip>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div class="info">
|
||||||
|
<p class="filename" :title="item.filename">{{ item.filename }}</p>
|
||||||
|
<p class="date">{{ $utils.niceDate(item.createdAt, true) }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<b-table-column v-slot="props" field="name" width="40%" :label="$t('globals.fields.name')">
|
<!-- Empty State -->
|
||||||
<a @click="(e) => onMediaSelect(props.row, e)" :href="props.row.url" target="_blank" rel="noopener noreferer"
|
<div v-else-if="!loading.media">
|
||||||
class="link" :title="props.row.filename">
|
<empty-placeholder />
|
||||||
{{ props.row.filename }}
|
</div>
|
||||||
</a>
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column v-slot="props" field="thumb" width="30%">
|
<!-- Pagination -->
|
||||||
<a @click="(e) => onMediaSelect(props.row, e)" :href="props.row.url" target="_blank" rel="noopener noreferer"
|
<div v-if="media.total > media.perPage" class="pagination-wrapper mt-5">
|
||||||
class="thumb box">
|
<b-pagination :total="media.total" :current.sync="media.page" :per-page="media.perPage"
|
||||||
<img v-if="props.row.thumbUrl" :src="props.row.thumbUrl" :title="props.row.filename" alt="" />
|
@change="onPageChange" />
|
||||||
<span v-else class="ext">
|
</div>
|
||||||
{{ props.row.filename.split(".").pop() }}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column v-slot="props" field="created_at" width="25%" :label="$t('globals.fields.createdAt')" sortable>
|
|
||||||
{{ $utils.niceDate(props.row.createdAt, true) }}
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<b-table-column v-slot="props" field="actions" width="5%" cell-class="has-text-right">
|
|
||||||
<a href="#" @click.prevent="$utils.confirm(null, () => onDeleteMedia(props.row.id))" data-cy="btn-delete"
|
|
||||||
:aria-label="$t('globals.buttons.delete')">
|
|
||||||
<b-tooltip :label="$t('globals.buttons.delete')" type="is-dark">
|
|
||||||
<b-icon icon="trash-can-outline" size="is-small" />
|
|
||||||
</b-tooltip>
|
|
||||||
</a>
|
|
||||||
</b-table-column>
|
|
||||||
|
|
||||||
<template #empty v-if="!loading.media">
|
|
||||||
<empty-placeholder />
|
|
||||||
</template>
|
|
||||||
</b-table>
|
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user