Creates item-metadata and item-metadatum blocks. #566.

This commit is contained in:
mateuswetah 2022-04-17 19:35:11 -03:00
parent 7f7deab0be
commit c2ca3a3437
19 changed files with 1019 additions and 3 deletions

View File

@ -0,0 +1,69 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "tainacan/item-metadata",
"title": "Tainacan Item Metadata",
"apiVersion": 2,
"category": "tainacan-blocks",
"keywords": [ "item", "metadata", "fields", "values" ],
"description": "The item metadata, including a label and its value.",
"textdomain": "tainacan",
"example": {
"attributes": {
"content": "preview"
}
},
"attributes": {
"content": {
"type": "array",
"source": "query",
"selector": "div"
},
"collectionId": {
"type": "string",
"default": ""
},
"itemId": {
"type": "string",
"default": ""
},
"isModalOpen": {
"type": "boolean",
"default": false
},
"isLoading": {
"type": "boolean",
"default": false
},
"itemRequestSource": {
"type": "string",
"default": ""
},
"itemMetadata": {
"type": "array",
"default": []
},
"itemMetadataTemplate": {
"type": "array",
"default": []
}
},
"providesContext": {
"tainacan/itemId": "itemId",
"tainacan/collectionId": "collectionId"
},
"supports": {
"align": ["full", "wide"],
"multiple": true,
"color": {
"text": true,
"background": true,
"gradients": true,
"link": true
},
"spacing": {
"padding": true
}
},
"editorScript": "item-metadata",
"editorStyle": "item-metadata"
}

View File

@ -0,0 +1 @@
export default [];

View File

@ -0,0 +1,165 @@
const { __ } = wp.i18n;
const { Button, Spinner, Placeholder } = wp.components;
const { useBlockProps, InnerBlocks } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
import SingleItemModal from '../../js/selection/single-item-modal.js';
import tainacan from '../../js/axios.js';
import axios from 'axios';
export default function ({ attributes, setAttributes, className, isSelected, clientId }) {
let {
content,
collectionId,
itemId,
isLoading,
itemRequestSource,
isModalOpen,
itemMetadata,
itemMetadataTemplate
} = attributes;
// Gets blocks props from hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps();
function setContent() {
isLoading = true;
setAttributes({
isLoading: isLoading
});
if (itemRequestSource != undefined && typeof itemRequestSource == 'function')
itemRequestSource.cancel('Previous items search canceled.');
itemRequestSource = axios.CancelToken.source();
let endpoint = '/item/'+ itemId + '/metadata';
tainacan.get(endpoint, { cancelToken: itemRequestSource.token })
.then(response => {
itemMetadata = response.data ? response.data : [];
setAttributes({
itemMetadata: itemMetadata,
isLoading: false,
itemRequestSource: itemRequestSource
});
getItemMetadataTemplates();
});
}
function getItemMetadataTemplates() {
itemMetadataTemplate = [];
itemMetadata.forEach((itemMetadatum) => {
if (itemMetadatum.value && itemMetadatum.metadatum && itemMetadatum.metadatum.id) {
itemMetadataTemplate.push([
'tainacan/item-metadatum',
{
placeholder: __( 'Item Metadatum', 'tainacan' ),
metadatumId: itemMetadatum.metadatum.id,
itemId: itemId,
collectionId: collectionId
}
]);
}
});
setAttributes({ itemMetadataTemplate: itemMetadataTemplate });
}
return content == 'preview' ?
<div className={className}>
<img
width="100%"
src={ `${tainacan_blocks.base_url}/assets/images/related-carousel-items.png` } />
</div>
: (
<div { ...blockProps }>
{ isSelected ?
(
<div>
{ isModalOpen ?
<SingleItemModal
modalTitle={ __('Select one item to render its metadata', 'tainacan') }
applyButtonLabel={ __('List metadata for this item', 'tainacan') }
existingCollectionId={ collectionId }
existingItemId={ itemId }
onSelectCollection={ (selectedCollectionId) => {
collectionId = selectedCollectionId;
setAttributes({
collectionId: collectionId
});
}}
onApplySelectedItem={ (selectedItemId) => {
itemId = selectedItemId;
setAttributes({
itemId: itemId,
isModalOpen: false
});
setContent();
}}
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
: null
}
</div>
) : null
}
{ !itemId ? (
<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="M16,6H12a2,2,0,0,0-2,2v6.52A6,6,0,0,1,12,19a6,6,0,0,1-.73,2.88A1.92,1.92,0,0,0,12,22h8a2,2,0,0,0,2-2V12Zm-1,6V7.5L19.51,12ZM15,2V4H8v9.33A5.8,5.8,0,0,0,6,13V4A2,2,0,0,1,8,2ZM10.09,19.05,7,22.11V16.05L8,17l2,2ZM5,16.05v6.06L2,19.11Z"/>
</svg>
{__('Select an item to display its metadata list.', 'tainacan')}
</p>
<Button
isPrimary
type="button"
onClick={ () => {
isModalOpen = true;
setAttributes( {
isModalOpen: isModalOpen
});
}
}>
{__('Select Item', 'tainacan')}
</Button>
</Placeholder>
) : null
}
{ isLoading ?
<div class="spinner-container">
<Spinner />
</div> :
<div className={ 'item-metadata-edit-container' }>
{ itemMetadata.length ?
<InnerBlocks
allowedBlocks={ true }
template={ itemMetadataTemplate } />
: null
}
</div>
}
</div>
);
};

