Image manager: Redesigned header bar(s)

This commit is contained in:
Dan Brown 2023-05-26 14:30:59 +01:00
parent e467324658
commit 6c91e09c73
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
6 changed files with 123 additions and 48 deletions

View File

@ -26,7 +26,7 @@ class GalleryImageController extends Controller
$uploadedToFilter = $request->get('uploaded_to', null);
$parentTypeFilter = $request->get('filter_type', null);
$imgData = $this->imageRepo->getEntityFiltered('gallery', $parentTypeFilter, $page, 24, $uploadedToFilter, $searchTerm);
$imgData = $this->imageRepo->getEntityFiltered('gallery', $parentTypeFilter, $page, 30, $uploadedToFilter, $searchTerm);
return view('pages.parts.image-manager-list', [
'images' => $imgData['images'],

View File

@ -23,6 +23,7 @@ export class ImageManager extends Component {
this.formContainer = this.$refs.formContainer;
this.formContainerPlaceholder = this.$refs.formContainerPlaceholder;
this.dropzoneContainer = this.$refs.dropzoneContainer;
this.loadMore = this.$refs.loadMore;
// Instance data
this.type = 'gallery';
@ -59,12 +60,11 @@ export class ImageManager extends Component {
this.loadGallery();
});
onChildEvent(this.listContainer, '.load-more button', 'click', async event => {
onChildEvent(this.container, '.load-more button', 'click', async event => {
const wrapper = event.target.closest('.load-more');
showLoading(wrapper);
this.page += 1;
await this.loadGallery();
wrapper.remove();
});
this.listContainer.addEventListener('event-emit-select-image', this.onImageSelectEvent.bind(this));
@ -145,6 +145,14 @@ export class ImageManager extends Component {
addReturnedHtmlElementsToList(html) {
const el = document.createElement('div');
el.innerHTML = html;
const loadMore = el.querySelector('.load-more');
if (loadMore) {
loadMore.remove();
this.loadMore.innerHTML = loadMore.innerHTML;
}
this.loadMore.toggleAttribute('hidden', !loadMore);
window.$components.init(el);
for (const child of [...el.children]) {
this.listContainer.appendChild(child);

View File

@ -200,10 +200,6 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
flex: 1;
}
.image-manager-body {
min-height: 70vh;
}
.dropzone-overlay {
position: absolute;
display: flex;
@ -347,13 +343,67 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
display: none;
}
.image-manager-body {
min-height: 70vh;
}
.image-manager-filter-bar {
position: sticky;
top: 0;
z-index: 5;
background-color: rgba(255, 255, 255, 0.85);
}
.image-manager-filter-bar-bg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: .15;
z-index: -1;
}
.image-manager-filter-bar .contained-search-box {
box-shadow: $bs-med;
border-radius: 4px;
margin: $-s $-m;
overflow: hidden;
input, button {
border: 0;
}
input:focus, input:active {
border: 0;
outline: 1px dotted var(--color-primary);
}
button {
width: 48px;
color: #444;
border-left: 1px solid #DDD;
background-color: #FFF;
}
}
.image-manager-filters {
box-shadow: $bs-med;
border-radius: 4px;
margin: $-s $-m;
overflow: hidden;
border-bottom: 0 !important;
button {
line-height: 0;
background-color: #FFF;
}
svg {
margin: 0;
}
}
.image-manager-list {
padding: 3px;
overflow-y: scroll;
flex: 1;
display: grid;
grid-template-columns: repeat( auto-fit, minmax(140px, 1fr) );
gap: 3px;
z-index: 3;
> div {
aspect-ratio: 1;
}
}
.image-manager-list .image {
@ -411,7 +461,6 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
}
.image-manager .load-more {
display: block;
text-align: center;
padding: $-s $-m;
clear: both;
@ -456,6 +505,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
display: flex;
flex-direction: column;
flex: 1;
overflow-y: scroll;
.container {
width: 100%;
}
@ -464,18 +514,14 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
}
}
.image-manager [role="tablist"] button[role="tab"] {
.tab-container.bordered [role="tablist"] button[role="tab"] {
border-right: 1px solid #DDD;
@include lightDark(border-color, #DDD, #000);
@include lightDark(border-right-color, #DDD, #000);
&:last-child {
border-right: none;
}
}
.image-manager-header {
z-index: 4;
}
.tab-container [role="tablist"] {
display: flex;
align-items: end;
@ -486,8 +532,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
margin-bottom: $-m;
}
.tab-container [role="tablist"] button[role="tab"],
.image-manager [role="tablist"] button[role="tab"] {
.tab-container [role="tablist"] button[role="tab"] {
display: inline-block;
padding: $-s;
@include lightDark(color, rgba(0, 0, 0, .5), rgba(255, 255, 255, .5));
@ -503,6 +548,10 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
@include lightDark(border-bottom-color, rgba(0, 0, 0, .2), rgba(255, 255, 255, .2));
}
}
.tab-container.tab-primary [role="tablist"] button[role="tab"][aria-selected="true"] {
color: var(--color-primary) !important;
border-bottom-color: var(--color-primary) !important;
}
.tab-container [role="tablist"].controls-card {
margin-bottom: 0;
border-bottom: 0;

View File

@ -17,4 +17,9 @@
@include('pages.parts.image-manager', ['uploaded_to' => $page->id])
@include('pages.parts.code-editor')
@include('entities.selector-popup')
<script nonce="{{ $cspNonce }}" type="module">
window.$components.first('image-manager').show((image) => {
console.log(image);
}, 'gallery');
</script>
@stop

View File

@ -18,6 +18,9 @@
</button>
</div>
@endforeach
@if(count($images) === 0)
<p class="m-m text-bigger italic text-muted">{{ trans('common.no_items') }}</p>
@endif
@if($hasMore)
<div class="load-more">
<button type="button" class="button small outline">{{ trans('components.image_load_more') }}</button>

View File

@ -25,39 +25,49 @@
</div>
<div refs="dropzone@drop-target" class="flex-fill image-manager-body">
<div class="image-manager-content">
<div role="tablist" class="image-manager-header grid third no-gap">
<button refs="image-manager@filterTabs"
data-filter="all"
role="tab"
aria-selected="true"
type="button" class="tab-item" title="{{ trans('components.image_all_title') }}">@icon('images') {{ trans('components.image_all') }}</button>
<button refs="image-manager@filterTabs"
data-filter="book"
role="tab"
aria-selected="false"
type="button" class="tab-item" title="{{ trans('components.image_book_title') }}">@icon('book', ['class' => 'svg-icon']) {{ trans('entities.book') }}</button>
<button refs="image-manager@filterTabs"
data-filter="page"
role="tab"
aria-selected="false"
type="button" class="tab-item" title="{{ trans('components.image_page_title') }}">@icon('page', ['class' => 'svg-icon']) {{ trans('entities.page') }}</button>
</div>
<div>
<form refs="image-manager@searchForm" class="contained-search-box">
<input refs="image-manager@searchInput"
placeholder="{{ trans('components.image_search_hint') }}"
type="text">
<button refs="image-manager@cancelSearch"
title="{{ trans('common.search_clear') }}"
type="button"
class="cancel">@icon('close')</button>
<button type="submit" class="primary-background text-white"
title="{{ trans('common.search') }}">@icon('search')</button>
</form>
<div class="image-manager-filter-bar flex-container-row justify-space-between">
<div class="primary-background image-manager-filter-bar-bg"></div>
<div>
<form refs="image-manager@searchForm" class="contained-search-box">
<input refs="image-manager@searchInput"
placeholder="{{ trans('components.image_search_hint') }}"
type="text">
<button refs="image-manager@cancelSearch"
title="{{ trans('common.search_clear') }}"
type="button"
class="cancel">@icon('close')</button>
<button type="submit"
title="{{ trans('common.search') }}">@icon('search')</button>
</form>
</div>
<div class="tab-container bordered tab-primary">
<div role="tablist" class="image-manager-filters flex-container-row">
<button refs="image-manager@filterTabs"
data-filter="all"
role="tab"
aria-selected="true"
type="button"
title="{{ trans('components.image_all_title') }}">@icon('images')</button>
<button refs="image-manager@filterTabs"
data-filter="book"
role="tab"
aria-selected="false"
type="button"
title="{{ trans('components.image_book_title') }}">@icon('book', ['class' => 'svg-icon'])</button>
<button refs="image-manager@filterTabs"
data-filter="page"
role="tab"
aria-selected="false"
type="button"
title="{{ trans('components.image_page_title') }}">@icon('page', ['class' => 'svg-icon'])</button>
</div>
</div>
</div>
<div refs="image-manager@listContainer" class="image-manager-list"></div>
<div refs="image-manager@loadMore" class="load-more" hidden>
<button type="button" class="button small outline">Load More</button>
</div>
</div>
<div class="image-manager-sidebar flex-container-column">