Creates Mosaic View Mode and fixes some alignement issues with previous ones.
This commit is contained in:
parent
0a6b472398
commit
bf2571230e
|
@ -132,7 +132,7 @@ class Collections extends Repository {
|
|||
'title' => __( 'Enabled view modes', 'tainacan' ),
|
||||
'type' => 'array',
|
||||
'description' => __( 'Which visualization modes will be available for the public to choose from', 'tainacan' ),
|
||||
'default' => [ 'table', 'cards' ],
|
||||
'default' => [ 'table', 'cards', 'masonry' ],
|
||||
'items' => [ 'type' => 'string' ],
|
||||
//'validation' => v::stringType(),
|
||||
],
|
||||
|
|
|
@ -2493,5 +2493,23 @@ class Theme_Helper {
|
|||
'requires_thumbnail' => false,
|
||||
'placeholder_template' => $map_view_mode_placeholder
|
||||
]);
|
||||
|
||||
$this->register_view_mode('mosaic', [
|
||||
'label' => __('Mosaic', 'tainacan'),
|
||||
'dynamic_metadata' => false,
|
||||
'description' => __('A mosaic view, similar to Flickr and Google Photos, which will display images without cropping.', 'tainacan'),
|
||||
'icon' => '<span class="icon"><i class="tainacan-icon tainacan-icon-viewmasonry tainacan-icon-rotate-90 tainacan-icon-1-25em"></i></span>',
|
||||
'type' => 'component',
|
||||
'implements_skeleton' => true,
|
||||
'placeholder_template' => '<ul style="list-style: none;width: 100%; height: auto; display: flex; gap: 24px 0; flex-wrap: wrap;">' .
|
||||
array_reduce( range(0,11), function($container, $i) {
|
||||
$container .= '<li style="flex-grow: 1; max-width: 35%; width: ' . ($i % 2 == 0 ? rand(100, 180) : rand(90, 170)) . 'px; height: 120px ; background-color: var(--tainacan-block-gray1, #f2f2f2); margin: 0; padding: 5px;">
|
||||
<div style="width: 100%;height: 100%; background-color: var(--tainacan-block-gray2, #dbdbdb);margin-bottom: 10px;"></div>
|
||||
<div style="width: 100%;height: 10px; background-color: var(--tainacan-block-gray3, #a5a5a5);"></div>
|
||||
</li>';
|
||||
return $container;
|
||||
}) .
|
||||
'</ul>'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1979,6 +1979,181 @@
|
|||
</l-control>
|
||||
</l-map>
|
||||
</div>
|
||||
|
||||
<!-- MOSAIC VIEW MODE -->
|
||||
<ul
|
||||
v-if="viewMode == 'mosaic'"
|
||||
:class="{
|
||||
'hide-items-selection': $adminOptions.hideItemsListSelection
|
||||
}"
|
||||
class="tainacan-mosaic-container">
|
||||
<li
|
||||
v-for="(item, index) of items"
|
||||
:key="index"
|
||||
:data-tainacan-item-id="item.id"
|
||||
:style="{
|
||||
'--tainacan-mosaic-item-width': getAcceptableWidthBasedOnRatio(item['thumbnail'], 'tainacan-large-full', 300),
|
||||
'--tainacan-mosaic-item-height': $thumbHelper.getHeight(item['thumbnail'], 'tainacan-large-full', 300)
|
||||
}">
|
||||
<div
|
||||
:class="{
|
||||
'selected-mosaic-item': getSelectedItemChecked(item.id) == true
|
||||
}"
|
||||
class="tainacan-mosaic-item"
|
||||
@click.left="onClickItem($event, item)"
|
||||
@click.right="onRightClickItem($event, item)">
|
||||
|
||||
<!-- Thumbnail -->
|
||||
<blur-hash-image
|
||||
v-if="item.thumbnail != undefined"
|
||||
class="tainacan-mosaic-item-thumbnail"
|
||||
:width="$thumbHelper.getWidth(item['thumbnail'], 'tainacan-large-full', 320)"
|
||||
:height="$thumbHelper.getHeight(item['thumbnail'], 'tainacan-large-full', 320)"
|
||||
:hash="$thumbHelper.getBlurhashString(item['thumbnail'], 'tainacan-large-full')"
|
||||
:src="$thumbHelper.getSrc(item['thumbnail'], 'tainacan-large-full', item.document_mimetype)"
|
||||
:srcset="$thumbHelper.getSrcSet(item['thumbnail'], 'tainacan-large-full', item.document_mimetype)"
|
||||
:alt="item.thumbnail_alt ? item.thumbnail_alt : $i18n.get('label_thumbnail')"
|
||||
:transition-duration="500"
|
||||
/>
|
||||
|
||||
<!-- Checkbox -->
|
||||
<!-- TODO: Remove v-if="collectionId" from this element when the bulk edit in repository is done -->
|
||||
<div
|
||||
v-if="collectionId && !$adminOptions.hideItemsListSelection && ($adminOptions.itemsSingleSelectionMode || $adminOptions.itemsMultipleSelectionMode || (collection && collection.current_user_can_bulk_edit))"
|
||||
:class="{ 'is-selecting': isSelectingItems }"
|
||||
class="mosaic-item-checkbox">
|
||||
<label
|
||||
tabindex="0"
|
||||
:class="(!$adminOptions.itemsSingleSelectionMode ? 'b-checkbox checkbox' : 'b-radio radio') + ' is-small'">
|
||||
<input
|
||||
v-if="!$adminOptions.itemsSingleSelectionMode"
|
||||
type="checkbox"
|
||||
:checked="getSelectedItemChecked(item.id)"
|
||||
@input="setSelectedItemChecked(item.id)">
|
||||
<input
|
||||
v-else
|
||||
v-model="singleItemSelection"
|
||||
type="radio"
|
||||
name="item-single-selection"
|
||||
:value="item.id">
|
||||
<span class="check" />
|
||||
<span class="control-label" />
|
||||
<span class="sr-only">{{ $i18n.get('label_select_item') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Title -->
|
||||
<div
|
||||
class="metadata-title"
|
||||
:style="{
|
||||
'padding-left': !collectionId || !($adminOptions.itemsSingleSelectionMode || $adminOptions.itemsMultipleSelectionMode || (collection && collection.current_user_can_bulk_edit)) || $adminOptions.itemsSearchSelectionMode ? '0 !important' : (isOnAllItemsTabs ? '0.5em' : '1em')
|
||||
}">
|
||||
<p
|
||||
v-tooltip="{
|
||||
delay: {
|
||||
show: 750,
|
||||
hide: 100,
|
||||
},
|
||||
content: item.title != undefined ? item.title : '',
|
||||
html: true,
|
||||
placement: 'auto-start',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
|
||||
}">
|
||||
<span
|
||||
v-if="isOnAllItemsTabs && $statusHelper.hasIcon(item.status)"
|
||||
v-tooltip="{
|
||||
content: $i18n.get('status_' + item.status),
|
||||
autoHide: true,
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : ''],
|
||||
placement: 'auto-start'
|
||||
}"
|
||||
class="icon has-text-gray">
|
||||
<i
|
||||
class="tainacan-icon tainacan-icon-1em"
|
||||
:class="$statusHelper.getIcon(item.status)"
|
||||
/>
|
||||
</span>
|
||||
{{ item.title != undefined ? item.title : '' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div
|
||||
v-if="item.current_user_can_edit && !$adminOptions.hideItemsListActionAreas"
|
||||
class="actions-area"
|
||||
:label="$i18n.get('label_actions')">
|
||||
<a
|
||||
v-if="!isOnTrash"
|
||||
id="button-edit"
|
||||
:aria-label="$i18n.getFrom('items','edit_item')"
|
||||
@click.prevent.stop="goToItemEditPage(item)">
|
||||
<span
|
||||
v-tooltip="{
|
||||
content: $i18n.get('edit'),
|
||||
autoHide: true,
|
||||
placement: 'auto',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
|
||||
}"
|
||||
class="icon">
|
||||
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-edit" />
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
v-if="isOnTrash"
|
||||
:aria-lavel="$i18n.get('label_button_untrash')"
|
||||
@click.prevent.stop="untrashOneItem(item.id)">
|
||||
<span
|
||||
v-tooltip="{
|
||||
content: $i18n.get('label_recover_from_trash'),
|
||||
autoHide: true,
|
||||
placement: 'auto',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
|
||||
}"
|
||||
class="icon">
|
||||
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-undo" />
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
v-if="item.current_user_can_delete"
|
||||
id="button-delete"
|
||||
:aria-label="$i18n.get('label_button_delete')"
|
||||
@click.prevent.stop="deleteOneItem(item.id)">
|
||||
<span
|
||||
v-tooltip="{
|
||||
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
|
||||
autoHide: true,
|
||||
placement: 'auto',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
|
||||
}"
|
||||
class="icon">
|
||||
<i
|
||||
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
|
||||
class="has-text-secondary tainacan-icon tainacan-icon-1-25em" />
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
v-if="!isOnTrash"
|
||||
id="button-open-external"
|
||||
:aria-label="$i18n.getFrom('items','view_item')"
|
||||
target="_blank"
|
||||
:href="item.url"
|
||||
@click.stop="">
|
||||
<span
|
||||
v-tooltip="{
|
||||
content: $i18n.get('label_item_page_on_website'),
|
||||
autoHide: true,
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : ''],
|
||||
placement: 'auto',
|
||||
html: true
|
||||
}"
|
||||
class="icon">
|
||||
<i class="tainacan-icon tainacan-icon-1-125em tainacan-icon-openurl" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -2674,6 +2849,12 @@ export default {
|
|||
duration: 3000
|
||||
});
|
||||
}
|
||||
},
|
||||
getAcceptableWidthBasedOnRatio(thumbnail, size, defaultSize) {
|
||||
const width = this.$thumbHelper.getWidth(thumbnail, size, defaultSize);
|
||||
const height = this.$thumbHelper.getHeight(thumbnail, size, defaultSize);
|
||||
|
||||
return (width / height) > 0.7 ? width : ( height * 0.7 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2685,6 +2866,7 @@ export default {
|
|||
@import "../../scss/_tables.scss";
|
||||
@import "../../scss/_view-mode-cards.scss";
|
||||
@import "../../scss/_view-mode-masonry.scss";
|
||||
@import "../../scss/_view-mode-mosaic.scss";
|
||||
@import "../../scss/_view-mode-grid.scss";
|
||||
@import "../../scss/_view-mode-records.scss";
|
||||
@import "../../scss/_view-mode-list.scss";
|
||||
|
|
|
@ -226,13 +226,13 @@
|
|||
show: 500,
|
||||
hide: 300,
|
||||
},
|
||||
content: (totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? (adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry') ? $i18n.get('info_current_view_mode_metadata_not_allowed') : $i18n.get('info_cant_select_metadata_without_items') : '',
|
||||
content: (totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry' || adminViewMode == 'mosaic') ? (adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry' || adminViewMode == 'mosaic') ? $i18n.get('info_current_view_mode_metadata_not_allowed') : $i18n.get('info_cant_select_metadata_without_items') : '',
|
||||
autoHide: false,
|
||||
placement: 'auto-start',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
|
||||
}"
|
||||
:mobile-modal="true"
|
||||
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
|
||||
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry' || adminViewMode == 'mosaic'"
|
||||
class="show metadata-options-dropdown"
|
||||
aria-role="list"
|
||||
trap-focus>
|
||||
|
@ -383,12 +383,15 @@
|
|||
<span class="view-mode-icon icon is-small gray-icon">
|
||||
<i
|
||||
v-if="adminViewMode !== 'map'"
|
||||
:class="{'tainacan-icon-viewtable' : ( adminViewMode == 'table' || adminViewMode == undefined),
|
||||
'tainacan-icon-viewcards' : adminViewMode == 'cards',
|
||||
'tainacan-icon-viewminiature' : adminViewMode == 'grid',
|
||||
'tainacan-icon-viewrecords' : adminViewMode == 'records',
|
||||
'tainacan-icon-viewlist' : adminViewMode == 'list',
|
||||
'tainacan-icon-viewmasonry' : adminViewMode == 'masonry' }"
|
||||
:class="{
|
||||
'tainacan-icon-viewtable' : ( adminViewMode == 'table' || adminViewMode == undefined),
|
||||
'tainacan-icon-viewcards' : adminViewMode == 'cards',
|
||||
'tainacan-icon-viewminiature' : adminViewMode == 'grid',
|
||||
'tainacan-icon-viewrecords' : adminViewMode == 'records',
|
||||
'tainacan-icon-viewlist' : adminViewMode == 'list',
|
||||
'tainacan-icon-viewmasonry' : adminViewMode == 'masonry' || adminViewMode == 'mosaic',
|
||||
'tainacan-icon-rotate-90' : adminViewMode == 'mosaic'
|
||||
}"
|
||||
class="tainacan-icon tainacan-icon-1-25em" />
|
||||
<svg
|
||||
v-else
|
||||
|
@ -426,6 +429,17 @@
|
|||
</span>
|
||||
<span>{{ $i18n.get('label_cards') }}</span>
|
||||
</b-dropdown-item>
|
||||
<b-dropdown-item
|
||||
aria-controls="items-list-results"
|
||||
role="button"
|
||||
:class="{ 'is-active': adminViewMode == 'mosaic' }"
|
||||
:value="'mosaic'"
|
||||
aria-role="listitem">
|
||||
<span class="icon gray-icon">
|
||||
<i class="tainacan-icon tainacan-icon-viewmasonry tainacan-icon-rotate-90" />
|
||||
</span>
|
||||
<span>{{ $i18n.get('label_mosaic') }}</span>
|
||||
</b-dropdown-item>
|
||||
<b-dropdown-item
|
||||
v-if="!collection || (collection && collection.hide_items_thumbnail_on_lists != 'yes')"
|
||||
aria-controls="items-list-results"
|
||||
|
@ -773,7 +787,7 @@
|
|||
},
|
||||
adminViewMode() {
|
||||
const currentAdminViewMode = this.getAdminViewMode();
|
||||
return ['table', 'cards', 'records', 'grid', 'masonry', 'list', 'map'].indexOf(currentAdminViewMode) >= 0 ? currentAdminViewMode : 'table';
|
||||
return ['table', 'cards', 'records', 'grid', 'masonry', 'list', 'map', 'mosaic'].indexOf(currentAdminViewMode) >= 0 ? currentAdminViewMode : 'table';
|
||||
},
|
||||
orderByName() {
|
||||
const metadatumName = this.$orderByHelper.getOrderByMetadatumName({
|
||||
|
@ -994,6 +1008,7 @@
|
|||
existingViewMode == 'list' ||
|
||||
existingViewMode == 'grid' ||
|
||||
existingViewMode == 'masonry'||
|
||||
existingViewMode == 'mosaic'||
|
||||
existingViewMode == 'map')
|
||||
this.$eventBusSearch.setInitialAdminViewMode(this.$userPrefs.get(prefsAdminViewMode));
|
||||
else
|
||||
|
|
|
@ -140,7 +140,7 @@
|
|||
.metadata-title {
|
||||
flex-shrink: 0;
|
||||
padding: 0.6em 7em 0.5em 2.75em;
|
||||
min-height: 40px;
|
||||
min-height: 1.5em;
|
||||
position: relative;
|
||||
font-size: 1em !important;
|
||||
text-overflow: ellipsis;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
:deep(img) {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
@ -111,7 +112,7 @@
|
|||
.metadata-title {
|
||||
flex-shrink: 0;
|
||||
padding: 0.5em 7em 0.5em 2.75em;
|
||||
min-height: 40px;
|
||||
min-height: 1.5em;
|
||||
position: relative;
|
||||
font-size: 1em !important;
|
||||
text-overflow: ellipsis;
|
||||
|
|
|
@ -264,6 +264,7 @@
|
|||
z-index: 1;
|
||||
}
|
||||
.metadata-title {
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
padding: 0.25em 1.125em;
|
||||
font-size: 1.0em !important;
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
|
||||
:deep(img) {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&:hover:not(.skeleton) {
|
||||
|
@ -191,7 +192,7 @@
|
|||
flex-shrink: 0;
|
||||
margin: 0px 6px 0px 24px;
|
||||
padding: 8px 1em;
|
||||
min-height: 41px;
|
||||
min-height: calc(1em + 8px);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
.tainacan-mosaic-container,
|
||||
.tainacan-mosaic-container--skeleton {
|
||||
--tainacan-mosaic-view-mode-gap: 12px;
|
||||
--tainacan-mosaic-view-mode-min-height: 180px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
grid-gap: calc(2em + 16px) var(--tainacan-mosaic-view-mode-gap, 12px);
|
||||
list-style: none;
|
||||
height: auto;
|
||||
min-height: 0px; /* While most view modes set this to 50vh, this causes a bug for this one if there are few items to display */
|
||||
margin: 0;
|
||||
margin-bottom: calc(2em + 16px + var(--tainacan-container-padding));
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
animation-name: appear;
|
||||
animation-duration: 0.5s;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
flex-grow: 1000000000;
|
||||
}
|
||||
|
||||
& > li,
|
||||
& > .skeleton {
|
||||
flex-grow: calc(var(--tainacan-mosaic-item-width, 300) * (100000 / var(--tainacan-mosaic-item-height, 300)));
|
||||
flex-basis: calc(var(--tainacan-mosaic-view-mode-min-height, 180) * (var(--tainacan-mosaic-item-width, 300) / var(--tainacan-mosaic-item-height, 300)));
|
||||
aspect-ratio: var(--tainacan-mosaic-item-width, 300) / var(--tainacan-mosaic-item-height, 300);
|
||||
position: relative;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
|
||||
:deep(img) {
|
||||
position: absolute;
|
||||
width: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:deep(canvas.child) {
|
||||
aspect-ratio: var(--tainacan-mosaic-item-width, 300) / var(--tainacan-mosaic-item-height, 300);
|
||||
}
|
||||
|
||||
&:hover:not(.skeleton) {
|
||||
background-color: var(--tainacan-item-heading-hover-background-color);
|
||||
}
|
||||
&.selected-mosaic-item:not(.skeleton) {
|
||||
background-color: var(--tainacan-turquoise1);
|
||||
}
|
||||
&:not(.skeleton) {
|
||||
background-color: var(--tainacan-item-background-color);
|
||||
}
|
||||
|
||||
.tainacan-mosaic-item {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.mosaic-item-checkbox {
|
||||
position: absolute;
|
||||
margin-top: 8px;
|
||||
margin-left: 1em;
|
||||
z-index: 9;
|
||||
}
|
||||
.actions-area {
|
||||
position: relative;
|
||||
float: right;
|
||||
width: 100%;
|
||||
height: 0px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
opacity: 0.0;
|
||||
padding: 8px;
|
||||
margin-top: -25px;
|
||||
background-color: var(--tainacan-item-heading-hover-background-color);
|
||||
transition: visibility 0.2s ease, opacity 0.3s ease, height 0.2s ease, margin-top 0.1s ease;
|
||||
|
||||
a {
|
||||
margin-left: 8px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease-in;
|
||||
}
|
||||
}
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:focus-within,
|
||||
&:focus-visible,
|
||||
& > a:focus,
|
||||
& > a:focus-within,
|
||||
& > a:focus-visible {
|
||||
background: var(--tainacan-item-hover-background-color);
|
||||
|
||||
.actions-area {
|
||||
visibility: visible;
|
||||
opacity: 1.0;
|
||||
height: 42px;
|
||||
margin-top: 0px;
|
||||
background-color: var(--tainacan-item-heading-hover-background-color);
|
||||
|
||||
a {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.selected-mosaic-item {
|
||||
.actions-area {
|
||||
background-color: var(--tainacan-turquoise1);
|
||||
}
|
||||
}
|
||||
|
||||
.tainacan-mosaic-item-thumbnail {
|
||||
background-size: cover;
|
||||
background-color: var(--tainacan-item-background-color);
|
||||
background-blend-mode: multiply;
|
||||
border-radius: 0px;
|
||||
min-width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.metadata-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
margin: 0;
|
||||
padding: 8px 1em;
|
||||
min-height: calc(1em + 8px);
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
p {
|
||||
font-size: 0.875em !important;
|
||||
color: var(--tainacan-heading-color) !important;
|
||||
text-align: left !important;
|
||||
margin-bottom: 0 !important;
|
||||
line-height: 1.5em;
|
||||
word-break: break-word;
|
||||
margin: 0;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.slideshow-icon {
|
||||
color: var(--tainacan-info-color);
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 8px;
|
||||
transform: scale(0.0);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.icon:not(.slideshow-icon) {
|
||||
float: left;
|
||||
margin-top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:focus-within,
|
||||
&:focus-visible,
|
||||
& > a:focus,
|
||||
& > a:focus-within,
|
||||
& > a:focus-visible {
|
||||
.metadata-title {
|
||||
background: var(--tainacan-item-heading-hover-background-color);
|
||||
|
||||
.slideshow-icon {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hide-items-selection {
|
||||
.tainacan-mosaic-item {
|
||||
&:hover { background-color: transparent; cursor: default; }
|
||||
&:hover .tainacan-mosaic-item-thumbnail { cursor: default; }
|
||||
}
|
||||
}
|
||||
|
||||
&.has-title-inside {
|
||||
gap: var(--tainacan-mosaic-view-mode-gap, 12px);
|
||||
|
||||
& > li {
|
||||
.metadata-title {
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
white-space: wrap;
|
||||
overflow: visible;
|
||||
text-overflow: none;
|
||||
|
||||
p {
|
||||
white-space: wrap;
|
||||
overflow: visible;
|
||||
text-overflow: none;
|
||||
}
|
||||
}
|
||||
&:not(:hover):not(:focus):not(:focus-within):not(:focus-visible),
|
||||
& > a:not(:hover):not(:focus):not(:focus-within):not(:focus-visible) {
|
||||
.metadata-title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@
|
|||
|
||||
:deep(img) {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
@ -150,7 +151,7 @@
|
|||
flex-shrink: 0;
|
||||
padding: 0.5em 7em 0.5em 2.75em;
|
||||
font-size: 1.0em !important;
|
||||
min-height: 40px;
|
||||
min-height: 1.5em;
|
||||
position: relative;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
|
|
@ -28,7 +28,7 @@ export default (element) => {
|
|||
let registeredViewModes =
|
||||
( tainacan_blocks && tainacan_blocks.registered_view_modes && tainacan_blocks.registered_view_modes.length ) ?
|
||||
tainacan_blocks.registered_view_modes :
|
||||
[ 'table', 'cards', 'records', 'masonry', 'list', 'map' ];
|
||||
[ 'table', 'cards', 'records', 'masonry', 'mosaic', 'list', 'map'];
|
||||
|
||||
// At first, we consider that all registered view modes are included.
|
||||
let possibleViewModes = registeredViewModes.filter((aViewMode) => aViewMode === 'slideshow');
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<div class="table-container">
|
||||
<div class="table-wrapper">
|
||||
|
||||
<!-- Empty result placeholder, rendered in the parent component -->
|
||||
<slot />
|
||||
|
||||
<!-- SKELETON LOADING -->
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="tainacan-mosaic-container--skeleton">
|
||||
<div
|
||||
v-for="item in 12"
|
||||
:key="item"
|
||||
:style="{
|
||||
'--tainacan-mosaic-item-width': randomHeightForMosaicItem(),
|
||||
'--tainacan-mosaic-item-height': randomHeightForMosaicItem()
|
||||
}"
|
||||
class="skeleton" />
|
||||
</div>
|
||||
|
||||
<!-- MOSAIC VIEW MODE -->
|
||||
<ul
|
||||
v-if="!isLoading"
|
||||
class="tainacan-mosaic-container">
|
||||
<li
|
||||
v-for="(item, index) of items"
|
||||
:key="index"
|
||||
:style="{
|
||||
'--tainacan-mosaic-item-width': getAcceptableWidthBasedOnRatio(item['thumbnail'], 'tainacan-large-full', 300),
|
||||
'--tainacan-mosaic-item-height': $thumbHelper.getHeight(item['thumbnail'], 'tainacan-large-full', 300)
|
||||
}"
|
||||
:data-tainacan-item-id="item.id"
|
||||
:aria-setsize="totalItems"
|
||||
:aria-posinset="getPosInSet(index)">
|
||||
<a
|
||||
|
||||
class="tainacan-mosaic-item"
|
||||
:href="getItemLink(item.url, index)">
|
||||
|
||||
<!-- JS-side hook for extra content -->
|
||||
<div
|
||||
v-if="hasBeforeHook()"
|
||||
class="faceted-search-hook faceted-search-hook-item-before"
|
||||
v-html="getBeforeHook(item)" />
|
||||
|
||||
<!-- Thumbnail -->
|
||||
<blur-hash-image
|
||||
v-if="item.thumbnail != undefined"
|
||||
class="tainacan-mosaic-item-thumbnail"
|
||||
:width="$thumbHelper.getWidth(item['thumbnail'], 'tainacan-large-full', 320)"
|
||||
:height="$thumbHelper.getHeight(item['thumbnail'], 'tainacan-large-full', 320)"
|
||||
:hash="$thumbHelper.getBlurhashString(item['thumbnail'], 'tainacan-large-full')"
|
||||
:src="$thumbHelper.getSrc(item['thumbnail'], 'tainacan-large-full', item.document_mimetype)"
|
||||
:srcset="$thumbHelper.getSrcSet(item['thumbnail'], 'tainacan-large-full', item.document_mimetype)"
|
||||
:alt="item.thumbnail_alt ? item.thumbnail_alt : $i18n.get('label_thumbnail')"
|
||||
:transition-duration="500"
|
||||
/>
|
||||
|
||||
|
||||
<!-- Title -->
|
||||
<div
|
||||
class="metadata-title"
|
||||
:style="isSlideshowViewModeEnabled ? 'padding-right: 2rem;' : ''">
|
||||
<p
|
||||
v-tooltip="{
|
||||
delay: {
|
||||
show: 750,
|
||||
hide: 100,
|
||||
},
|
||||
content: item.title != undefined ? item.title : '',
|
||||
html: true,
|
||||
placement: 'auto-start',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip']
|
||||
}"
|
||||
v-html="item.title != undefined ? item.title : ''" />
|
||||
<span
|
||||
v-if="isSlideshowViewModeEnabled"
|
||||
v-tooltip="{
|
||||
delay: {
|
||||
show: 500,
|
||||
hide: 100,
|
||||
},
|
||||
content: $i18n.get('label_see_on_fullscreen'),
|
||||
placement: 'auto-start',
|
||||
popperClass: ['tainacan-tooltip', 'tooltip']
|
||||
}"
|
||||
class="icon slideshow-icon"
|
||||
@click.prevent="starSlideshowFromHere(index)">
|
||||
<i class="tainacan-icon tainacan-icon-viewgallery tainacan-icon-1-125em" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- JS-side hook for extra content -->
|
||||
<div
|
||||
v-if="hasAfterHook()"
|
||||
class="faceted-search-hook faceted-search-hook-item-after"
|
||||
v-html="getAfterHook(item)" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { viewModesMixin } from '../js/view-modes-mixin.js';
|
||||
|
||||
export default {
|
||||
name: 'ViewModeMosaic',
|
||||
mixins: [
|
||||
viewModesMixin
|
||||
],
|
||||
methods: {
|
||||
randomHeightForMosaicItem() {
|
||||
let min = 120;
|
||||
let max = 280;
|
||||
|
||||
return Math.floor(Math.random()*(max-min+1)+min);
|
||||
},
|
||||
getAcceptableWidthBasedOnRatio(thumbnail, size, defaultSize) {
|
||||
const width = this.$thumbHelper.getWidth(thumbnail, size, defaultSize);
|
||||
const height = this.$thumbHelper.getHeight(thumbnail, size, defaultSize);
|
||||
|
||||
return (width / height) > 0.7 ? width : ( height * 0.7 );
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@import "../../../../../admin/scss/_view-mode-mosaic.scss";
|
||||
|
||||
</style>
|
||||
|
||||
|
|
@ -179,6 +179,7 @@
|
|||
width: 100%;
|
||||
max-width: 100% !important;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.filters-components-list {
|
||||
|
|
|
@ -77,7 +77,7 @@ export default (element) => {
|
|||
const registeredViewModes =
|
||||
( tainacan_plugin && tainacan_plugin.registered_view_modes && tainacan_plugin.registered_view_modes.length ) ?
|
||||
tainacan_plugin.registered_view_modes :
|
||||
[ 'table', 'cards', 'records', 'masonry', 'slideshow', 'list', 'map' ];
|
||||
[ 'table', 'cards', 'records', 'masonry', 'mosaic', 'slideshow', 'list', 'map'];
|
||||
|
||||
// At first, we consider that all registered view modes are included.
|
||||
let possibleViewModes = registeredViewModes;
|
||||
|
|
|
@ -336,6 +336,7 @@ return apply_filters( 'tainacan-i18n', [
|
|||
'label_grid' => __( 'Thumbnails', 'tainacan' ),
|
||||
'label_table' => __( 'Table', 'tainacan' ),
|
||||
'label_cards' => __( 'Cards', 'tainacan' ),
|
||||
'label_mosaic' => __( 'Mosaic', 'tainacan' ),
|
||||
/* translators: The 'records' view mode, in the sense of a catalog file */
|
||||
'label_records' => __( 'Records', 'tainacan' ),
|
||||
'label_masonry' => __( 'Masonry', 'tainacan' ),
|
||||
|
|
Loading…
Reference in New Issue