Begins creation of metatada section block. #566.

This commit is contained in:
mateuswetah 2022-09-22 09:17:39 -03:00
parent 460ee41f30
commit 8d7fc7c92b
27 changed files with 1237 additions and 107 deletions

View File

@ -0,0 +1,87 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "tainacan/item-metadata-section",
"title": "Tainacan Item Metadata Section",
"apiVersion": 2,
"category": "tainacan-blocks",
"keywords": [ "item", "metadata", "section", "regions", "fields" ],
"description": "The metadata sections, including its label and metadata whitin it.",
"textdomain": "tainacan",
"example": {
"attributes": {
"content": "preview"
}
},
"attributes": {
"content": {
"type": "array",
"source": "query",
"selector": "div"
},
"dataSource": {
"type": "string",
"default": "selection"
},
"collectionId": {
"type": "integer"
},
"itemId": {
"type": "integer"
},
"isModalOpen": {
"type": "boolean",
"default": false
},
"isLoading": {
"type": "boolean",
"default": false
},
"metadataSectionRequestSource": {
"type": "string",
"default": ""
},
"metadataSectionTemplate": {
"type": "array",
"default": []
},
"sectionId": {
"type": "string"
},
"sectionName": {
"type": "string"
},
"sectionDescription": {
"type": "string"
},
"sectionMetadata": {
"type": "array",
"default": []
}
},
"providesContext": {
"tainacan/itemId": "itemId"
},
"supports": {
"align": ["full", "wide"],
"multiple": true,
"html": true,
"anchor": true,
"color": {
"text": true,
"background": true,
"gradients": true,
"link": true
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"spacing": {
"margin": true,
"padding": true,
"spacing": true
}
},
"editorScript": "item-metadata-section",
"editorStyle": "item-metadata-section"
}

View File

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

View File

