diff --git a/src/gutenberg-blocks/class-tainacan-gutenberg-block.php b/src/gutenberg-blocks/class-tainacan-gutenberg-block.php
index 0f0e1dab4..42c70c443 100644
--- a/src/gutenberg-blocks/class-tainacan-gutenberg-block.php
+++ b/src/gutenberg-blocks/class-tainacan-gutenberg-block.php
@@ -18,6 +18,7 @@ function tainacan_blocks_add_gutenberg_blocks_actions() {
add_action('init', 'tainacan_blocks_register_tainacan_dynamic_items_list');
add_action('init', 'tainacan_blocks_register_tainacan_carousel_items_list');
add_action('init', 'tainacan_blocks_register_tainacan_collections_list');
+ add_action('init', 'tainacan_blocks_register_tainacan_carousel_collections_list');
add_action('init', 'tainacan_blocks_register_tainacan_facets_list');
add_action('init', 'tainacan_blocks_add_plugin_settings');
@@ -197,6 +198,36 @@ function tainacan_blocks_register_tainacan_collections_list(){
}
}
+function tainacan_blocks_register_tainacan_carousel_collections_list(){
+ global $TAINACAN_BASE_URL;
+
+ wp_enqueue_script(
+ 'carousel-collections-list-theme',
+ $TAINACAN_BASE_URL . '/assets/gutenberg_carousel_collections_list_theme-components.js',
+ array('wp-components')
+ );
+
+ wp_register_script(
+ 'carousel-collections-list',
+ $TAINACAN_BASE_URL . '/assets/gutenberg_carousel_collections_list-components.js',
+ array('wp-blocks', 'wp-element', 'wp-components', 'wp-editor')
+ );
+
+ wp_register_style(
+ 'carousel-collections-list',
+ $TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-carousel-collections-list.css',
+ array('wp-edit-blocks')
+ );
+
+ if (function_exists('register_block_type')) {
+ register_block_type( 'tainacan/carousel-collections-list', array(
+ 'editor_script' => 'carousel-collections-list',
+ 'style' => 'carousel-collections-list',
+ 'script' => 'carousel-collections-list-theme'
+ ) );
+ }
+}
+
function tainacan_blocks_get_plugin_js_settings(){
global $TAINACAN_BASE_URL;
@@ -221,5 +252,6 @@ function tainacan_blocks_add_plugin_settings() {
wp_localize_script( 'dynamic-items-list', 'tainacan_plugin', $settings );
wp_localize_script( 'carousel-items-list', 'tainacan_plugin', $settings );
wp_localize_script( 'collections-list', 'tainacan_plugin', $settings );
+ wp_localize_script( 'carousel-collections-list', 'tainacan_plugin', $settings );
wp_localize_script( 'facets-list', 'tainacan_plugin', $settings );
}
diff --git a/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.js b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.js
new file mode 100644
index 000000000..5d6a56e91
--- /dev/null
+++ b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.js
@@ -0,0 +1,73 @@
+import Vue from 'vue';
+import CarouselCollectionsListTheme from './carousel-collections-list-theme.vue';
+
+// This is rendered on the theme side.
+document.addEventListener("DOMContentLoaded", () => {
+
+ // Configure Vue logic before passing it to constructor:
+ let vueOptions = {
+ data: {
+ collectionId: '',
+ selectedItems: [],
+ maxItemsNumber: 12,
+ arrowsPosition: 'around',
+ autoPlay: false,
+ autoPlaySpeed: 3,
+ loopSlides: false,
+ hideTitle: true,
+ tainacanApiRoot: '',
+ tainacanBaseUrl: '',
+ className: '',
+ extraParams: {}
+ },
+ render(h){
+ return h(CarouselCollectionsListTheme, {
+ props: {
+ collectionId: this.collectionId,
+ selectedItems: this.selectedItems,
+ maxItemsNumber: this.maxItemsNumber,
+ arrowsPosition: this.arrowsPosition,
+ autoPlay: this.autoPlay,
+ autoPlaySpeed: this.autoPlaySpeed,
+ loopSlides: this.loopSlides,
+ hideTitle: this.hideTitle,
+ tainacanApiRoot: this.tainacanApiRoot,
+ tainacanBaseUrl: this.tainacanBaseUrl,
+ className: this.className,
+ extraParams: this.extraParams
+ }
+ });
+ },
+ beforeMount () {
+ this.className = this.$el.attributes.class != undefined ? this.$el.attributes.class.value : undefined;
+ this.selectedItems = this.$el.attributes['selected-collections'] != undefined ? JSON.parse(this.$el.attributes['selected-collections'].value) : undefined;
+ this.collectionId = this.$el.attributes['collection-id'] != undefined ? this.$el.attributes['collection-id'].value : undefined;
+ this.maxItemsNumber = this.$el.attributes['max-collections-number'] != undefined ? this.$el.attributes['max-collections-number'].value : undefined;
+ this.arrowsPosition = this.$el.attributes['arrows-position'] != undefined ? this.$el.attributes['arrows-position'].value : undefined;
+ this.autoPlay = this.$el.attributes['auto-play'] != undefined ? this.$el.attributes['auto-play'].value == 'true' : false;
+ this.autoPlaySpeed = this.$el.attributes['auto-play-speed'] != undefined ? this.$el.attributes['auto-play-speed'].value : 3;
+ this.loopSlides = this.$el.attributes['loop-slides'] != undefined ? this.$el.attributes['loop-slides'].value == 'true' : false;
+ this.hideTitle = this.$el.attributes['hide-title'] != undefined ? this.$el.attributes['hide-title'].value == 'true' : 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;
+ this.extraParams = this.$el.attributes['extra-params'] != undefined ? JSON.parse(this.$el.attributes['extra-params'].value) : undefined;
+ },
+ methods: {
+ __(text, domain) {
+ return wp.i18n.__(text, domain);
+ }
+ }
+ };
+
+ // Gets all divs with content created by our block;
+ let blocks = document.getElementsByClassName('wp-block-tainacan-carousel-collections-list');
+
+ if (blocks) {
+ let blockIds = Object.values(blocks).map((block) => block.id);
+
+ // Creates a new Vue Instance to manage each block isolatelly
+ for (let blockId of blockIds) {
+ new Vue( Object.assign({ el: '#' + blockId }, jQuery.extend(true, {}, vueOptions)) );
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.vue b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.vue
new file mode 100644
index 000000000..9f33d4ab1
--- /dev/null
+++ b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.vue
@@ -0,0 +1,221 @@
+
+
+
+
+
+ {{ $root.__('No collections found.', 'tainacan') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list.scss b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list.scss
new file mode 100644
index 000000000..743e049ec
--- /dev/null
+++ b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list.scss
@@ -0,0 +1,223 @@
+@import '../../gutenberg-blocks-style.scss';
+
+.wp-block-tainacan-carousel-collections-list {
+ margin: 2rem 0px;
+
+ // Spinner
+ .spinner-container {
+ min-height: 56px;
+ padding: 1rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: #555758;
+ }
+
+ // Skeleton loading
+ @-webkit-keyframes skeleton-animation {
+ 0%{opacity: 1.0}
+ 50%{opacity: 0.2}
+ 100%{opacity: 1.0}
+ }
+ @-moz-keyframes skeleton-animation {
+ 0%{opacity: 1.0}
+ 50%{opacity: 0.2}
+ 100%{opacity: 1.0}
+ }
+ @-o-keyframes skeleton-animation {
+ 0%{opacity: 1.0}
+ 50%{opacity: 0.2}
+ 100%{opacity: 1.0}
+ }
+ @keyframes skeleton-animation {
+ 0%{opacity: 1.0}
+ 50%{opacity: 0.2}
+ 100%{opacity: 1.0}
+ }
+ .skeleton {
+ border-radius: 2px;
+ background: #f2f2f2;
+
+ -webkit-animation: skeleton-animation 1.8s ease infinite;
+ -moz-animation: skeleton-animation 1.8s ease infinite;
+ -o-animation: skeleton-animation 1.8s ease infinite;
+ animation: skeleton-animation 1.8s ease infinite;
+ }
+
+ // Tainacan Carousel
+ .tainacan-carousel {
+ position: relative;
+ width: calc(100% + 50px);
+ left: -50px;
+
+ .swiper-container {
+ margin: 0 50px;
+
+ a>span,
+ a:hover>span {
+ color: black;
+ font-weight: bold;
+ text-decoration: none;
+ padding: 8px 16px;
+ display: block;
+ line-height: 1.2rem;
+ }
+ a:hover {
+ text-decoration: none;
+ }
+ }
+ }
+
+ .preview-warning {
+ width: 100%;
+ font-size: 0.875rem;
+ font-style: italic;
+ color: #898d8f;
+ text-align: center;
+ margin: 4px auto;
+ }
+
+ // Next and previous buttons
+ .swiper-button-prev, .swiper-button-next {
+ top: initial;
+ bottom: calc(50% + 10px);
+ background: none;
+ border: none;
+ width: 42px;
+ height: 42px;
+ padding: 0;
+ margin: 0 -4px;
+
+ svg {
+ fill: #298596;
+ }
+ }
+
+ // Carousel placeholder on editor side ----------------------------------------------------
+ .items-list-edit-container,
+ .tainacan-carousel {
+ position: relative;
+
+ & .skeleton {
+ min-height: 150px;
+ max-height: 150px;
+ }
+
+ &.has-arrows-none .swiper-button-prev,
+ &.has-arrows-none .swiper-button-next {
+ display: none;
+ }
+ &.has-arrows-left .swiper-button-next {
+ left: 10px;
+ right: auto;
+ bottom: calc(50% + 36px);
+ }
+ &.has-arrows-right .swiper-button-prev {
+ right: 10px;
+ left: auto;
+ }
+ &.has-arrows-right .swiper-button-next {
+ bottom: calc(50% + 36px);
+ }
+ }
+ ul.items-list-edit {
+ display: flex;
+ align-items: flex-start;
+ overflow-x: scroll;
+ list-style: none;
+ margin: 0 36px;
+
+ li.collection-list-item {
+ position: relative;
+ display: block;
+ margin: 16px;
+ width: calc(14.286% - 32px);
+ min-width: calc(14.286% - 32px);
+
+ a {
+ color: #454647;
+ font-weight: bold;
+ line-height: normal;
+ }
+
+ img {
+ height: auto;
+
+ padding: 0px;
+ margin-bottom: 0.5rem;
+ }
+
+ &:hover a {
+ color: #454647;
+ text-decoration: none;
+ }
+
+ button {
+ position: absolute !important;
+ background-color: rgba(255, 255, 255, 0.75);
+ color: #454647;
+ padding: 2px;
+ margin-left: 5px;
+ min-width: 14px;
+ visibility: hidden;
+ position: relative;
+ opacity: 0;
+ right: -14px;
+ top: 0px;
+ justify-content: center;
+ z-index: 999;
+ }
+
+ &:hover button {
+ visibility: visible;
+ background-color: rgba(255, 255, 255, 1) !important;
+ opacity: 1;
+ right: -8px;
+ top: -8px;
+ border: 1px solid #cbcbcb;
+ border-radius: 12px;
+ transition: opacity linear 0.15s, right linear 0.15s;
+ }
+ &:hover button:hover {
+ background-color: rgba(255, 255, 255, 1) !important;
+ border: 1px solid #cbcbcb !important;
+ }
+ }
+ }
+ @media only screen and (max-width: 1686px) {
+
+ ul.items-list-edit li.collection-list-item {
+ width: calc(16.666% - 32px);
+ min-width: calc(16.666% - 32px);
+ }
+ }
+ @media only screen and (max-width: 1452px) {
+
+ ul.items-list-edit li.collection-list-item {
+ width: calc(20% - 32px);
+ min-width: calc(20% - 32px);
+ }
+ }
+ @media only screen and (max-width: 1118px) {
+
+ ul.items-list-edit li.collection-list-item {
+ width: calc(25% - 32px);
+ min-width: calc(25% - 32px);
+ }
+ }
+ @media only screen and (max-width: 854px) {
+
+ ul.items-list-edit li.collection-list-item {
+ width: calc(33.333% - 32px);
+ min-width: calc(33.333% - 32px);
+ }
+ }
+ @media only screen and (max-width: 584px) {
+
+ ul.items-list-edit li.collection-list-item {
+ width: calc(50% - 32px);
+ min-width: calc(50% - 32px);
+ }
+ }
+
+}
diff --git a/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-modal.js b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-modal.js
new file mode 100644
index 000000000..145555eea
--- /dev/null
+++ b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-modal.js
@@ -0,0 +1,320 @@
+import tainacan from '../../api-client/axios.js';
+import axios from 'axios';
+
+const { __ } = wp.i18n;
+
+const { TextControl, Button, Modal, RadioControl, Spinner } = wp.components;
+
+export default class CarouselCollectionsModal extends React.Component {
+ constructor(props) {
+ super(props);
+
+ // Initialize state
+ this.state = {
+ collectionsPerPage: 24,
+ collectionId: undefined,
+ collectionName: '',
+ isLoadingCollections: false,
+ modalCollections: [],
+ totalModalCollections: 0,
+ collectionPage: 1,
+ temporaryCollectionId: '',
+ searchCollectionName: '',
+ collections: [],
+ collectionsRequestSource: undefined,
+ searchURL: '',
+ itemsPerPage: 12,
+ loadStrategy: 'search'
+ };
+
+ // Bind events
+ this.resetCollections = this.resetCollections.bind(this);
+ this.selectCollection = this.selectCollection.bind(this);
+ this.fetchCollections = this.fetchCollections.bind(this);
+ this.fetchModalCollections = this.fetchModalCollections.bind(this);
+ this.fetchCollection = this.fetchCollection.bind(this);
+ this.applySelectedSearchURL = this.applySelectedSearchURL.bind(this);
+ this.applySelectedItems = this.applySelectedItems.bind(this);
+ }
+
+ componentWillMount() {
+
+ this.setState({
+ collectionId: this.props.existingCollectionId
+ });
+
+ if (this.props.existingCollectionId != null && this.props.existingCollectionId != undefined) {
+ this.fetchCollection(this.props.existingCollectionId);
+ this.setState({
+ searchURL: this.props.existingSearchURL ? this.props.existingSearchURL : tainacan_plugin.admin_url + 'admin.php?page=tainacan_admin#/collections/'+ this.props.existingCollectionId + (this.props.loadStrategy == 'search' ? '/items/?iframemode=true&readmode=true' : '/items/?iframemode=true') });
+ } else {
+ this.setState({ collectionPage: 1 });
+ this.fetchModalCollections();
+ }
+ }
+
+ // COLLECTIONS RELATED --------------------------------------------------
+ fetchModalCollections() {
+
+ let someModalCollections = this.state.modalCollections;
+ if (this.state.collectionPage <= 1)
+ someModalCollections = [];
+
+ let endpoint = '/collections/?orderby=title&order=asc&perpage=' + this.state.collectionsPerPage + '&paged=' + this.state.collectionPage;
+
+ this.setState({
+ isLoadingCollections: true,
+ collectionPage: this.state.collectionPage + 1,
+ modalCollections: someModalCollections
+ });
+
+ tainacan.get(endpoint)
+ .then(response => {
+
+ let otherModalCollections = this.state.modalCollections;
+ for (let collection of response.data) {
+ otherModalCollections.push({
+ name: collection.name,
+ id: collection.id
+ });
+ }
+
+ this.setState({
+ isLoadingCollections: false,
+ modalCollections: otherModalCollections,
+ totalModalCollections: response.headers['x-wp-total']
+ });
+
+ return otherModalCollections;
+ })
+ .catch(error => {
+ console.log('Error trying to fetch collections: ' + error);
+ });
+ }
+
+ fetchCollection(collectionId) {
+ tainacan.get('/collections/' + collectionId)
+ .then((response) => {
+ this.setState({ collectionName: response.data.name });
+ }).catch(error => {
+ console.log('Error trying to fetch collection: ' + error);
+ });
+ }
+
+ selectCollection(selectedCollectionId) {
+ this.setState({
+ collectionId: selectedCollectionId,
+ searchURL: tainacan_plugin.admin_url + 'admin.php?page=tainacan_admin#/collections/' + selectedCollectionId + (this.props.loadStrategy == 'search' ? '/items/?iframemode=true&readmode=true' : '/items/?iframemode=true')
+ });
+
+ this.props.onSelectCollection(selectedCollectionId);
+ this.fetchCollection(selectedCollectionId);
+ }
+
+ fetchCollections(name) {
+
+ if (this.state.collectionsRequestSource != undefined)
+ this.state.collectionsRequestSource.cancel('Previous collections search canceled.');
+
+ let aCollectionRequestSource = axios.CancelToken.source();
+
+ this.setState({
+ collectionsRequestSource: aCollectionRequestSource,
+ isLoadingCollections: true,
+ collections: [],
+ items: []
+ });
+
+ let endpoint = '/collections/?orderby=title&order=asc&perpage=' + this.state.collectionsPerPage;
+ if (name != undefined && name != '')
+ endpoint += '&search=' + name;
+
+ tainacan.get(endpoint, { cancelToken: aCollectionRequestSource.token })
+ .then(response => {
+ let someCollections = response.data.map((collection) => ({ name: collection.name, id: collection.id + '' }));
+
+ this.setState({
+ isLoadingCollections: false,
+ collections: someCollections
+ });
+
+ return someCollections;
+ })
+ .catch(error => {
+ console.log('Error trying to fetch collections: ' + error);
+ });
+ }
+
+ applySelectedSearchURL() {
+ let iframe = document.getElementById("itemsFrame");
+ if (iframe) {
+ this.props.onApplySearchURL(iframe.contentWindow.location.href);
+ }
+ }
+
+ applySelectedItems() {
+ let iframe = document.getElementById("itemsFrame");
+ if (iframe) {
+ let params = new URLSearchParams(iframe.contentWindow.location.search);
+ let selectedItems = params.getAll('selecteditems');
+ params.delete('selecteditems')
+ this.props.onApplySelectedItems(selectedItems);
+ }
+ }
+
+ resetCollections() {
+
+ this.setState({
+ collectionId: null,
+ collectionPage: 1,
+ modalCollections: []
+ });
+ this.fetchModalCollections();
+ }
+
+ cancelSelection() {
+
+ this.setState({
+ modalCollections: []
+ });
+
+ this.props.onCancelSelection();
+ }
+
+ render() {
+ return this.state.collectionId != null && this.state.collectionId != undefined ? (
+ // Items modal
+ this.cancelSelection() }
+ contentLabel={ this.props.loadStrategy == 'selection' ? __('Select items that will be added on block', 'tainacan') : __('Configure your items search that will load items on block', 'tainacan')}>
+
+
+
+ { this.props.loadStrategy == 'selection' ?
+
+ : null
+ }
+ { this.props.loadStrategy == 'search' ?
+
+ : null
+ }
+
+
+ ) : (
+ // Collections modal
+ this.cancelSelection() }
+ contentLabel={__('Select items', 'tainacan')}>
+
+
+ {
+ this.setState({
+ searchCollectionName: value
+ });
+ _.debounce(this.fetchCollections(value), 300);
+ }}/>
+
+ {(
+ this.state.searchCollectionName != '' ? (
+ this.state.collections.length > 0 ?
+ (
+
+
+ {
+ {
+ return { label: collection.name, value: '' + collection.id }
+ })
+ }
+ onChange={ ( aCollectionId ) => {
+ this.setState({ temporaryCollectionId: aCollectionId });
+ } } />
+ }
+
+
+ ) :
+ this.state.isLoadingCollections ? (
+
+ ) :
+
+
{ __('Sorry, no collection found.', 'tainacan') }
+
+ ):
+ this.state.modalCollections.length > 0 ?
+ (
+
+
+ {
+ {
+ return { label: collection.name, value: '' + collection.id }
+ })
+ }
+ onChange={ ( aCollectionId ) => {
+ this.setState({ temporaryCollectionId: aCollectionId });
+ } } />
+ }
+
+
+
{ __('Showing', 'tainacan') + " " + this.state.modalCollections.length + " " + __('of', 'tainacan') + " " + this.state.totalModalCollections + " " + __('collections', 'tainacan') + "."}
+ {
+ this.state.modalCollections.length < this.state.totalModalCollections ? (
+
+ ) : null
+ }
+
+
+ ) : this.state.isLoadingCollections ?
:
+
+
{ __('Sorry, no collection found.', 'tainacan') }
+
+ )}
+
+
+
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/index.js b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/index.js
new file mode 100644
index 000000000..bd8742337
--- /dev/null
+++ b/src/gutenberg-blocks/tainacan-collections/carousel-collections-list/index.js
@@ -0,0 +1,457 @@
+const { registerBlockType } = wp.blocks;
+
+const { __ } = wp.i18n;
+
+const { RangeControl, Spinner, Button, ToggleControl, SelectControl, Placeholder, IconButton, ColorPicker, ColorPalette, BaseControl, PanelBody } = wp.components;
+
+const { InspectorControls } = wp.editor;
+
+import CarouselCollectionsModal from './carousel-collections-modal.js';
+import tainacan from '../../api-client/axios.js';
+import axios from 'axios';
+import qs from 'qs';
+
+registerBlockType('tainacan/carousel-collections-list', {
+ title: __('Tainacan Collections Carousel', 'tainacan'),
+ icon:
+ ,
+ category: 'tainacan-blocks',
+ keywords: [ __( 'collections', 'tainacan' ), __( 'carousel', 'tainacan' ), __( 'slider', 'tainacan' ) ],
+ attributes: {
+ content: {
+ type: 'array',
+ source: 'children',
+ selector: 'div'
+ },
+ collectionId: {
+ type: String,
+ default: undefined
+ },
+ collections: {
+ type: Array,
+ default: []
+ },
+ isModalOpen: {
+ type: Boolean,
+ default: false
+ },
+ selectedCollections: {
+ type: Array,
+ default: []
+ },
+ itemsRequestSource: {
+ type: String,
+ default: undefined
+ },
+ maxCollectionsNumber: {
+ type: Number,
+ value: undefined
+ },
+ isLoading: {
+ type: Boolean,
+ value: false
+ },
+ isLoadingCollection: {
+ type: Boolean,
+ value: false
+ },
+ arrowsPosition: {
+ type: String,
+ value: 'search'
+ },
+ autoPlay: {
+ type: Boolean,
+ value: false
+ },
+ autoPlaySpeed: {
+ type: Number,
+ value: 3
+ },
+ loopSlides: {
+ type: Boolean,
+ value: false
+ },
+ hideTitle: {
+ type: Boolean,
+ value: true
+ },
+ showCollectionHeader: {
+ type: Boolean,
+ value: false
+ },
+ showCollectionLabel: {
+ type: Boolean,
+ value: false
+ },
+ collection: {
+ type: Object,
+ value: undefined
+ },
+ blockId: {
+ type: String,
+ default: undefined
+ },
+ collectionBackgroundColor: {
+ type: String,
+ default: "#454647"
+ },
+ collectionTextColor: {
+ type: String,
+ default: "#ffffff"
+ },
+ extraParams: {
+ type: Object,
+ default: {}
+ }
+ },
+ supports: {
+ align: ['full', 'wide'],
+ html: false,
+ multiple: false
+ },
+ edit({ attributes, setAttributes, className, isSelected, clientId }){
+ let {
+ collections,
+ content,
+ collectionId,
+ isModalOpen,
+ itemsRequestSource,
+ selectedCollections,
+ isLoading,
+ arrowsPosition,
+ autoPlay,
+ autoPlaySpeed,
+ loopSlides,
+ hideTitle
+ } = attributes;
+
+ // Obtains block's client id to render it on save function
+ setAttributes({ blockId: clientId });
+
+ function prepareItem(collection) {
+ return (
+
+ removeItemOfId(collection.id) }
+ icon="no-alt"
+ label={__('Remove', 'tainacan')}/>
+
+
+ { !hideTitle ? { collection.title ? collection.title : '' } : null }
+
+
+ );
+ }
+
+ function setContent(){
+ isLoading = true;
+
+ setAttributes({
+ isLoading: isLoading
+ });
+
+ if (itemsRequestSource != undefined && typeof itemsRequestSource == 'function')
+ itemsRequestSource.cancel('Previous collections search canceled.');
+
+ itemsRequestSource = axios.CancelToken.source();
+
+ collections = [];
+
+ let endpoint = '/collection/' + collectionId + '/collections?'+ qs.stringify({ postin: selectedCollections }) + '&fetch_only=title,url,thumbnail';
+ tainacan.get(endpoint, { cancelToken: itemsRequestSource.token })
+ .then(response => {
+
+ for (let collection of response.data.collections)
+ collections.push(prepareItem(collection));
+
+ setAttributes({
+ content: ,
+ collections: collections,
+ isLoading: false,
+ itemsRequestSource: itemsRequestSource
+ });
+ });
+
+ }
+
+ function openCarouselModal() {
+ isModalOpen = true;
+ setAttributes( {
+ isModalOpen: isModalOpen
+ } );
+ }
+
+ function removeItemOfId(itemId) {
+
+ let existingItemIndex = collections.findIndex((existingItem) => existingItem.key == itemId);
+ if (existingItemIndex >= 0)
+ collections.splice(existingItemIndex, 1);
+
+ let existingSelectedItemIndex = selectedCollections.findIndex((existingSelectedItem) => existingSelectedItem == itemId);
+ if (existingSelectedItemIndex >= 0)
+ selectedCollections.splice(existingSelectedItemIndex, 1);
+
+ setAttributes({
+ selectedCollections: selectedCollections,
+ collections: collections,
+ content:
+ });
+
+ }
+
+ // Executed only on the first load of page
+ if(content && content.length && content[0].type)
+ setContent();
+
+ return (
+
+
+
+
+
+
+
+ {
+ hideTitle = isChecked;
+ setAttributes({ hideTitle: hideTitle });
+ setContent();
+ }
+ }
+ />
+ {
+ loopSlides = isChecked;
+ setAttributes({ loopSlides: loopSlides });
+ }
+ }
+ />
+ {
+ autoPlay = isChecked;
+ setAttributes({ autoPlay: autoPlay });
+ }
+ }
+ />
+ {
+ autoPlay ?
+ {
+ autoPlaySpeed = aAutoPlaySpeed;
+ setAttributes( { autoPlaySpeed: aAutoPlaySpeed } )
+ }}
+ min={ 1 }
+ max={ 5 }
+ />
+ : null
+ }
+ {
+ arrowsPosition = aPosition;
+
+ setAttributes({ arrowsPosition: arrowsPosition });
+ }}/>
+
+
+
+
+
+ { isSelected ?
+ (
+
+ { isModalOpen ?
+
{
+ selectedCollections = selectedCollections.concat(aSelectionOfCollections);
+ setAttributes({
+ selectedCollections: selectedCollections,
+ isModalOpen: false
+ });
+ setContent();
+ }}
+ onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
+ : null
+ }
+
+ { collections.length ? (
+
+
+
+ {__('List collections on a Carousel', 'tainacan')}
+
+
+
+ ): null
+ }
+
+ ) : null
+ }
+
+ { !collections.length && !isLoading ? (
+
+ )}>
+
+
+ {__('List collections on a Carousel, using search or collection selection.', 'tainacan')}
+
+
+
+ ) : null
+ }
+
+ { isLoading ?
+
+
+
:
+
+ { isSelected && collections.length ?
+
{__('Warning: this is just a demonstration. To see the carousel in action, either preview or publish your post.', 'tainacan')}
+ : null
+ }
+ { collections.length ? (
+
+
+
+
+
+ ):null
+ }
+
+ }
+
+ );
+ },
+ save({ attributes, className }){
+ const {
+ content,
+ blockId,
+ collectionId,
+ selectedCollections,
+ arrowsPosition,
+ maxCollectionsNumber,
+ autoPlay,
+ autoPlaySpeed,
+ loopSlides,
+ hideTitle,
+ extraParams
+ } = attributes;
+ return
+ { content }
+
+ }
+});
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 06ef0592c..778c76cf4 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -17,6 +17,8 @@ module.exports = {
gutenberg_carousel_items_list: './src/gutenberg-blocks/tainacan-items/carousel-items-list/index.js',
gutenberg_carousel_items_list_theme: './src/gutenberg-blocks/tainacan-items/carousel-items-list/carousel-items-list-theme.js',
gutenberg_collections_list: './src/gutenberg-blocks/tainacan-collections/collections-list/index.js',
+ gutenberg_carousel_collections_list: './src/gutenberg-blocks/tainacan-collections/carousel-collections-list/index.js',
+ gutenberg_carousel_collections_list_theme: './src/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list-theme.js',
gutenberg_facets_list: './src/gutenberg-blocks/tainacan-facets/facets-list/index.js',
gutenberg_facets_list_theme: './src/gutenberg-blocks/tainacan-facets/facets-list/facets-list-theme.js'
},