diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/block.json b/src/views/gutenberg-blocks/blocks/item-metadata-section/block.json new file mode 100644 index 000000000..9a4d192d5 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/block.json @@ -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" +} \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/deprecated.js b/src/views/gutenberg-blocks/blocks/item-metadata-section/deprecated.js new file mode 100644 index 000000000..109fa8b38 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/deprecated.js @@ -0,0 +1 @@ +export default []; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/edit.js b/src/views/gutenberg-blocks/blocks/item-metadata-section/edit.js new file mode 100644 index 000000000..6ecb0ea58 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/edit.js @@ -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' ? +
+ +
+ : ( +
+ + { isSelected ? + ( +
+ { isModalOpen ? + { + collectionId = Number(selectedCollectionId); + setAttributes({ + collectionId: collectionId + }); + }} + onApplySelectedItem={ (selectedItemId) => { + itemId = Number(selectedItemId); + setAttributes({ + itemId: itemId, + isModalOpen: false + }); + setContent(); + }} + onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/> + : null + } + +
+ ) : null + } + + { !itemId && dataSource !== 'template' ? ( + + )}> +

+ + + + {__('Select an item to display its metadata list.', 'tainacan')} +

+ +
+ ) : null + } + + { isLoading ? +
+ +
: +
+ { metadataSectionTemplate.length ? + + : null + } +
+ } + +
+ ); +}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/icon.js b/src/views/gutenberg-blocks/blocks/item-metadata-section/icon.js new file mode 100644 index 000000000..42c450677 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/icon.js @@ -0,0 +1,14 @@ + const { SVG, Path } = wp.components; + + export default ( + + + + ); + \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/index.js b/src/views/gutenberg-blocks/blocks/item-metadata-section/index.js new file mode 100644 index 000000000..a1408e341 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/index.js @@ -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 +}); diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/save.js b/src/views/gutenberg-blocks/blocks/item-metadata-section/save.js new file mode 100644 index 000000000..d17ed6351 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/save.js @@ -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
+}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/style.scss b/src/views/gutenberg-blocks/blocks/item-metadata-section/style.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-section/transforms.js b/src/views/gutenberg-blocks/blocks/item-metadata-section/transforms.js new file mode 100644 index 000000000..7716d74b8 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-section/transforms.js @@ -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 + } + ); + }, + } + ] +}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/block.json b/src/views/gutenberg-blocks/blocks/item-metadata-sections/block.json new file mode 100644 index 000000000..4969bef28 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/block.json @@ -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" +} \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/deprecated.js b/src/views/gutenberg-blocks/blocks/item-metadata-sections/deprecated.js new file mode 100644 index 000000000..109fa8b38 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/deprecated.js @@ -0,0 +1 @@ +export default []; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/edit.js b/src/views/gutenberg-blocks/blocks/item-metadata-sections/edit.js new file mode 100644 index 000000000..45518dacd --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/edit.js @@ -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' ? +
+ +
+ : ( +
+ + { isSelected ? + ( +
+ { isModalOpen ? + { + collectionId = Number(selectedCollectionId); + setAttributes({ + collectionId: collectionId + }); + }} + onApplySelectedItem={ (selectedItemId) => { + itemId = Number(selectedItemId); + setAttributes({ + itemId: itemId, + isModalOpen: false + }); + setContent(); + }} + onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/> + : null + } + +
+ ) : null + } + + { !itemId && dataSource !== 'template' ? ( + + )}> +

+ + + + {__('Select an item to display its metadata list.', 'tainacan')} +

