Continues refactor for block.json strategy #580
This commit is contained in:
parent
4115e40d57
commit
6cb63649f4
|
@ -318,7 +318,9 @@
|
|||
display: -ms-grid;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 50% 50%; }
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-gap: 5px;
|
||||
gap: 5px; }
|
||||
.wp-block-tainacan-carousel-terms-list ul.terms-list-edit li.term-list-item .term-items-grid img:first-of-type {
|
||||
flex-basis: 100%;
|
||||
-ms-grid-column: 1;
|
||||
|
@ -329,7 +331,6 @@
|
|||
grid-row: 1/3; }
|
||||
.wp-block-tainacan-carousel-terms-list ul.terms-list-edit li.term-list-item .term-items-grid img {
|
||||
flex-basis: 50%;
|
||||
padding: 2px;
|
||||
margin-bottom: 0px; }
|
||||
.wp-block-tainacan-carousel-terms-list ul.terms-list-edit li.terms-list-item {
|
||||
width: calc(20% - 32px);
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -229,7 +229,7 @@ function tainacan_blocks_register_block($block_slug, $options = []) {
|
|||
if (function_exists('register_block_type')) {
|
||||
if (
|
||||
version_compare( $wp_version, '5.8-RC', '>=') &&
|
||||
($block_slug == 'carousel-collections-list' || $block_slug == 'collections-list' || $block_slug == 'carousel-items-list')
|
||||
($block_slug == 'carousel-collections-list' || $block_slug == 'collections-list' || $block_slug == 'carousel-items-list' || $block_slug == 'carousel-terms-list' || $block_slug == 'dynamic-items-list')
|
||||
)
|
||||
register_block_type( __DIR__ . '/tainacan-blocks/' . $block_slug );
|
||||
else
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class CarouselItemsModal extends React.Component {
|
|||
collectionId: this.props.existingCollectionId
|
||||
});
|
||||
|
||||
if (this.props.existingCollectionId != null && this.props.existingCollectionId != undefined) {
|
||||
if (this.props.existingCollectionId) {
|
||||
this.fetchCollection(this.props.existingCollectionId);
|
||||
this.setState({
|
||||
searchURL: this.props.existingSearchURL ? this.props.existingSearchURL : tainacan_blocks.admin_url + 'admin.php?page=tainacan_admin#/collections/'+ this.props.existingCollectionId + (this.props.loadStrategy == 'search' ? '/items/?iframemode=true&readmode=true&status=publish' : '/items/?iframemode=true&status=publish') });
|
||||
|
@ -116,7 +116,8 @@ export default class CarouselItemsModal extends React.Component {
|
|||
collectionId: selectedCollectionId,
|
||||
searchURL: tainacan_blocks.admin_url + 'admin.php?page=tainacan_admin#/collections/' + selectedCollectionId + (this.props.loadStrategy == 'search' ? '/items/?iframemode=true&readmode=true&status=publish' : '/items/?iframemode=true&status=publish')
|
||||
});
|
||||
|
||||
console.log(selectedCollectionId)
|
||||
console.log(tainacan_blocks.admin_url + 'admin.php?page=tainacan_admin#/collections/' + selectedCollectionId + (this.props.loadStrategy == 'search' ? '/items/?iframemode=true&readmode=true&status=publish' : '/items/?iframemode=true&status=publish'));
|
||||
this.props.onSelectCollection(selectedCollectionId);
|
||||
this.fetchCollection(selectedCollectionId);
|
||||
}
|
||||
|
@ -201,7 +202,7 @@ export default class CarouselItemsModal extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return this.state.collectionId != null && this.state.collectionId != undefined ? (
|
||||
return this.state.collectionId ? (
|
||||
// Items modal
|
||||
<Modal
|
||||
className="wp-block-tainacan-modal dynamic-modal"
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"name": "tainacan/carousel-terms-list",
|
||||
"title": "Tainacan Terms Carousel",
|
||||
"category": "tainacan-blocks",
|
||||
"keywords": [ "carousel", "slider", "taxonomy" ],
|
||||
"description": "List terms on a Carousel, showing their thumbnails or a preview of items.",
|
||||
"example": {
|
||||
"attributes": {
|
||||
"content": "preview"
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"content": {
|
||||
"type": "Array",
|
||||
"source": "children",
|
||||
"selector": "div"
|
||||
},
|
||||
"terms": {
|
||||
"type": "Array",
|
||||
"default": []
|
||||
},
|
||||
"isModalOpen": {
|
||||
"type": "Boolean",
|
||||
"default": false
|
||||
},
|
||||
"selectedTerms": {
|
||||
"type": "Array",
|
||||
"default": []
|
||||
},
|
||||
"itemsRequestSource": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"maxTermsNumber": {
|
||||
"type": "Number",
|
||||
"value": 12
|
||||
},
|
||||
"maxTermsPerScreen": {
|
||||
"type": "Number",
|
||||
"value": 6
|
||||
},
|
||||
"isLoading": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"isLoadingTerm": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"arrowsPosition": {
|
||||
"type": "String",
|
||||
"value": "around"
|
||||
},
|
||||
"largeArrows": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"autoPlay": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"autoPlaySpeed": {
|
||||
"type": "Number",
|
||||
"value": 3
|
||||
},
|
||||
"loopSlides": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"hideName": {
|
||||
"type": "Boolean",
|
||||
"value": true
|
||||
},
|
||||
"showTermThumbnail": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"term": {
|
||||
"type": "Object",
|
||||
"value": {}
|
||||
},
|
||||
"blockId": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"termBackgroundColor": {
|
||||
"type": "String",
|
||||
"default": "#454647"
|
||||
},
|
||||
"termTextColor": {
|
||||
"type": "String",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"taxonomyId": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"supports": {
|
||||
"align": ["full", "wide"],
|
||||
"html": false,
|
||||
"multiple": true,
|
||||
"typography": {
|
||||
"fontSize": true
|
||||
}
|
||||
},
|
||||
"editorScript": "carousel-terms-list",
|
||||
"script": "carousel-terms-list-theme",
|
||||
"editorStyle": "carousel-terms-list",
|
||||
"style": "carousel-terms-list"
|
||||
}
|
|
@ -1,4 +1,135 @@
|
|||
export default [
|
||||
/* Deprecated on Tainacan 0.18.4 due to the new block.json strategy */
|
||||
{
|
||||
attributes: {
|
||||
content: {
|
||||
type: 'array',
|
||||
source: 'children',
|
||||
selector: 'div'
|
||||
},
|
||||
terms: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
isModalOpen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
selectedTerms: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
itemsRequestSource: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
maxTermsNumber: {
|
||||
type: Number,
|
||||
value: undefined
|
||||
},
|
||||
maxTermsPerScreen: {
|
||||
type: Number,
|
||||
value: 6
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
isLoadingTerm: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
arrowsPosition: {
|
||||
type: String,
|
||||
value: 'search'
|
||||
},
|
||||
largeArrows: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
autoPlay: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
autoPlaySpeed: {
|
||||
type: Number,
|
||||
value: 3
|
||||
},
|
||||
loopSlides: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
hideName: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
showTermThumbnail: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
term: {
|
||||
type: Object,
|
||||
value: undefined
|
||||
},
|
||||
blockId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
termBackgroundColor: {
|
||||
type: String,
|
||||
default: "#454647"
|
||||
},
|
||||
termTextColor: {
|
||||
type: String,
|
||||
default: "#ffffff"
|
||||
},
|
||||
taxonomyId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
supports: {
|
||||
align: ['full', 'wide'],
|
||||
html: false,
|
||||
multiple: true,
|
||||
fontSize: true
|
||||
},
|
||||
save({ attributes, className }){
|
||||
const {
|
||||
content,
|
||||
blockId,
|
||||
selectedTerms,
|
||||
arrowsPosition,
|
||||
largeArrows,
|
||||
maxTermsPerScreen,
|
||||
maxTermsNumber,
|
||||
autoPlay,
|
||||
autoPlaySpeed,
|
||||
loopSlides,
|
||||
hideName,
|
||||
showTermThumbnail,
|
||||
taxonomyId
|
||||
} = attributes;
|
||||
return <div
|
||||
className={ className }
|
||||
selected-terms={ JSON.stringify(selectedTerms.map((term) => { return term.id; })) }
|
||||
arrows-position={ arrowsPosition }
|
||||
auto-play={ '' + autoPlay }
|
||||
auto-play-speed={ autoPlaySpeed }
|
||||
loop-slides={ '' + loopSlides }
|
||||
hide-name={ '' + hideName }
|
||||
large-arrows={ '' + largeArrows }
|
||||
max-terms-number={ maxTermsNumber }
|
||||
max-terms-per-screen={ maxTermsPerScreen }
|
||||
taxonomy-id={ taxonomyId }
|
||||
tainacan-api-root={ tainacan_blocks.root }
|
||||
tainacan-base-url={ tainacan_blocks.base_url }
|
||||
show-term-thumbnail={ '' + showTermThumbnail }
|
||||
id={ 'wp-block-tainacan-carousel-terms-list_' + blockId }>
|
||||
{ content }
|
||||
</div>
|
||||
}
|
||||
},
|
||||
/* Deprecated on Tainacan 0.17.2, due to the introduction of support: fontSize */
|
||||
{
|
||||
attributes: {
|
|
@ -0,0 +1,429 @@
|
|||
const { __ } = wp.i18n;
|
||||
|
||||
const { RangeControl, Spinner, Button, BaseControl, ToggleControl, SelectControl, Placeholder, IconButton, PanelBody } = wp.components;
|
||||
|
||||
const { InspectorControls, BlockControls } = ( tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
|
||||
|
||||
import TermsModal from '../terms-list/terms-modal.js';
|
||||
import tainacan from '../../js/axios.js';
|
||||
import axios from 'axios';
|
||||
import qs from 'qs';
|
||||
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
|
||||
import TainacanBlocksCompatToolbar from '../../js/tainacan-blocks-compat-toolbar.js';
|
||||
import 'swiper/css/swiper.min.css';
|
||||
|
||||
export default function({ attributes, setAttributes, className, isSelected, clientId }){
|
||||
let {
|
||||
terms,
|
||||
content,
|
||||
isModalOpen,
|
||||
itemsRequestSource,
|
||||
selectedTerms,
|
||||
isLoading,
|
||||
largeArrows,
|
||||
maxTermsPerScreen,
|
||||
arrowsPosition,
|
||||
autoPlay,
|
||||
autoPlaySpeed,
|
||||
loopSlides,
|
||||
hideName,
|
||||
showTermThumbnail,
|
||||
taxonomyId
|
||||
} = attributes;
|
||||
|
||||
// Obtains block's client id to render it on save function
|
||||
setAttributes({ blockId: clientId });
|
||||
|
||||
// Sets some defaults that were not working
|
||||
if (maxTermsPerScreen === undefined) {
|
||||
maxTermsPerScreen = 6;
|
||||
setAttributes({ maxTermsPerScreen: maxTermsPerScreen });
|
||||
}
|
||||
|
||||
const thumbHelper = ThumbnailHelperFunctions();
|
||||
|
||||
function prepareItem(term, termItems) {
|
||||
return (
|
||||
<li
|
||||
key={ term.id }
|
||||
className={ 'term-list-item ' + (!showTermThumbnail ? 'term-list-item-grid ' : '') + (maxTermsPerScreen ? ' max-terms-per-screen-' + maxTermsPerScreen : '') }>
|
||||
{ tainacan_blocks.wp_version < '5.4' ?
|
||||
<IconButton
|
||||
onClick={ () => removeItemOfId(term.id) }
|
||||
icon="no-alt"
|
||||
label={__('Remove', 'tainacan')}/>
|
||||
:
|
||||
<Button
|
||||
onClick={ () => removeItemOfId(term.id) }
|
||||
icon="no-alt"
|
||||
label={__('Remove', 'tainacan')}/>
|
||||
}
|
||||
<a
|
||||
id={ isNaN(term.id) ? term.id : 'term-id-' + term.id }
|
||||
href={ term.url }
|
||||
target="_blank">
|
||||
{ !showTermThumbnail ?
|
||||
<div class="term-items-grid">
|
||||
<img
|
||||
src={ termItems[0] ? thumbHelper.getSrc(termItems[0]['thumbnail'], 'tainacan-medium', termItems[0]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
srcSet={ termItems[0] ? thumbHelper.getSrcSet(termItems[0]['thumbnail'], 'tainacan-medium', termItems[0]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
alt={ termItems[0] && termItems[0].thumbnail_alt ? termItems[0].thumbnail_alt : (termItems[0] && termItems[0].name ? termItems[0].name : __( 'Thumbnail', 'tainacan' )) } />
|
||||
<img
|
||||
src={ termItems[1] ? thumbHelper.getSrc(termItems[1]['thumbnail'], 'tainacan-medium', termItems[1]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
srcSet={ termItems[1] ? thumbHelper.getSrcSet(termItems[1]['thumbnail'], 'tainacan-medium', termItems[1]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
alt={ termItems[1] && termItems[1].thumbnail_alt ? termItems[1].thumbnail_alt : (termItems[1] && termItems[1].name ? termItems[1].name : __( 'Thumbnail', 'tainacan' )) } />
|
||||
<img
|
||||
src={ termItems[2] ? thumbHelper.getSrc(termItems[2]['thumbnail'], 'tainacan-medium', termItems[2]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
srcSet={ termItems[2] ? thumbHelper.getSrcSet(termItems[2]['thumbnail'], 'tainacan-medium', termItems[2]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
alt={ termItems[2] && termItems[2].thumbnail_alt ? termItems[2].thumbnail_alt : (termItems[2] && termItems[2].name ? termItems[2].name : __( 'Thumbnail', 'tainacan' )) } />
|
||||
</div>
|
||||
:
|
||||
<img
|
||||
src={ term.header_image ? term.header_image : `${tainacan_blocks.base_url}/assets/images/placeholder_square.png`}
|
||||
alt={ term.name ? term.name : __( 'Thumbnail', 'tainacan' )}/>
|
||||
}
|
||||
{ !hideName ? <span>{ term.name ? term.name : '' }</span> : null }
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
function setContent(){
|
||||
isLoading = true;
|
||||
|
||||
setAttributes({
|
||||
isLoading: isLoading
|
||||
});
|
||||
|
||||
if (itemsRequestSource != undefined && typeof itemsRequestSource == 'function')
|
||||
itemsRequestSource.cancel('Previous terms search canceled.');
|
||||
|
||||
itemsRequestSource = axios.CancelToken.source();
|
||||
|
||||
terms = [];
|
||||
|
||||
let endpoint = '/taxonomy/' + taxonomyId + '/terms/?'+ qs.stringify({ hideempty: 0, include: selectedTerms.map((term) => { return term.id; }) }) + '&order=asc&fetch_only=id,name,url,header_image';
|
||||
tainacan.get(endpoint, { cancelToken: itemsRequestSource.token })
|
||||
.then(response => {
|
||||
|
||||
if (showTermThumbnail) {
|
||||
for (let term of response.data) {
|
||||
terms.push(prepareItem(term));
|
||||
}
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
terms: terms,
|
||||
isLoading: false,
|
||||
itemsRequestSource: itemsRequestSource
|
||||
});
|
||||
} else {
|
||||
let promises = [];
|
||||
for (let term of response.data) {
|
||||
promises.push(
|
||||
tainacan.get('/items/?perpage=3&fetch_only=name,url,thumbnail&taxquery[0][taxonomy]=tnc_tax_' + taxonomyId + '&taxquery[0][terms][0]=' + term.id + '&taxquery[0][compare]=IN')
|
||||
.then(response => { return({ term: term, termItems: response.data.items }) })
|
||||
.catch((error) => console.log(error))
|
||||
);
|
||||
}
|
||||
axios.all(promises).then((results) => {
|
||||
for (let result of results) {
|
||||
terms.push(prepareItem(result.term, result.termItems));
|
||||
}
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
terms: terms,
|
||||
isLoading: false,
|
||||
itemsRequestSource: itemsRequestSource
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openCarouselModal() {
|
||||
isModalOpen = true;
|
||||
setAttributes( {
|
||||
isModalOpen: isModalOpen
|
||||
} );
|
||||
}
|
||||
|
||||
function removeItemOfId(itemId) {
|
||||
|
||||
let existingItemIndex = terms.findIndex((existingItem) => existingItem.key == itemId);
|
||||
if (existingItemIndex >= 0)
|
||||
terms.splice(existingItemIndex, 1);
|
||||
|
||||
let existingSelectedItemIndex = selectedTerms.findIndex((existingSelectedItem) => existingSelectedItem.id == itemId);
|
||||
if (existingSelectedItemIndex >= 0)
|
||||
selectedTerms.splice(existingSelectedItemIndex, 1);
|
||||
|
||||
setAttributes({
|
||||
selectedTerms: selectedTerms,
|
||||
terms: terms,
|
||||
content: <div></div>
|
||||
});
|
||||
}
|
||||
|
||||
// Executed only on the first load of page
|
||||
if(content && content.length && content[0].type)
|
||||
setContent();
|
||||
|
||||
return content == 'preview' ?
|
||||
<div className={className}>
|
||||
<img
|
||||
width="100%"
|
||||
src={ `${tainacan_blocks.base_url}/assets/images/carousel-terms-list.png` } />
|
||||
</div>
|
||||
: (
|
||||
<div className={className}>
|
||||
|
||||
{ terms.length ?
|
||||
<BlockControls>
|
||||
{
|
||||
TainacanBlocksCompatToolbar({
|
||||
label: __('Add more terms', 'tainacan'),
|
||||
icon: <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -2 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path d="M21.43,14.64,19.32,17a2.57,2.57,0,0,1-2,1H12.05a6,6,0,0,0-6-6H6V10.64A2.59,2.59,0,0,1,8.59,8H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,14.64ZM4,4A2,2,0,0,0,2,6v7.63a5.74,5.74,0,0,1,2-1.2V6H16V4ZM7,15.05v6.06l3.06-3.06ZM5,21.11V15.05L1.94,18.11Z"/>
|
||||
</svg>,
|
||||
onClick: openCarouselModal
|
||||
})
|
||||
}
|
||||
</BlockControls>
|
||||
: null }
|
||||
|
||||
<div>
|
||||
<InspectorControls>
|
||||
|
||||
<PanelBody
|
||||
title={__('Carousel', 'tainacan')}
|
||||
initialOpen={ true }
|
||||
>
|
||||
<BaseControl
|
||||
id="term-carousel-view-modes"
|
||||
label={ __('Term layout', 'tainacan')}>
|
||||
<div className="term-carousel-view-modes">
|
||||
<button
|
||||
onClick={ () => {
|
||||
showTermThumbnail = false;
|
||||
setAttributes({ showTermThumbnail: showTermThumbnail });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
className={'term-carousel-view-mode-grid' + (showTermThumbnail ? '' : ' is-active')}>
|
||||
<div>
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
<label>{ __('Items\'s grid', 'tainacan') }</label>
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => {
|
||||
showTermThumbnail = true;
|
||||
setAttributes({ showTermThumbnail: showTermThumbnail });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
className={'term-carousel-view-mode-thumbnail' + (showTermThumbnail ? ' is-active' : '')}>
|
||||
<div />
|
||||
<label>{ __('Thumbnail', 'tainacan') }</label>
|
||||
</button>
|
||||
</div>
|
||||
</BaseControl>
|
||||
<RangeControl
|
||||
label={ __('Maximum terms per slide on a wide screen', 'tainacan') }
|
||||
help={ (showTermThumbnail && maxTermsPerScreen <= 3) ? __('Warning: with such a small number of terms per slide, the image size is greater and might be pixelated.', 'tainacan') : null }
|
||||
value={ maxTermsPerScreen ? maxTermsPerScreen : 6 }
|
||||
onChange={ ( aMaxTermsPerScreen ) => {
|
||||
maxTermsPerScreen = aMaxTermsPerScreen;
|
||||
setAttributes( { maxTermsPerScreen: aMaxTermsPerScreen } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 9 }
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Hide name', 'tainacan')}
|
||||
help={ !hideName ? __('Toggle to hide term\'s name', 'tainacan') : __('Do not hide term\'s name', 'tainacan')}
|
||||
checked={ hideName }
|
||||
onChange={ ( isChecked ) => {
|
||||
hideName = isChecked;
|
||||
setAttributes({ hideName: hideName });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Loop slides', 'tainacan')}
|
||||
help={ !loopSlides ? __('Toggle to make slides loop from first to last', 'tainacan') : __('Do not loop slides from first to last', 'tainacan')}
|
||||
checked={ loopSlides }
|
||||
onChange={ ( isChecked ) => {
|
||||
loopSlides = isChecked;
|
||||
setAttributes({ loopSlides: loopSlides });
|
||||
}
|
||||
}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Auto play', 'tainacan')}
|
||||
help={ !autoPlay ? __('Toggle to automatically slide to next term', 'tainacan') : __('Do not automatically slide to next term', 'tainacan')}
|
||||
checked={ autoPlay }
|
||||
onChange={ ( isChecked ) => {
|
||||
autoPlay = isChecked;
|
||||
setAttributes({ autoPlay: autoPlay });
|
||||
}
|
||||
}
|
||||
/>
|
||||
{
|
||||
autoPlay ?
|
||||
<RangeControl
|
||||
label={__('Seconds before translating to next', 'tainacan')}
|
||||
value={ autoPlaySpeed ? autoPlaySpeed : 3 }
|
||||
onChange={ ( aAutoPlaySpeed ) => {
|
||||
autoPlaySpeed = aAutoPlaySpeed;
|
||||
setAttributes( { autoPlaySpeed: aAutoPlaySpeed } )
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 5 }
|
||||
/>
|
||||
: null
|
||||
}
|
||||
<SelectControl
|
||||
label={__('Arrows', 'tainacan')}
|
||||
value={ arrowsPosition }
|
||||
options={ [
|
||||
{ label: __('Around', 'tainacan'), value: 'around' },
|
||||
{ label: __('Left', 'tainacan'), value: 'left' },
|
||||
{ label: __('Right', 'tainacan'), value: 'right' }
|
||||
] }
|
||||
onChange={ ( aPosition ) => {
|
||||
arrowsPosition = aPosition;
|
||||
|
||||
setAttributes({ arrowsPosition: arrowsPosition });
|
||||
}}/>
|
||||
<ToggleControl
|
||||
label={__('Large arrows', 'tainacan')}
|
||||
help={ !largeArrows ? __('Toggle to display arrows bigger than the default size.', 'tainacan') : __('Do not show arrows bigger than the default size.', 'tainacan')}
|
||||
checked={ largeArrows }
|
||||
onChange={ ( isChecked ) => {
|
||||
largeArrows = isChecked;
|
||||
setAttributes({ largeArrows: largeArrows });
|
||||
}
|
||||
}
|
||||
/>
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
</div>
|
||||
|
||||
{ isSelected ?
|
||||
(
|
||||
<div>
|
||||
{ isModalOpen ?
|
||||
<TermsModal
|
||||
replaceTermId={ false } // The Terms modal adds `term-id-` string to terms ids. Here we dont' need it
|
||||
existingTaxonomyId={ taxonomyId }
|
||||
selectedTermsObject={ selectedTerms }
|
||||
onSelectTaxonomy={ (selectedTaxonomyId) => {
|
||||
taxonomyId = selectedTaxonomyId;
|
||||
setAttributes({ taxonomyId: taxonomyId });
|
||||
}}
|
||||
onApplySelection={ (aSelectionOfTerms) =>{
|
||||
selectedTerms = aSelectionOfTerms;
|
||||
|
||||
setAttributes({
|
||||
selectedTerms: selectedTerms,
|
||||
isModalOpen: false
|
||||
});
|
||||
setContent();
|
||||
}}
|
||||
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
|
||||
: null
|
||||
}
|
||||
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{ !terms.length && !isLoading ? (
|
||||
<Placeholder
|
||||
className="tainacan-block-placeholder"
|
||||
icon={(
|
||||
<img
|
||||
width={148}
|
||||
src={ `${tainacan_blocks.base_url}/assets/images/tainacan_logo_header.svg` }
|
||||
alt="Tainacan Logo"/>
|
||||
)}>
|
||||
<p>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path d="M21.43,14.64,19.32,17a2.57,2.57,0,0,1-2,1H12.05a6,6,0,0,0-6-6H6V10.64A2.59,2.59,0,0,1,8.59,8H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,14.64ZM4,4A2,2,0,0,0,2,6v7.63a5.74,5.74,0,0,1,2-1.2V6H16V4ZM7,15.05v6.06l3.06-3.06ZM5,21.11V15.05L1.94,18.11Z"/>
|
||||
</svg>
|
||||
{__('List terms on a Carousel, showing their thumbnails or a preview of items.', 'tainacan')}
|
||||
</p>
|
||||
<Button
|
||||
isPrimary
|
||||
type="button"
|
||||
onClick={ () => openCarouselModal() }>
|
||||
{__('Select Terms', 'tainacan')}
|
||||
</Button>
|
||||
</Placeholder>
|
||||
) : null
|
||||
}
|
||||
|
||||
{ isLoading ?
|
||||
<div class="spinner-container">
|
||||
<Spinner />
|
||||
</div> :
|
||||
<div>
|
||||
{ isSelected && terms.length ?
|
||||
<div class="preview-warning">{__('Warning: this is just a demonstration. To see the carousel in action, either preview or publish your post.', 'tainacan')}</div>
|
||||
: null
|
||||
}
|
||||
{ terms.length ? (
|
||||
<div
|
||||
className={'terms-list-edit-container ' + (arrowsPosition ? 'has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') }>
|
||||
<button
|
||||
class="swiper-button-prev"
|
||||
slot="button-prev"
|
||||
style={{ cursor: 'not-allowed' }}>
|
||||
<svg
|
||||
width={ largeArrows ? 60 : 42 }
|
||||
height={ largeArrows ? 60 : 42 }
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"/>
|
||||
</svg>
|
||||
</button>
|
||||
<ul className={'terms-list-edit'}>
|
||||
{ terms }
|
||||
</ul>
|
||||
<button
|
||||
class="swiper-button-next"
|
||||
slot="button-next"
|
||||
style={{ cursor: 'not-allowed' }}>
|
||||
<svg
|
||||
width={ largeArrows ? 60 : 42 }
|
||||
height={ largeArrows ? 60 : 42 }
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
):null
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
const { SVG, Path } = wp.components;
|
||||
|
||||
export default (
|
||||
<SVG
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<Path
|
||||
fill="#298596"
|
||||
d="M21.43,14.64,19.32,17a2.57,2.57,0,0,1-2,1H12.05a6,6,0,0,0-6-6H6V10.64A2.59,2.59,0,0,1,8.59,8H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,14.64ZM4,4A2,2,0,0,0,2,6v7.63a5.74,5.74,0,0,1,2-1.2V6H16V4ZM7,15.05v6.06l3.06-3.06ZM5,21.11V15.05L1.94,18.11Z"/>
|
||||
</SVG>
|
||||
);
|
||||
|
|
@ -1,582 +1,15 @@
|
|||
const { registerBlockType } = wp.blocks;
|
||||
import tainacanRegisterBlockType from '../../js/tainacan-blocks-compat-register.js';
|
||||
|
||||
const { __ } = wp.i18n;
|
||||
import metadata from './block.json';
|
||||
import icon from './icon.js';
|
||||
import edit from './edit.js';
|
||||
import save from './save.js';
|
||||
import deprecated from './deprecated.js';
|
||||
|
||||
const { RangeControl, Spinner, Button, BaseControl, ToggleControl, SelectControl, Placeholder, IconButton, PanelBody } = wp.components;
|
||||
|
||||
const { InspectorControls, BlockControls } = ( tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
|
||||
|
||||
import TermsModal from '../terms-list/terms-modal.js';
|
||||
import tainacan from '../../js/axios.js';
|
||||
import axios from 'axios';
|
||||
import qs from 'qs';
|
||||
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
|
||||
import TainacanBlocksCompatToolbar from '../../js/tainacan-blocks-compat-toolbar.js';
|
||||
import DeprecatedBlocks from './carousel-terms-list-deprecated.js';
|
||||
import 'swiper/css/swiper.min.css';
|
||||
|
||||
registerBlockType('tainacan/carousel-terms-list', {
|
||||
title: __('Tainacan Terms Carousel', 'tainacan'),
|
||||
icon:
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path
|
||||
fill="#298596"
|
||||
d="M21.43,14.64,19.32,17a2.57,2.57,0,0,1-2,1H12.05a6,6,0,0,0-6-6H6V10.64A2.59,2.59,0,0,1,8.59,8H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,14.64ZM4,4A2,2,0,0,0,2,6v7.63a5.74,5.74,0,0,1,2-1.2V6H16V4ZM7,15.05v6.06l3.06-3.06ZM5,21.11V15.05L1.94,18.11Z"/>
|
||||
</svg>,
|
||||
category: 'tainacan-blocks',
|
||||
keywords: [ __( 'carousel', 'tainacan' ), __( 'slider', 'tainacan' ), __( 'taxonomy', 'tainacan' ) ],
|
||||
description: __('List terms on a Carousel, showing their thumbnails or a preview of items.', 'tainacan'),
|
||||
example: {
|
||||
attributes: {
|
||||
content: 'preview'
|
||||
}
|
||||
},
|
||||
attributes: {
|
||||
content: {
|
||||
type: 'array',
|
||||
source: 'children',
|
||||
selector: 'div'
|
||||
},
|
||||
terms: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
isModalOpen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
selectedTerms: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
itemsRequestSource: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
maxTermsNumber: {
|
||||
type: Number,
|
||||
value: undefined
|
||||
},
|
||||
maxTermsPerScreen: {
|
||||
type: Number,
|
||||
value: 6
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
isLoadingTerm: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
arrowsPosition: {
|
||||
type: String,
|
||||
value: 'search'
|
||||
},
|
||||
largeArrows: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
autoPlay: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
autoPlaySpeed: {
|
||||
type: Number,
|
||||
value: 3
|
||||
},
|
||||
loopSlides: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
hideName: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
showTermThumbnail: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
term: {
|
||||
type: Object,
|
||||
value: undefined
|
||||
},
|
||||
blockId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
termBackgroundColor: {
|
||||
type: String,
|
||||
default: "#454647"
|
||||
},
|
||||
termTextColor: {
|
||||
type: String,
|
||||
default: "#ffffff"
|
||||
},
|
||||
taxonomyId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
supports: {
|
||||
align: ['full', 'wide'],
|
||||
html: false,
|
||||
multiple: true,
|
||||
fontSize: true
|
||||
},
|
||||
edit({ attributes, setAttributes, className, isSelected, clientId }){
|
||||
let {
|
||||
terms,
|
||||
content,
|
||||
isModalOpen,
|
||||
itemsRequestSource,
|
||||
selectedTerms,
|
||||
isLoading,
|
||||
largeArrows,
|
||||
maxTermsPerScreen,
|
||||
arrowsPosition,
|
||||
autoPlay,
|
||||
autoPlaySpeed,
|
||||
loopSlides,
|
||||
hideName,
|
||||
showTermThumbnail,
|
||||
taxonomyId
|
||||
} = attributes;
|
||||
|
||||
// Obtains block's client id to render it on save function
|
||||
setAttributes({ blockId: clientId });
|
||||
|
||||
// Sets some defaults that were not working
|
||||
if (maxTermsPerScreen === undefined) {
|
||||
maxTermsPerScreen = 6;
|
||||
setAttributes({ maxTermsPerScreen: maxTermsPerScreen });
|
||||
}
|
||||
|
||||
const thumbHelper = ThumbnailHelperFunctions();
|
||||
|
||||
function prepareItem(term, termItems) {
|
||||
return (
|
||||
<li
|
||||
key={ term.id }
|
||||
className={ 'term-list-item ' + (!showTermThumbnail ? 'term-list-item-grid ' : '') + (maxTermsPerScreen ? ' max-terms-per-screen-' + maxTermsPerScreen : '') }>
|
||||
{ tainacan_blocks.wp_version < '5.4' ?
|
||||
<IconButton
|
||||
onClick={ () => removeItemOfId(term.id) }
|
||||
icon="no-alt"
|
||||
label={__('Remove', 'tainacan')}/>
|
||||
:
|
||||
<Button
|
||||
onClick={ () => removeItemOfId(term.id) }
|
||||
icon="no-alt"
|
||||
label={__('Remove', 'tainacan')}/>
|
||||
}
|
||||
<a
|
||||
id={ isNaN(term.id) ? term.id : 'term-id-' + term.id }
|
||||
href={ term.url }
|
||||
target="_blank">
|
||||
{ !showTermThumbnail ?
|
||||
<div class="term-items-grid">
|
||||
<img
|
||||
src={ termItems[0] ? thumbHelper.getSrc(termItems[0]['thumbnail'], 'tainacan-medium', termItems[0]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
srcSet={ termItems[0] ? thumbHelper.getSrcSet(termItems[0]['thumbnail'], 'tainacan-medium', termItems[0]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
alt={ termItems[0] && termItems[0].thumbnail_alt ? termItems[0].thumbnail_alt : (termItems[0] && termItems[0].name ? termItems[0].name : __( 'Thumbnail', 'tainacan' )) } />
|
||||
<img
|
||||
src={ termItems[1] ? thumbHelper.getSrc(termItems[1]['thumbnail'], 'tainacan-medium', termItems[1]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
srcSet={ termItems[1] ? thumbHelper.getSrcSet(termItems[1]['thumbnail'], 'tainacan-medium', termItems[1]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
alt={ termItems[1] && termItems[1].thumbnail_alt ? termItems[1].thumbnail_alt : (termItems[1] && termItems[1].name ? termItems[1].name : __( 'Thumbnail', 'tainacan' )) } />
|
||||
<img
|
||||
src={ termItems[2] ? thumbHelper.getSrc(termItems[2]['thumbnail'], 'tainacan-medium', termItems[2]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
srcSet={ termItems[2] ? thumbHelper.getSrcSet(termItems[2]['thumbnail'], 'tainacan-medium', termItems[2]['document_mimetype']) :`${tainacan_blocks.base_url}/assets/images/placeholder_square.png` }
|
||||
alt={ termItems[2] && termItems[2].thumbnail_alt ? termItems[2].thumbnail_alt : (termItems[2] && termItems[2].name ? termItems[2].name : __( 'Thumbnail', 'tainacan' )) } />
|
||||
</div>
|
||||
:
|
||||
<img
|
||||
src={ term.header_image ? term.header_image : `${tainacan_blocks.base_url}/assets/images/placeholder_square.png`}
|
||||
alt={ term.name ? term.name : __( 'Thumbnail', 'tainacan' )}/>
|
||||
}
|
||||
{ !hideName ? <span>{ term.name ? term.name : '' }</span> : null }
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
function setContent(){
|
||||
isLoading = true;
|
||||
|
||||
setAttributes({
|
||||
isLoading: isLoading
|
||||
});
|
||||
|
||||
if (itemsRequestSource != undefined && typeof itemsRequestSource == 'function')
|
||||
itemsRequestSource.cancel('Previous terms search canceled.');
|
||||
|
||||
itemsRequestSource = axios.CancelToken.source();
|
||||
|
||||
terms = [];
|
||||
|
||||
let endpoint = '/taxonomy/' + taxonomyId + '/terms/?'+ qs.stringify({ hideempty: 0, include: selectedTerms.map((term) => { return term.id; }) }) + '&order=asc&fetch_only=id,name,url,header_image';
|
||||
tainacan.get(endpoint, { cancelToken: itemsRequestSource.token })
|
||||
.then(response => {
|
||||
|
||||
if (showTermThumbnail) {
|
||||
for (let term of response.data) {
|
||||
terms.push(prepareItem(term));
|
||||
}
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
terms: terms,
|
||||
isLoading: false,
|
||||
itemsRequestSource: itemsRequestSource
|
||||
});
|
||||
} else {
|
||||
let promises = [];
|
||||
for (let term of response.data) {
|
||||
promises.push(
|
||||
tainacan.get('/items/?perpage=3&fetch_only=name,url,thumbnail&taxquery[0][taxonomy]=tnc_tax_' + taxonomyId + '&taxquery[0][terms][0]=' + term.id + '&taxquery[0][compare]=IN')
|
||||
.then(response => { return({ term: term, termItems: response.data.items }) })
|
||||
.catch((error) => console.log(error))
|
||||
);
|
||||
}
|
||||
axios.all(promises).then((results) => {
|
||||
for (let result of results) {
|
||||
terms.push(prepareItem(result.term, result.termItems));
|
||||
}
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
terms: terms,
|
||||
isLoading: false,
|
||||
itemsRequestSource: itemsRequestSource
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openCarouselModal() {
|
||||
isModalOpen = true;
|
||||
setAttributes( {
|
||||
isModalOpen: isModalOpen
|
||||
} );
|
||||
}
|
||||
|
||||
function removeItemOfId(itemId) {
|
||||
|
||||
let existingItemIndex = terms.findIndex((existingItem) => existingItem.key == itemId);
|
||||
if (existingItemIndex >= 0)
|
||||
terms.splice(existingItemIndex, 1);
|
||||
|
||||
let existingSelectedItemIndex = selectedTerms.findIndex((existingSelectedItem) => existingSelectedItem.id == itemId);
|
||||
if (existingSelectedItemIndex >= 0)
|
||||
selectedTerms.splice(existingSelectedItemIndex, 1);
|
||||
|
||||
setAttributes({
|
||||
selectedTerms: selectedTerms,
|
||||
terms: terms,
|
||||
content: <div></div>
|
||||
});
|
||||
}
|
||||
|
||||
// Executed only on the first load of page
|
||||
if(content && content.length && content[0].type)
|
||||
setContent();
|
||||
|
||||
return content == 'preview' ?
|
||||
<div className={className}>
|
||||
<img
|
||||
width="100%"
|
||||
src={ `${tainacan_blocks.base_url}/assets/images/carousel-terms-list.png` } />
|
||||
</div>
|
||||
: (
|
||||
<div className={className}>
|
||||
|
||||
{ terms.length ?
|
||||
<BlockControls>
|
||||
{
|
||||
TainacanBlocksCompatToolbar({
|
||||
label: __('Add more terms', 'tainacan'),
|
||||
icon: <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -2 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path d="M21.43,14.64,19.32,17a2.57,2.57,0,0,1-2,1H12.05a6,6,0,0,0-6-6H6V10.64A2.59,2.59,0,0,1,8.59,8H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,14.64ZM4,4A2,2,0,0,0,2,6v7.63a5.74,5.74,0,0,1,2-1.2V6H16V4ZM7,15.05v6.06l3.06-3.06ZM5,21.11V15.05L1.94,18.11Z"/>
|
||||
</svg>,
|
||||
onClick: openCarouselModal
|
||||
})
|
||||
}
|
||||
</BlockControls>
|
||||
: null }
|
||||
|
||||
<div>
|
||||
<InspectorControls>
|
||||
|
||||
<PanelBody
|
||||
title={__('Carousel', 'tainacan')}
|
||||
initialOpen={ true }
|
||||
>
|
||||
<BaseControl
|
||||
id="term-carousel-view-modes"
|
||||
label={ __('Term layout', 'tainacan')}>
|
||||
<div className="term-carousel-view-modes">
|
||||
<button
|
||||
onClick={ () => {
|
||||
showTermThumbnail = false;
|
||||
setAttributes({ showTermThumbnail: showTermThumbnail });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
className={'term-carousel-view-mode-grid' + (showTermThumbnail ? '' : ' is-active')}>
|
||||
<div>
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
<label>{ __('Items\'s grid', 'tainacan') }</label>
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => {
|
||||
showTermThumbnail = true;
|
||||
setAttributes({ showTermThumbnail: showTermThumbnail });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
className={'term-carousel-view-mode-thumbnail' + (showTermThumbnail ? ' is-active' : '')}>
|
||||
<div />
|
||||
<label>{ __('Thumbnail', 'tainacan') }</label>
|
||||
</button>
|
||||
</div>
|
||||
</BaseControl>
|
||||
<RangeControl
|
||||
label={ __('Maximum terms per slide on a wide screen', 'tainacan') }
|
||||
help={ (showTermThumbnail && maxTermsPerScreen <= 3) ? __('Warning: with such a small number of terms per slide, the image size is greater and might be pixelated.', 'tainacan') : null }
|
||||
value={ maxTermsPerScreen ? maxTermsPerScreen : 6 }
|
||||
onChange={ ( aMaxTermsPerScreen ) => {
|
||||
maxTermsPerScreen = aMaxTermsPerScreen;
|
||||
setAttributes( { maxTermsPerScreen: aMaxTermsPerScreen } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 9 }
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Hide name', 'tainacan')}
|
||||
help={ !hideName ? __('Toggle to hide term\'s name', 'tainacan') : __('Do not hide term\'s name', 'tainacan')}
|
||||
checked={ hideName }
|
||||
onChange={ ( isChecked ) => {
|
||||
hideName = isChecked;
|
||||
setAttributes({ hideName: hideName });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Loop slides', 'tainacan')}
|
||||
help={ !loopSlides ? __('Toggle to make slides loop from first to last', 'tainacan') : __('Do not loop slides from first to last', 'tainacan')}
|
||||
checked={ loopSlides }
|
||||
onChange={ ( isChecked ) => {
|
||||
loopSlides = isChecked;
|
||||
setAttributes({ loopSlides: loopSlides });
|
||||
}
|
||||
}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Auto play', 'tainacan')}
|
||||
help={ !autoPlay ? __('Toggle to automatically slide to next term', 'tainacan') : __('Do not automatically slide to next term', 'tainacan')}
|
||||
checked={ autoPlay }
|
||||
onChange={ ( isChecked ) => {
|
||||
autoPlay = isChecked;
|
||||
setAttributes({ autoPlay: autoPlay });
|
||||
}
|
||||
}
|
||||
/>
|
||||
{
|
||||
autoPlay ?
|
||||
<RangeControl
|
||||
label={__('Seconds before translating to next', 'tainacan')}
|
||||
value={ autoPlaySpeed ? autoPlaySpeed : 3 }
|
||||
onChange={ ( aAutoPlaySpeed ) => {
|
||||
autoPlaySpeed = aAutoPlaySpeed;
|
||||
setAttributes( { autoPlaySpeed: aAutoPlaySpeed } )
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 5 }
|
||||
/>
|
||||
: null
|
||||
}
|
||||
<SelectControl
|
||||
label={__('Arrows', 'tainacan')}
|
||||
value={ arrowsPosition }
|
||||
options={ [
|
||||
{ label: __('Around', 'tainacan'), value: 'around' },
|
||||
{ label: __('Left', 'tainacan'), value: 'left' },
|
||||
{ label: __('Right', 'tainacan'), value: 'right' }
|
||||
] }
|
||||
onChange={ ( aPosition ) => {
|
||||
arrowsPosition = aPosition;
|
||||
|
||||
setAttributes({ arrowsPosition: arrowsPosition });
|
||||
}}/>
|
||||
<ToggleControl
|
||||
label={__('Large arrows', 'tainacan')}
|
||||
help={ !largeArrows ? __('Toggle to display arrows bigger than the default size.', 'tainacan') : __('Do not show arrows bigger than the default size.', 'tainacan')}
|
||||
checked={ largeArrows }
|
||||
onChange={ ( isChecked ) => {
|
||||
largeArrows = isChecked;
|
||||
setAttributes({ largeArrows: largeArrows });
|
||||
}
|
||||
}
|
||||
/>
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
</div>
|
||||
|
||||
{ isSelected ?
|
||||
(
|
||||
<div>
|
||||
{ isModalOpen ?
|
||||
<TermsModal
|
||||
replaceTermId={ false } // The Terms modal adds `term-id-` string to terms ids. Here we dont' need it
|
||||
existingTaxonomyId={ taxonomyId }
|
||||
selectedTermsObject={ selectedTerms }
|
||||
onSelectTaxonomy={ (selectedTaxonomyId) => {
|
||||
taxonomyId = selectedTaxonomyId;
|
||||
setAttributes({ taxonomyId: taxonomyId });
|
||||
}}
|
||||
onApplySelection={ (aSelectionOfTerms) =>{
|
||||
selectedTerms = aSelectionOfTerms;
|
||||
|
||||
setAttributes({
|
||||
selectedTerms: selectedTerms,
|
||||
isModalOpen: false
|
||||
});
|
||||
setContent();
|
||||
}}
|
||||
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
|
||||
: null
|
||||
}
|
||||
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{ !terms.length && !isLoading ? (
|
||||
<Placeholder
|
||||
className="tainacan-block-placeholder"
|
||||
icon={(
|
||||
<img
|
||||
width={148}
|
||||
src={ `${tainacan_blocks.base_url}/assets/images/tainacan_logo_header.svg` }
|
||||
alt="Tainacan Logo"/>
|
||||
)}>
|
||||
<p>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path d="M21.43,14.64,19.32,17a2.57,2.57,0,0,1-2,1H12.05a6,6,0,0,0-6-6H6V10.64A2.59,2.59,0,0,1,8.59,8H17.3a2.57,2.57,0,0,1,2,1l2.11,2.38A2.59,2.59,0,0,1,21.43,14.64ZM4,4A2,2,0,0,0,2,6v7.63a5.74,5.74,0,0,1,2-1.2V6H16V4ZM7,15.05v6.06l3.06-3.06ZM5,21.11V15.05L1.94,18.11Z"/>
|
||||
</svg>
|
||||
{__('List terms on a Carousel, showing their thumbnails or a preview of items.', 'tainacan')}
|
||||
</p>
|
||||
<Button
|
||||
isPrimary
|
||||
type="button"
|
||||
onClick={ () => openCarouselModal() }>
|
||||
{__('Select Terms', 'tainacan')}
|
||||
</Button>
|
||||
</Placeholder>
|
||||
) : null
|
||||
}
|
||||
|
||||
{ isLoading ?
|
||||
<div class="spinner-container">
|
||||
<Spinner />
|
||||
</div> :
|
||||
<div>
|
||||
{ isSelected && terms.length ?
|
||||
<div class="preview-warning">{__('Warning: this is just a demonstration. To see the carousel in action, either preview or publish your post.', 'tainacan')}</div>
|
||||
: null
|
||||
}
|
||||
{ terms.length ? (
|
||||
<div
|
||||
className={'terms-list-edit-container ' + (arrowsPosition ? 'has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') }>
|
||||
<button
|
||||
class="swiper-button-prev"
|
||||
slot="button-prev"
|
||||
style={{ cursor: 'not-allowed' }}>
|
||||
<svg
|
||||
width={ largeArrows ? 60 : 42 }
|
||||
height={ largeArrows ? 60 : 42 }
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"/>
|
||||
</svg>
|
||||
</button>
|
||||
<ul className={'terms-list-edit'}>
|
||||
{ terms }
|
||||
</ul>
|
||||
<button
|
||||
class="swiper-button-next"
|
||||
slot="button-next"
|
||||
style={{ cursor: 'not-allowed' }}>
|
||||
<svg
|
||||
width={ largeArrows ? 60 : 42 }
|
||||
height={ largeArrows ? 60 : 42 }
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
):null
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
save({ attributes, className }){
|
||||
const {
|
||||
content,
|
||||
blockId,
|
||||
selectedTerms,
|
||||
arrowsPosition,
|
||||
largeArrows,
|
||||
maxTermsPerScreen,
|
||||
maxTermsNumber,
|
||||
autoPlay,
|
||||
autoPlaySpeed,
|
||||
loopSlides,
|
||||
hideName,
|
||||
showTermThumbnail,
|
||||
taxonomyId
|
||||
} = attributes;
|
||||
return <div
|
||||
className={ className }
|
||||
selected-terms={ JSON.stringify(selectedTerms.map((term) => { return term.id; })) }
|
||||
arrows-position={ arrowsPosition }
|
||||
auto-play={ '' + autoPlay }
|
||||
auto-play-speed={ autoPlaySpeed }
|
||||
loop-slides={ '' + loopSlides }
|
||||
hide-name={ '' + hideName }
|
||||
large-arrows={ '' + largeArrows }
|
||||
max-terms-number={ maxTermsNumber }
|
||||
max-terms-per-screen={ maxTermsPerScreen }
|
||||
taxonomy-id={ taxonomyId }
|
||||
tainacan-api-root={ tainacan_blocks.root }
|
||||
tainacan-base-url={ tainacan_blocks.base_url }
|
||||
show-term-thumbnail={ '' + showTermThumbnail }
|
||||
id={ 'wp-block-tainacan-carousel-terms-list_' + blockId }>
|
||||
{ content }
|
||||
</div>
|
||||
},
|
||||
deprecated: DeprecatedBlocks
|
||||
});
|
||||
tainacanRegisterBlockType({
|
||||
metadata,
|
||||
icon,
|
||||
edit,
|
||||
save,
|
||||
deprecated
|
||||
});
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
export default function({ attributes, className }) {
|
||||
const {
|
||||
content,
|
||||
blockId,
|
||||
selectedTerms,
|
||||
arrowsPosition,
|
||||
largeArrows,
|
||||
maxTermsPerScreen,
|
||||
maxTermsNumber,
|
||||
autoPlay,
|
||||
autoPlaySpeed,
|
||||
loopSlides,
|
||||
hideName,
|
||||
showTermThumbnail,
|
||||
taxonomyId
|
||||
} = attributes;
|
||||
return <div
|
||||
className={ className }
|
||||
selected-terms={ JSON.stringify(selectedTerms.map((term) => { return term.id; })) }
|
||||
arrows-position={ arrowsPosition }
|
||||
auto-play={ '' + autoPlay }
|
||||
auto-play-speed={ autoPlaySpeed }
|
||||
loop-slides={ '' + loopSlides }
|
||||
hide-name={ '' + hideName }
|
||||
large-arrows={ '' + largeArrows }
|
||||
max-terms-number={ maxTermsNumber }
|
||||
max-terms-per-screen={ maxTermsPerScreen }
|
||||
taxonomy-id={ taxonomyId }
|
||||
tainacan-api-root={ tainacan_blocks.root }
|
||||
tainacan-base-url={ tainacan_blocks.base_url }
|
||||
show-term-thumbnail={ '' + showTermThumbnail }
|
||||
id={ 'wp-block-tainacan-carousel-terms-list_' + blockId }>
|
||||
{ content }
|
||||
</div>
|
||||
};
|
|
@ -382,7 +382,9 @@
|
|||
.term-items-grid {
|
||||
@include display-grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 50% 50%;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-gap: 5px;
|
||||
gap: 5px;
|
||||
|
||||
img:first-of-type {
|
||||
flex-basis: 100%;
|
||||
|
@ -391,7 +393,6 @@
|
|||
|
||||
img {
|
||||
flex-basis: 50%;
|
||||
padding: 2px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
{
|
||||
"name": "tainacan/dynamic-items-list",
|
||||
"title": "Tainacan Collection\"s Items List",
|
||||
"category": "tainacan-blocks",
|
||||
"keywords": [ "items", "search", "collection" ],
|
||||
"description": "Dynamically list items from a Tainacan items search",
|
||||
"example": {
|
||||
"attributes": {
|
||||
"content": "preview"
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"content": {
|
||||
"type": "Array",
|
||||
"source": "children",
|
||||
"selector": "div"
|
||||
},
|
||||
"collectionId": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"items": {
|
||||
"type": "Array",
|
||||
"default": []
|
||||
},
|
||||
"showImage": {
|
||||
"type": "Boolean",
|
||||
"default": true
|
||||
},
|
||||
"showName": {
|
||||
"type": "Boolean",
|
||||
"default": true
|
||||
},
|
||||
"layout": {
|
||||
"type": "String",
|
||||
"default": "grid"
|
||||
},
|
||||
"isModalOpen": {
|
||||
"type": "Boolean",
|
||||
"default": false
|
||||
},
|
||||
"gridMargin": {
|
||||
"type": "Number",
|
||||
"default": 0
|
||||
},
|
||||
"searchURL": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"itemsRequestSource": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"maxItemsNumber": {
|
||||
"type": "Number",
|
||||
"value": 12
|
||||
},
|
||||
"isLoading": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"isLoadingCollection": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"showSearchBar": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"showCollectionHeader": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"showCollectionLabel": {
|
||||
"type": "Boolean",
|
||||
"value": false
|
||||
},
|
||||
"collection": {
|
||||
"type": "Object",
|
||||
"value": {}
|
||||
},
|
||||
"searchString": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"order": {
|
||||
"type": "String",
|
||||
"default": "asc"
|
||||
},
|
||||
"blockId": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"collectionBackgroundColor": {
|
||||
"type": "String",
|
||||
"default": "#454647"
|
||||
},
|
||||
"collectionTextColor": {
|
||||
"type": "String",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"mosaicHeight": {
|
||||
"type": "Number",
|
||||
"value": 280
|
||||
},
|
||||
"mosaicGridColumns": {
|
||||
"type": "Number",
|
||||
"value": 3
|
||||
},
|
||||
"mosaicGridRows": {
|
||||
"type": "Number",
|
||||
"value": 3
|
||||
},
|
||||
"sampleBackgroundImage": {
|
||||
"type": "String",
|
||||
"default": ""
|
||||
},
|
||||
"mosaicItemFocalPoint": {
|
||||
"type": "Object",
|
||||
"default": {
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
}
|
||||
},
|
||||
"mosaicDensity": {
|
||||
"type": "Number",
|
||||
"default": 5
|
||||
},
|
||||
"maxColumnsCount": {
|
||||
"type": "Number",
|
||||
"default": 4
|
||||
},
|
||||
"cropImagesToSquare": {
|
||||
"type": "Boolean",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"supports": {
|
||||
"align": ["full", "wide"],
|
||||
"html": false,
|
||||
"typography": {
|
||||
"fontSize": true
|
||||
}
|
||||
},
|
||||
"editorScript": "dynamic-items-list",
|
||||
"script": "dynamic-items-list-theme",
|
||||
"editorStyle": "dynamic-items-list",
|
||||
"style": "dynamic-items-list"
|
||||
}
|
|
@ -1,4 +1,193 @@
|
|||
export default [
|
||||
/* Deprecated on Tainacan 0.18.4, due to the new block.json strategy */
|
||||
{
|
||||
attributes: {
|
||||
content: {
|
||||
type: 'array',
|
||||
source: 'children',
|
||||
selector: 'div'
|
||||
},
|
||||
collectionId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
showImage: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showName: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'grid'
|
||||
},
|
||||
isModalOpen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
gridMargin: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
searchURL: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
itemsRequestSource: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
maxItemsNumber: {
|
||||
type: Number,
|
||||
value: undefined
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
isLoadingCollection: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
showSearchBar: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
showCollectionHeader: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
showCollectionLabel: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
collection: {
|
||||
type: Object,
|
||||
value: undefined
|
||||
},
|
||||
searchString: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
order: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
blockId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
collectionBackgroundColor: {
|
||||
type: String,
|
||||
default: "#454647"
|
||||
},
|
||||
collectionTextColor: {
|
||||
type: String,
|
||||
default: "#ffffff"
|
||||
},
|
||||
mosaicHeight: {
|
||||
type: Number,
|
||||
value: 280
|
||||
},
|
||||
mosaicGridColumns: {
|
||||
type: Number,
|
||||
value: 3
|
||||
},
|
||||
mosaicGridRows: {
|
||||
type: Number,
|
||||
value: 3
|
||||
},
|
||||
sampleBackgroundImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
mosaicItemFocalPoint: {
|
||||
type: Object,
|
||||
default: {
|
||||
x: 0.5,
|
||||
y: 0.5
|
||||
}
|
||||
},
|
||||
mosaicDensity: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
maxColumnsCount: {
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
cropImagesToSquare: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
}
|
||||
},
|
||||
supports: {
|
||||
align: ['full', 'wide'],
|
||||
html: false,
|
||||
fontSize: true
|
||||
},
|
||||
save({ attributes, className }){
|
||||
const {
|
||||
content,
|
||||
blockId,
|
||||
collectionId,
|
||||
showImage,
|
||||
showName,
|
||||
layout,
|
||||
gridMargin,
|
||||
searchURL,
|
||||
maxItemsNumber,
|
||||
order,
|
||||
showSearchBar,
|
||||
showCollectionHeader,
|
||||
showCollectionLabel,
|
||||
collectionBackgroundColor,
|
||||
collectionTextColor,
|
||||
mosaicHeight,
|
||||
mosaicGridRows,
|
||||
mosaicGridColumns,
|
||||
mosaicItemFocalPoint,
|
||||
mosaicDensity,
|
||||
maxColumnsCount,
|
||||
cropImagesToSquare
|
||||
} = attributes;
|
||||
|
||||
return <div
|
||||
search-url={ searchURL }
|
||||
className={ className }
|
||||
collection-id={ collectionId }
|
||||
show-image={ '' + showImage }
|
||||
show-name={ '' + showName }
|
||||
show-search-bar={ '' + showSearchBar }
|
||||
show-collection-header={ '' + showCollectionHeader }
|
||||
show-collection-label={ '' + showCollectionLabel }
|
||||
crop-images-to-square={ '' + cropImagesToSquare }
|
||||
layout={ layout }
|
||||
mosaic-height={ mosaicHeight }
|
||||
mosaic-density={ mosaicDensity }
|
||||
mosaic-grid-rows={ mosaicGridRows }
|
||||
mosaic-grid-columns={ mosaicGridColumns }
|
||||
mosaic-item-focal-point-x={ (mosaicItemFocalPoint && mosaicItemFocalPoint.x ? mosaicItemFocalPoint.x : 0.5) }
|
||||
mosaic-item-focal-point-y={ (mosaicItemFocalPoint && mosaicItemFocalPoint.y ? mosaicItemFocalPoint.y : 0.5) }
|
||||
max-columns-count={ maxColumnsCount }
|
||||
collection-background-color={ collectionBackgroundColor }
|
||||
collection-text-color={ collectionTextColor }
|
||||
grid-margin={ gridMargin }
|
||||
max-items-number={ maxItemsNumber }
|
||||
order={ order }
|
||||
tainacan-api-root={ tainacan_blocks.root }
|
||||
tainacan-base-url={ tainacan_blocks.base_url }
|
||||
id={ 'wp-block-tainacan-dynamic-items-list_' + blockId }>
|
||||
{ content }
|
||||
</div>
|
||||
}
|
||||
},
|
||||
/* Deprecated on Tainacan 0.18, due to the introduction of maxColumnsCount and fix of osaicItemFocalPointm */
|
||||
{
|
||||
attributes: {
|
|
@ -40,7 +40,7 @@ export default class DynamicItemsModal extends React.Component {
|
|||
collectionId: this.props.existingCollectionId
|
||||
});
|
||||
|
||||
if (this.props.existingCollectionId != null && this.props.existingCollectionId != undefined) {
|
||||
if (this.props.existingCollectionId) {
|
||||
this.fetchCollection(this.props.existingCollectionId);
|
||||
this.setState({ searchURL: this.props.existingSearchURL ? this.props.existingSearchURL : tainacan_blocks.admin_url + 'admin.php?page=tainacan_admin#/collections/'+ this.props.existingCollectionId + '/items/?readmode=true&iframemode=true&status=publish' });
|
||||
} else {
|
||||
|
@ -165,7 +165,7 @@ export default class DynamicItemsModal extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return this.state.collectionId != null && this.state.collectionId != undefined ? (
|
||||
return this.state.collectionId ? (
|
||||
// Items modal
|
||||
<Modal
|
||||
className="wp-block-tainacan-modal dynamic-modal"
|
||||
|
|
|
@ -0,0 +1,876 @@
|
|||
const { __ } = wp.i18n;
|
||||
|
||||
const { ResizableBox, FocalPointPicker, SelectControl, RangeControl, Spinner, Button, ToggleControl, Placeholder, ColorPicker, ColorPalette, BaseControl, PanelBody } = wp.components;
|
||||
|
||||
const { InspectorControls, BlockControls } = ( tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
|
||||
|
||||
import DynamicItemsModal from './dynamic-items-modal.js';
|
||||
import tainacan from '../../js/axios.js';
|
||||
import axios from 'axios';
|
||||
import qs from 'qs';
|
||||
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
|
||||
import TainacanBlocksCompatToolbar from '../../js/tainacan-blocks-compat-toolbar.js';
|
||||
|
||||
export default function({ attributes, setAttributes, className, isSelected, clientId }){
|
||||
let {
|
||||
items,
|
||||
content,
|
||||
collection,
|
||||
collectionId,
|
||||
showImage,
|
||||
showName,
|
||||
layout,
|
||||
isModalOpen,
|
||||
gridMargin,
|
||||
searchURL,
|
||||
itemsRequestSource,
|
||||
maxItemsNumber,
|
||||
order,
|
||||
searchString,
|
||||
isLoading,
|
||||
showSearchBar,
|
||||
showCollectionHeader,
|
||||
showCollectionLabel,
|
||||
isLoadingCollection,
|
||||
collectionBackgroundColor,
|
||||
collectionTextColor,
|
||||
mosaicHeight,
|
||||
mosaicGridColumns,
|
||||
mosaicGridRows,
|
||||
mosaicItemFocalPoint,
|
||||
sampleBackgroundImage,
|
||||
mosaicDensity,
|
||||
maxColumnsCount,
|
||||
cropImagesToSquare
|
||||
} = attributes;
|
||||
|
||||
// Obtains block's client id to render it on save function
|
||||
setAttributes({ blockId: clientId });
|
||||
|
||||
// Sets some defaults that were not working
|
||||
if (maxColumnsCount === undefined) {
|
||||
maxColumnsCount = 5;
|
||||
setAttributes({ maxColumnsCount: maxColumnsCount });
|
||||
}
|
||||
if (cropImagesToSquare === undefined) {
|
||||
cropImagesToSquare = true;
|
||||
setAttributes({ cropImagesToSquare: cropImagesToSquare });
|
||||
}
|
||||
|
||||
const thumbHelper = ThumbnailHelperFunctions();
|
||||
|
||||
function prepareItem(item) {
|
||||
return (
|
||||
<li
|
||||
key={ item.id }
|
||||
className="item-list-item"
|
||||
style={ {
|
||||
backgroundImage: layout == 'mosaic' ? `url(${ thumbHelper.getSrc(item['thumbnail'], 'medium_large', item['document_mimetype']) })` : 'none',
|
||||
backgroundPosition: layout == 'mosaic' ? `${ (mosaicItemFocalPoint && mosaicItemFocalPoint.x ? mosaicItemFocalPoint.x : 0.5) * 100 }% ${ (mosaicItemFocalPoint && mosaicItemFocalPoint.y ? mosaicItemFocalPoint.y : 0.5) * 100 }%` : 'none'
|
||||
}}
|
||||
>
|
||||
<a
|
||||
id={ isNaN(item.id) ? item.id : 'item-id-' + item.id }
|
||||
href={ item.url }
|
||||
onClick={ (event) => event.preventDefault() }
|
||||
target="_blank"
|
||||
style={ {
|
||||
|
||||
} }
|
||||
className={ (!showName ? 'item-without-title' : '') + ' ' + (!showImage ? 'item-without-image' : '') }>
|
||||
<img
|
||||
src={ thumbHelper.getSrc(item['thumbnail'], ( (layout == 'list' || cropImagesToSquare) ? 'tainacan-medium' : 'tainacan-medium-full'), item['document_mimetype']) }
|
||||
srcSet={ thumbHelper.getSrcSet(item['thumbnail'], ( (layout == 'list' || cropImagesToSquare) ? 'tainacan-medium' : 'tainacan-medium-full'), item['document_mimetype']) }
|
||||
alt={ item.thumbnail_alt ? item.thumbnail_alt : (item && item.title ? item.title : __( 'Thumbnail', 'tainacan' )) }/>
|
||||
<span>{ item.title ? item.title : '' }</span>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
function prepareMosaicItem(mosaicGroup, mosaicGroupsLength) {
|
||||
|
||||
return (
|
||||
<div
|
||||
style={
|
||||
{
|
||||
width: 'calc((100% / ' + mosaicGroupsLength + ') - ' + gridMargin + 'px)',
|
||||
height: 'calc(((' + (mosaicGridRows - 1) + ' * ' + gridMargin + 'px) + ' + mosaicHeight + 'px))',
|
||||
gridTemplateColumns: 'repeat(' + mosaicGridColumns + ', calc((100% / ' + mosaicGridColumns + ') - (' + ((mosaicGridColumns - 1)*Number(gridMargin)) + 'px/' + mosaicGridColumns + ')))',
|
||||
margin: gridMargin + 'px',
|
||||
gridGap: gridMargin + 'px',
|
||||
}
|
||||
}
|
||||
className={ 'mosaic-container mosaic-container--' + mosaicGroup.length + '-' + mosaicGridRows + 'x' + mosaicGridColumns }>
|
||||
{ buildMosaic(mosaicGroup) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function setContent(){
|
||||
|
||||
if (searchURL) {
|
||||
|
||||
items = [];
|
||||
isLoading = true;
|
||||
|
||||
if (itemsRequestSource != undefined && typeof itemsRequestSource == 'function')
|
||||
itemsRequestSource.cancel('Previous items search canceled.');
|
||||
|
||||
itemsRequestSource = axios.CancelToken.source();
|
||||
|
||||
setAttributes({
|
||||
isLoading: isLoading
|
||||
});
|
||||
|
||||
let endpoint = '/collection' + searchURL.split('#')[1].split('/collections')[1];
|
||||
let query = endpoint.split('?')[1];
|
||||
let queryObject = qs.parse(query);
|
||||
|
||||
// Set up max items to be shown
|
||||
if (maxItemsNumber != undefined && maxItemsNumber > 0)
|
||||
queryObject.perpage = maxItemsNumber;
|
||||
else if (queryObject.perpage != undefined && queryObject.perpage > 0)
|
||||
setAttributes({ maxItemsNumber: queryObject.perpage });
|
||||
else {
|
||||
queryObject.perpage = 12;
|
||||
setAttributes({ maxItemsNumber: 12 });
|
||||
}
|
||||
|
||||
// Set up sorting order
|
||||
if (!order)
|
||||
queryObject.order = order;
|
||||
else if (!queryObject.order)
|
||||
setAttributes({ order: queryObject.order });
|
||||
else {
|
||||
queryObject.order = 'asc';
|
||||
setAttributes({ order: 'asc' });
|
||||
}
|
||||
|
||||
// Set up sorting order
|
||||
if (searchString != undefined)
|
||||
queryObject.search = searchString;
|
||||
else if (queryObject.search != undefined)
|
||||
setAttributes({ searchString: queryObject.search });
|
||||
else {
|
||||
delete queryObject.search;
|
||||
setAttributes({ searchString: undefined });
|
||||
}
|
||||
|
||||
// Remove unecessary queries
|
||||
delete queryObject.readmode;
|
||||
delete queryObject.iframemode;
|
||||
delete queryObject.admin_view_mode;
|
||||
delete queryObject.fetch_only_meta;
|
||||
|
||||
endpoint = endpoint.split('?')[0] + '?' + qs.stringify(queryObject) + '&fetch_only=title,url,thumbnail';
|
||||
|
||||
tainacan.get(endpoint, { cancelToken: itemsRequestSource.token })
|
||||
.then(response => {
|
||||
|
||||
if (layout !== 'mosaic') {
|
||||
|
||||
for (let item of response.data.items)
|
||||
items.push(prepareItem(item));
|
||||
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
items: items,
|
||||
isLoading: false,
|
||||
itemsRequestSource: itemsRequestSource
|
||||
});
|
||||
|
||||
} else {
|
||||
// Initializes some variables
|
||||
mosaicDensity = mosaicDensity ? mosaicDensity : 5;
|
||||
mosaicGridRows = mosaicGridRows ? mosaicGridRows : 3;
|
||||
mosaicGridColumns = mosaicGridColumns ? mosaicGridColumns : 3;
|
||||
mosaicHeight = mosaicHeight ? mosaicHeight : 280;
|
||||
mosaicItemFocalPoint = mosaicItemFocalPoint ? mosaicItemFocalPoint : { x: 0.5, y: 0.5 };
|
||||
sampleBackgroundImage = response.data.items && response.data.items[0] && response.data.items[0] ? getItemThumbnail(response.data.items[0], 'tainacan-medium') : '';
|
||||
|
||||
const mosaicGroups = mosaicPartition(response.data.items);
|
||||
for (let mosaicGroup of mosaicGroups)
|
||||
items.push(prepareMosaicItem(mosaicGroup, mosaicGroups.length));
|
||||
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
items: items,
|
||||
isLoading: false,
|
||||
itemsRequestSource: itemsRequestSource,
|
||||
mosaicDensity: mosaicDensity,
|
||||
mosaicHeight: mosaicHeight,
|
||||
mosaicGridRows: mosaicGridRows,
|
||||
mosaicGridColumns: mosaicGridColumns,
|
||||
mosaicItemFocalPoint: mosaicItemFocalPoint,
|
||||
sampleBackgroundImage: sampleBackgroundImage
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function fetchCollectionForHeader() {
|
||||
if (showCollectionHeader) {
|
||||
|
||||
isLoadingCollection = true;
|
||||
setAttributes({
|
||||
isLoadingCollection: isLoadingCollection
|
||||
});
|
||||
|
||||
tainacan.get('/collections/' + collectionId + '?fetch_only=name,thumbnail,header_image')
|
||||
.then(response => {
|
||||
collection = response.data;
|
||||
isLoadingCollection = false;
|
||||
|
||||
if (collection.tainacan_theme_collection_background_color)
|
||||
collectionBackgroundColor = collection.tainacan_theme_collection_background_color;
|
||||
else
|
||||
collectionBackgroundColor = '#454647';
|
||||
|
||||
if (collection.tainacan_theme_collection_color)
|
||||
collectionTextColor = collection.tainacan_theme_collection_color;
|
||||
else
|
||||
collectionTextColor = '#ffffff';
|
||||
|
||||
setAttributes({
|
||||
content: <div></div>,
|
||||
collection: collection,
|
||||
isLoadingCollection: isLoadingCollection,
|
||||
collectionBackgroundColor: collectionBackgroundColor,
|
||||
collectionTextColor: collectionTextColor
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getItemThumbnail(item, size) {
|
||||
return (
|
||||
item.thumbnail && item.thumbnail[size][0] && item.thumbnail[size][0]
|
||||
?
|
||||
item.thumbnail[size][0]
|
||||
:
|
||||
(item.thumbnail && item.thumbnail['thumbnail'][0] && item.thumbnail['thumbnail'][0]
|
||||
?
|
||||
item.thumbnail['thumbnail'][0]
|
||||
:
|
||||
`${tainacan_blocks.base_url}/assets/images/placeholder_square.png`)
|
||||
)
|
||||
}
|
||||
|
||||
function openDynamicItemsModal() {
|
||||
isModalOpen = true;
|
||||
setAttributes( {
|
||||
isModalOpen: isModalOpen
|
||||
} );
|
||||
}
|
||||
|
||||
function updateLayout(newLayout) {
|
||||
layout = newLayout;
|
||||
|
||||
if ((layout == 'grid' || layout == 'mosaic') && showImage == false)
|
||||
showImage = true;
|
||||
|
||||
if (layout == 'list' && showName == false)
|
||||
showName = true;
|
||||
|
||||
setAttributes({
|
||||
layout: layout,
|
||||
showImage: showImage,
|
||||
showName: showName
|
||||
});
|
||||
setContent();
|
||||
}
|
||||
|
||||
function applySearchString(event) {
|
||||
|
||||
let value = event.target.value;
|
||||
|
||||
if (searchString != value) {
|
||||
searchString = value;
|
||||
setAttributes({ searchString: searchString });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
|
||||
function updateMosaicItemFocalPoint(focalPoint) {
|
||||
if (Math.abs(focalPoint.x - (mosaicItemFocalPoint && mosaicItemFocalPoint.x ? mosaicItemFocalPoint.x : 0.5)) > 0.025 || Math.abs(focalPoint.y - (mosaicItemFocalPoint && mosaicItemFocalPoint.y ? mosaicItemFocalPoint.y : 0.5)) > 0.025) {
|
||||
mosaicItemFocalPoint = focalPoint;
|
||||
setAttributes({ mosaicItemFocalPoint: focalPoint });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
|
||||
function mosaicPartition(items) {
|
||||
const partition = _.groupBy(items, (item, i) => {
|
||||
if (i % 2 == 0)
|
||||
return Math.floor(i/mosaicDensity)
|
||||
else
|
||||
return Math.floor(i/(mosaicDensity + 1))
|
||||
});
|
||||
return _.values(partition);
|
||||
}
|
||||
|
||||
function buildMosaic(mosaicGroup) {
|
||||
let mosaic = []
|
||||
for (let item of mosaicGroup)
|
||||
mosaic.push(prepareItem(item))
|
||||
return mosaic;
|
||||
}
|
||||
|
||||
// Executed only on the first load of page
|
||||
if(content && content.length && content[0].type)
|
||||
setContent();
|
||||
|
||||
const layoutControls = [
|
||||
{
|
||||
icon: 'grid-view',
|
||||
title: __( 'Grid View', 'tainacan' ),
|
||||
onClick: () => updateLayout('grid'),
|
||||
isActive: layout === 'grid',
|
||||
},
|
||||
{
|
||||
icon: 'list-view',
|
||||
title: __( 'List View', 'tainacan' ),
|
||||
onClick: () => updateLayout('list'),
|
||||
isActive: layout === 'list',
|
||||
},
|
||||
{
|
||||
icon: 'layout',
|
||||
title: __( 'Mosaic View', 'tainacan' ),
|
||||
onClick: () => updateLayout('mosaic'),
|
||||
isActive: layout === 'mosaic',
|
||||
}
|
||||
];
|
||||
|
||||
return content == 'preview' ?
|
||||
<div className={className}>
|
||||
<img
|
||||
width="100%"
|
||||
src={ `${tainacan_blocks.base_url}/assets/images/dynamic-items-list.png` } />
|
||||
</div>
|
||||
: (
|
||||
<div className={className}>
|
||||
|
||||
<div>
|
||||
<BlockControls>
|
||||
{ TainacanBlocksCompatToolbar({ controls: layoutControls }) }
|
||||
{ items.length ?
|
||||
TainacanBlocksCompatToolbar({
|
||||
label: __('Configure search', 'tainacan'),
|
||||
icon: <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -2 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path d="M14,2V4H7v7.24A5.33,5.33,0,0,0,5.5,11a4.07,4.07,0,0,0-.5,0V4A2,2,0,0,1,7,2Zm7,10v8a2,2,0,0,1-2,2H12l1-1-2.41-2.41A5.56,5.56,0,0,0,11,16.53a5.48,5.48,0,0,0-2-4.24V8a2,2,0,0,1,2-2h4Zm-2.52,0L14,7.5V12ZM11,21l-1,1L8.86,20.89,8,20H8l-.57-.57A3.42,3.42,0,0,1,5.5,20a3.5,3.5,0,0,1-.5-7,2.74,2.74,0,0,1,.5,0,3.41,3.41,0,0,1,1.5.34,3.5,3.5,0,0,1,2,3.16,3.42,3.42,0,0,1-.58,1.92L9,19H9l.85.85Zm-4-4.5A1.5,1.5,0,0,0,5.5,15a1.39,1.39,0,0,0-.5.09A1.5,1.5,0,0,0,5.5,18a1.48,1.48,0,0,0,1.42-1A1.5,1.5,0,0,0,7,16.53Z"/>
|
||||
</svg>,
|
||||
onClick: openDynamicItemsModal
|
||||
})
|
||||
: null }
|
||||
</BlockControls>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<InspectorControls>
|
||||
|
||||
<PanelBody
|
||||
title={__('Collection header', 'tainacan')}
|
||||
initialOpen={ false }
|
||||
>
|
||||
<ToggleControl
|
||||
label={__('Display header', 'tainacan')}
|
||||
help={ !showCollectionHeader ? __('Toggle to show collection header', 'tainacan') : __('Do not show collection header', 'tainacan')}
|
||||
checked={ showCollectionHeader }
|
||||
onChange={ ( isChecked ) => {
|
||||
showCollectionHeader = isChecked;
|
||||
if (isChecked) fetchCollectionForHeader();
|
||||
setAttributes({ showCollectionHeader: showCollectionHeader });
|
||||
}
|
||||
}
|
||||
/>
|
||||
{ showCollectionHeader ?
|
||||
<div style={{ margin: '6px' }}>
|
||||
|
||||
<ToggleControl
|
||||
label={__('Display "Collection" label', 'tainacan')}
|
||||
help={ !showCollectionLabel ? __('Toggle to show "Collection" label above header', 'tainacan') : __('Do not show "Collection" label', 'tainacan')}
|
||||
checked={ showCollectionLabel }
|
||||
onChange={ ( isChecked ) => {
|
||||
showCollectionLabel = isChecked;
|
||||
setAttributes({ showCollectionLabel: showCollectionLabel });
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
<BaseControl
|
||||
id="colorpicker"
|
||||
label={ __('Background color', 'tainacan')}>
|
||||
<ColorPicker
|
||||
color={ collectionBackgroundColor }
|
||||
onChangeComplete={ ( value ) => {
|
||||
collectionBackgroundColor = value.hex;
|
||||
setAttributes({ collectionBackgroundColor: collectionBackgroundColor })
|
||||
}}
|
||||
disableAlpha
|
||||
/>
|
||||
</BaseControl>
|
||||
|
||||
<BaseControl
|
||||
id="colorpallete"
|
||||
label={ __('Collection name color', 'tainacan')}>
|
||||
<ColorPalette
|
||||
colors={ [{ name: __('Black', 'tainacan'), color: '#000000'}, { name: __('White', 'tainacan'), color: '#ffffff'} ] }
|
||||
value={ collectionTextColor }
|
||||
onChange={ ( color ) => {
|
||||
collectionTextColor = color;
|
||||
setAttributes({ collectionTextColor: collectionTextColor })
|
||||
}}
|
||||
/>
|
||||
</BaseControl>
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={__('Search bar', 'tainacan')}
|
||||
initialOpen={ true }
|
||||
>
|
||||
<ToggleControl
|
||||
label={__('Display bar', 'tainacan')}
|
||||
help={ showSearchBar ? __('Toggle to show search bar on block', 'tainacan') : __('Do not show search bar', 'tainacan')}
|
||||
checked={ showSearchBar }
|
||||
onChange={ ( isChecked ) => {
|
||||
showSearchBar = isChecked;
|
||||
setAttributes({ showSearchBar: showSearchBar });
|
||||
}
|
||||
}
|
||||
/>
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={__('Items', 'tainacan')}
|
||||
initialOpen={ true }
|
||||
>
|
||||
<div>
|
||||
<RangeControl
|
||||
label={__('Maximum number of items', 'tainacan')}
|
||||
value={ maxItemsNumber ? maxItemsNumber : 12 }
|
||||
onChange={ ( aMaxItemsNumber ) => {
|
||||
maxItemsNumber = aMaxItemsNumber;
|
||||
setAttributes( { maxItemsNumber: aMaxItemsNumber } )
|
||||
setContent();
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 96 }
|
||||
/>
|
||||
</div>
|
||||
<hr></hr>
|
||||
<div>
|
||||
{ layout == 'list' ?
|
||||
<div style={{ marginTop: '16px'}}>
|
||||
<RangeControl
|
||||
label={ __('Maximum number of columns on a wide screen', 'tainacan') }
|
||||
value={ maxColumnsCount ? maxColumnsCount : 5 }
|
||||
onChange={ ( aMaxColumnsCount ) => {
|
||||
maxColumnsCount = aMaxColumnsCount;
|
||||
setAttributes( { maxColumnsCount: aMaxColumnsCount } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 7 }
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Image', 'tainacan')}
|
||||
help={ showImage ? __("Toggle to show item's image", 'tainacan') : __("Do not show item's image", 'tainacan')}
|
||||
checked={ showImage }
|
||||
onChange={ ( isChecked ) => {
|
||||
showImage = isChecked;
|
||||
setAttributes({ showImage: showImage });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
: null }
|
||||
{ layout == 'grid' || layout == 'mosaic' ?
|
||||
<div>
|
||||
<ToggleControl
|
||||
label={__("Item's title", 'tainacan')}
|
||||
help={ showName ? __("Toggle to show item's title", 'tainacan') : __("Do not show item's title", 'tainacan')}
|
||||
checked={ showName }
|
||||
onChange={ ( isChecked ) => {
|
||||
showName = isChecked;
|
||||
setAttributes({ showName: showName });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div style={{ marginTop: '16px'}}>
|
||||
<RangeControl
|
||||
label={__('Margin between items in pixels', 'tainacan')}
|
||||
value={ gridMargin ? gridMargin : 0 }
|
||||
onChange={ ( margin ) => {
|
||||
gridMargin = margin;
|
||||
setAttributes( { gridMargin: margin } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 0 }
|
||||
max={ 48 }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
: null }
|
||||
{ layout == 'grid' ?
|
||||
<div style={{ marginTop: '16px'}}>
|
||||
<RangeControl
|
||||
label={ __('Maximum number of columns on a wide screen', 'tainacan') }
|
||||
value={ maxColumnsCount ? maxColumnsCount : 5 }
|
||||
onChange={ ( aMaxColumnsCount ) => {
|
||||
maxColumnsCount = aMaxColumnsCount;
|
||||
setAttributes( { maxColumnsCount: aMaxColumnsCount } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 7 }
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Crop Images', 'tainacan')}
|
||||
help={ cropImagesToSquare ? __('Do not use square cropeed version of the item thumbnail.', 'tainacan') : __('Toggle to use square cropped version of the item thumbnail.', 'tainacan') }
|
||||
checked={ cropImagesToSquare }
|
||||
onChange={ ( isChecked ) => {
|
||||
cropImagesToSquare = isChecked;
|
||||
setAttributes({ cropImagesToSquare: cropImagesToSquare });
|
||||
setContent();
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
: null }
|
||||
</div>
|
||||
</PanelBody>
|
||||
{ layout == 'mosaic' ?
|
||||
<PanelBody
|
||||
title={__('Mosaic', 'tainacan')}
|
||||
initialOpen={ true }
|
||||
>
|
||||
<div>
|
||||
<RangeControl
|
||||
label={__('Container height (px)', 'tainacan')}
|
||||
value={ mosaicHeight ? mosaicHeight : 280 }
|
||||
onChange={ ( height ) => {
|
||||
mosaicHeight = height;
|
||||
setAttributes( { mosaicHeight: height } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 100 }
|
||||
max={ 2000 }
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<RangeControl
|
||||
label={__('Group Grid Density', 'tainacan')}
|
||||
value={ mosaicDensity ? mosaicDensity : 5 }
|
||||
onChange={ ( value ) => {
|
||||
mosaicDensity = value;
|
||||
setAttributes( { mosaicDensity: mosaicDensity } );
|
||||
setContent();
|
||||
}}
|
||||
min={ 1 }
|
||||
max={ 5 }
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<SelectControl
|
||||
label={__('Group Grid Dimensions', 'tainacan')}
|
||||
value={ mosaicGridRows + 'x' + mosaicGridColumns }
|
||||
options={ [
|
||||
{ label: '2 x 3', value: '2x3' },
|
||||
{ label: '3 x 2', value: '3x2' },
|
||||
{ label: '3 x 3', value: '3x3' },
|
||||
{ label: '3 x 4', value: '3x4' },
|
||||
{ label: '4 x 3', value: '4x3' },
|
||||
{ label: '4 x 5', value: '4x5' },
|
||||
{ label: '5 x 4', value: '5x4' },
|
||||
] }
|
||||
onChange={ ( aGrid ) => {
|
||||
mosaicGridRows = aGrid.split('x')[0];
|
||||
mosaicGridColumns = aGrid.split('x')[1];
|
||||
|
||||
setAttributes({
|
||||
mosaicGridRows: mosaicGridRows,
|
||||
mosaicGridColumns: mosaicGridColumns
|
||||
});
|
||||
setContent();
|
||||
}}/>
|
||||
</div>
|
||||
<div>
|
||||
<FocalPointPicker
|
||||
label={ __('Item focal point for background image', 'tainacan') }
|
||||
url={ sampleBackgroundImage }
|
||||
dimensions={ {
|
||||
width: 400,
|
||||
height: 400
|
||||
} }
|
||||
value={ mosaicItemFocalPoint }
|
||||
onChange={ ( focalPoint ) =>_.debounce( updateMosaicItemFocalPoint(focalPoint), 700) }
|
||||
/>
|
||||
</div>
|
||||
</PanelBody>
|
||||
: null}
|
||||
</InspectorControls>
|
||||
</div>
|
||||
|
||||
{ isSelected ?
|
||||
(
|
||||
<div>
|
||||
{ isModalOpen ?
|
||||
<DynamicItemsModal
|
||||
existingCollectionId={ collectionId }
|
||||
existingSearchURL={ searchURL }
|
||||
onSelectCollection={ (selectedCollectionId) => {
|
||||
collectionId = selectedCollectionId;
|
||||
setAttributes({ collectionId: collectionId });
|
||||
fetchCollectionForHeader();
|
||||
}}
|
||||
onApplySearchURL={ (aSearchURL) =>{
|
||||
searchURL = aSearchURL
|
||||
setAttributes({
|
||||
searchURL: searchURL,
|
||||
isModalOpen: false
|
||||
});
|
||||
setContent();
|
||||
}}
|
||||
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
|
||||
: null
|
||||
}
|
||||
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{
|
||||
showCollectionHeader ?
|
||||
|
||||
<div> {
|
||||
isLoadingCollection ?
|
||||
<div class="spinner-container">
|
||||
<Spinner />
|
||||
</div>
|
||||
:
|
||||
<a
|
||||
href={ collection.url ? collection.url : '' }
|
||||
target="_blank"
|
||||
class="dynamic-items-collection-header">
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: collectionBackgroundColor ? collectionBackgroundColor : '',
|
||||
paddingRight: collection && collection.thumbnail && (collection.thumbnail['tainacan-medium'] || collection.thumbnail['medium']) ? '' : '20px',
|
||||
paddingTop: (!collection || !collection.thumbnail || (!collection.thumbnail['tainacan-medium'] && !collection.thumbnail['medium'])) ? '1rem' : '',
|
||||
width: collection && collection.header_image ? '' : '100%'
|
||||
}}
|
||||
className={
|
||||
'collection-name ' +
|
||||
((!collection || !collection.thumbnail || (!collection.thumbnail['tainacan-medium'] && !collection.thumbnail['medium'])) && (!collection || !collection.header_image) ? 'only-collection-name' : '')
|
||||
}>
|
||||
<h3 style={{ color: collectionTextColor ? collectionTextColor : '' }}>
|
||||
{ showCollectionLabel ? <span class="label">{ __('Collection', 'tainacan') }<br/></span> : null }
|
||||
{ collection && collection.name ? collection.name : '' }
|
||||
</h3>
|
||||
</div>
|
||||
{
|
||||
collection && collection.thumbnail && (collection.thumbnail['tainacan-medium'] || collection.thumbnail['medium']) ?
|
||||
<div
|
||||
class="collection-thumbnail"
|
||||
style={{
|
||||
backgroundImage: 'url(' + (collection.thumbnail['tainacan-medium'] != undefined ? (collection.thumbnail['tainacan-medium'][0]) : (collection.thumbnail['medium'][0])) + ')',
|
||||
}}/>
|
||||
: null
|
||||
}
|
||||
<div
|
||||
class="collection-header-image"
|
||||
style={{
|
||||
backgroundImage: collection.header_image ? 'url(' + collection.header_image + ')' : '',
|
||||
minHeight: collection && collection.header_image ? '' : '80px',
|
||||
display: !(collection && collection.thumbnail && (collection.thumbnail['tainacan-medium'] || collection.thumbnail['medium'])) ? collection && collection.header_image ? '' : 'none' : ''
|
||||
}}/>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
|
||||
{
|
||||
showSearchBar ?
|
||||
<div class="dynamic-items-search-bar">
|
||||
<Button
|
||||
onClick={ () => { order = 'asc'; setAttributes({ order: order }); setContent(); }}
|
||||
className={order == 'asc' ? 'sorting-button-selected' : ''}
|
||||
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
|
||||
onClick={ () => { order = 'desc'; setAttributes({ order: order }); setContent(); }}
|
||||
className={order == 'desc' ? 'sorting-button-selected' : ''}
|
||||
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
|
||||
onClick={ () => { setContent(); }}
|
||||
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 }
|
||||
onChange={ (value) => { _.debounce(applySearchString(value), 300); } }
|
||||
type="text"/>
|
||||
<Button
|
||||
class="previous-button"
|
||||
disabled
|
||||
label={__('Previous page', 'tainacan')}>
|
||||
<span class="icon">
|
||||
<i>
|
||||
<svg
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 2 20 20">
|
||||
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
class="next-button"
|
||||
disabled
|
||||
label={__('Next page', 'tainacan')}>
|
||||
<span class="icon">
|
||||
<i>
|
||||
<svg
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 2 20 20">
|
||||
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
|
||||
<path
|
||||
d="M0 0h24v24H0z"
|
||||
fill="none"/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
|
||||
{ !items.length && !isLoading ? (
|
||||
<Placeholder
|
||||
className="tainacan-block-placeholder"
|
||||
icon={(
|
||||
<img
|
||||
width={148}
|
||||
src={ `${tainacan_blocks.base_url}/assets/images/tainacan_logo_header.svg` }
|
||||
alt="Tainacan Logo"/>
|
||||
)}>
|
||||
<p>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<path d="M14,2V4H7v7.24A5.33,5.33,0,0,0,5.5,11a4.07,4.07,0,0,0-.5,0V4A2,2,0,0,1,7,2Zm7,10v8a2,2,0,0,1-2,2H12l1-1-2.41-2.41A5.56,5.56,0,0,0,11,16.53a5.48,5.48,0,0,0-2-4.24V8a2,2,0,0,1,2-2h4Zm-2.52,0L14,7.5V12ZM11,21l-1,1L8.86,20.89,8,20H8l-.57-.57A3.42,3.42,0,0,1,5.5,20a3.5,3.5,0,0,1-.5-7,2.74,2.74,0,0,1,.5,0,3.41,3.41,0,0,1,1.5.34,3.5,3.5,0,0,1,2,3.16,3.42,3.42,0,0,1-.58,1.92L9,19H9l.85.85Zm-4-4.5A1.5,1.5,0,0,0,5.5,15a1.39,1.39,0,0,0-.5.09A1.5,1.5,0,0,0,5.5,18a1.48,1.48,0,0,0,1.42-1A1.5,1.5,0,0,0,7,16.53Z"/>
|
||||
</svg>
|
||||
{__('Dynamically list items from a Tainacan items search', 'tainacan')}
|
||||
</p>
|
||||
<Button
|
||||
isPrimary
|
||||
type="button"
|
||||
onClick={ () => openDynamicItemsModal() }>
|
||||
{__('Configure search', 'tainacan')}
|
||||
</Button>
|
||||
</Placeholder>
|
||||
) : null
|
||||
}
|
||||
|
||||
{ isLoading ?
|
||||
<div class="spinner-container">
|
||||
<Spinner />
|
||||
</div> :
|
||||
<div>
|
||||
{ layout !== 'mosaic' ? (
|
||||
<ul
|
||||
style={{
|
||||
gridGap: layout == 'grid' ? ((showName ? gridMargin + 24 : gridMargin) + 'px') : 'inherit',
|
||||
marginTop: showSearchBar || showCollectionHeader ? '-' + (Number(gridMargin)/2) : '0px',
|
||||
padding: (Number(gridMargin)/4) + 'px',
|
||||
}}
|
||||
className={'items-list-edit items-layout-' + layout + (!showName ? ' items-list-without-margin' : '') + (maxColumnsCount ? ' max-columns-count-' + maxColumnsCount : '') }>
|
||||
{ items }
|
||||
</ul>
|
||||
) :
|
||||
<ResizableBox
|
||||
size={ {
|
||||
height: mosaicHeight ? mosaicHeight + (3 * gridMargin) : 280 + (3 * gridMargin),
|
||||
width: '100%'
|
||||
} }
|
||||
minHeight="80"
|
||||
maxHeight="2000"
|
||||
minWidth="100%"
|
||||
maxWidth="100%"
|
||||
showHandle={ true }
|
||||
enable={ {
|
||||
top: false,
|
||||
right: false,
|
||||
bottom: true,
|
||||
left: false,
|
||||
topRight: false,
|
||||
bottomRight: true,
|
||||
bottomLeft: true,
|
||||
topLeft: false,
|
||||
} }
|
||||
onResizeStop={ ( event, direction, elt, delta ) => {
|
||||
mosaicHeight = delta.height ? parseInt(delta.height) + parseInt(mosaicHeight) : 280;
|
||||
setAttributes({ mosaicHeight: parseInt(mosaicHeight) });
|
||||
setContent();
|
||||
} }
|
||||
>
|
||||
<ul
|
||||
style={{
|
||||
marginTop: showSearchBar || showCollectionHeader ? '-' + (Number(gridMargin)/2) : '0px',
|
||||
padding: (Number(gridMargin)/4) + 'px',
|
||||
minHeight: mosaicHeight + 'px'
|
||||
}}
|
||||
className={'items-list-edit items-layout-' + layout + (!showName ? ' items-list-without-margin' : '')}>
|
||||
{ items }
|
||||
</ul>
|
||||
</ResizableBox>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
const { SVG, Path } = wp.components;
|
||||
|
||||
export default (
|
||||
<SVG
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
height="24px"
|
||||
width="24px">
|
||||
<Path
|
||||
fill="#298596"
|
||||
d="M14,2V4H7v7.24A5.33,5.33,0,0,0,5.5,11a4.07,4.07,0,0,0-.5,0V4A2,2,0,0,1,7,2Zm7,10v8a2,2,0,0,1-2,2H12l1-1-2.41-2.41A5.56,5.56,0,0,0,11,16.53a5.48,5.48,0,0,0-2-4.24V8a2,2,0,0,1,2-2h4Zm-2.52,0L14,7.5V12ZM11,21l-1,1L8.86,20.89,8,20H8l-.57-.57A3.42,3.42,0,0,1,5.5,20a3.5,3.5,0,0,1-.5-7,2.74,2.74,0,0,1,.5,0,3.41,3.41,0,0,1,1.5.34,3.5,3.5,0,0,1,2,3.16,3.42,3.42,0,0,1-.58,1.92L9,19H9l.85.85Zm-4-4.5A1.5,1.5,0,0,0,5.5,15a1.39,1.39,0,0,0-.5.09A1.5,1.5,0,0,0,5.5,18a1.48,1.48,0,0,0,1.42-1A1.5,1.5,0,0,0,7,16.53Z"/>
|
||||
</SVG>
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,55 @@
|
|||
export default function({ attributes, className }) {
|
||||
const {
|
||||
content,
|
||||
blockId,
|
||||
collectionId,
|
||||
showImage,
|
||||
showName,
|
||||
layout,
|
||||
gridMargin,
|
||||
searchURL,
|
||||
maxItemsNumber,
|
||||
order,
|
||||
showSearchBar,
|
||||
showCollectionHeader,
|
||||
showCollectionLabel,
|
||||
collectionBackgroundColor,
|
||||
collectionTextColor,
|
||||
mosaicHeight,
|
||||
mosaicGridRows,
|
||||
mosaicGridColumns,
|
||||
mosaicItemFocalPoint,
|
||||
mosaicDensity,
|
||||
maxColumnsCount,
|
||||
cropImagesToSquare
|
||||
} = attributes;
|
||||
|
||||
return <div
|
||||
search-url={ searchURL }
|
||||
className={ className }
|
||||
collection-id={ collectionId }
|
||||
show-image={ '' + showImage }
|
||||
show-name={ '' + showName }
|
||||
show-search-bar={ '' + showSearchBar }
|
||||
show-collection-header={ '' + showCollectionHeader }
|
||||
show-collection-label={ '' + showCollectionLabel }
|
||||
crop-images-to-square={ '' + cropImagesToSquare }
|
||||
layout={ layout }
|
||||
mosaic-height={ mosaicHeight }
|
||||
mosaic-density={ mosaicDensity }
|
||||
mosaic-grid-rows={ mosaicGridRows }
|
||||
mosaic-grid-columns={ mosaicGridColumns }
|
||||
mosaic-item-focal-point-x={ (mosaicItemFocalPoint && mosaicItemFocalPoint.x ? mosaicItemFocalPoint.x : 0.5) }
|
||||
mosaic-item-focal-point-y={ (mosaicItemFocalPoint && mosaicItemFocalPoint.y ? mosaicItemFocalPoint.y : 0.5) }
|
||||
max-columns-count={ maxColumnsCount }
|
||||
collection-background-color={ collectionBackgroundColor }
|
||||
collection-text-color={ collectionTextColor }
|
||||
grid-margin={ gridMargin }
|
||||
max-items-number={ maxItemsNumber }
|
||||
order={ order }
|
||||
tainacan-api-root={ tainacan_blocks.root }
|
||||
tainacan-base-url={ tainacan_blocks.base_url }
|
||||
id={ 'wp-block-tainacan-dynamic-items-list_' + blockId }>
|
||||
{ content }
|
||||
</div>
|
||||
};
|
|
@ -52,7 +52,7 @@ export default class TermsModal extends React.Component {
|
|||
temporarySelectedTerms: JSON.parse(JSON.stringify(this.props.selectedTermsObject))
|
||||
});
|
||||
|
||||
if (this.props.existingTaxonomyId != null && this.props.existingTaxonomyId != undefined) {
|
||||
if (this.props.existingTaxonomyId) {
|
||||
this.fetchTaxonomy(this.props.existingTaxonomyId);
|
||||
this.fetchModalTerms(0, this.props.existingTaxonomyId);
|
||||
} else {
|
||||
|
@ -309,7 +309,7 @@ export default class TermsModal extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return this.state.taxonomyId != null && this.state.taxonomyId != undefined ? (
|
||||
return this.state.taxonomyId ? (
|
||||
// Terms modal
|
||||
<Modal
|
||||
className="wp-block-tainacan-modal"
|
||||
|
|
Loading…
Reference in New Issue