@ -0,0 +1,275 @@
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, context }) {
let {
content,
collectionId,
itemId,
isLoading,
metadataSectionRequestSource,
isModalOpen,
sectionId,
sectionName,
sectionDescription,
sectionMetadata,
metadataSectionTemplate,
dataSource
} = attributes;
// Gets blocks props from hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps();
checkIfTemplateEdition();
function setContent() {
isLoading = true;
setAttributes({
isLoading: isLoading
});
if ( dataSource === 'parent' && sectionId && sectionDescription && sectionName && sectionMetadata.length ) {
getMetadataSectionTemplates({
sectionId: sectionId,
sectionName: sectionName,
sectionDescription: sectionDescription,
sectionMetadata: sectionMetadata,
metadataSectionRequestSource: metadataSectionRequestSource
});
} else {
if (metadataSectionRequestSource != undefined && typeof metadataSectionRequestSource == 'function')
metadataSectionRequestSource.cancel('Previous metadata sections search canceled.');
metadataSectionRequestSource = axios.CancelToken.source();
let endpoint = '/collection/'+ collectionId + '/metadata-sections/' + sectionId;
tainacan.get(endpoint, { cancelToken: metadataSectionRequestSource.token })
.then(response => {
metadataSection = response.data ? response.data : [];
getMetadataSectionTemplates({
sectionId: metadataSection.id,
sectionName: metadataSection.name,
sectionDescription: metadataSection.description,
sectionMetadata: metadataSection['metadata_object_list'],
metadataSectionRequestSource: metadataSectionRequestSource
});
})
.catch((error) => {
console.error(error);
setAttributes({
sectionId: '',
sectionName: '',
sectionDescription: '',
sectionMetadata: [],
isLoading: false
});
});
}
}
function getMetadataSectionTemplates({
sectionId,
sectionName,
sectionDescription,
sectionMetadata,
metadataSectionRequestSource
}) {
console.log(sectionName)
if (sectionName) {
metadataSectionTemplate.push([
'tainacan/metadata-section-name',
{
sectionId: sectionId,
itemId: Number(itemId),
collectionId: Number(collectionId),
sectionName: sectionName,
dataSource: 'parent'
}
]);
}
if (sectionDescription) {
metadataSectionTemplate.push([
'core/paragraph',
{
content: sectionDescription,
}
]);
}
if (sectionMetadata.length) {
metadataSectionTemplate.push([
'tainacan/item-metadata',
{
sectionId: sectionId,
itemId: Number(itemId),
collectionId: Number(collectionId),
metadata: sectionMetadata,
dataSource: 'parent'
}
]);
}
setAttributes({
metadataSectionTemplate: metadataSectionTemplate,
sectionId: sectionId,
sectionName: sectionName,
sectionDescription: sectionDescription,
sectionMetadata: sectionMetadata,
isLoading: false,
metadataSectionRequestSource: metadataSectionRequestSource
});
}
function checkIfTemplateEdition() {
// Check custom template edition state
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.get('postType') == 'wp_template') {
// Extracts collectionId from a string like theme-slug//single-tnc_col_123_item
let postId = queryParams.get('postId');
if (typeof postId == 'string') {
postId = postId.split('single-tnc_col_');
if (postId.length == 2) {
postId = postId[1];
if (typeof postId == 'string') {
postId = postId.split('_item');
if (postId.length == 2) {
postId = postId[0];
collectionId = Number(postId);
itemId = 0;
const shouldSetContent = dataSource !== 'template';
dataSource = 'template';
setAttributes({
collectionId: itemId,
itemId: itemId,
dataSource: dataSource
});
if (shouldSetContent)
setContent();
}
}
}
}
}
}
// Executed only on the first load of page
if (content === undefined || (content && content.length && content[0].type)) {
setAttributes({ content: '' });
setContent();
}
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 = Number(selectedCollectionId);
setAttributes({
collectionId: collectionId
});
}}
onApplySelectedItem={ (selectedItemId) => {
itemId = Number(selectedItemId);
setAttributes({
itemId: itemId,
isModalOpen: false
});
setContent();
}}
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
: null
}
</div>
) : null
}
{ !itemId && dataSource !== 'template' ? (
<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-sections-edit-container' }>
{ metadataSectionTemplate.length ?
<InnerBlocks
allowedBlocks={ true }
template={ metadataSectionTemplate }
templateInsertUpdatesSelection={ true } />
: 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="0 0 24 24"
height="24px"
width="24px">
<Path
d="m 3.996,3.9959991 h 5.016 q 0.816,0 1.392,0.576 l 7.008,7.0079999 q 0.576,0.576 0.576,1.416 0,0.84 -0.576,1.416 l -4.992,4.992 q -0.264,0.264 -0.648,0.432 -0.36,0.168 -0.768,0.168 -0.408,0 -0.792,-0.168 -0.36,-0.168 -0.624,-0.432 l -6.984,-6.984 q -0.6,-0.6 -0.6,-1.416 V 5.9879991 q 0,-0.84 0.576,-1.416 0.576,-0.576 1.416,-0.576 z m 9.552,1.704 0.984,-0.984 6.864,6.8639999 q 0.6,0.6 0.6,1.416 0,0.84 -0.576,1.416 l -5.376,5.376 -1.008,-1.008 5.712,-5.784 z m -8.04,3.288 q 0.624,0 1.056,-0.432 0.432,-0.432 0.432,-1.056 0,-0.624 -0.432,-1.056 -0.432,-0.456 -1.056,-0.456 -0.624,0 -1.08,0.456 -0.432,0.432 -0.432,1.056 0,0.624 0.432,1.056 0.456,0.432 1.08,0.432 z"
/>
</SVG>
);

View File

@ -0,0 +1,17 @@
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';
import transforms from './transforms.js';
tainacanRegisterBlockType({
metadata,
icon,
edit,
save,
deprecated,
transforms
});

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 { ...blockProps }><InnerBlocks.Content /></div>
};

View File

@ -0,0 +1,48 @@
const { createBlock } = wp.blocks;
export default {
to: [
{
type: 'block',
blocks: [ 'tainacan/carousel-items-list' ],
isMultiBlock: true,
transform: ( itemMetadataBlocks ) => {
const items = itemMetadataBlocks.map((anItemMetadataBlock) => anItemMetadataBlock.itemId);
return createBlock(
'tainacan/carousel-items-list',
{
selectedItems: items,
loadStrategy: 'selection',
content: [ { type: true } ],
collectionId: itemMetadataBlocks[0].collectionId,
isModalOpen: false,
align: itemMetadataBlocks[0].align,
textColor: itemMetadataBlocks[0].textColor,
fontSize: itemMetadataBlocks[0].fontSize
}
);
},
},
{
type: 'block',
blocks: [ 'tainacan/dynamic-items-list' ],
isMultiBlock: true,
transform: ( itemMetadataBlocks ) => {
const items = itemMetadataBlocks.map((anItemMetadataBlock) => anItemMetadataBlock.itemId);
return createBlock(
'tainacan/dynamic-items-list',
{
selectedItems: items,
loadStrategy: 'selection',
content: [ { type: true } ],
collectionId: itemMetadataBlocks[0].collectionId,
isModalOpen: false,
align: itemMetadataBlocks[0].align,
textColor: itemMetadataBlocks[0].textColor,
fontSize: itemMetadataBlocks[0].fontSize
}
);
},
}
]
};

View File

@ -0,0 +1,78 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "tainacan/item-metadata-sections",
"title": "Tainacan Item Metadata Sections",
"apiVersion": 2,
"category": "tainacan-blocks",
"keywords": [ "item", "metadata", "sections", "regions", "fields" ],
"description": "The metadata section, including its label and metadata whitin it.",
"textdomain": "tainacan",
"example": {
"attributes": {
"content": "preview"
}
},
"attributes": {
"content": {
"type": "array",
"source": "query",
"selector": "div"
},
"dataSource": {
"type": "string",
"default": "selection"
},
"collectionId": {
"type": "integer"
},
"itemId": {
"type": "integer"
},
"isModalOpen": {
"type": "boolean",
"default": false
},
"isLoading": {
"type": "boolean",
"default": false
},
"metadataSectionsRequestSource": {
"type": "string",
"default": ""
},
"metadataSections": {
"type": "array",
"default": []
},
"metadataSectionsTemplate": {
"type": "array",
"default": []
}
},
"providesContext": {
"tainacan/itemId": "itemId"
},
"supports": {
"align": ["full", "wide"],
"multiple": true,
"html": true,
"anchor": true,
"color": {
"text": true,
"background": true,
"gradients": true,
"link": true
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"spacing": {
"margin": true,
"padding": true,
"spacing": true
}
},
"editorScript": "item-metadata-sections",
"editorStyle": "item-metadata-sections"
}

View File

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

View File

@ -0,0 +1,231 @@
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, context }) {
let {
content,
collectionId,
itemId,
isLoading,
metadataSectionsRequestSource,
isModalOpen,
metadataSections,
metadataSectionsTemplate,
dataSource
} = attributes;
// Gets blocks props from hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps();
checkIfTemplateEdition();
function setContent() {
isLoading = true;
setAttributes({
isLoading: isLoading
});
if (metadataSectionsRequestSource != undefined && typeof metadataSectionsRequestSource == 'function')
metadataSectionsRequestSource.cancel('Previous metadata sections search canceled.');
metadataSectionsRequestSource = axios.CancelToken.source();
let endpoint = '/collection/'+ collectionId + '/metadata-sections';
tainacan.get(endpoint, { cancelToken: metadataSectionsRequestSource.token })
.then(response => {
metadataSections = response.data ? response.data : [];
getMetadataSectionsTemplates({
metadataSections: metadataSections,
metadataSectionsRequestSource: metadataSectionsRequestSource
});
})
.catch((error) => {
console.error(error);
setAttributes({
metadataSections: [],
isLoading: false
});
});
}
function getMetadataSectionsTemplates({
metadataSections,
metadataSectionsRequestSource
}) {
let metadataSectionsTemplate = [];
metadataSections.forEach((aMetadataSection) => {
if ( aMetadataSection['metadata_object_list'] && aMetadataSection['metadata_object_list'].length ) {
metadataSectionsTemplate.push([
'tainacan/item-metadata-section',
{
sectionId: aMetadataSection.id,
sectionName: aMetadataSection.name,
sectionDescription: aMetadataSection.description,
sectionMetadata: aMetadataSection['metadata_object_list'],
itemId: Number(itemId),
collectionId: Number(collectionId),
dataSource: 'parent',
}
]);
}
});
setAttributes({
metadataSectionsTemplate: metadataSectionsTemplate,
metadataSections: metadataSections,
isLoading: false,
metadataSectionsRequestSource: metadataSectionsRequestSource
});
}
function checkIfTemplateEdition() {
// Check custom template edition state
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.get('postType') == 'wp_template') {
// Extracts collectionId from a string like theme-slug//single-tnc_col_123_item
let postId = queryParams.get('postId');
if (typeof postId == 'string') {
postId = postId.split('single-tnc_col_');
if (postId.length == 2) {
postId = postId[1];
if (typeof postId == 'string') {
postId = postId.split('_item');
if (postId.length == 2) {
postId = postId[0];
collectionId = Number(postId);
itemId = 0;
const shouldSetContent = dataSource !== 'template';
dataSource = 'template';
setAttributes({
collectionId: itemId,
itemId: itemId,
dataSource: dataSource
});
if (shouldSetContent)
setContent();
}
}
}
}
}
}
// Executed only on the first load of page
if (content && content.length && content[0].type) {
setAttributes({ content: '' });
setContent();
}
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 = Number(selectedCollectionId);
setAttributes({
collectionId: collectionId
});
}}
onApplySelectedItem={ (selectedItemId) => {
itemId = Number(selectedItemId);
setAttributes({
itemId: itemId,
isModalOpen: false
});
setContent();
}}
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
: null
}
</div>
) : null
}
{ !itemId && dataSource !== 'template' ? (
<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-sections-edit-container' }>
{ metadataSectionsTemplate.length ?
<InnerBlocks
allowedBlocks={ true }
template={ metadataSectionsTemplate } />
: 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="0 0 24 24"
height="24px"
width="24px">
<Path
d="m 3.996,3.9959991 h 5.016 q 0.816,0 1.392,0.576 l 7.008,7.0079999 q 0.576,0.576 0.576,1.416 0,0.84 -0.576,1.416 l -4.992,4.992 q -0.264,0.264 -0.648,0.432 -0.36,0.168 -0.768,0.168 -0.408,0 -0.792,-0.168 -0.36,-0.168 -0.624,-0.432 l -6.984,-6.984 q -0.6,-0.6 -0.6,-1.416 V 5.9879991 q 0,-0.84 0.576,-1.416 0.576,-0.576 1.416,-0.576 z m 9.552,1.704 0.984,-0.984 6.864,6.8639999 q 0.6,0.6 0.6,1.416 0,0.84 -0.576,1.416 l -5.376,5.376 -1.008,-1.008 5.712,-5.784 z m -8.04,3.288 q 0.624,0 1.056,-0.432 0.432,-0.432 0.432,-1.056 0,-0.624 -0.432,-1.056 -0.432,-0.456 -1.056,-0.456 -0.624,0 -1.08,0.456 -0.432,0.432 -0.432,1.056 0,0.624 0.432,1.056 0.456,0.432 1.08,0.432 z"
/>
</SVG>
);

View File

@ -0,0 +1,17 @@
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';
import transforms from './transforms.js';
tainacanRegisterBlockType({
metadata,
icon,
edit,
save,
deprecated,
transforms
});

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 { ...blockProps }><InnerBlocks.Content /></div>
};

View File

@ -0,0 +1,48 @@
const { createBlock } = wp.blocks;
export default {
to: [
{
type: 'block',
blocks: [ 'tainacan/carousel-items-list' ],
isMultiBlock: true,
transform: ( itemMetadataBlocks ) => {
const items = itemMetadataBlocks.map((anItemMetadataBlock) => anItemMetadataBlock.itemId);
return createBlock(
'tainacan/carousel-items-list',
{
selectedItems: items,
loadStrategy: 'selection',
content: [ { type: true } ],
collectionId: itemMetadataBlocks[0].collectionId,
isModalOpen: false,
align: itemMetadataBlocks[0].align,
textColor: itemMetadataBlocks[0].textColor,
fontSize: itemMetadataBlocks[0].fontSize
}
);
},
},
{
type: 'block',
blocks: [ 'tainacan/dynamic-items-list' ],
isMultiBlock: true,
transform: ( itemMetadataBlocks ) => {
const items = itemMetadataBlocks.map((anItemMetadataBlock) => anItemMetadataBlock.itemId);
return createBlock(
'tainacan/dynamic-items-list',
{
selectedItems: items,
loadStrategy: 'selection',
content: [ { type: true } ],
collectionId: itemMetadataBlocks[0].collectionId,
isModalOpen: false,
align: itemMetadataBlocks[0].align,
textColor: itemMetadataBlocks[0].textColor,
fontSize: itemMetadataBlocks[0].fontSize
}
);
},
}
]
};

View File

@ -36,21 +36,25 @@
"type": "boolean",
"default": false
},
"metadataSectionsRequestSource": {
"itemMetadataRequestSource": {
"type": "string",
"default": ""
},
"metadataSections": {
"itemMetadata": {
"type": "array",
"default": []
},
"itemMetadata": {
"metadata": {
"type": "array",
"default": []
},
"itemMetadataTemplate": {
"type": "array",
"default": []
},
"sectionId": {
"type": "string",
"default": ""
}
},
"providesContext": {

View File

@ -15,12 +15,12 @@ export default function ({ attributes, setAttributes, className, isSelected, con
collectionId,
itemId,
isLoading,
metadataSectionsRequestSource,
itemMetadataRequestSource,
isModalOpen,
metadataSections,
itemMetadata,
itemMetadataTemplate,
dataSource
dataSource,
sectionId
} = attributes;
// Gets blocks props from hook
@ -35,56 +35,28 @@ export default function ({ attributes, setAttributes, className, isSelected, con
isLoading: isLoading
});
if (metadataSectionsRequestSource != undefined && typeof metadataSectionsRequestSource == 'function')
metadataSectionsRequestSource.cancel('Previous metadata sections search canceled.');
if (itemMetadataRequestSource != undefined && typeof itemMetadataRequestSource == 'function')
itemMetadataRequestSource.cancel('Previous metadata sections search canceled.');
metadataSectionsRequestSource = axios.CancelToken.source();
itemMetadataRequestSource = axios.CancelToken.source();
let endpoint = '/collection/'+ collectionId + '/metadata-sections';
let endpoint = '/item/' + itemId + '/metadata';
let requests = [];
requests.push(tainacan.get(endpoint, { cancelToken: metadataSectionsRequestSource.token }));
if (dataSource !== 'template') {
endpoint = '/item/' + itemId + '/metadata';
requests.push(tainacan.get(endpoint, { cancelToken: metadataSectionsRequestSource.token }));
}
axios.all(requests)
tainacan.get(endpoint, { cancelToken: itemMetadataRequestSource.token })
.then(response => {
if (
(dataSource !== 'template' && response.length !== 2) ||
(dataSource === 'template' && response.length !== 1)
) {
setAttributes({
metadataSections: [],
itemMetadata: [],
isLoading: false
});
return;
}
const metadataSectionsResponse = response[0];
metadataSections = metadataSectionsResponse.data ? metadataSectionsResponse.data : [];
if (dataSource !== 'template') {
const itemMetadataResponse = response[1];
itemMetadata = itemMetadataResponse.data ? itemMetadataResponse.data : [];
}
itemMetadata = response.data ? response.data : [];
getItemMetadataTemplates({
metadataSections: metadataSections,
itemMetadata: dataSource !== 'template' ? itemMetadata : [],
metadataSectionsRequestSource: metadataSectionsRequestSource
metadata: itemMetadata.map(anItemMetadata => anItemMetadata.metadatum),
itemMetadata: itemMetadata,
itemMetadataRequestSource: itemMetadataRequestSource
});
})
.catch((error) => {
console.error(error);
setAttributes({
metadataSections: [],
itemMetadata: [],
isLoading: false
});
@ -92,50 +64,33 @@ export default function ({ attributes, setAttributes, className, isSelected, con
}
function getItemMetadataTemplates({
metadataSections,
metadata,
itemMetadata,
metadataSectionsRequestSource
itemMetadataRequestSource
}) {
let itemMetadataTemplate = [];
metadataSections.forEach((aMetadataSection) => {
if ( aMetadataSection['metadata_object_list'] && aMetadataSection['metadata_object_list'].length ) {
let itemMetadataBySection = [];
itemMetadataBySection.push([
'core/heading',
{
placeholder: __( 'Metadata section name', 'tainacan' ),
content: aMetadataSection.name
}
]);
if (dataSource === 'template') {
aMetadataSection['metadata_object_list'].forEach((aMetadatum) => {
itemMetadataBySection.push([
metadata.forEach((aMetadatum) => {
itemMetadataTemplate.push([
'tainacan/item-metadatum',
{
placeholder: __( 'Item Metadatum', 'tainacan' ),
metadatumId: aMetadatum.id,
itemId: Number(itemId),
collectionId: Number(collectionId),
dataSource: 'template'
}
]);
});
} else {
const metadataIds = aMetadataSection['metadata_object_list'].map(aMetadataSection => aMetadataSection.id);
itemMetadata.forEach((itemMetadatum) => {
if (
itemMetadatum.metadatum &&
itemMetadatum.metadatum.id &&
metadataIds.includes(itemMetadatum.metadatum.id) &&
(itemMetadatum.value !== '' && itemMetadatum.value !== false) &&
(!Array.isArray(itemMetadatum.value) || itemMetadatum.value.length)
) {
itemMetadataBySection.push([
itemMetadataTemplate.push([
'tainacan/item-metadatum',
{
placeholder: __( 'Item Metadatum', 'tainacan' ),
@ -148,19 +103,12 @@ export default function ({ attributes, setAttributes, className, isSelected, con
}
});
}
itemMetadataTemplate.push([
'core/group',
{},
itemMetadataBySection
]);
}
});
setAttributes({
itemMetadataTemplate: itemMetadataTemplate,
metadata: metadata,
itemMetadata: itemMetadata,
metadataSections: metadataSections,
isLoading: false,
metadataSectionsRequestSource: metadataSectionsRequestSource
itemMetadataRequestSource: itemMetadataRequestSource
});
}
@ -204,8 +152,9 @@ export default function ({ attributes, setAttributes, className, isSelected, con
}
}
}
// Executed only on the first load of page
if (content && content.length && content[0].type) {
if (content === undefined || (content && content.length && content[0].type)) {
setAttributes({ content: '' });
setContent();
}
@ -290,11 +239,10 @@ export default function ({ attributes, setAttributes, className, isSelected, con
<Spinner />
</div> :
<div className={ 'item-metadata-edit-container' }>
{ metadataSections.length ?
{ itemMetadataTemplate.length ?
<InnerBlocks
allowedBlocks={ true }
template={ itemMetadataTemplate }
templateLock={ "all" } />
template={ itemMetadataTemplate } />
: null
}
</div>

View File

@ -0,0 +1,76 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "tainacan/metadata-section-name",
"title": "Tainacan Metadata Section Name",
"apiVersion": 2,
"category": "tainacan-blocks",
"keywords": ["metadata", "field", "section", "region" ],
"description": "A metadata section label, used to identify different metadata sections.",
"textdomain": "tainacan",
"parent": [ "tainacan/item-metadata-section" ],
"example": {
"attributes": {
"content": "preview"
}
},
"attributes": {
"content": {
"type": "array",
"source": "query",
"selector": "div"
},
"dataSource": {
"type": "string",
"default": "selection"
},
"collectionId": {
"type": "integer"
},
"itemId": {
"type": "integer"
},
"sectionId": {
"type": "string"
},
"sectionName": {
"type": "string",
"default": ""
},
"isModalOpen": {
"type": "boolean",
"default": false
},
"labelLevel": {
"type": "number",
"default": 3
},
"textAlign": {
"type": "string"
}
},
"usesContext": [
"tainacan/itemId"
],
"supports": {
"align": ["full", "wide"],
"multiple": true,
"html": true,
"anchor": true,
"color": {
"text": true,
"background": true,
"gradients": true,
"link": true
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"spacing": {
"margin": true,
"padding": true
}
},
"editorScript": "metadata-section-name",
"editorStyle": "metadata-section-name"
}

View File

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

View File

@ -0,0 +1,205 @@
const { __ } = wp.i18n;
const { Button, Placeholder, ToolbarDropdownMenu, SVG, Path, __experimentalHeading: Heading } = wp.components;
const ServerSideRender = wp.serverSideRender;
const { useBlockProps, BlockControls, AlignmentControl } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
import SingleItemMetadatumModal from '../../js/selection/single-item-metadatum-modal.js';
import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js';
const levelToPath = {
1: 'M9 5h2v10H9v-4H5v4H3V5h2v4h4V5zm6.6 0c-.6.9-1.5 1.7-2.6 2v1h2v7h2V5h-1.4z',
2: 'M7 5h2v10H7v-4H3v4H1V5h2v4h4V5zm8 8c.5-.4.6-.6 1.1-1.1.4-.4.8-.8 1.2-1.3.3-.4.6-.8.9-1.3.2-.4.3-.8.3-1.3 0-.4-.1-.9-.3-1.3-.2-.4-.4-.7-.8-1-.3-.3-.7-.5-1.2-.6-.5-.2-1-.2-1.5-.2-.4 0-.7 0-1.1.1-.3.1-.7.2-1 .3-.3.1-.6.3-.9.5-.3.2-.6.4-.8.7l1.2 1.2c.3-.3.6-.5 1-.7.4-.2.7-.3 1.2-.3s.9.1 1.3.4c.3.3.5.7.5 1.1 0 .4-.1.8-.4 1.1-.3.5-.6.9-1 1.2-.4.4-1 .9-1.6 1.4-.6.5-1.4 1.1-2.2 1.6V15h8v-2H15z',
3: 'M12.1 12.2c.4.3.8.5 1.2.7.4.2.9.3 1.4.3.5 0 1-.1 1.4-.3.3-.1.5-.5.5-.8 0-.2 0-.4-.1-.6-.1-.2-.3-.3-.5-.4-.3-.1-.7-.2-1-.3-.5-.1-1-.1-1.5-.1V9.1c.7.1 1.5-.1 2.2-.4.4-.2.6-.5.6-.9 0-.3-.1-.6-.4-.8-.3-.2-.7-.3-1.1-.3-.4 0-.8.1-1.1.3-.4.2-.7.4-1.1.6l-1.2-1.4c.5-.4 1.1-.7 1.6-.9.5-.2 1.2-.3 1.8-.3.5 0 1 .1 1.6.2.4.1.8.3 1.2.5.3.2.6.5.8.8.2.3.3.7.3 1.1 0 .5-.2.9-.5 1.3-.4.4-.9.7-1.5.9v.1c.6.1 1.2.4 1.6.8.4.4.7.9.7 1.5 0 .4-.1.8-.3 1.2-.2.4-.5.7-.9.9-.4.3-.9.4-1.3.5-.5.1-1 .2-1.6.2-.8 0-1.6-.1-2.3-.4-.6-.2-1.1-.6-1.6-1l1.1-1.4zM7 9H3V5H1v10h2v-4h4v4h2V5H7v4z',
4: 'M9 15H7v-4H3v4H1V5h2v4h4V5h2v10zm10-2h-1v2h-2v-2h-5v-2l4-6h3v6h1v2zm-3-2V7l-2.8 4H16z',
5: 'M12.1 12.2c.4.3.7.5 1.1.7.4.2.9.3 1.3.3.5 0 1-.1 1.4-.4.4-.3.6-.7.6-1.1 0-.4-.2-.9-.6-1.1-.4-.3-.9-.4-1.4-.4H14c-.1 0-.3 0-.4.1l-.4.1-.5.2-1-.6.3-5h6.4v1.9h-4.3L14 8.8c.2-.1.5-.1.7-.2.2 0 .5-.1.7-.1.5 0 .9.1 1.4.2.4.1.8.3 1.1.6.3.2.6.6.8.9.2.4.3.9.3 1.4 0 .5-.1 1-.3 1.4-.2.4-.5.8-.9 1.1-.4.3-.8.5-1.3.7-.5.2-1 .3-1.5.3-.8 0-1.6-.1-2.3-.4-.6-.2-1.1-.6-1.6-1-.1-.1 1-1.5 1-1.5zM9 15H7v-4H3v4H1V5h2v4h4V5h2v10z',
6: 'M9 15H7v-4H3v4H1V5h2v4h4V5h2v10zm8.6-7.5c-.2-.2-.5-.4-.8-.5-.6-.2-1.3-.2-1.9 0-.3.1-.6.3-.8.5l-.6.9c-.2.5-.2.9-.2 1.4.4-.3.8-.6 1.2-.8.4-.2.8-.3 1.3-.3.4 0 .8 0 1.2.2.4.1.7.3 1 .6.3.3.5.6.7.9.2.4.3.8.3 1.3s-.1.9-.3 1.4c-.2.4-.5.7-.8 1-.4.3-.8.5-1.2.6-1 .3-2 .3-3 0-.5-.2-1-.5-1.4-.9-.4-.4-.8-.9-1-1.5-.2-.6-.3-1.3-.3-2.1s.1-1.6.4-2.3c.2-.6.6-1.2 1-1.6.4-.4.9-.7 1.4-.9.6-.3 1.1-.4 1.7-.4.7 0 1.4.1 2 .3.5.2 1 .5 1.4.8 0 .1-1.3 1.4-1.3 1.4zm-2.4 5.8c.2 0 .4 0 .6-.1.2 0 .4-.1.5-.2.1-.1.3-.3.4-.5.1-.2.1-.5.1-.7 0-.4-.1-.8-.4-1.1-.3-.2-.7-.3-1.1-.3-.3 0-.7.1-1 .2-.4.2-.7.4-1 .7 0 .3.1.7.3 1 .1.2.3.4.4.6.2.1.3.3.5.3.2.1.5.2.7.1z',
};
export default function ({ attributes, setAttributes, className, isSelected }) {
let {
content,
collectionId,
itemId,
sectionId,
sectionName,
isModalOpen,
dataSource,
labelLevel,
textAlign,
style
} = attributes;
// Gets blocks props from hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps( {
className: {
[ `has-text-align-${ textAlign }` ]: textAlign,
},
style,
} );
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>
: (
<>
<BlockControls group="block">
{ dataSource == 'selection' ? (
TainacanBlocksCompatToolbar({
label: __('Select item', 'tainacan'),
icon: <svg
xmlns="http://www.w3.org/2000/svg"
viewBox="-2 -2 24 24"
height="24px"
width="24px">
<path d="m 6,3.9960001 h 5.016 c 0.544,0 1.008,0.192 1.392,0.576 L 19.416,11.58 c 0.384,0.384 0.576,0.856 0.576,1.416 0,0.56 -0.192,1.032 -0.576,1.416 l -4.992,4.992 c -0.176,0.176 -0.392,0.32 -0.648,0.432 -0.24,0.112 -0.496,0.168 -0.768,0.168 -0.272,0 -0.536,-0.056 -0.792,-0.168 -0.24,-0.112 -0.448,-0.256 -0.624,-0.432 L 4.608,12.42 c -0.4,-0.4 -0.6,-0.872 -0.6,-1.416 V 5.988 C 4.008,5.428 4.2,4.956 4.584,4.572 4.968,4.188 5.44,3.996 6,3.9960001 Z m 1.512,4.992 c 0.416,0 0.768,-0.144 1.056,-0.432 C 8.856,8.2680001 9,7.916 9,7.5 9,7.084 8.856,6.732 8.568,6.444 8.28,6.14 7.928,5.988 7.512,5.988 7.096,5.988 6.736,6.14 6.432,6.444 6.144,6.732 6,7.084 6,7.5 c 0,0.416 0.144,0.7680001 0.432,1.0560001 0.304,0.288 0.664,0.432 1.08,0.432 z"/>
</svg>,
onClick: () => {
isModalOpen = true;
setAttributes( {
isModalOpen: isModalOpen
});
}
})
): null
}
<ToolbarDropdownMenu
popoverProps={{
className: 'block-library-heading-level-dropdown',
}}
icon={ (
<SVG
width="24"
height="24"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<Path d={ levelToPath[ labelLevel ] } />
</SVG>
) }
label={ __( 'Change heading level', 'tainacan' ) }
controls={ [ 1, 2, 3, 4, 5, 6 ].map( ( targetLevel ) => {
const isActive = targetLevel === labelLevel;
return {
label: sprintf(
// translators: %s: heading level e.g: "1", "2", "3"
__( 'Heading %d', 'tainacan' ),
targetLevel
),
icon: (
<SVG
width="24"
height="24"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
isPressed={ isActive }
>
<Path d={ levelToPath[ targetLevel ] } />
</SVG>
),
isActive,
onClick: () => {
labelLevel = targetLevel;
setAttributes({ labelLevel: labelLevel });
}
};
} ) }
/>
<AlignmentControl
value={ textAlign }
onChange={ ( nextAlign ) => {
setAttributes( { textAlign: nextAlign } );
} }
/>
</BlockControls>
{ isSelected ?
(
<div>
{ isModalOpen ?
<SingleItemMetadatumModal
modalTitle={ __('Select one item to render its metadata', 'tainacan') }
existingCollectionId={ collectionId }
existingItemId={ itemId }
existingSectionId={ sectionId }
onSelectCollection={ (selectedCollectionId) => {
collectionId = selectedCollectionId;
setAttributes({
collectionId: collectionId
});
}}
onSelectItem={ (selectedItemId) => {
itemId = selectedItemId;
setAttributes({
itemId: itemId
});
}}
onApplySelectedMetadatum={ (selectedMetadatum) => {
sectionId = selectedMetadatum.sectionId;
setAttributes({
sectionId: sectionId,
isModalOpen: false
});
}}
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
: null
}
</div>
) : null
}
{ dataSource == 'selection' && !(collectionId && itemId && sectionId) ? (
<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="-2 -2 24 24"
height="24px"
width="24px">
<path d="m 6,3.9960001 h 5.016 c 0.544,0 1.008,0.192 1.392,0.576 L 19.416,11.58 c 0.384,0.384 0.576,0.856 0.576,1.416 0,0.56 -0.192,1.032 -0.576,1.416 l -4.992,4.992 c -0.176,0.176 -0.392,0.32 -0.648,0.432 -0.24,0.112 -0.496,0.168 -0.768,0.168 -0.272,0 -0.536,-0.056 -0.792,-0.168 -0.24,-0.112 -0.448,-0.256 -0.624,-0.432 L 4.608,12.42 c -0.4,-0.4 -0.6,-0.872 -0.6,-1.416 V 5.988 C 4.008,5.428 4.2,4.956 4.584,4.572 4.968,4.188 5.44,3.996 6,3.9960001 Z m 1.512,4.992 c 0.416,0 0.768,-0.144 1.056,-0.432 C 8.856,8.2680001 9,7.916 9,7.5 9,7.084 8.856,6.732 8.568,6.444 8.28,6.14 7.928,5.988 7.512,5.988 7.096,5.988 6.736,6.14 6.432,6.444 6.144,6.732 6,7.084 6,7.5 c 0,0.416 0.144,0.7680001 0.432,1.0560001 0.304,0.288 0.664,0.432 1.08,0.432 z"/>
</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
}
{ sectionName ? (
<Heading
{ ...blockProps }
level={ labelLevel }>
{ sectionName }
</Heading>
) : null
}
</>
);
};

View File

@ -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
d="m 6,3.9960001 h 5.016 c 0.544,0 1.008,0.192 1.392,0.576 L 19.416,11.58 c 0.384,0.384 0.576,0.856 0.576,1.416 0,0.56 -0.192,1.032 -0.576,1.416 l -4.992,4.992 c -0.176,0.176 -0.392,0.32 -0.648,0.432 -0.24,0.112 -0.496,0.168 -0.768,0.168 -0.272,0 -0.536,-0.056 -0.792,-0.168 -0.24,-0.112 -0.448,-0.256 -0.624,-0.432 L 4.608,12.42 c -0.4,-0.4 -0.6,-0.872 -0.6,-1.416 V 5.988 C 4.008,5.428 4.2,4.956 4.584,4.572 4.968,4.188 5.44,3.996 6,3.9960001 Z m 1.512,4.992 c 0.416,0 0.768,-0.144 1.056,-0.432 C 8.856,8.2680001 9,7.916 9,7.5 9,7.084 8.856,6.732 8.568,6.444 8.28,6.14 7.928,5.988 7.512,5.988 7.096,5.988 6.736,6.14 6.432,6.444 6.144,6.732 6,7.084 6,7.5 c 0,0.416 0.144,0.7680001 0.432,1.0560001 0.304,0.288 0.664,0.432 1.08,0.432 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,16 @@
const { useBlockProps, InnerBlocks } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
export default function({ attributes, className }) {
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps.save();
switch (attributes.labelLevel) {
case 1: return <h1 { ...blockProps }>{ attributes.sectionName }</h1>;
case 2: return <h2 { ...blockProps }>{ attributes.sectionName }</h2>;
case 3: return <h3 { ...blockProps }>{ attributes.sectionName }</h3>;
case 4: return <h4 { ...blockProps }>{ attributes.sectionName }</h4>;
case 5: return <h5 { ...blockProps }>{ attributes.sectionName }</h5>;
case 6: return <h6 { ...blockProps }>{ attributes.sectionName }</h6>;
default: return <h2 { ...blockProps }>{ attributes.sectionName }</h2>;
}
};

View File

@ -17,8 +17,11 @@ const TAINACAN_BLOCKS = [
'faceted-search' => [],
'item-submission-form' => [],
'item-gallery' => ['render_callback' => 'tainacan_blocks_render_items_gallery'],
'item-metadata-sections' => [],
'item-metadata-section' => [],
'item-metadata' => [],
'item-metadatum' => ['render_callback' => 'tainacan_blocks_render_item_metadatum']
'item-metadatum' => ['render_callback' => 'tainacan_blocks_render_item_metadatum'],
'metadata-section-name' => []
];
// Lets do this!

View File

@ -23,8 +23,11 @@ module.exports = {
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_metadata_sections: './src/views/gutenberg-blocks/blocks/item-metadata-sections/index.js',
block_item_metadata_section: './src/views/gutenberg-blocks/blocks/item-metadata-section/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'
block_item_metadatum: './src/views/gutenberg-blocks/blocks/item-metadatum/index.js',
block_metadata_section_name: './src/views/gutenberg-blocks/blocks/metadata-section-name/index.js'
},
output: {
path: path.resolve(__dirname, './src/assets/js/'),