+ +
+ ) : null + } + + { isLoading ? +
+ +
: +
+ { metadataSectionsTemplate.length ? + + : null + } +
+ } + +
+ ); +}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/icon.js b/src/views/gutenberg-blocks/blocks/item-metadata-sections/icon.js new file mode 100644 index 000000000..42c450677 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/icon.js @@ -0,0 +1,14 @@ + const { SVG, Path } = wp.components; + + export default ( + + + + ); + \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/index.js b/src/views/gutenberg-blocks/blocks/item-metadata-sections/index.js new file mode 100644 index 000000000..a1408e341 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/index.js @@ -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 +}); diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/save.js b/src/views/gutenberg-blocks/blocks/item-metadata-sections/save.js new file mode 100644 index 000000000..d17ed6351 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/save.js @@ -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
+}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/style.scss b/src/views/gutenberg-blocks/blocks/item-metadata-sections/style.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/views/gutenberg-blocks/blocks/item-metadata-sections/transforms.js b/src/views/gutenberg-blocks/blocks/item-metadata-sections/transforms.js new file mode 100644 index 000000000..7716d74b8 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/item-metadata-sections/transforms.js @@ -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 + } + ); + }, + } + ] +}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/item-metadata/block.json b/src/views/gutenberg-blocks/blocks/item-metadata/block.json index bdead2e9c..b28d6cff2 100644 --- a/src/views/gutenberg-blocks/blocks/item-metadata/block.json +++ b/src/views/gutenberg-blocks/blocks/item-metadata/block.json @@ -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": { diff --git a/src/views/gutenberg-blocks/blocks/item-metadata/edit.js b/src/views/gutenberg-blocks/blocks/item-metadata/edit.js index a1d8e9af7..6673d722b 100644 --- a/src/views/gutenberg-blocks/blocks/item-metadata/edit.js +++ b/src/views/gutenberg-blocks/blocks/item-metadata/edit.js @@ -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 @@ -30,61 +30,33 @@ export default function ({ attributes, setAttributes, className, isSelected, con function setContent() { isLoading = true; - + setAttributes({ 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,75 +64,51 @@ export default function ({ attributes, setAttributes, className, isSelected, con } function getItemMetadataTemplates({ - metadataSections, - itemMetadata, - metadataSectionsRequestSource + metadata, + itemMetadata, + itemMetadataRequestSource }) { let itemMetadataTemplate = []; - metadataSections.forEach((aMetadataSection) => { - if ( aMetadataSection['metadata_object_list'] && aMetadataSection['metadata_object_list'].length ) { - - let itemMetadataBySection = []; - - itemMetadataBySection.push([ - 'core/heading', + if (dataSource === 'template') { + metadata.forEach((aMetadatum) => { + itemMetadataTemplate.push([ + 'tainacan/item-metadatum', { - placeholder: __( 'Metadata section name', 'tainacan' ), - content: aMetadataSection.name + placeholder: __( 'Item Metadatum', 'tainacan' ), + metadatumId: aMetadatum.id, + collectionId: Number(collectionId), + dataSource: 'template' } ]); - - if (dataSource === 'template') { - aMetadataSection['metadata_object_list'].forEach((aMetadatum) => { - itemMetadataBySection.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([ - 'tainacan/item-metadatum', - { - placeholder: __( 'Item Metadatum', 'tainacan' ), - metadatumId: itemMetadatum.metadatum.id, - itemId: Number(itemId), - collectionId: Number(collectionId), - dataSource: 'parent' - } - ]); + }); + } else { + itemMetadata.forEach((itemMetadatum) => { + if ( + itemMetadatum.metadatum && + itemMetadatum.metadatum.id && + (itemMetadatum.value !== '' && itemMetadatum.value !== false) && + (!Array.isArray(itemMetadatum.value) || itemMetadatum.value.length) + ) { + itemMetadataTemplate.push([ + 'tainacan/item-metadatum', + { + placeholder: __( 'Item Metadatum', 'tainacan' ), + metadatumId: itemMetadatum.metadatum.id, + itemId: Number(itemId), + collectionId: Number(collectionId), + dataSource: 'parent' } - }); + ]); } - 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 :
- { metadataSections.length ? + { itemMetadataTemplate.length ? + template={ itemMetadataTemplate } /> : null }
diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/block.json b/src/views/gutenberg-blocks/blocks/metadata-section-name/block.json new file mode 100644 index 000000000..6891411b0 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/metadata-section-name/block.json @@ -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" +} \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/deprecated.js b/src/views/gutenberg-blocks/blocks/metadata-section-name/deprecated.js new file mode 100644 index 000000000..109fa8b38 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/metadata-section-name/deprecated.js @@ -0,0 +1 @@ +export default []; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/edit.js b/src/views/gutenberg-blocks/blocks/metadata-section-name/edit.js new file mode 100644 index 000000000..70cb3f012 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/metadata-section-name/edit.js @@ -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' ? +
+ +
+ : ( + <> + + + { dataSource == 'selection' ? ( + TainacanBlocksCompatToolbar({ + label: __('Select item', 'tainacan'), + icon: + + , + onClick: () => { + isModalOpen = true; + setAttributes( { + isModalOpen: isModalOpen + }); + } + }) + ): null + } + + + + ) } + 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: ( + + + + ), + isActive, + onClick: () => { + labelLevel = targetLevel; + setAttributes({ labelLevel: labelLevel }); + } + }; + } ) } + /> + { + setAttributes( { textAlign: nextAlign } ); + } } + /> + + + { isSelected ? + ( +
+ { isModalOpen ? + { + 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 + } + +
+ ) : null + } + + { dataSource == 'selection' && !(collectionId && itemId && sectionId) ? ( + + )}> +

+ + + + {__('Select an item metadata to display its label and value.', 'tainacan')} +

+ +
+ ) : null + } + + { sectionName ? ( + + { sectionName } + + ) : null + } + + + ); +}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/icon.js b/src/views/gutenberg-blocks/blocks/metadata-section-name/icon.js new file mode 100644 index 000000000..9067dba1d --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/metadata-section-name/icon.js @@ -0,0 +1,14 @@ + const { SVG, Path } = wp.components; + + export default ( + + + + ); + \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/index.js b/src/views/gutenberg-blocks/blocks/metadata-section-name/index.js new file mode 100644 index 000000000..f8cd05987 --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/metadata-section-name/index.js @@ -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 +}); diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/save.js b/src/views/gutenberg-blocks/blocks/metadata-section-name/save.js new file mode 100644 index 000000000..7f281b60f --- /dev/null +++ b/src/views/gutenberg-blocks/blocks/metadata-section-name/save.js @@ -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

{ attributes.sectionName }

; + case 2: return

{ attributes.sectionName }

; + case 3: return

{ attributes.sectionName }

; + case 4: return

{ attributes.sectionName }

; + case 5: return
{ attributes.sectionName }
; + case 6: return
{ attributes.sectionName }
; + default: return

{ attributes.sectionName }

; + } + +}; \ No newline at end of file diff --git a/src/views/gutenberg-blocks/blocks/metadata-section-name/style.scss b/src/views/gutenberg-blocks/blocks/metadata-section-name/style.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/views/gutenberg-blocks/class-tainacan-gutenberg-block.php b/src/views/gutenberg-blocks/class-tainacan-gutenberg-block.php index c0c0d03ab..bf977fc47 100644 --- a/src/views/gutenberg-blocks/class-tainacan-gutenberg-block.php +++ b/src/views/gutenberg-blocks/class-tainacan-gutenberg-block.php @@ -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! diff --git a/webpack.common.js b/webpack.common.js index 177bf561c..375bcf666 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -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/'),