View File

@ -0,0 +1,14 @@
const { SVG, Path } = wp.components;
export default (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="-1 -1 26 26"
height="24px"
width="24px">
<Path
d="M 7.5947245,4.2973622 H 16.405277 V 19.702638 H 7.5947245 Z M 18.594724,7.5947241 H 23 V 16.405276 H 18.594724 Z M 1.0000002,16.405276 V 7.5947241 H 5.405276 v 8.8105519 z"
/>
</SVG>
);

View File

@ -0,0 +1,15 @@
import tainacanRegisterBlockType from '../../js/compatibility/tainacan-blocks-compat-register.js';
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';
tainacanRegisterBlockType({
metadata,
icon,
edit,
save,
deprecated
});

View File

@ -0,0 +1,7 @@
const { useBlockProps, InnerBlocks } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
export default function({ className }) {
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps.save();
return <div data-module="item-metadata" { ...blockProps }><InnerBlocks.Content /></div>
};

View File

@ -0,0 +1,61 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "tainacan/item-metadatum",
"title": "Tainacan Item metadatum",
"apiVersion": 2,
"category": "tainacan-blocks",
"keywords": [ "item", "metadatum", "field", "value" ],
"description": "A single item metadatum, including a label and its value.",
"textdomain": "tainacan",
"example": {
"attributes": {
"content": "preview"
}
},
"attributes": {
"content": {
"type": "array",
"source": "query",
"selector": "div"
},
"collectionId": {
"type": "integer",
"default": ""
},
"itemId": {
"type": "integer",
"default": ""
},
"metadatumId": {
"type": "integer",
"default": ""
},
"metadatumType": {
"type": "string",
"default": ""
},
"isModalOpen": {
"type": "boolean",
"default": false
}
},
"usesContext": [
"tainacan/itemId",
"tainacan/collectionId"
],
"supports": {
"align": ["full", "wide"],
"multiple": true,
"color": {
"text": true,
"background": true,
"gradients": true,
"link": true
},
"spacing": {
"padding": true
}
},
"editorScript": "item-metadatum",
"editorStyle": "item-metadatum"
}

View File

@ -0,0 +1 @@
export default [];

View File

