diff --git a/CHANGELOG.md b/CHANGELOG.md
index c97eec6..f73a7e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,8 +4,29 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
+#### [0.2.0](https://github.com/eea/volto-forests-theme/compare/0.2.0-beta.0...0.2.0)
+
+- Develop [`#51`](https://github.com/eea/volto-forests-theme/pull/51)
+
+#### [0.2.0-beta.0](https://github.com/eea/volto-forests-theme/compare/0.1.37...0.2.0-beta.0)
+
+> 3 February 2022
+
+- adapt to data-blocks v3 [`#52`](https://github.com/eea/volto-forests-theme/pull/52)
+- Release 0.2.0-beta.0 [`4c7e23a`](https://github.com/eea/volto-forests-theme/commit/4c7e23a7d710c656ad39260b9d4509cc903c424c)
+- Use latest volto-datablocks [`cc5e03b`](https://github.com/eea/volto-forests-theme/commit/cc5e03b45ba8ce1b3e632353bd1f43c4ae62c54e)
+- Added DiscodataConnectorBlock [`7502a9e`](https://github.com/eea/volto-forests-theme/commit/7502a9ea2c57aacfdfabf86fbf80c752c856cb6a)
+- fix navigationBlock View [`ee0891a`](https://github.com/eea/volto-forests-theme/commit/ee0891addb9e7c78283b2d9b03a36224ac6904b6)
+- object list widget [`874c0d7`](https://github.com/eea/volto-forests-theme/commit/874c0d7077b9e36fccf765547e550679c4bfb5bb)
+- rafactor navigation block [`e96c48e`](https://github.com/eea/volto-forests-theme/commit/e96c48ed5995b075a2b8a7c0834befd6608763db)
+- Updated style [`26d2e5e`](https://github.com/eea/volto-forests-theme/commit/26d2e5ee9cef90533338359e35bc6df1ada7f7eb)
+- WIP: adapt to volto-datablocks v3 [`e5d143e`](https://github.com/eea/volto-forests-theme/commit/e5d143e8a76a1d90921b73f7e6f7238b31fd4164)
+
#### [0.1.37](https://github.com/eea/volto-forests-theme/compare/0.1.36...0.1.37)
+> 28 January 2022
+
+- Develop [`#51`](https://github.com/eea/volto-forests-theme/pull/51)
- nice homepage buttons [`14616da`](https://github.com/eea/volto-forests-theme/commit/14616da40f1d51b24d1fee540b0ea9331569306b)
#### [0.1.36](https://github.com/eea/volto-forests-theme/compare/0.1.35...0.1.36)
diff --git a/package.json b/package.json
index 771822c..f6b79e7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@eeacms/volto-forests-theme",
- "version": "0.1.37",
+ "version": "0.2.0",
"description": "@eeacms/volto-forests-theme: Volto add-on",
"main": "src/index.js",
"author": "European Environment Agency: IDM2 A-Team",
@@ -25,7 +25,7 @@
"dependencies": {
"@eeacms/volto-plotlycharts": "*",
"@eeacms/volto-addons-forest": "*",
- "@eeacms/volto-datablocks": "2.0.16",
+ "@eeacms/volto-datablocks": "*",
"@eeacms/volto-matomo": "*",
"react-highlight-words": "^0.16.0",
"react-image-gallery": "1.2.7",
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/index.js b/src/components/manage/Blocks/DiscodataConnectorBlock/index.js
new file mode 100644
index 0000000..d775912
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/index.js
@@ -0,0 +1,24 @@
+import worldSVG from '@plone/volto/icons/world.svg';
+import DiscodataConnectorBlockEdit from './v1/Edit';
+import DiscodataConnectorBlockView from './v1/View';
+
+// TODO: Move this to volto-forests-theme
+
+export default (config) => {
+ config.blocks.blocksConfig.discodata_connector_block = {
+ id: 'discodata_connector_block',
+ title: 'Discodata connector block',
+ icon: worldSVG,
+ group: 'data_blocks',
+ view: DiscodataConnectorBlockView,
+ edit: DiscodataConnectorBlockEdit,
+ restricted: false,
+ mostUsed: false,
+ sidebarTab: 1,
+ security: {
+ addPermission: [],
+ view: [],
+ },
+ };
+ return config;
+};
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/styles.css b/src/components/manage/Blocks/DiscodataConnectorBlock/styles.css
new file mode 100644
index 0000000..db5c8e9
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/styles.css
@@ -0,0 +1,16 @@
+.connected-data-block {
+ background-color: lightblue;
+}
+
+.block-container .data-content span {
+ white-space: break-spaces;
+}
+
+#sidebar-properties .accordion .ui.menu {
+ flex-wrap: wrap;
+}
+
+#sidebar-properties .accordion .ui.menu .active.item {
+ border: 1px solid #d4d4d5;
+ border-radius: 0.28rem !important;
+}
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/v1/Edit.jsx b/src/components/manage/Blocks/DiscodataConnectorBlock/v1/Edit.jsx
new file mode 100644
index 0000000..d0b04df
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/v1/Edit.jsx
@@ -0,0 +1,90 @@
+import React, { useState, useEffect } from 'react';
+import { compose } from 'redux';
+import _uniqueId from 'lodash/uniqueId';
+import { v4 as uuid } from 'uuid';
+import View from './View';
+import { SidebarPortal } from '@plone/volto/components';
+import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
+import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
+
+import { getSchema } from './schema';
+
+import '../styles.css';
+
+const Edit = (props) => {
+ const [state, setState] = useState({
+ id: _uniqueId('block_'),
+ schema: getSchema(props),
+ });
+
+ useEffect(() => {
+ const newData = { ...props.data };
+ if (props.data.data_providers) {
+ if (
+ typeof props.data?.data_providers === 'object' &&
+ props.data?.data_providers?.value
+ ) {
+ try {
+ newData.data_providers = [];
+ const dataProvidersSchema = JSON.parse(
+ props.data?.data_providers?.value,
+ );
+ dataProvidersSchema?.fieldsets?.[0]?.fields &&
+ dataProvidersSchema.fieldsets[0].fields.forEach((dataProvider) => {
+ newData.data_providers.push({
+ ...dataProvidersSchema.properties[dataProvider],
+ '@id': uuid(),
+ id: dataProvider,
+ });
+ });
+ } catch {}
+ }
+ }
+ if (JSON.stringify(newData) !== JSON.stringify(props.data)) {
+ props.onChangeBlock(props.block, {
+ ...newData,
+ });
+ }
+ /* eslint-disable-next-line */
+ }, []);
+
+ useEffect(() => {
+ setState({
+ ...state,
+ schema: getSchema(props),
+ });
+ /* eslint-disable-next-line */
+ }, [props.providers_data, props.data.data_providers_new]);
+
+ return (
+
+
+ {
+ props.onChangeBlock(props.block, {
+ ...(props.data || {}),
+ [field]: data,
+ });
+ }}
+ formData={props.data || {}}
+ block={props.block}
+ />
+
+
+
+ );
+};
+
+export default compose(
+ connectToMultipleProviders((props) => ({
+ providers:
+ props.data?.data_providers
+ ?.map((provider) => ({
+ provider_url: provider.path,
+ title: provider.title,
+ }))
+ ?.filter((provider) => provider.provider_url) || [],
+ })),
+)(Edit);
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/v1/View.jsx b/src/components/manage/Blocks/DiscodataConnectorBlock/v1/View.jsx
new file mode 100644
index 0000000..bb82ae5
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/v1/View.jsx
@@ -0,0 +1,180 @@
+import React, { useState, useEffect } from 'react';
+import { compose } from 'redux';
+import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
+import { DataConnectedValue } from '@eeacms/volto-datablocks/Utils';
+import { Sources } from '@eeacms/volto-datablocks/Utils';
+
+const providerView = (dataProviderKey, dataProvider) => {
+ return (
+
+
+ {dataProvider.hasDiscodataConnector && (
+
+ )}
+ {dataProvider.measurmentUnit || ''}
+
+ {' ' + (dataProvider.additionalText || '')}
+
+ );
+};
+
+const bulletListView = (items) => (
+
+ {items &&
+ Object.entries(items).map(([key, item]) => (
+
+ {item.leftText}
+ {item.rightText}
+
+ ))}
+
+);
+
+const View = (props) => {
+ const [dataProviders, setDataProviders] = useState({});
+ const [parentsDataProviders, setParentsDataProviders] = useState({});
+ const { providers_data, providers_metadata } = props;
+ const bulletList =
+ props.data?.bullet_list?.value &&
+ JSON.parse(props.data?.bullet_list?.value).properties;
+
+ const updateDataProviders = () => {
+ let newDataProviders = { ...dataProviders };
+ if (props.data.data_providers) {
+ if (
+ typeof props.data.data_providers === 'object' &&
+ props.data.data_providers.value
+ ) {
+ newDataProviders = {};
+ const dataProvidersSchema =
+ props.data?.data_providers?.value &&
+ JSON.parse(props.data?.data_providers?.value);
+ dataProvidersSchema?.fieldsets?.[0]?.fields &&
+ dataProvidersSchema.fieldsets[0].fields.forEach((dataProvider) => {
+ newDataProviders[dataProvider] = {
+ ...dataProvidersSchema.properties[dataProvider],
+ };
+ });
+ } else if (Array.isArray(props.data.data_providers)) {
+ newDataProviders = {};
+ props.data.data_providers.forEach((provider) => {
+ newDataProviders[provider.id] = { ...provider };
+ });
+ }
+ }
+ setDataProviders({ ...newDataProviders });
+ return newDataProviders;
+ };
+
+ const updateParentsDataProviders = () => {
+ const newParentsDataProviders = {};
+ dataProviders &&
+ Object.entries(dataProviders).forEach(
+ ([dataProviderKey, dataProvider]) => {
+ if (!dataProvider.hasParent) {
+ newParentsDataProviders[dataProviderKey] = { ...dataProvider };
+ } else if (
+ dataProvider.parent &&
+ newParentsDataProviders[dataProvider.parent]
+ ) {
+ if (!newParentsDataProviders[dataProvider.parent].children) {
+ newParentsDataProviders[dataProvider.parent].children = {};
+ }
+ newParentsDataProviders[dataProvider.parent].children[
+ dataProviderKey
+ ] = dataProvider;
+ }
+ },
+ );
+ setParentsDataProviders({ ...newParentsDataProviders });
+ return newParentsDataProviders;
+ };
+
+ useEffect(() => {
+ updateDataProviders();
+ /* eslint-disable-next-line */
+ }, [JSON.stringify(props.data?.data_providers)]);
+
+ useEffect(() => {
+ updateParentsDataProviders();
+ /* eslint-disable-next-line */
+ }, [JSON.stringify(dataProviders)]);
+
+ const view = (
+
+
+ {/* {props.data?.block_title ?
{props.data.block_title}
: ''} */}
+ {parentsDataProviders &&
+ Object.entries(parentsDataProviders).map(
+ ([dataProviderKey, dataProvider]) => {
+ if (dataProvider.children) {
+ return (
+
+ {providerView(dataProviderKey, dataProvider)}
+ {Object.entries(
+ dataProvider.children,
+ ).map(([cildrenKey, children]) =>
+ providerView(cildrenKey, children),
+ )}
+
+ );
+ }
+ return (
+
+ {providerView(dataProviderKey, dataProvider)}
+
+ );
+ },
+ )}
+ {bulletList && bulletListView(bulletList)}
+ {props?.data?.chartSources && (
+
+ provider.path)
+ ?.filter((path) => path)?.[0]
+ }
+ />
+
+ )}
+
+
+ );
+ return view;
+};
+
+export default compose(
+ connectToMultipleProviders((props) => ({
+ providers:
+ props.data?.data_providers
+ ?.map((provider) => ({
+ provider_url: provider.path,
+ title: provider.title,
+ has_data_query_by_context: provider.has_data_query_by_context,
+ has_data_query_by_provider: provider.has_data_query_by_provider,
+ data_query: provider.data_query,
+ }))
+ ?.filter((provider) => provider.provider_url) || [],
+ })),
+)(View);
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/v1/schema.js b/src/components/manage/Blocks/DiscodataConnectorBlock/v1/schema.js
new file mode 100644
index 0000000..cb983b2
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/v1/schema.js
@@ -0,0 +1,254 @@
+import React from 'react';
+
+const makeChoices = (keys) => keys && keys.map((k) => [k, k]);
+
+const getDataProvidersIds = (data_providers = [], child = {}) => {
+ const ids = data_providers
+ .map((data_provider) => data_provider.id)
+ .filter((id) => id && id !== child.id);
+ return makeChoices(ids);
+};
+
+const dataProviderSchemaExtender = (schema, child = {}, props) => {
+ const data_providers = props.data.data_providers || [];
+ return {
+ ...schema,
+ fieldsets: [
+ {
+ ...schema.fieldsets[0],
+ },
+ {
+ id: 'properties',
+ title: 'Properties',
+ fields: ['measurmentUnit', 'additionalText', 'className'],
+ },
+ ...(child.hasDiscodataConnector
+ ? [
+ {
+ id: 'Discodata connector',
+ title: 'Discodata connector',
+ fields: [
+ 'path',
+ 'displayColumn',
+ 'textTemplate',
+ 'specifier',
+ 'data_query',
+ ],
+ },
+ ]
+ : []),
+ ...(child.hasParent
+ ? [
+ {
+ id: 'parent',
+ title: 'Parent',
+ fields: ['parent'],
+ },
+ ]
+ : []),
+ ],
+ properties: {
+ ...schema.properties,
+ displayColumn: {
+ ...schema.properties.displayColumn,
+ choices: makeChoices(
+ Object.keys(props.providers_data?.[child.title] || {}),
+ ),
+ },
+ parent: {
+ ...schema.properties.parent,
+ choices: getDataProvidersIds(data_providers, child),
+ },
+ },
+ };
+};
+
+const dataProviderSchema = {
+ title: 'Data provider',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: [
+ 'title',
+ 'id',
+ 'hasDiscodataConnector',
+ 'hasParent',
+ 'wrapperClassName',
+ ],
+ },
+ {
+ id: 'advanced',
+ title: 'Advanced',
+ fields: [
+ 'path',
+ 'displayColumn',
+ 'textTemplate',
+ 'specifier',
+ 'measurmentUnit',
+ 'additionalText',
+ 'className',
+ 'parent',
+ 'wrapperClassName',
+ ],
+ },
+ ],
+ properties: {
+ title: {
+ type: 'text',
+ title: 'Title',
+ },
+ id: {
+ type: 'text',
+ title: 'Id',
+ },
+ hasDiscodataConnector: {
+ type: 'boolean',
+ title: 'Has discodata connector',
+ },
+ hasParent: {
+ type: 'boolean',
+ title: 'Has parent',
+ },
+ path: {
+ widget: 'object_by_path',
+ title: 'Discodata connector',
+ },
+ displayColumn: {
+ type: 'select',
+ title: 'Display column',
+ choices: [],
+ },
+ textTemplate: {
+ title: 'Text template',
+ widget: 'textarea',
+ description: 'Add suffix/prefix to text. Use {} for value placeholder',
+ },
+ specifier: {
+ title: 'Format',
+ description: (
+ <>
+ See{' '}
+
+ D3 format documentation
+
+ >
+ ),
+ },
+ measurmentUnit: {
+ type: 'text',
+ title: 'Measurment unit',
+ },
+ additionalText: {
+ type: 'text',
+ title: 'Additional text',
+ },
+
+ className: {
+ type: 'select',
+ title: 'Class name',
+ choices: [
+ ['data', 'Data'],
+ ['data-content', 'Data content'],
+ ],
+ },
+ parent: {
+ type: 'select',
+ title: 'Parent',
+ choices: [],
+ },
+ wrapperClassName: {
+ type: 'select',
+ title: 'Wrapper class name',
+ choices: [
+ ['data-wrapper brown', 'Brown wrapper'],
+ ['data-wrapper green', 'Green wrapper'],
+ ['data-wrapper blue', 'Blue wrapper'],
+ ['data-wrapper purple', 'Purple wrapper'],
+ ],
+ },
+ data_query: {
+ title: 'Data query',
+ widget: 'data_query',
+ },
+ },
+ required: ['title', 'id'],
+};
+
+const SourceSchema = {
+ title: 'Source',
+
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['chart_source', 'chart_source_link'],
+ },
+ ],
+
+ properties: {
+ chart_source: {
+ type: 'string',
+ title: 'Source',
+ },
+ chart_source_link: {
+ type: 'string',
+ title: 'Link',
+ },
+ },
+
+ required: ['source'],
+};
+
+export const getSchema = (props) => ({
+ title: 'Discodata connector block',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['block_title'],
+ },
+ {
+ id: 'advanced',
+ title: 'Advanced',
+ fields: ['data_providers'],
+ },
+ {
+ id: 'sources',
+ title: 'Sources',
+ fields: ['chartSources', 'download_button'],
+ },
+ ],
+ properties: {
+ block_title: {
+ title: 'Title',
+ widget: 'textarea',
+ },
+ download_button: {
+ title: 'Download button',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ chartSources: {
+ widget: 'object_list',
+ title: 'Sources',
+ schema: SourceSchema,
+ },
+ data_providers: {
+ title: 'Data providers',
+ widget: 'object_list',
+ schema: dataProviderSchema,
+ schemaExtender: (schema, child) =>
+ dataProviderSchemaExtender(schema, child, props),
+ defaultData: {
+ hasDiscodataConnector: true,
+ hasParent: false,
+ },
+ },
+ },
+ required: [],
+});
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/v2/Edit.jsx b/src/components/manage/Blocks/DiscodataConnectorBlock/v2/Edit.jsx
new file mode 100644
index 0000000..70a1926
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/v2/Edit.jsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { compose } from 'redux';
+import { SidebarPortal } from '@plone/volto/components';
+import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
+import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
+import getSchema from './schema';
+import View from './View';
+
+const Edit = (props) => {
+ const schema = React.useMemo(() => getSchema(props), [props]);
+
+ return (
+ <>
+
+
+
+ {
+ props.onChangeBlock(props.block, {
+ ...props.data,
+ [id]: value,
+ });
+ }}
+ formData={props.data}
+ />
+
+ >
+ );
+};
+
+export default compose(
+ connectToMultipleProviders((props) => ({
+ providers: props.data?.providers,
+ })),
+)(Edit);
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/v2/View.jsx b/src/components/manage/Blocks/DiscodataConnectorBlock/v2/View.jsx
new file mode 100644
index 0000000..b0f1d11
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/v2/View.jsx
@@ -0,0 +1,70 @@
+import React from 'react';
+import { compose } from 'redux';
+import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
+import { DataConnectedValue } from '@eeacms/volto-datablocks/Utils';
+import { Sources } from '@eeacms/volto-datablocks/Utils';
+
+const ProviderView = ({ provider }) => {
+ if (!provider) return '';
+ return (
+
+
+
+
+
+ );
+};
+
+const View = (props) => {
+ const { data = {} } = props;
+ const { providers = [] } = data;
+
+ if (!providers.length) return Add providers
;
+
+ return (
+
+
+ {providers.map((provider, index) => {
+ if ((index + 1) % 2 === 0) return '';
+ return (
+
+ );
+ })}
+ {props.data?.chartSources && providers?.[0]?.url && (
+
+
+
+ )}
+
+
+ );
+};
+
+export default compose(
+ connectToMultipleProviders((props) => ({
+ providers: props.data.providers,
+ })),
+)(View);
diff --git a/src/components/manage/Blocks/DiscodataConnectorBlock/v2/schema.js b/src/components/manage/Blocks/DiscodataConnectorBlock/v2/schema.js
new file mode 100644
index 0000000..629743d
--- /dev/null
+++ b/src/components/manage/Blocks/DiscodataConnectorBlock/v2/schema.js
@@ -0,0 +1,204 @@
+import React from 'react';
+
+const dataProviderSchemaExtender = (schema = {}, child = {}, props) => {
+ const title = child.title || child.url;
+ if (!title || !props.providers_data) return schema;
+ const provider_data = props.providers_data[title] || {};
+ const columns = Array.from(
+ new Set(Object.keys(provider_data || {})),
+ ).map((n) => [n, n]);
+ const rows =
+ child.column && provider_data[child.column]
+ ? provider_data[child.column].map((value, index) => [index, value])
+ : [];
+
+ return {
+ ...schema,
+ properties: {
+ ...schema.properties,
+ column: {
+ title: 'Column',
+ choices: columns,
+ },
+ row: {
+ title: 'Row',
+ choices: rows,
+ },
+ },
+ };
+};
+
+const dataProviderSchema = {
+ title: 'Data provider',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Properties',
+ fields: [
+ 'title',
+ 'url',
+ 'column',
+ 'row',
+ 'specifier',
+ 'textTemplate',
+ 'placeholder',
+ ],
+ },
+ {
+ id: 'advanced',
+ title: 'Advanced',
+ fields: [
+ 'className',
+ 'wrapperClassName',
+ 'has_data_query_by_context',
+ 'has_data_query_by_provider',
+ 'data_query',
+ ],
+ },
+ ],
+ properties: {
+ title: {
+ type: 'text',
+ title: 'Title',
+ },
+ url: {
+ widget: 'object_by_path',
+ title: 'Data provider',
+ },
+ column: {
+ title: 'Column',
+ choices: [],
+ },
+ row: {
+ title: 'Row',
+ default: 0,
+ choices: [],
+ },
+ specifier: {
+ title: 'Format specifier',
+ description: (
+ <>
+ See{' '}
+
+ D3 format documentation
+
+ >
+ ),
+ },
+ textTemplate: {
+ title: 'Text template',
+ widget: 'textarea',
+ description: 'Add suffix/prefix to text. Use {} for value placeholder',
+ },
+ placeholder: {
+ title: 'Placeholder',
+ },
+ className: {
+ type: 'select',
+ title: 'Class name',
+ choices: [
+ ['data', 'Data'],
+ ['data-content', 'Data content'],
+ ],
+ },
+ wrapperClassName: {
+ type: 'select',
+ title: 'Wrapper class name',
+ choices: [
+ ['data-wrapper brown', 'Brown wrapper'],
+ ['data-wrapper green', 'Green wrapper'],
+ ['data-wrapper blue', 'Blue wrapper'],
+ ['data-wrapper purple', 'Purple wrapper'],
+ ],
+ },
+ has_data_query_by_context: {
+ title: 'Has data_query by context',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ has_data_query_by_provider: {
+ title: 'Has data_query by provider',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ data_query: {
+ title: 'Data query',
+ widget: 'data_query',
+ },
+ },
+ required: ['title', 'id'],
+};
+
+const SourceSchema = {
+ title: 'Source',
+
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['chart_source', 'chart_source_link'],
+ },
+ ],
+
+ properties: {
+ chart_source: {
+ type: 'string',
+ title: 'Source',
+ },
+ chart_source_link: {
+ type: 'string',
+ title: 'Link',
+ },
+ },
+
+ required: ['source'],
+};
+
+export default (props) => ({
+ title: 'Discodata connector block',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['block_title'],
+ },
+ {
+ id: 'advanced',
+ title: 'Advanced',
+ fields: ['providers'],
+ },
+ {
+ id: 'sources',
+ title: 'Sources',
+ fields: ['chartSources', 'download_button'],
+ },
+ ],
+ properties: {
+ block_title: {
+ title: 'Title',
+ widget: 'textarea',
+ },
+ chartSources: {
+ widget: 'object_list',
+ title: 'Sources',
+ schema: SourceSchema,
+ },
+ download_button: {
+ title: 'Download button',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ providers: {
+ title: 'Data providers',
+ widget: 'object_list',
+ schema: dataProviderSchema,
+ schemaExtender: (schema, child) =>
+ dataProviderSchemaExtender(schema, child, props),
+ },
+ },
+ required: [],
+});
diff --git a/src/components/manage/Blocks/NavigationBlock/Edit.jsx b/src/components/manage/Blocks/NavigationBlock/Edit.jsx
index c3c69c2..8409b01 100644
--- a/src/components/manage/Blocks/NavigationBlock/Edit.jsx
+++ b/src/components/manage/Blocks/NavigationBlock/Edit.jsx
@@ -1,92 +1,31 @@
-import React, { useState, useEffect } from 'react';
+import React from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
-import _uniqueId from 'lodash/uniqueId';
-import RenderFields from '@eeacms/volto-datablocks/Utils/RenderFields';
+import { SidebarPortal } from '@plone/volto/components';
+import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
+
import View from './View';
-import config from '@plone/volto/registry';
-const getSchema = (props) => {
- return {
- parent: {
- title: 'Parent page',
- widget: 'object_by_path',
- },
- className: {
- title: 'Classname',
- type: 'text',
- },
- fixedTabs: {
- title: 'Fixed navigation',
- type: 'boolean',
- },
- navFromParent: {
- title: 'Show navigation from parent',
- type: 'boolean',
- },
- pages: {
- title: 'Specific pages',
- type: 'schema',
- fieldSetTitle: 'specific pages',
- fieldSetId: 'specific-pages',
- fieldSetSchema: {
- fieldsets: [
- {
- id: 'default',
- title: 'Default',
- fields: ['title', 'url'],
- },
- ],
- properties: {
- title: {
- title: 'Title',
- type: 'text',
- },
- url: {
- title: 'Url',
- widget: 'text',
- },
- },
- required: ['title', 'url'],
- },
- editFieldset: false,
- deleteFieldset: false,
- },
- };
-};
+import schema from './schema';
const Edit = (props) => {
- const [state, setState] = useState({
- schema: getSchema({ ...props, providerUrl: config.settings.providerUrl }),
- id: _uniqueId('block_'),
- });
- useEffect(() => {
- setState({
- ...state,
- schema: getSchema({
- ...props,
- }),
- });
- /* eslint-disable-next-line */
- }, [state.item, props.data.components]);
return (
-
+ <>
+
+
+ {
+ props.onChangeBlock(props.block, {
+ ...props.data,
+ [id]: value,
+ });
+ }}
+ formData={props.data}
+ />
+
+ >
);
};
diff --git a/src/components/manage/Blocks/NavigationBlock/View.jsx b/src/components/manage/Blocks/NavigationBlock/View.jsx
index 511f994..c8f482a 100644
--- a/src/components/manage/Blocks/NavigationBlock/View.jsx
+++ b/src/components/manage/Blocks/NavigationBlock/View.jsx
@@ -28,14 +28,12 @@ const View = ({ content, ...props }) => {
const isLoggedIn = cookie.load('auth_token');
const parent =
- data?.navFromParent?.value && props.properties?.parent
+ data?.navFromParent && props.properties?.parent
? getBasePath(props.properties?.parent?.['@id'])
- : data.parent?.value;
+ : data.parent;
const history = useHistory();
useEffect(() => {
- const pagesProperties = data.pages?.value
- ? data.pages?.value?.properties || {}
- : {};
+ const pagesProperties = data.pages ? data.pages?.properties || {} : {};
const newPages =
Object.keys(pagesProperties).map((page) => pagesProperties[page]) || [];
setPages(newPages);
@@ -49,7 +47,7 @@ const View = ({ content, ...props }) => {
setIsMobile(false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [props.navigation, data.pages?.value]);
+ }, [props.navigation, data.pages]);
const isFixed = props.fixedTabs;
@@ -82,9 +80,7 @@ const View = ({ content, ...props }) => {
props.navigation?.items?.length ||
pages.length
}
- className={
- props.data.className?.value ? props.data.className.value : ''
- }
+ className={props.data.className || ''}
>
{isMobile ? (
@@ -235,13 +231,13 @@ export default compose(
discodata_resources: state.discodata_resources,
navItems: state.navigation?.items,
flags: state.flags,
- fixedTabs: props.data?.fixedTabs?.value,
+ fixedTabs: props.data?.fixedTabs,
navigation: props.properties?.parent
? getNavigationByParent(
state.navigation?.items,
- props.data?.navFromParent?.value
+ props.data?.navFromParent
? getBasePath(props.properties?.parent?.['@id'])
- : props.data?.parent?.value,
+ : props.data?.parent,
)
: {},
}),
diff --git a/src/components/manage/Blocks/NavigationBlock/schema.js b/src/components/manage/Blocks/NavigationBlock/schema.js
new file mode 100644
index 0000000..e15dd38
--- /dev/null
+++ b/src/components/manage/Blocks/NavigationBlock/schema.js
@@ -0,0 +1,56 @@
+const pagesSchema = {
+ title: 'Specific pages',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['title', 'url'],
+ },
+ ],
+ properties: {
+ title: {
+ title: 'Title',
+ type: 'text',
+ },
+ url: {
+ title: 'Url',
+ widget: 'text',
+ },
+ },
+ required: ['title', 'url'],
+};
+
+export default {
+ title: 'Navigation block',
+ fieldsets: [
+ {
+ id: 'default',
+ title: 'Default',
+ fields: ['navFromParent', 'className', 'fixedTabs', 'parent', 'pages'],
+ },
+ ],
+ properties: {
+ parent: {
+ title: 'Parent page',
+ widget: 'object_by_path',
+ },
+ className: {
+ title: 'Classname',
+ type: 'text',
+ },
+ fixedTabs: {
+ title: 'Fixed navigation',
+ type: 'boolean',
+ },
+ navFromParent: {
+ title: 'Show navigation from parent',
+ type: 'boolean',
+ },
+ pages: {
+ title: 'Pages',
+ schema: pagesSchema,
+ widget: 'object_list',
+ },
+ },
+ required: [],
+};
diff --git a/src/customizations/volto/components/manage/Widgets/ObjectListWidget.jsx b/src/customizations/volto/components/manage/Widgets/ObjectListWidget.jsx
deleted file mode 100644
index 1cc7db4..0000000
--- a/src/customizations/volto/components/manage/Widgets/ObjectListWidget.jsx
+++ /dev/null
@@ -1,200 +0,0 @@
-import React from 'react';
-import { defineMessages, useIntl } from 'react-intl';
-import { Accordion, Button, Segment } from 'semantic-ui-react';
-import { DragDropList, FormFieldWrapper, Icon } from '@plone/volto/components';
-import ObjectWidget from '@plone/volto/components/manage/Widgets/ObjectWidget';
-
-import upSVG from '@plone/volto/icons/up-key.svg';
-import downSVG from '@plone/volto/icons/down-key.svg';
-import deleteSVG from '@plone/volto/icons/delete.svg';
-import addSVG from '@plone/volto/icons/add.svg';
-import dragSVG from '@plone/volto/icons/drag.svg';
-import { v4 as uuid } from 'uuid';
-
-const messages = defineMessages({
- labelRemoveItem: {
- id: 'Remove item',
- defaultMessage: 'Remove item',
- },
- labelCollapseItem: {
- id: 'Collapse item',
- defaultMessage: 'Collapse item',
- },
- labelShowItem: {
- id: 'Show item',
- defaultMessage: 'Show item',
- },
- emptyObjectList: {
- id: 'Empty object list',
- defaultMessage: 'Empty object list',
- },
-});
-
-const ObjectListWidget = (props) => {
- const {
- block,
- fieldSet,
- id,
- schema,
- value = [],
- onChange,
- schemaExtender,
- } = props;
- const [activeColumn, setActiveColumn] = React.useState(value.length - 1);
- const intl = useIntl();
-
- function handleChangeColumn(e, blockProps) {
- const { index } = blockProps;
- const newIndex = activeColumn === index ? -1 : index;
-
- setActiveColumn(newIndex);
- }
- const objectSchema = typeof schema === 'function' ? schema(props) : schema;
-
- const topLayerShadow = '0 1px 1px rgba(0,0,0,0.15)';
- const secondLayer = ', 0 10px 0 -5px #eee, 0 10px 1px -4px rgba(0,0,0,0.15)';
- const thirdLayer = ', 0 20px 0 -10px #eee, 0 20px 1px -9px rgba(0,0,0,0.15)';
-
- return (
-
-
-
-
-
- {value.length === 0 && (
-
- )}
-
-
1 ? secondLayer : ''}${
- value.length > 2 ? thirdLayer : ''
- }`,
- }}
- forwardedAriaLabelledBy={`fieldset-${
- fieldSet || 'default'
- }-field-label-${id}`}
- childList={value.map((o, index) => [o['@id'] || index + 1, o])}
- onMoveItem={(result) => {
- const { source, destination } = result;
- if (!destination) {
- return;
- }
-
- const first = value[source.index];
- const second = value[destination.index];
- value[destination.index] = first;
- value[source.index] = second;
-
- onChange(id, value);
- return true;
- }}
- >
- {({ child, childId, index, draginfo }) => {
- return (
-
-
-
-
-
-
- {`${objectSchema.title} #${index + 1}`}
-
-
-
- {activeColumn === index ? (
-
- ) : (
-
- )}
-
-
-
-
- {
- const newvalue = value.map((v, i) =>
- i !== index ? v : fv,
- );
- onChange(id, newvalue);
- }}
- />
-
-
-
-
- );
- }}
-
-
- );
-};
-export default ObjectListWidget;
diff --git a/src/helpers/index.js b/src/helpers/index.js
index db2302d..2114dfd 100644
--- a/src/helpers/index.js
+++ b/src/helpers/index.js
@@ -1,41 +1,9 @@
import { getBaseUrl, flattenToAppURL } from '@plone/volto/helpers';
-import { setConnectedDataParameters } from '@eeacms/volto-datablocks/actions';
export function getBasePath(url) {
return flattenToAppURL(getBaseUrl(url));
}
-export const objectHasData = (obj) => {
- return typeof obj === 'object' && obj !== null && Object.keys(obj).length > 0;
-};
-
-export const getSchemaWithDataQuery = (props) => {
- if (!props.schema) return {};
- let schemaWithDataQuery = {};
- Object.keys(props.schema).forEach((element) => {
- if (props.schema[element].type === 'data-provider') {
- if (
- !objectHasData(
- props?.connected_data_parameters?.byProviderPath?.[props.path],
- ) &&
- !objectHasData(
- props?.connected_data_parameters?.byContextPath?.[props.path],
- )
- ) {
- const dataQuery = {};
- dataQuery[element + '_data_query'] = {
- defaultformat: 'compactnumber',
- type: 'data-query',
- };
- schemaWithDataQuery[element] = props.schema[element];
- schemaWithDataQuery = { ...schemaWithDataQuery, ...dataQuery };
- }
- }
- schemaWithDataQuery[element] = props.schema[element];
- });
- return schemaWithDataQuery;
-};
-
export function getLocation(href) {
var match = href.match(
/^(https?:)\/\/(([^:/?#]*)(?::([0-9]+))?)([/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/,
@@ -65,40 +33,3 @@ export function samePath(url, path) {
const cleanPath = path.replace(/\/$/, '');
return clean === cleanPath;
}
-
-export const updateConnectedDataParameters = (props) => {
- props.schema &&
- Object.keys(props.schema).forEach((element) => {
- if (props.schema[element].type === 'data-query') {
- if (
- props?.newData?.columns?.[element] &&
- (props?.newData?.columns?.[element]?.value?.i !==
- props?.data?.columns?.[element]?.value?.i ||
- props?.newData?.columns?.[element]?.value?.v !==
- props?.data?.columns?.[element]?.value?.v)
- ) {
- const path = getBasePath(props.pathname);
- const byPath = props?.connected_data_parameters?.byPath;
- const connected_data_parameters =
- (byPath?.[path]?.override?.length > 0 &&
- byPath?.[path]?.override?.[`${props.id}_${element}`]) ||
- null;
- if (
- connected_data_parameters === null ||
- connected_data_parameters?.i !==
- props?.newData?.columns?.[element]?.value?.i ||
- connected_data_parameters?.v?.join(',') !==
- props?.newData?.columns?.[element]?.value?.v
- ) {
- props.dispatch(
- setConnectedDataParameters(
- path.replace('/edit', ''),
- props?.newData?.columns?.[element]?.value,
- `${props.id}_${element}`,
- ),
- );
- }
- }
- }
- });
-};
diff --git a/src/index.js b/src/index.js
index 6121174..6100ebe 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,8 +2,9 @@ import Forbidden from '@plone/volto/components/theme/Forbidden/Forbidden';
import Unauthorized from '@plone/volto/components/theme/Unauthorized/Unauthorized';
import installAppExtras from '@eeacms/volto-forests-theme/components/theme/AppExtras';
-import { installBlocks } from '@eeacms/volto-plotlycharts';
+
import { applyConfig as installFiseFrontend } from './localconfig';
+import installDiscodataConnectorBlock from '@eeacms/volto-forests-theme/components/manage/Blocks/DiscodataConnectorBlock';
import ObjectListInlineWidget from './components/manage/Widgets/ObjectListInlineWidget';
import reducers from '@eeacms/volto-forests-theme/reducers';
@@ -12,10 +13,11 @@ import './slate-styles.css';
export default function applyConfig(config) {
// Add here your project's configuration here by modifying `config` accordingly
- config = [installBlocks, installAppExtras, installFiseFrontend].reduce(
- (acc, apply) => apply(acc),
- config,
- );
+ config = [
+ installAppExtras,
+ installFiseFrontend,
+ installDiscodataConnectorBlock,
+ ].reduce((acc, apply) => apply(acc), config);
config.settings = {
...config.settings,
diff --git a/theme/site/globals/site.overrides b/theme/site/globals/site.overrides
index 98c9089..e8b80e0 100644
--- a/theme/site/globals/site.overrides
+++ b/theme/site/globals/site.overrides
@@ -176,7 +176,7 @@ body.has-toolbar {
.sticky-header-nav {
-
+
position: absolute;
bottom: -5px;
z-index: 4;
@@ -190,7 +190,7 @@ body.has-toolbar {
.header-navigation-lead {
-
+
.navigation-prev {
position: absolute;
@@ -1607,6 +1607,14 @@ span.float-right {
padding: 1em;
margin-bottom: 1em;
border-radius: 5px;
+
+ .formatted-value {
+ span {
+ color: #000 !important;
+ font-size: 13px;
+ font-weight: normal;
+ }
+ }
}
.land-data,