Adds list component to client side of the block. Still needs to deal with translation, debouncing search and adjust pagination on both sides.
This commit is contained in:
parent
e8982aff1b
commit
f0551d6173
|
@ -417,7 +417,10 @@
|
||||||
margin-bottom: 1rem; }
|
margin-bottom: 1rem; }
|
||||||
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar button {
|
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar button {
|
||||||
margin-right: 0.75rem;
|
margin-right: 0.75rem;
|
||||||
z-index: 2; }
|
z-index: 2;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer; }
|
||||||
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar button svg {
|
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar button svg {
|
||||||
fill: #cbcbcb;
|
fill: #cbcbcb;
|
||||||
transition: fill 0.4s ease; }
|
transition: fill 0.4s ease; }
|
||||||
|
@ -429,6 +432,7 @@
|
||||||
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar button.sorting-button-selected svg {
|
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar button.sorting-button-selected svg {
|
||||||
fill: #545758; }
|
fill: #545758; }
|
||||||
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar input {
|
.wp-block-tainacan-dynamic-items-list .dynamic-items-search-bar input {
|
||||||
|
height: 32px;
|
||||||
width: 20%;
|
width: 20%;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
margin-left: -52px;
|
margin-left: -52px;
|
||||||
|
@ -443,7 +447,8 @@
|
||||||
.wp-block-tainacan-dynamic-items-list ul.items-list-edit.items-list-without-margin {
|
.wp-block-tainacan-dynamic-items-list ul.items-list-edit.items-list-without-margin {
|
||||||
grid-template-columns: repeat(auto-fill, 185px);
|
grid-template-columns: repeat(auto-fill, 185px);
|
||||||
justify-content: center !important;
|
justify-content: center !important;
|
||||||
grid-template-rows: auto !important; }
|
grid-template-rows: auto !important;
|
||||||
|
list-style: none; }
|
||||||
.wp-block-tainacan-dynamic-items-list ul.items-list.items-list-without-margin li,
|
.wp-block-tainacan-dynamic-items-list ul.items-list.items-list-without-margin li,
|
||||||
.wp-block-tainacan-dynamic-items-list ul.items-list-edit.items-list-without-margin li {
|
.wp-block-tainacan-dynamic-items-list ul.items-list-edit.items-list-without-margin li {
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,13 +7,34 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
// Configure Vue logic before passing it to constructor:
|
// Configure Vue logic before passing it to constructor:
|
||||||
let vueOptions = {
|
let vueOptions = {
|
||||||
data: {
|
data: {
|
||||||
searchURL: ''
|
collectionId: '',
|
||||||
|
showImage: true,
|
||||||
|
showName: true,
|
||||||
|
layout: 'grid',
|
||||||
|
gridMargin: 0,
|
||||||
|
searchURL: '',
|
||||||
|
maxItemsNumber: 12,
|
||||||
|
order: 'asc',
|
||||||
|
showSearchBar: false,
|
||||||
|
tainacanApiRoot: '',
|
||||||
|
tainacanBaseUrl: '',
|
||||||
|
className: ''
|
||||||
},
|
},
|
||||||
render: h => h(DynamicItemsListTheme),
|
render: h => h(DynamicItemsListTheme),
|
||||||
beforeMount () {
|
beforeMount () {
|
||||||
this.searchURL = this.$el.attributes['searchurl'] != undefined ? this.$el.attributes['searchurl'].value : undefined;
|
this.className = this.$el.attributes.class != undefined ? this.$el.attributes.class.value : undefined;
|
||||||
},
|
this.searchURL = this.$el.attributes['search-url'] != undefined ? this.$el.attributes['search-url'].value : undefined;
|
||||||
// All the Vue logic that we need.
|
this.collectionId = this.$el.attributes['collection-id'] != undefined ? this.$el.attributes['collection-id'].value : undefined;
|
||||||
|
this.showImage = this.$el.attributes['show-image'] != undefined ? Boolean(this.$el.attributes['show-image'].value) : true;
|
||||||
|
this.showName = this.$el.attributes['show-name'] != undefined ? Boolean(this.$el.attributes['show-name'].value) : true;
|
||||||
|
this.layout = this.$el.attributes['layout'] != undefined ? this.$el.attributes['layout'].value : undefined;
|
||||||
|
this.gridMargin = this.$el.attributes['grid-margin'] != undefined ? this.$el.attributes['grid-margin'].value : undefined;
|
||||||
|
this.maxItemsNumber = this.$el.attributes['max-items-number'] != undefined ? this.$el.attributes['max-items-number'].value : undefined;
|
||||||
|
this.order = this.$el.attributes['order'] != undefined ? this.$el.attributes['order'].value : undefined;
|
||||||
|
this.showSearchBar = this.$el.attributes['show-search-bar'] != undefined ? Boolean(this.$el.attributes['show-search-bar'].value) : false;
|
||||||
|
this.tainacanApiRoot = this.$el.attributes['tainacan-api-root'] != undefined ? this.$el.attributes['tainacan-api-root'].value : undefined;
|
||||||
|
this.tainacanBaseUrl = this.$el.attributes['tainacan-base-url'] != undefined ? this.$el.attributes['tainacan-base-url'].value : undefined;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Gets all divs with content created by our block;
|
// Gets all divs with content created by our block;
|
||||||
|
|
|
@ -1,11 +1,211 @@
|
||||||
<template>
|
<template>
|
||||||
<div><h3>{{ $root.searchURL }}</h3></div>
|
<div :class="$root.className">
|
||||||
|
<div
|
||||||
|
v-if="$root.showSearchBar"
|
||||||
|
class="dynamic-items-search-bar">
|
||||||
|
<button
|
||||||
|
@click="localOrder = 'asc'; fetchItems()"
|
||||||
|
:class="localOrder == 'asc' ? 'sorting-button-selected' : ''"
|
||||||
|
label="__('label_sort_ascending', 'tainacan')">
|
||||||
|
<span class="icon">
|
||||||
|
<i>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="-2 -4 20 20">
|
||||||
|
<path d="M6.7,10.8l-3.3,3.3L0,10.8h2.5V0h1.7v10.8H6.7z M11.7,0.8H8.3v1.7h3.3V0.8z M14.2,5.8H8.3v1.7h5.8V5.8z M16.7,10.8H8.3v1.7 h8.3V10.8z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="localOrder = 'desc'; fetchItems(); "
|
||||||
|
:class="localOrder == 'desc' ? 'sorting-button-selected' : ''"
|
||||||
|
label="__('label_sort_descending', 'tainacan')">
|
||||||
|
<span class="icon">
|
||||||
|
<i>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="-2 -4 20 20">
|
||||||
|
<path
|
||||||
|
d="M6.7,3.3H4.2v10.8H2.5V3.3H0L3.3,0L6.7,3.3z M11.6,2.5H8.3v1.7h3.3V2.5z M14.1,7.5H8.3v1.7h5.8V7.5z M16.6,12.5H8.3v1.7 h8.3V12.5z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="fetchItems()"
|
||||||
|
label="__('search', 'tainacan')">
|
||||||
|
<span class="icon">
|
||||||
|
<i>
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="-2 -4 20 20">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="M0,5.8C0,5,0.2,4.2,0.5,3.5s0.7-1.3,1.2-1.8s1.1-0.9,1.8-1.2C4.2,0.1,5,0,5.8,0S7.3,0.1,8,0.5
|
||||||
|
c0.7,0.3,1.3,0.7,1.8,1.2s0.9,1.1,1.2,1.8c0.5,1.2,0.5,2.5,0.2,3.7c0,0.2-0.1,0.4-0.2,0.6c0,0.1-0.2,0.6-0.2,0.6
|
||||||
|
c0.6,0.6,1.3,1.3,1.9,1.9c0.7,0.7,1.3,1.3,2,2c0,0,0.3,0.2,0.3,0.3c0,0.3-0.1,0.7-0.3,1c-0.2,0.6-0.8,1-1.4,1.2
|
||||||
|
c-0.1,0-0.6,0.2-0.6,0.1c0,0-4.2-4.2-4.2-4.2c0,0-0.8,0.3-0.8,0.4c-1.3,0.4-2.8,0.5-4.1-0.1c-0.7-0.3-1.3-0.7-1.8-1.2
|
||||||
|
C1.2,9.3,0.8,8.7,0.5,8S0,6.6,0,5.8z M1.6,5.8c0,0.4,0.1,0.9,0.2,1.3C2.1,8.2,3,9.2,4.1,9.6c0.5,0.2,1,0.3,1.6,0.3
|
||||||
|
c0.6,0,1.1-0.1,1.6-0.3C8.7,9,9.7,7.6,9.8,6c0.1-1.5-0.6-3.1-2-3.9c-0.9-0.5-2-0.6-3-0.4C4.6,1.8,4.4,1.9,4.1,2
|
||||||
|
c-0.5,0.2-1,0.5-1.4,0.9C2,3.7,1.6,4.7,1.6,5.8z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<input
|
||||||
|
:value="searchString"
|
||||||
|
@change="(value) => { applySearchString(value) } "
|
||||||
|
type="text" >
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isLoading"
|
||||||
|
class="spinner-container">
|
||||||
|
LOADING SÔ
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<ul
|
||||||
|
v-if="items.length > 0"
|
||||||
|
:style="{ gridTemplateColumns: $root.layout == 'grid' ? 'repeat(auto-fill, ' + ($root.gridMargin + ($root.showName ? 220 : 185)) + 'px)' : 'inherit' }"
|
||||||
|
class="items-list"
|
||||||
|
:class="'items-layout-' + $root.layout + (!$root.showName ? ' items-list-without-margin' : '')">
|
||||||
|
<li
|
||||||
|
:key="index"
|
||||||
|
v-for="(item, index) of items"
|
||||||
|
class="item-list-item"
|
||||||
|
:style="{ marginBottom: $root.layout == 'grid' ? $root.gridMargin + 'px' : ''}">
|
||||||
|
<a
|
||||||
|
:id="isNaN(item.id) ? item.id : 'item-id-' + item.id"
|
||||||
|
:href="item.url"
|
||||||
|
target="_blank"
|
||||||
|
:class="(!$root.showName ? 'item-without-title' : '') + ' ' + (!$root.showImage ? 'item-without-image' : '')">
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
item.thumbnail && item.thumbnail['tainacan-medium'][0] && item.thumbnail['tainacan-medium'][0]
|
||||||
|
?
|
||||||
|
item.thumbnail['tainacan-medium'][0]
|
||||||
|
:
|
||||||
|
(item.thumbnail && item.thumbnail['thumbnail'][0] && item.thumbnail['thumbnail'][0]
|
||||||
|
?
|
||||||
|
item.thumbnail['thumbnail'][0]
|
||||||
|
:
|
||||||
|
`${$root.tainacanBaseUrl}/admin/images/placeholder_square.png`)
|
||||||
|
"
|
||||||
|
:alt="item.title">
|
||||||
|
<span>{{ item.title ? item.title : '' }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div v-else>
|
||||||
|
No items baby.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'qs';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DynamicItemsListTheme",
|
name: "DynamicItemsListTheme",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
items: [],
|
||||||
|
itemsRequestSource: undefined,
|
||||||
|
searchString: '',
|
||||||
|
isLoading: false,
|
||||||
|
localMaxItemsNumber: undefined,
|
||||||
|
localOrder: undefined,
|
||||||
|
tainacanAxios: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
applySearchString(event) {
|
||||||
|
|
||||||
|
let value = event.target.value;
|
||||||
|
|
||||||
|
if (this.searchString != value) {
|
||||||
|
this.searchString = value;
|
||||||
|
this.fetchItems();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fetchItems() {
|
||||||
|
|
||||||
|
this.items = [];
|
||||||
|
this.isLoading = true;
|
||||||
|
|
||||||
|
if (this.itemsRequestSource != undefined && typeof this.itemsRequestSource == 'function')
|
||||||
|
this.itemsRequestSource.cancel('Previous items search canceled.');
|
||||||
|
|
||||||
|
this.itemsRequestSource = axios.CancelToken.source();
|
||||||
|
|
||||||
|
let endpoint = '/collection' + this.$root.searchURL.split('#')[1].split('/collections')[1];
|
||||||
|
let query = endpoint.split('?')[1];
|
||||||
|
let queryObject = qs.parse(query);
|
||||||
|
|
||||||
|
// Set up max items to be shown
|
||||||
|
if (this.$root.maxItemsNumber != undefined && this.$root.maxItemsNumber > 0)
|
||||||
|
queryObject.perpage = this.$root.maxItemsNumber;
|
||||||
|
else if (queryObject.perpage != undefined && queryObject.perpage > 0)
|
||||||
|
this.localMaxItemsNumber = queryObject.perpage;
|
||||||
|
else {
|
||||||
|
queryObject.perpage = 12;
|
||||||
|
this.localMaxItemsNumber = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up sorting order
|
||||||
|
if (this.localOrder != undefined)
|
||||||
|
queryObject.order = this.localOrder;
|
||||||
|
else if (queryObject.order != undefined)
|
||||||
|
this.localOrder = queryObject.order;
|
||||||
|
else {
|
||||||
|
queryObject.order = 'asc';
|
||||||
|
this.localOrder = 'asc';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up sorting order
|
||||||
|
if (this.searchString != undefined)
|
||||||
|
queryObject.search = this.searchString;
|
||||||
|
else if (queryObject.search != undefined)
|
||||||
|
this.searchString = queryObject.search;
|
||||||
|
else {
|
||||||
|
delete queryObject.search;
|
||||||
|
this.searchString = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unecessary queries
|
||||||
|
delete queryObject.readmode;
|
||||||
|
delete queryObject.iframemode;
|
||||||
|
delete queryObject.admin_view_mode;
|
||||||
|
|
||||||
|
endpoint = endpoint.split('?')[0] + '?' + qs.stringify(queryObject) + '&fetch_only=title,url,thumbnail';
|
||||||
|
|
||||||
|
this.tainacanAxios.get(endpoint, { cancelToken: this.itemsRequestSource.token })
|
||||||
|
.then(response => {
|
||||||
|
for (let item of response.data.items)
|
||||||
|
this.items.push(item);
|
||||||
|
this.isLoading = false;
|
||||||
|
}).catch((error) => {
|
||||||
|
this.isLoading = false;
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
}
|
this.localOrder = this.$root.order;
|
||||||
|
|
||||||
|
this.tainacanAxios = axios.create({ baseURL: this.$root.tainacanApiRoot });
|
||||||
|
this.fetchItems();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
@import './dynamic-items-list.scss';
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
button {
|
button {
|
||||||
margin-right: 0.75rem;
|
margin-right: 0.75rem;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: #cbcbcb;
|
fill: #cbcbcb;
|
||||||
|
@ -34,6 +37,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
|
height: 32px;
|
||||||
width: 20%;
|
width: 20%;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
margin-left: -52px;
|
margin-left: -52px;
|
||||||
|
@ -57,6 +61,7 @@
|
||||||
grid-template-columns: repeat(auto-fill, 185px);
|
grid-template-columns: repeat(auto-fill, 185px);
|
||||||
justify-content: center !important;
|
justify-content: center !important;
|
||||||
grid-template-rows: auto !important;
|
grid-template-rows: auto !important;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
|
|
|
@ -489,14 +489,34 @@ registerBlockType('tainacan/dynamic-items-list', {
|
||||||
},
|
},
|
||||||
save({ attributes, className }){
|
save({ attributes, className }){
|
||||||
const {
|
const {
|
||||||
|
content,
|
||||||
|
blockId,
|
||||||
|
collectionId,
|
||||||
|
showImage,
|
||||||
|
showName,
|
||||||
|
layout,
|
||||||
|
gridMargin,
|
||||||
searchURL,
|
searchURL,
|
||||||
content,
|
maxItemsNumber,
|
||||||
blockId
|
order,
|
||||||
|
showSearchBar
|
||||||
} = attributes;
|
} = attributes;
|
||||||
|
console.log(className)
|
||||||
return <div
|
return <div
|
||||||
searchURL={ searchURL }
|
search-url={ searchURL }
|
||||||
className={ className }
|
className={ className }
|
||||||
id={ 'wp-block-tainacan-dynamic-items-list_' + blockId }>{ content }</div>
|
collection-id={ collectionId }
|
||||||
|
show-image={ '' + showImage }
|
||||||
|
show-name={ '' + showName }
|
||||||
|
show-search-bar={ '' + showSearchBar }
|
||||||
|
layout={ layout }
|
||||||
|
grid-margin={ gridMargin }
|
||||||
|
max-items-number={ maxItemsNumber }
|
||||||
|
order={ order }
|
||||||
|
tainacan-api-root={ tainacan_plugin.root }
|
||||||
|
tainacan-base-url={ tainacan_plugin.base_url }
|
||||||
|
id={ 'wp-block-tainacan-dynamic-items-list_' + blockId }>
|
||||||
|
{ content }
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
});
|
});
|
Loading…
Reference in New Issue