@ -0,0 +1,121 @@
const { __ } = wp.i18n;
const { Button, Placeholder } = wp.components;
const ServerSideRender = wp.serverSideRender;
const { useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
import SingleItemMetadatumModal from '../../js/selection/single-item-metadatum-modal.js';
export default function ({ attributes, setAttributes, className, isSelected }) {
let {
content,
collectionId,
itemId,
metadatumId,
metadatumType,
isModalOpen,
} = attributes;
// Gets blocks props from hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps();
const currentWPVersion = (typeof tainacan_blocks != 'undefined') ? tainacan_blocks.wp_version : tainacan_plugin.wp_version;
return content == 'preview' ?
<div className={className}>
<img
width="100%"
src={ `${tainacan_blocks.base_url}/assets/images/related-carousel-items.png` } />
</div>
: (
<div { ...blockProps }>
{ isSelected ?
(
<div>
{ isModalOpen ?
<SingleItemMetadatumModal
modalTitle={ __('Select one item to render its metadata', 'tainacan') }
existingCollectionId={ collectionId }
existingItemId={ itemId }
existingMetadatumId={ metadatumId }
onSelectCollection={ (selectedCollectionId) => {
collectionId = selectedCollectionId;
setAttributes({
collectionId: collectionId
});
}}
onSelectItem={ (selectedItemId) => {
itemId = selectedItemId;
setAttributes({
itemId: itemId
});
}}
onApplySelectedMetadatum={ (selectedMetadatum) => {
metadatumId = selectedMetadatum.metadatumId;
metadatumType = selectedMetadatum.metadatumType;
setAttributes({
metadatumId: metadatumId,
metadatumType: metadatumType,
isModalOpen: false
});
}}
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
: null
}
</div>
) : null
}
{ !(collectionId && itemId && metadatumId) ? (
<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="M16,6H12a2,2,0,0,0-2,2v6.52A6,6,0,0,1,12,19a6,6,0,0,1-.73,2.88A1.92,1.92,0,0,0,12,22h8a2,2,0,0,0,2-2V12Zm-1,6V7.5L19.51,12ZM15,2V4H8v9.33A5.8,5.8,0,0,0,6,13V4A2,2,0,0,1,8,2ZM10.09,19.05,7,22.11V16.05L8,17l2,2ZM5,16.05v6.06L2,19.11Z"/>
</svg>
{__('Select an item metadata to display its label and value.', 'tainacan')}
</p>
<Button
isPrimary
type="button"
onClick={ () => {
isModalOpen = true;
setAttributes( {
isModalOpen: isModalOpen
});
}
}>
{__('Select Item Metadatum', 'tainacan')}
</Button>
</Placeholder>
) : null
}
{ (collectionId && itemId && metadatumId) ? (
<div className={ 'item-metadatum-edit-container' }>
<ServerSideRender
block="tainacan/item-metadatum"
attributes={ attributes }
httpMethod={ currentWPVersion >= '5.5' ? 'POST' : 'GET' }
/>
</div>
) : null
}
</div>
);
};

View File

@ -0,0 +1,14 @@
const { SVG, Path } = wp.components;
export default (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="-1 -1 26 26"
height="24px"
width="24px">
<Path
d="M 7.5947245,4.2973622 H 16.405277 V 19.702638 H 7.5947245 Z M 18.594724,7.5947241 H 23 V 16.405276 H 18.594724 Z M 1.0000002,16.405276 V 7.5947241 H 5.405276 v 8.8105519 z"
/>
</SVG>
);

View File

@ -0,0 +1,15 @@
import tainacanRegisterBlockType from '../../js/compatibility/tainacan-blocks-compat-register.js';
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';
tainacanRegisterBlockType({
metadata,
icon,
edit,
save,
deprecated
});

View File

@ -0,0 +1,3 @@
export default function() {
return null
};

View File

@ -0,0 +1,29 @@
<?php
/**
* Renders the content of the item metadata block
* using Tainacan template functions
*/
function tainacan_blocks_render_item_metadatum( $block_attributes, $content, $block ) {
$item_id = !empty($block->context['tainacan/itemId']) ? $block->context['tainacan/itemId'] : (isset($block_attributes['itemId']) ? $block_attributes['itemId'] : false);
$metadatum_id = isset($block_attributes['metadatumId']) ? $block_attributes['metadatumId'] : false;
if ( !$item_id || !$metadatum_id )
return '';
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => 'metadata-type-$type'
)
);
return tainacan_get_the_metadata(
array(
'metadata' => $metadatum_id,
'before' => '<div ' . $wrapper_attributes . '>',
'after' => '</div>'
),
$item_id
);
}

View File

@ -16,7 +16,9 @@ const TAINACAN_BLOCKS = [
'terms-list' => [],
'faceted-search' => [],
'item-submission-form' => [],
'item-gallery' => ['render_callback' => 'tainacan_blocks_render_items_gallery']
'item-gallery' => ['render_callback' => 'tainacan_blocks_render_items_gallery'],
'item-metadata' => [],
'item-metadatum' => ['render_callback' => 'tainacan_blocks_render_item_metadatum']
];
// Lets do this!

View File

@ -0,0 +1,495 @@
import tainacan from '../axios.js';
import axios from 'axios';
const { __ } = wp.i18n;
const { TextControl, Button, Modal, RadioControl, SelectControl, Spinner } = wp.components;
const currentWPVersion = (typeof tainacan_blocks != 'undefined') ? tainacan_blocks.wp_version : tainacan_plugin.wp_version;
export default class SingleItemModal extends React.Component {
constructor(props) {
super(props);
// Initialize state
this.state = {
collectionsPerPage: 24,
collectionId: undefined,
itemId: undefined,
metadatumId: undefined,
collectionName: '',
isLoadingCollections: false,
modalCollections: [],
itemTitle: '',
metadatumType: undefined,
isLoadingMetadata: false,
modalMetadata: [],
totalModalCollections: 0,
collectionOrderBy: 'date-desc',
collectionPage: 1,
temporaryCollectionId: '',
temporaryItemId: '',
temporaryMetadatumId: '',
searchCollectionName: '',
collections: [],
collectionsRequestSource: undefined,
metadata: [],
metadataRequestSource: undefined,
searchURL: '',
itemsPerPage: 12
};
// 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.fetchItem = this.fetchItem.bind(this);
this.selectItem = this.selectItem.bind(this);
this.fetchModalMetadata = this.fetchModalMetadata.bind(this);
this.applySelectedMetadatum = this.applySelectedMetadatum.bind(this);
}
componentWillMount() {
this.setState({
collectionId: this.props.existingCollectionId,
itemId: this.props.existingItemId,
metadatumId: this.props.existingMetadatumId
});
if (this.props.existingCollectionId) {
this.fetchCollection(this.props.existingCollectionId);
this.setState({
searchURL: tainacan_blocks.admin_url + 'admin.php?itemsSingleSelectionMode=true&page=tainacan_admin#/collections/'+ this.props.existingCollectionId + '/items/?status=publish'
});
if (this.props.existingItemId) {
this.fetchItem(this.props.existingItemId);
this.fetchModalMetadata();
}
} else {
this.setState({ collectionPage: 1 });
this.fetchModalCollections();
}
}
// COLLECTIONS RELATED --------------------------------------------------
fetchModalCollections() {
let someModalCollections = this.state.modalCollections;
if (this.state.collectionPage <= 1)
someModalCollections = [];
let endpoint = '/collections/?perpage=' + this.state.collectionsPerPage + '&paged=' + this.state.collectionPage;
if (this.state.collectionOrderBy == 'date')
endpoint += '&orderby=date&order=asc';
else if (this.state.collectionOrderBy == 'date-desc')
endpoint += '&orderby=date&order=desc';
else if (this.state.collectionOrderBy == 'title')
endpoint += '&orderby=title&order=asc';
else if (this.state.collectionOrderBy == 'title-desc')
endpoint += '&orderby=title&order=desc';
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);
});
}
fetchItem(itemId) {
tainacan.get('/collections/' + this.state.collectionId + '/items/' + itemId)
.then((response) => {
this.setState({ itemTitle: response.data.title });
}).catch(error => {
console.log('Error trying to fetch collection: ' + error);
});
}
selectCollection(selectedCollectionId) {
this.setState({
collectionId: selectedCollectionId,
searchURL: tainacan_blocks.admin_url + 'admin.php?itemsSingleSelectionMode=true&page=tainacan_admin#/collections/' + selectedCollectionId + '/items/?status=publish'
});
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/?perpage=' + this.state.collectionsPerPage;
if (name != undefined && name != '')
endpoint += '&search=' + name;
if (this.state.collectionOrderBy == 'date')
endpoint += '&orderby=date&order=asc';
else if (this.state.collectionOrderBy == 'date-desc')
endpoint += '&orderby=date&order=desc';
else if (this.state.collectionOrderBy == 'title')
endpoint += '&orderby=title&order=asc';
else if (this.state.collectionOrderBy == 'title-desc')
endpoint += '&orderby=title&order=desc';
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);
});
}
fetchModalMetadata() {
let someModalMetadata = [];
let endpoint = '/collection/' + this.state.collectionId + '/metadata/?nopaging=1';
this.setState({
isLoadingMetadata: true,
modalMetadata: someModalMetadata
});
tainacan.get(endpoint)
.then(response => {
let otherModalMetadata = this.state.modalMetadata;
for (let metadatum of response.data) {
otherModalMetadata.push({
name: metadatum.name,
id: metadatum.id,
type: metadatum.metadata_type,
typeLabel: metadatum.metadata_type_object ? metadatum.metadata_type_object.name : ''
});
}
this.setState({
isLoadingMetadata: false,
modalMetadata: otherModalMetadata
});
return otherModalMetadata;
})
.catch(error => {
console.log('Error trying to fetch metadata: ' + error);
});
}
selectItem() {
let iframe = document.getElementById("itemsFrame");
if (iframe) {
let params = new URLSearchParams(iframe.contentWindow.location.search);
let selectedItems = params.getAll('selecteditems');
params.delete('selecteditems')
if (selectedItems[0]) {
this.setState({
itemId: selectedItems[0]
});
this.props.onSelectItem(selectedItems[0]);
this.fetchModalMetadata();
}
}
}
applySelectedMetadatum(selectedMetadatum) {
this.setState({
metadatumId: selectedMetadatum.id,
metadatumType: selectedMetadatum.type
});
this.props.onApplySelectedMetadatum({
metadatumId: selectedMetadatum.id,
metadatumType: selectedMetadatum.type
});
}
resetCollections() {
this.setState({
collectionId: null,
collectionPage: 1,
modalCollections: []
});
this.fetchModalCollections();
}
resetItem() {
this.setState({
itemId: null,
});
}
cancelSelection() {
this.setState({
modalCollections: [],
modalMetadata: []
});
this.props.onCancelSelection();
}
render() {
return (this.state.collectionId && this.state.itemId) ? (
// Metadata modal
<Modal
className="wp-block-tainacan-modal"
title={__('Select a metadatum to show it\'s value', 'tainacan')}
onRequestClose={ () => this.cancelSelection() }
contentLabel={__('Select metadatum', 'tainacan')}>
{(
this.state.modalMetadata.length > 0 ?
(
<div>
<div className="modal-radio-list">
<RadioControl
selected={ this.state.temporaryMetadatumId }
options={
this.state.modalMetadata.map((metadatum) => {
return { label: metadatum.name + ' (' + metadatum.typeLabel + ')', value: '' + metadatum.id }
})
}
onChange={ ( aMetadatumId ) => {
this.setState({
temporaryMetadatumId: aMetadatumId
});
} } />
</div>
<br/>
</div>
) : this.state.isLoadingMetadata ? <Spinner/> :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no metadatum found.', 'tainacan') }</p>
</div>
)
}
<div className="modal-footer-area">
<Button
isSecondary
onClick={ () => { this.resetCollections(); }}>
{__('Switch Collection', 'tainacan')}
</Button>
<Button
isSecondary
onClick={ () => { this.resetItem(); }}>
{__('Switch Item', 'tainacan')}
</Button>
<Button
isPrimary
disabled={ this.state.temporaryMetadatumId == undefined || this.state.temporaryMetadatumId == null || this.state.temporaryMetadatumId == ''}
onClick={ () => { this.applySelectedMetadatum(this.state.modalMetadata.find((metadatatum) => metadatatum.id == this.state.temporaryMetadatumId)); } }>
{__('Use this metadatum', 'tainacan')}
</Button>
</div>
</Modal>
) : (
this.state.collectionId ? (
// Item modal
<Modal
className={ 'wp-block-tainacan-modal dynamic-modal ' + (currentWPVersion < 5.9 ? 'wp-version-smaller-than-5-9' : '') }
title={ this.props.modalTitle ? this.props.modalTitle : __('Select one item for the block', 'tainacan') }
onRequestClose={ () => this.cancelSelection() }
shouldCloseOnClickOutside={ false }
contentLabel={ this.props.modalTitle ? this.props.modalTitle : __('Select one item for the block', 'tainacan') }>
<iframe
id="itemsFrame"
src={ this.state.searchURL } />
<div className="modal-footer-area">
<Button
isSecondary
onClick={ () => { this.resetCollections() }}>
{__('Switch collection', 'tainacan')}
</Button>
<Button
style={{ marginLeft: 'auto' }}
isPrimary
onClick={ () => this.selectItem() }>
{ __('Use this item', 'tainacan') }
</Button>
</div>
</Modal>
) : (
// Collections modal
<Modal
className="wp-block-tainacan-modal"
title={__('Select a collection to fetch items from', 'tainacan')}
onRequestClose={ () => this.cancelSelection() }
shouldCloseOnClickOutside={ false }
contentLabel={__('Select item', 'tainacan')}>
<div>
<div className="modal-search-area">
<TextControl
label={__('Search for a collection', 'tainacan')}
placeholder={ __('Search by collection\'s name', 'tainacan') }
value={ this.state.searchCollectionName }
onChange={(value) => {
this.setState({
searchCollectionName: value
});
_.debounce(this.fetchCollections(value), 300);
}}/>
<SelectControl
label={__('Order by', 'tainacan')}
value={ this.state.collectionOrderBy }
options={ [
{ label: __('Latest', 'tainacan'), value: 'date-desc' },
{ label: __('Oldest', 'tainacan'), value: 'date' },
{ label: __('Name (A-Z)', 'tainacan'), value: 'title' },
{ label: __('Name (Z-A)', 'tainacan'), value: 'title-desc' }
] }
onChange={ ( aCollectionOrderBy ) => {
this.state.collectionOrderBy = aCollectionOrderBy;
this.state.collectionPage = 1;
this.setState({
collectionOrderBy: this.state.collectionOrderBy,
collectionPage: this.state.collectionPage
});
if (this.state.searchCollectionName && this.state.searchCollectionName != '') {
this.fetchCollections(this.state.searchCollectionName);
} else {
this.fetchModalCollections();
}
}}/>
</div>
{(
this.state.searchCollectionName != '' ? (
this.state.collections.length > 0 ?
(
<div>
<div className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporaryCollectionId }
options={
this.state.collections.map((collection) => {
return { label: collection.name, value: '' + collection.id }
})
}
onChange={ ( aCollectionId ) => {
this.setState({ temporaryCollectionId: aCollectionId });
} } />
}
</div>
</div>
) :
this.state.isLoadingCollections ? (
<Spinner />
) :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no collection found.', 'tainacan') }</p>
</div>
):
this.state.modalCollections.length > 0 ?
(
<div>
<div className="modal-radio-list">
{
<RadioControl
selected={ this.state.temporaryCollectionId }
options={
this.state.modalCollections.map((collection) => {
return { label: collection.name, value: '' + collection.id }
})
}
onChange={ ( aCollectionId ) => {
this.setState({ temporaryCollectionId: aCollectionId });
} } />
}
</div>
<div className="modal-loadmore-section">
<p>{ __('Showing', 'tainacan') + " " + this.state.modalCollections.length + " " + __('of', 'tainacan') + " " + this.state.totalModalCollections + " " + __('collections', 'tainacan') + "."}</p>
{
this.state.modalCollections.length < this.state.totalModalCollections ? (
<Button
isSecondary
isSmall
onClick={ () => this.fetchModalCollections() }>
{__('Load more', 'tainacan')}
</Button>
) : null
}
</div>
</div>
) : this.state.isLoadingCollections ? <Spinner/> :
<div className="modal-loadmore-section">
<p>{ __('Sorry, no collection found.', 'tainacan') }</p>
</div>
)}
<div className="modal-footer-area">
<Button
isSecondary
onClick={ () => { this.cancelSelection() }}>
{__('Cancel', 'tainacan')}
</Button>
<Button
isPrimary
disabled={ this.state.temporaryCollectionId == undefined || this.state.temporaryCollectionId == null || this.state.temporaryCollectionId == ''}
onClick={ () => { this.selectCollection(this.state.temporaryCollectionId); } }>
{ __('Select item', 'tainacan') }
</Button>
</div>
</div>
</Modal>)
);
}
}

View File

@ -24,7 +24,9 @@ const addDataModuleToOldBlocks = () => {
'carousel-terms-list',
'related-items-list',
'carousel-collections-list',
'item-gallery'
'item-gallery',
'item-metadata',
'item-metadatum'
];
// Looks for Tainacan Blocks based on their classes.

View File

@ -22,7 +22,9 @@ module.exports = {
block_item_submission_form: './src/views/gutenberg-blocks/blocks/item-submission-form/index.js',
block_faceted_search: './src/views/gutenberg-blocks/blocks/faceted-search/index.js',
block_carousel_terms_list: './src/views/gutenberg-blocks/blocks/carousel-terms-list/index.js',
block_item_gallery: './src/views/gutenberg-blocks/blocks/item-gallery/index.js'
block_item_gallery: './src/views/gutenberg-blocks/blocks/item-gallery/index.js',
block_item_metadata: './src/views/gutenberg-blocks/blocks/item-metadata/index.js',
block_item_metadatum: './src/views/gutenberg-blocks/blocks/item-metadatum/index.js'
},
output: {
path: path.resolve(__dirname, './src/assets/js/'),