From 81cfd76b23cbf2a78ab95c9e8147c626f7844d19 Mon Sep 17 00:00:00 2001 From: Miu Razvan Date: Thu, 10 Sep 2020 15:08:21 +0300 Subject: [PATCH] Updated blocks --- .../DiscodataComponents/Custom/Edit.jsx | 131 ++++++ .../DiscodataComponents/Custom/View.jsx | 222 ++++++++++ .../DiscodataComponents/Select/Edit.jsx | 12 +- .../DiscodataComponents/Select/View.jsx | 2 +- .../Blocks/DiscodataComponents/Text/Edit.jsx | 2 +- .../Blocks/DiscodataComponents/Text/View.jsx | 2 +- .../Blocks/DiscodataComponents/schema.jsx | 73 ++++ .../Blocks/DiscodataComponentsBlock/style.css | 69 ++- .../DiscodataOpenlayersMapBlock/View.jsx | 71 +++- .../DiscodataOpenlayersMapBlock/style.css | 7 +- .../manage/Blocks/DummyBlock/Edit.jsx | 46 ++ .../manage/Blocks/DummyBlock/View.jsx | 10 + .../manage/Blocks/DummyBlock/schema.jsx | 22 + .../manage/Blocks/FiltersBlock/View.jsx | 69 +-- .../manage/Blocks/FiltersBlock/style.css | 25 +- .../manage/Blocks/NavigationBlock/View.jsx | 7 + .../theme/Navigation/Navigation.jsx | 12 +- src/localconfig.js | 24 ++ theme/site/globals/site.overrides | 393 ++++++++++++------ 19 files changed, 990 insertions(+), 209 deletions(-) create mode 100644 src/components/manage/Blocks/DiscodataComponents/Custom/Edit.jsx create mode 100644 src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx create mode 100644 src/components/manage/Blocks/DummyBlock/Edit.jsx create mode 100644 src/components/manage/Blocks/DummyBlock/View.jsx create mode 100644 src/components/manage/Blocks/DummyBlock/schema.jsx diff --git a/src/components/manage/Blocks/DiscodataComponents/Custom/Edit.jsx b/src/components/manage/Blocks/DiscodataComponents/Custom/Edit.jsx new file mode 100644 index 00000000..6a090993 --- /dev/null +++ b/src/components/manage/Blocks/DiscodataComponents/Custom/Edit.jsx @@ -0,0 +1,131 @@ +import React, { useState, useEffect } from 'react'; +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import _uniqueId from 'lodash/uniqueId'; +import View from './View'; +import { settings } from '~/config'; +import { isArray, isObject } from 'lodash'; + +import InlineForm from '@plone/volto/components/manage/Form/InlineForm'; +import { SidebarPortal } from '@plone/volto/components'; + +import { makeCustomSchema } from '../schema'; + +const getSchema = (props) => { + return makeCustomSchema(props); +}; + +const Edit = (props) => { + const [discodataValues, setDiscodataValues] = useState([]); + const [mounted, setMounted] = useState(false); + const { data } = props; + const { resources = [], subResources = [] } = data; + const [state, setState] = useState({ + schema: getSchema({ ...props, discodataValues }), + id: _uniqueId('block_'), + }); + + const updateDiscodataValues = (mounted) => { + if ( + props.discodata_resources.data && + props.discodata_query.search && + mounted + ) { + let newDiscodataValues = []; + resources.forEach((resource) => { + if (isArray(props.discodata_resources.data[resource.package])) { + newDiscodataValues = [ + ...newDiscodataValues, + ...(props.discodata_resources.data[resource.package] || []), + ]; + } + }); + const selectedSubResources = subResources.map((subResource) => { + const keyValue = subResource.package?.split('@') || [null, null]; + return { + package: keyValue[0], + query: keyValue[1], + }; + }); + selectedSubResources.forEach((subResource) => { + const discodataPackage = resources.filter( + (resource) => resource.package === subResource.package, + )[0]; + if ( + props.discodata_query.search[discodataPackage.queryParameter] && + isArray( + props.discodata_resources.data[discodataPackage.package]?.[ + props.discodata_query.search[discodataPackage.queryParameter] + ]?.[subResource.query], + ) + ) { + newDiscodataValues = [ + ...newDiscodataValues, + ...(props.discodata_resources.data[discodataPackage.package]?.[ + props.discodata_query.search[discodataPackage.queryParameter] + ][subResource.query] || []), + ]; + } + }); + setDiscodataValues(newDiscodataValues); + return newDiscodataValues; + } + return []; + }; + + useEffect(() => { + setMounted(true); + updateDiscodataValues(true); + /* eslint-disable-next-line */ + }, []); + + useEffect(() => { + const schema = getSchema({ + ...props, + discodataValues: updateDiscodataValues(mounted), + }); + setState({ + ...state, + schema, + }); + /* eslint-disable-next-line */ + }, [ + JSON.stringify(props.discodata_query.search), + JSON.stringify(props.discodata_resources.data), + JSON.stringify(props.data), + ]); + + return ( +
+ + { + const { data } = props; + props.onChangeBlock(props.block, { + ...data, + [id]: value, + }); + }} + formData={props.data} + block={props.block} + /> + + +
+ ); +}; + +export default compose( + connect((state, props) => ({ + pathname: state.router.location.pathname, + discodata_resources: state.discodata_resources, + discodata_query: state.discodata_query, + })), +)(Edit); diff --git a/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx b/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx new file mode 100644 index 00000000..581f2f1f --- /dev/null +++ b/src/components/manage/Blocks/DiscodataComponents/Custom/View.jsx @@ -0,0 +1,222 @@ +/* REACT */ +import React, { useEffect, useState } from 'react'; +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { isArray, isDate } from 'lodash'; +import { Dropdown } from 'semantic-ui-react'; +import { setQueryParam } from 'volto-datablocks/actions'; +import ReactTooltip from 'react-tooltip'; +import Icon from '@plone/volto/components/theme/Icon/Icon'; +import moment from 'moment'; +import infoSVG from '@plone/volto/icons/info.svg'; +import cx from 'classnames'; + +const getDate = (field) => { + if (!field) return '-'; + if (Date.parse(field) > 0) { + return moment(field).format('DD MMM YYYY'); + } +}; + +const components = { + eprtrReportingYears: ( + options, + queryParameters, + packages, + search, + setQueryParam, + placeholder, + className, + mode, + ) => { + let activeValue = ''; + if (queryParameters[0]?.queryParameterToSet) { + activeValue = search[queryParameters[0].queryParameterToSet] || ''; + } + return ( +
+
+ + + +

Last report was submitted on:

+

{getDate(packages[0])}

+
+
+

Reporting year

+ { + const queryParametersToSet = {}; + queryParameters.forEach((queryParam) => { + queryParametersToSet[ + queryParam.queryParameterToSet + ] = data.options.filter((opt) => { + return opt.value === data.value; + })[0]?.[queryParam.selectorOptionKey]; + }); + setQueryParam({ + queryParam: { + ...(queryParametersToSet || {}), + }, + }); + }} + placeholder={placeholder} + options={options} + value={activeValue} + /> +
+
+

Publish date

+

{getDate(packages[1])}

+
+
+ ); + }, +}; + +const View = ({ content, ...props }) => { + const [packages, setPackages] = useState([]); + const [discodataValues, setDiscodataValues] = useState([]); + const [mounted, setMounted] = useState(false); + const { data } = props; + const { resources = [], subResources = [] } = data; + const { placeholder = 'Select', className = '' } = data; + const { key = '', value = '', text = '', queryParametersToSet = [] } = data; + + const options = discodataValues + .filter((discodata) => discodata[value]) + .map((discodata, index) => ({ + key: discodata[key] || index, + value: discodata[value] || index, + text: discodata[text] || index, + })); + + const updateDiscodataValues = (mounted) => { + if (props.discodata_resources && props.search && mounted) { + let newDiscodataValues = []; + resources.forEach((resource) => { + if (isArray(props.discodata_resources[resource.package])) { + newDiscodataValues = [ + ...newDiscodataValues, + ...(props.discodata_resources[resource.package] || []), + ]; + } + }); + const selectedSubResources = subResources.map((subResource) => { + const keyValue = subResource.package?.split('@') || [null, null]; + return { + package: keyValue[0], + query: keyValue[1], + }; + }); + selectedSubResources.forEach((subResource) => { + const discodataPackage = resources.filter( + (resource) => resource.package === subResource.package, + )[0]; + if ( + props.search[discodataPackage.queryParameter] && + isArray( + props.discodata_resources[discodataPackage.package]?.[ + props.search[discodataPackage.queryParameter] + ]?.[subResource.query], + ) + ) { + newDiscodataValues = [ + ...newDiscodataValues, + ...(props.discodata_resources[discodataPackage.package]?.[ + props.search[discodataPackage.queryParameter] + ][subResource.query] || []), + ]; + } + }); + setDiscodataValues(newDiscodataValues); + } + }; + + const updatePackages = (mounted) => { + if (props.discodata_resources && props.search && mounted) { + let newDiscodataValues = []; + const selectedSubResources = subResources.map((subResource) => { + const keyValue = subResource.package?.split('@') || [null, null]; + return { + package: keyValue[0], + query: keyValue[1], + }; + }); + selectedSubResources.forEach((subResource) => { + const discodataPackage = resources.filter( + (resource) => resource.package === subResource.package, + )[0]; + if (props.search[discodataPackage.queryParameter]) { + newDiscodataValues.push( + props.discodata_resources[discodataPackage.package]?.[ + props.search[discodataPackage.queryParameter] + ]?.[subResource.query], + ); + } + }); + setPackages(newDiscodataValues); + } + }; + + useEffect(() => { + setMounted(true); + updatePackages(true); + if (props.mode !== 'edit') { + updateDiscodataValues(true); + } else { + setDiscodataValues(props.discodataValues); + } + /* eslint-disable-next-line */ + }, []); + + useEffect(() => { + updatePackages(mounted); + if (props.mode !== 'edit') { + updateDiscodataValues(mounted); + } else { + setDiscodataValues(props.discodataValues); + } + /* eslint-disable-next-line */ + }, [props.search, props.discodata_resources, props.discodataValues]) + + + return ( + <> + {components[props.data.component] ? ( + components[props.data.component]( + options, + queryParametersToSet, + packages, + props.search, + props.setQueryParam, + placeholder, + className, + props.mode, + ) + ) : props.mode === 'edit' ? ( +

Component not selected

+ ) : ( + '' + )} + + + ); +}; + +export default compose( + connect( + (state, props) => ({ + query: state.router.location.search, + search: state.discodata_query.search, + discodata_resources: state.discodata_resources.data, + }), + { setQueryParam }, + ), +)(View); diff --git a/src/components/manage/Blocks/DiscodataComponents/Select/Edit.jsx b/src/components/manage/Blocks/DiscodataComponents/Select/Edit.jsx index 013428ba..8b92133f 100644 --- a/src/components/manage/Blocks/DiscodataComponents/Select/Edit.jsx +++ b/src/components/manage/Blocks/DiscodataComponents/Select/Edit.jsx @@ -82,7 +82,11 @@ const Edit = (props) => { useEffect(() => { updateDiscodataValues(mounted); /* eslint-disable-next-line */ - }, [props.discodata_query.search, props.discodata_resources.data]); + }, [ + JSON.stringify(props.discodata_query.search), + JSON.stringify(props.discodata_resources.data), + JSON.stringify(props.data), + ]); useEffect(() => { const schema = getSchema({ ...props, discodataValues }); @@ -92,11 +96,7 @@ const Edit = (props) => { }); /* eslint-disable-next-line */ }, [ - discodataValues, - JSON.stringify(props.data.resources), - JSON.stringify(props.data.subResource), - JSON.stringify(props.discodata_resources.data), - JSON.stringify(props.discodata_query.search), + JSON.stringify(discodataValues) ]); return ( diff --git a/src/components/manage/Blocks/DiscodataComponents/Select/View.jsx b/src/components/manage/Blocks/DiscodataComponents/Select/View.jsx index 0d67e4c3..68a7e101 100644 --- a/src/components/manage/Blocks/DiscodataComponents/Select/View.jsx +++ b/src/components/manage/Blocks/DiscodataComponents/Select/View.jsx @@ -20,7 +20,7 @@ const components = { ) => { let activeValue = ''; if (queryParameters[0]?.queryParameterToSet) { - activeValue = search[queryParameters[0].queryParameterToSet]; + activeValue = search[queryParameters[0].queryParameterToSet] || ''; } return (
diff --git a/src/components/manage/Blocks/DiscodataComponents/Text/Edit.jsx b/src/components/manage/Blocks/DiscodataComponents/Text/Edit.jsx index 0133dcf4..58a4b2c3 100644 --- a/src/components/manage/Blocks/DiscodataComponents/Text/Edit.jsx +++ b/src/components/manage/Blocks/DiscodataComponents/Text/Edit.jsx @@ -28,7 +28,7 @@ const Edit = (props) => { schema, }); /* eslint-disable-next-line */ - }, [props.discodata_query.search, props.discodata_resources.data, props.data.isLink, props.data.internalLink, props.data.tooltip]); + }, [props.discodata_query.search, props.discodata_resources.data, JSON.stringify(props.data)]); return (
diff --git a/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx b/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx index ff65d531..dce283fc 100644 --- a/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx +++ b/src/components/manage/Blocks/DiscodataComponents/Text/View.jsx @@ -116,7 +116,7 @@ const View = ({ content, ...props }) => { useEffect(() => { updateDiscodataValues(mounted); /* eslint-disable-next-line */ - }, [props.search, props.discodata_resources]) + }, [props.search, props.discodata_resources, JSON.stringify(props.data)]) const queryParametersText = queryParameters ? queryParameters diff --git a/src/components/manage/Blocks/DiscodataComponents/schema.jsx b/src/components/manage/Blocks/DiscodataComponents/schema.jsx index 89e02f14..ebe52b4d 100644 --- a/src/components/manage/Blocks/DiscodataComponents/schema.jsx +++ b/src/components/manage/Blocks/DiscodataComponents/schema.jsx @@ -337,6 +337,79 @@ export const makeSelectSchema = (props) => { }); }; +export const makeCustomSchema = (props) => { + const discodataValues = props.discodataValues; + const discodataKeys = + discodataValues && + discodataValues[0] && + !isArray(discodataValues[0]) && + isObject(discodataValues[0]) + ? makeChoices(Object.keys(discodataValues[0])) + : []; + const schemaTitle = 'Text'; + const schemaFieldsets = [ + { + id: 'settings', + title: 'Settings', + fields: [ + 'key', + 'value', + 'text', + 'queryParametersToSet', + 'placeholder', + 'className', + 'component', + ], + }, + ]; + const schemaProperties = { + key: { + title: 'Selector key', + type: 'array', + choices: discodataKeys || [], + }, + value: { + title: 'Selector value', + type: 'array', + choices: discodataKeys || [], + }, + text: { + title: 'Selector text', + type: 'array', + choices: discodataKeys || [], + }, + queryParametersToSet: { + title: 'Query parameters', + widget: 'object_list', + schema: getQueryParametersToSetSchema(props), + }, + placeholder: { + title: 'Placeholder', + widget: 'text', + }, + className: { + title: 'Class name', + widget: 'text', + }, + component: { + title: 'Component', + type: 'array', + choices: [ + ['eprtrReportingYears', 'EPRTR reporting years'], + ['eprtrBatConclusions', 'EPRTR bat conclusions'], + ], + }, + }; + const schemaRequired = []; + return makeSchema({ + ...props, + schemaTitle, + schemaFieldsets, + schemaProperties, + schemaRequired, + }); +}; + export const makeListSchema = (props) => { const discodataValues = props.discodataValues; const discodataKeys = diff --git a/src/components/manage/Blocks/DiscodataComponentsBlock/style.css b/src/components/manage/Blocks/DiscodataComponentsBlock/style.css index e17e2ea7..ab149755 100644 --- a/src/components/manage/Blocks/DiscodataComponentsBlock/style.css +++ b/src/components/manage/Blocks/DiscodataComponentsBlock/style.css @@ -431,44 +431,73 @@ a.small h1 { outline: none; } -.eprtrSelection h1.ui.header { - font-weight: bold; - font-size: 36px; - line-height: 45px; - color: #EC776A; +.custom-selector h1.ui.header { margin-bottom: 0; } -.eprtrSelection .ui.selection.dropdown { +.custom-selector .ui.selection.dropdown { width: fit-content; - color: #EC776A; padding: 0; border-bottom: none; min-width: unset; - margin-right: 40px; + min-height: unset; + line-height: 1em; } -.eprtrSelection .ui.selection.dropdown > .default.text, -.eprtrSelection .ui.selection.dropdown > .text, -.eprtrSelection .ui.selection.visible.dropdown > .text:not(.default) { - color: #EC776A; - font-weight: bold; - font-size: 30px; - line-height: 39px; - padding: 10px; +.custom-selector .ui.selection.dropdown > .default.text, +.custom-selector .ui.selection.dropdown > .text, +.custom-selector .ui.selection.visible.dropdown > .text:not(.default) { padding-left: 0; } -.eprtrSelection .ui.selection.dropdown > .dropdown.icon { - font-size: 30px !important; - line-height: 39px; +.custom-selector .ui.selection.dropdown > .dropdown.icon { position: relative; - padding: 10px 0; margin: 0; margin-left: 0 !important; top: unset; left: unset; right: unset; bottom: unset; + line-height: 1em; + font-size: 1.7em!important; +} + +.custom-selector.big h1.ui.header { + font-weight: bold; + font-size: 36px; + line-height: 45px; +} + +.custom-selector.big .ui.selection.dropdown > .dropdown.icon { + font-size: 30px !important; + line-height: 39px; + padding: 10px 0; +} + +.custom-selector.big .ui.selection.dropdown > .default.text, +.custom-selector.big .ui.selection.dropdown > .text, +.custom-selector.big .ui.selection.visible.dropdown > .text:not(.default) { + font-weight: bold; + font-size: 30px; + line-height: 39px; + padding: 10px; +} + +.custom-selector.red h1.ui.header, +.custom-selector.red .ui.selection.dropdown, +.custom-selector.red .ui.selection.dropdown > .default.text, +.custom-selector.red .ui.selection.dropdown > .text, +.custom-selector.red .ui.selection.visible.dropdown > .text:not(.default) { + color: #EC776A; + background-color: transparent; +} + +.custom-selector.white h1.ui.header, +.custom-selector.white .ui.selection.dropdown, +.custom-selector.white .ui.selection.dropdown > .default.text, +.custom-selector.white .ui.selection.dropdown > .text, +.custom-selector.white .ui.selection.visible.dropdown > .text:not(.default) { + color: #fff; + background-color: transparent; } diff --git a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx index a880c444..636c2472 100644 --- a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx +++ b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx @@ -4,6 +4,7 @@ import { useHistory } from 'react-router-dom'; import { compose } from 'redux'; import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; +import { Portal } from 'react-portal'; // HELPERS import qs from 'query-string'; import axios from 'axios'; @@ -18,6 +19,7 @@ import { setQueryParam } from 'volto-datablocks/actions'; import { Grid, Header, Loader, Dimmer } from 'semantic-ui-react'; // SVGs import clearSVG from '@plone/volto/icons/clear.svg'; +import navigationSVG from '@plone/volto/icons/navigation.svg'; // STYLES import 'ol/ol.css'; import './style.css'; @@ -55,7 +57,8 @@ let Map, tile, Control, defaultsControls, - defaultsInteractions; + defaultsInteractions, + DragRotateAndZoom; let OL_LOADED = false; const initialExtent = [ -10686671.0000035, @@ -93,6 +96,7 @@ const OpenlayersMapView = (props) => { const [mapRendered, setMapRendered] = useState(false); const [firstFilteringUpdate, setFirstFilteringUpdate] = useState(false); const ToggleSidebarControl = useRef(null); + const ViewYourAreaControl = useRef(null); const history = useHistory(); const draggable = !!props.data?.draggable?.value; const hasPopups = !!props.data?.hasPopups?.value; @@ -153,6 +157,7 @@ const OpenlayersMapView = (props) => { Control = require('ol/control/Control.js').default; defaultsControls = require('ol/control.js').defaults; defaultsInteractions = require('ol/interaction.js').defaults; + DragRotateAndZoom = require('ol/interaction.js').DragRotateAndZoom; OL_LOADED = true; } if (OL_LOADED && !ToggleSidebarControl.current && hasSidebar) { @@ -175,6 +180,27 @@ const OpenlayersMapView = (props) => { return ToggleSidebarControl; })(Control); } + + if (OL_LOADED && !ViewYourAreaControl.current) { + ViewYourAreaControl.current = /*@__PURE__*/ (function (Control) { + function ViewYourAreaControl(opt_options) { + const options = opt_options || {}; + const buttonContainer = document.createElement('div'); + buttonContainer.setAttribute('id', 'map-view-your-area-button'); + Control.call(this, { + element: buttonContainer, + target: options.target, + }); + } + if (Control) ViewYourAreaControl.__proto__ = Control; + ViewYourAreaControl.prototype = Object.create( + Control && Control.prototype, + ); + ViewYourAreaControl.prototype.constructor = ViewYourAreaControl; + + return ViewYourAreaControl; + })(Control); + } renderMap(); setMapRendered(true); } @@ -376,10 +402,15 @@ const OpenlayersMapView = (props) => { const map = new Map({ controls: draggable ? hasSidebar - ? defaultsControls().extend([new ToggleSidebarControl.current()]) - : defaultsControls() + ? defaultsControls().extend([ + new ToggleSidebarControl.current(), + new ViewYourAreaControl.current(), + ]) + : defaultsControls().extend([new ViewYourAreaControl.current()]) + : [], + interactions: draggable + ? defaultsInteractions().extend([new DragRotateAndZoom()]) : [], - interactions: draggable ? defaultsInteractions() : [], target: document.getElementById('map'), view: new View({ center: fromLonLat([20, 50]), @@ -488,7 +519,6 @@ const OpenlayersMapView = (props) => { stateRef.current.map.oldSitesSourceQuery.where || stateRef.current.updateMapPosition !== null ) { - console.log('ON SOURCE CHANGE'); setState({ ...stateRef.current, map: { @@ -503,12 +533,11 @@ const OpenlayersMapView = (props) => { } function centerPosition(map, position, zoom) { - map - .getView() - .setCenter( - fromLonLat([position.coords.longitude, position.coords.latitude]), - ); - map.getView().setZoom(zoom); + map.getView().animate({ + center: fromLonLat([position.coords.longitude, position.coords.latitude]), + duration: 1000, + zoom, + }); } function setFeatureInfo(map, pixel, coordinate, detailed) { @@ -1015,7 +1044,9 @@ const OpenlayersMapView = (props) => { +
+
); }; diff --git a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/style.css b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/style.css index cdb4659f..2ce4d3be 100644 --- a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/style.css +++ b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/style.css @@ -208,7 +208,12 @@ .ol-overlaycontainer-stopevent #dynamic-filter-toggle { display: none; - top: 65px; + top: 80px; + left: .5em; +} + +.ol-overlaycontainer-stopevent #view-your-area { + top: 55px; left: .5em; } diff --git a/src/components/manage/Blocks/DummyBlock/Edit.jsx b/src/components/manage/Blocks/DummyBlock/Edit.jsx new file mode 100644 index 00000000..9a2469d2 --- /dev/null +++ b/src/components/manage/Blocks/DummyBlock/Edit.jsx @@ -0,0 +1,46 @@ +import React, { useState } from 'react'; +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import _uniqueId from 'lodash/uniqueId'; +import View from './View'; + +import InlineForm from '@plone/volto/components/manage/Form/InlineForm'; +import { SidebarPortal } from '@plone/volto/components'; + +import { makeSchema } from './schema'; + +const Edit = (props) => { + const [state, setState] = useState({ + schema: makeSchema({ ...props }), + id: _uniqueId('block_'), + }); + + return ( +
+ + { + const { data } = props; + props.onChangeBlock(props.block, { + ...data, + [id]: value, + }); + }} + formData={props.data} + block={props.block} + /> + + +
+ ); +}; + +export default compose( + connect((state, props) => ({ + pathname: state.router.location.pathname, + discodata_resources: state.discodata_resources, + discodata_query: state.discodata_query, + })), +)(Edit); diff --git a/src/components/manage/Blocks/DummyBlock/View.jsx b/src/components/manage/Blocks/DummyBlock/View.jsx new file mode 100644 index 00000000..2430e4d5 --- /dev/null +++ b/src/components/manage/Blocks/DummyBlock/View.jsx @@ -0,0 +1,10 @@ +/* REACT */ +import React from 'react'; + +const View = ({ content, ...props }) => { + if (props.mode === 'edit') + return

Dummy block with {props.data.portalId} id

; + return
; +}; + +export default View; diff --git a/src/components/manage/Blocks/DummyBlock/schema.jsx b/src/components/manage/Blocks/DummyBlock/schema.jsx new file mode 100644 index 00000000..cd80b6b8 --- /dev/null +++ b/src/components/manage/Blocks/DummyBlock/schema.jsx @@ -0,0 +1,22 @@ +import { isArray, isObject } from 'lodash'; + +export const makeSchema = (props) => { + return { + title: props.schemaTitle || 'Title', + fieldsets: [ + { + id: 'default', + title: 'Resources', + fields: ['portalId'], + }, + ...(props.schemaFieldsets || []), + ], + properties: { + portalId: { + title: 'Portal id', + widget: 'text', + }, + }, + required: [...(props.schemaRequired || [])], + }; +}; diff --git a/src/components/manage/Blocks/FiltersBlock/View.jsx b/src/components/manage/Blocks/FiltersBlock/View.jsx index f4dfbf26..d6af53aa 100644 --- a/src/components/manage/Blocks/FiltersBlock/View.jsx +++ b/src/components/manage/Blocks/FiltersBlock/View.jsx @@ -56,14 +56,15 @@ const View = ({ content, ...props }) => { factsDataOrder: ['Country_quick_facts', 'EU_quick_facts'], mounted: false, firstLoad: false, - searchResultsActive: false, }); const [loadingData, setLoadingData] = useState(false); const [factsData, setFactsData] = useState({}); const [alphaFeature, setAlphaFeature] = useState({}); const [sitesResults, setSitesResults] = useState([]); + const [searchResultsActive, setSearchResultsActive] = useState(false); const [locationResults, setLocationResults] = useState([]); const [searchTerm, setSearchTerm] = useState(''); + const [triggerSearch, setTriggerSearch] = useState(false); const [sidebar, setSidebar] = useState(false); const searchContainerModal = useRef(null); const searchContainer = useRef(null); @@ -72,9 +73,6 @@ const View = ({ content, ...props }) => { const locationResultsTexts = locationResults.map((result) => result.text); const mapSidebarExists = document?.getElementById('map-sidebar'); - useEffect(() => { - /* eslint-disable-next-line */ - }, [mapSidebarExists]) const searchResults = [ ...sitesResults.slice( 0, @@ -92,7 +90,8 @@ const View = ({ content, ...props }) => { reqs = [ { factId: 'EU_quick_facts', - sql: 'SELECT AllSites FROM [IED].[latest].[vw_BrowseMainMap_EUFacts]', + sql: `SELECT count(id) AS AllSites + FROM [IED].[latest].[ProductionSite_NoGeo]`, descriptionDiscodataKey: ['AllSites'], title: 'EU Quick facts', description: [':descriptionDiscodataKey reporting sites'], @@ -159,7 +158,7 @@ const View = ({ content, ...props }) => { useEffect(function () { setState({ ...state, mounted: true }); - updateFactsData(true); + // updateFactsData(true); // document // .getElementById(`dynamic-filter`) // .addEventListener('featurechange', (e) => { @@ -182,8 +181,17 @@ const View = ({ content, ...props }) => { }, [alphaFeature]) useEffect(() => { - if (state.open && state.searchResultsActive) { - setState({ ...state, searchResultsActive: false }); + updateFactsData(false); + if (triggerSearch) { + submit(); + setTriggerSearch(false); + } + /* eslint-disable-next-line */ + }, [searchTerm, triggerSearch]) + + useEffect(() => { + if (state.open && searchResultsActive) { + setSearchResultsActive(false); } /* eslint-disable-next-line */ }, [state.open]); @@ -521,11 +529,13 @@ const View = ({ content, ...props }) => { if (metadata[index]?.key === 'permit_years') { // YEAH...FU*K TRACASA filtersMeta['permit_types'] = { - filteringInputs: [{ - id: _uniqueId('select_'), - type: 'select', - position: 0, - }], + filteringInputs: [ + { + id: _uniqueId('select_'), + type: 'select', + position: 0, + }, + ], placeholder: 'Select permit type', queryToSet: 'permitType', title: 'Permit', @@ -737,7 +747,7 @@ const View = ({ content, ...props }) => { if (searchContainerModalActive || searchContainerActive) { searchResultsActive = true; } - return setState({ ...state, searchResultsActive }); + return setSearchResultsActive(searchResultsActive); } const autoComplete = (data) => { @@ -864,20 +874,20 @@ const View = ({ content, ...props }) => { setState({ ...state, open: false }); }; - const searchView = (ref) => ( + const searchView = (ref, modal = true) => (
{ autoComplete(data); }} /> - {state.searchResultsActive && searchResults.length ? ( + {searchResultsActive && searchResults.length ? (
{searchResults.map((result, index) => { @@ -885,11 +895,9 @@ const View = ({ content, ...props }) => { { - setState({ - ...state, - searchResultsActive: false, - }); + setSearchResultsActive(false); setSearchTerm(result); + setTriggerSearch(!modal); }} > { return (
- {searchView(searchContainer)} + {searchView(searchContainer, false)}
{ onOpen={() => setState({ ...state, open: true })} open={state.open} trigger={ - } @@ -1072,17 +1080,14 @@ const View = ({ content, ...props }) => { })} - - -
@@ -1145,11 +1150,11 @@ const View = ({ content, ...props }) => {
Quick facts
{state.factsDataOrder && diff --git a/src/components/manage/Blocks/FiltersBlock/style.css b/src/components/manage/Blocks/FiltersBlock/style.css index 5e665329..481758e4 100644 --- a/src/components/manage/Blocks/FiltersBlock/style.css +++ b/src/components/manage/Blocks/FiltersBlock/style.css @@ -1,18 +1,37 @@ .filters-container { width: 100%; margin: 0 auto; + display: flex; + flex-flow: row; } .filters-container > .search-input-container { - padding: 0.5em 1em; + padding: 0.5em 0; + margin-right: 1em; + flex: 1 0 0; } .filters-container .search-input-container .ref { position: relative; } +.search-input-container .ui.input.search input { + border-radius: 22px; + padding-left: 1em !important; + padding-right: 3em !important; +} + +.search-input-container .ui.input.search .icon { + opacity: 1; +} + +.search-input-container .ui.input.search .icon::before { + color: #d63d27; + font-size: 1.3em; +} + .filters-container > .buttons-container { - padding: 0.5em; + padding: 0.5em 0; } .filters-block.ui.modal>.header:not(.ui) { @@ -194,4 +213,4 @@ #dynamic-filter { display: none; -} \ No newline at end of file +} diff --git a/src/components/manage/Blocks/NavigationBlock/View.jsx b/src/components/manage/Blocks/NavigationBlock/View.jsx index 0ce74a6f..889b6100 100644 --- a/src/components/manage/Blocks/NavigationBlock/View.jsx +++ b/src/components/manage/Blocks/NavigationBlock/View.jsx @@ -6,6 +6,7 @@ import { connect } from 'react-redux'; /* SEMANTIC UI */ import { Menu } from 'semantic-ui-react'; /* HELPERS */ +import cx from 'classnames'; import { isActive, getNavigationByParent, @@ -46,6 +47,12 @@ const View = ({ content, ...props }) => { } return ( 0 ? 'sibling-on-left' : '', + index < props.navigation.items.length - 1 + ? 'sibling-on-right' + : '', + )} name={name} key={url} active={state.activeItem === url} diff --git a/src/customizations/volto/components/theme/Navigation/Navigation.jsx b/src/customizations/volto/components/theme/Navigation/Navigation.jsx index 5e5833e6..61b79920 100644 --- a/src/customizations/volto/components/theme/Navigation/Navigation.jsx +++ b/src/customizations/volto/components/theme/Navigation/Navigation.jsx @@ -173,12 +173,12 @@ class Navigation extends Component { className="item" activeClassName="active" onClick={() => { - // if ( - // !item.url.includes('/industrial-site') && - // !item.url.includes('/analysis') - // ) { - // this.props.resetQueryParam(); - // } + if ( + !item.url.includes('/industrial-site') && + !item.url.includes('/analysis') + ) { + this.props.resetQueryParam(); + } }} exact={ settings.isMultilingual diff --git a/src/localconfig.js b/src/localconfig.js index c8dbb5de..b88fe29f 100644 --- a/src/localconfig.js +++ b/src/localconfig.js @@ -37,6 +37,9 @@ import QueryParamButtonView from '~/components/manage/Blocks/QueryParamButton/Vi import IframeEdit from '~/components/manage/Blocks/Iframe/Edit'; import IframeView from '~/components/manage/Blocks/Iframe/View'; +import DummyBlockEdit from '~/components/manage/Blocks/DummyBlock/Edit'; +import DummyBlockView from '~/components/manage/Blocks/DummyBlock/View'; + // Discodata components import DiscodataComponentsBlockEdit from '~/components/manage/Blocks/DiscodataComponentsBlock/Edit'; import DiscodataComponentsBlockView from '~/components/manage/Blocks/DiscodataComponentsBlock/View'; @@ -47,6 +50,9 @@ import TextView from '~/components/manage/Blocks/DiscodataComponents/Text/View'; import SelectEdit from '~/components/manage/Blocks/DiscodataComponents/Select/Edit'; import SelectView from '~/components/manage/Blocks/DiscodataComponents/Select/View'; +import CustomEdit from '~/components/manage/Blocks/DiscodataComponents/Custom/Edit'; +import CustomView from '~/components/manage/Blocks/DiscodataComponents/Custom/View'; + // import QueryParamButtonEdit from '~/components/manage/Blocks/LinkButton/Edit'; // import QueryParamButtonView from '~/components/manage/Blocks/QueryParamButton/View'; @@ -183,6 +189,15 @@ export function applyConfig(voltoConfig) { icon: packSVG, }; + config.blocks.blocksConfig.eprtr_dummy_block = { + id: 'eprtr_dummy_block', + title: 'Eprtr dummy block', + group: 'eprtr_blocks', + view: DummyBlockView, + edit: DummyBlockEdit, + icon: packSVG, + }; + config.blocks.blocksConfig.eprtr_openlayers_map_block = { id: 'eprtr_openlayers_map_block', title: 'Eprtr openlayers map block', @@ -212,6 +227,15 @@ export function applyConfig(voltoConfig) { icon: packSVG, }; + config.blocks.blocksConfig.discodata_components_custom = { + id: 'discodata_components_custom', + title: 'Custom', + group: 'discodata_components', + view: CustomView, + edit: CustomEdit, + icon: packSVG, + }; + config.blocks.blocksConfig.discodata_components_block = { id: 'discodata_components_block', title: 'Discodata components block', diff --git a/theme/site/globals/site.overrides b/theme/site/globals/site.overrides index bb84d14b..2f00f4b2 100644 --- a/theme/site/globals/site.overrides +++ b/theme/site/globals/site.overrides @@ -950,95 +950,195 @@ space-around { } } -a.solid, -button.solid, -.ui.form .searchbox.field button.solid { - border-color: #000; - background-color: #000; - color: #fff; - padding: 0.6rem 2rem; - border-radius: 2rem; - cursor: pointer; - margin: 0 0.5em; - max-width: 240px; - &:focus { - outline: none; - } - &:hover { - opacity: 0.9; - } - &.dark-blue { - border: none; - background-color: #32536B; - color: #fff; - font-weight: bold; - } +// a.solid, +// button.solid, +// .ui.form .searchbox.field button.solid { +// border-color: #000; +// background-color: #000; +// color: #fff; +// padding: 0.6rem 2rem; +// border-radius: 2rem; +// cursor: pointer; +// margin: 0 0.5em; +// max-width: 240px; +// &:focus { +// outline: none; +// } +// &:hover { +// opacity: 0.9; +// } +// &.dark-blue { +// border: none; +// background-color: #32536B; +// color: #fff; +// font-weight: bold; +// } - &.orange { - border: none; - background-color: #E16D5D; - color: #fff; - font-weight: bold; - } +// &.orange { +// border: none; +// background-color: #E16D5D; +// color: #fff; +// font-weight: bold; +// } - &.red { - border: none; - background-color: #d63d27; - color: #fff; - font-weight: bold; - } -} +// &.red { +// border: none; +// background-color: #d63d27; +// color: #fff; +// font-weight: bold; +// } +// } -a.solid { - margin: 0; - max-width: unset; - width: fit-content; -} +// a.solid { +// margin: 0; +// max-width: unset; +// width: fit-content; +// } -button.outline, -.ui.form .searchbox.field button.outline { - background-color: transparent; - color: #000; - border-color: #000; - padding: 0.6rem 2rem; - border-radius: 2rem; - cursor: pointer; - &:focus { - outline: none; - } - &.dark-blue { - border-color: #32536B; - color: #32536B; - font-weight: bold; +// button.outline, +// .ui.form .searchbox.field button.outline { +// background-color: transparent; +// color: #000; +// border-color: #000; +// padding: 0.6rem 2rem; +// border-radius: 2rem; +// cursor: pointer; +// &:focus { +// outline: none; +// } +// &.dark-blue { +// border-color: #32536B; +// color: #32536B; +// font-weight: bold; + +// &:hover { +// background-color: #32536B; +// border-color: #32536B; +// color: #fff; +// } +// } +// } +// a.back, +// button.back { +// font-weight: bold; +// display: inline-flex; +// align-items: center; +// border: none !important; +// &.red { +// color: #EC776A !important; +// } +// &.dark-blue { +// color: #32536B !important; +// } +// padding: 0 !important; +// &:before { +// content: '\21E6'; +// font-size: 2em; +// font-weight: bold; +// } +// span { +// margin-left: 4px; +// } +// } + +button { + cursor: pointer; + outline: none; + &.outline { + position: relative; + z-index: 3; + background: transparent; + color: #1172c4; + font-size: 14px; + border-color: #1172c4; + border-style: solid; + border-width: 1px; + border-radius: 22px; + padding: 10px 40px; + transition: all 0.2s linear; + a { + text-decoration: none; + } &:hover { - background-color: #32536B; + color: white; + background: #1172c4; + border-color: white; + transition: all 0.2s linear; + } + &:active { + border-radius: 22px; + } + &.red { + font-weight: 700; + color: #d63d27; + border-color: #d63d27; + background: transparent; + } + &.red:hover { + color: white; + background: #c73721; + border-color: #c73721; + } + &.dark-blue { + font-weight: 700; + color: #32536B; border-color: #32536B; - color: #fff; + background: transparent; + } + &.dark-blue:hover { + color: white; + background: #2d4b61; + border-color: #2d4b61; } } -} - -a.back, -button.back { - font-weight: bold; - display: inline-flex; - align-items: center; - border: none !important; - &.red { - color: #EC776A !important; - } - &.dark-blue { - color: #32536B !important; - } - padding: 0 !important; - &:before { - content: '\21E6'; - font-size: 2em; - font-weight: bold; - } - span { - margin-left: 4px; + &.solid { + position: relative; + z-index: 3; + color: white; + font-size: 14px; + background: #1172c4; + border-color: #1172c4; + border-style: solid; + border-width: 2px; + border-radius: 22px; + padding: 10px 40px; + transition: all 0.2s linear; + a { + text-decoration: none; + } + &:hover { + color: white; + opacity: 0.9; + background: #1172c4; + border-color: white; + transition: all 0.2s linear; + } + &:active { + border-radius: 22px; + } + &.red { + font-weight: 700; + color: white; + border-color: #d63d27; + background: #d63d27; + } + &.red:hover { + color: white; + background: #d63d27; + border-color: #d63d27; + } + &.dark-blue { + font-weight: 700; + color: white; + border-color: #32536B; + background: #32536B; + } + &.dark-blue:hover { + color: white; + border-color: #32536B; + background: #32536B; + } } } @@ -1064,6 +1164,13 @@ body.has-sidebar { top: auto; } + + +// background-color: transparent !important; +// color: #D63D27 !important; +// border: 1px solid #D63D27; + + /* Tabs view nav */ .content-area { .tabs-view-menu { @@ -1081,32 +1188,65 @@ body.has-sidebar { background-color: transparent; border-bottom: none !important; &.red-menu { - .item { - color: #D63D27; - background-color: transparent !important; - padding: 0 2em !important; - border-radius: 2em; - border-bottom: none !important; - &:before { - width: 0; + min-height: unset !important; + &.item { + flex-wrap: nowrap !important; + .item { + font-size: 14px !important; + font-weight: bold !important; + color: #D63D27 !important; background-color: transparent !important; + padding: 10px 40px !important; + border-radius: 22px; + border: 1px solid #D63D27; + margin-right: 0 !important; + margin-left: 0 !important; + &:before { + width: 0; + background-color: transparent !important; + } + &.sibling-on-left { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px !important; + } + &.sibling-on-right { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } } - } - .active.item { - color: #fff !important; - border-bottom: none; - padding: 0 2em !important; - border-radius: 2em; - background-color: #D63D27 !important; - border-bottom: none !important; - &:hover { - background: #D63D27 !important; + .active.item { color: #fff !important; + padding: 10px 40px !important; + border-radius: 22px; + background-color: #D63D27 !important; + border: 1px solid #D63D27 !important; + &:hover { + background-color: #D63D27 !important; + color: #fff !important; + } + &:before { + width: 0; + background: transparent !important; + background-color: transparent !important; + } + &.sibling-on-left { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px !important; + } + &.sibling-on-right { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } } - &:before { - width: 0; - background: transparent !important; - background-color: transparent !important; + } + font-weight: bold; + @media (max-width: 768px) { + &.item { + .item { + flex: 1 0 0; + } } } } @@ -1137,6 +1277,10 @@ body.has-sidebar { justify-content: start !important; margin-left: auto !important; margin-right: auto !important; + font-size: 18px; + &:before { + display: none; + } &::-webkit-scrollbar { height: 6px; } @@ -1153,12 +1297,6 @@ body.has-sidebar { margin-left: 1em !important; } } - .item { - font-size: 18px; - &:before { - display: none; - } - } .active.item { background-color: transparent !important; color: #4296B3 !important; @@ -1171,24 +1309,6 @@ body.has-sidebar { } } } - - // @media(min-width: 1300px) { - // .ui.item.menu { - // width: 1200px !important; - // } - // } - - // @media(min-width: 1000px) { - // .ui.item.menu { - // width: 900px !important; - // } - // } - - // @media(max-width: 999px) { - // .ui.item.menu { - // width: fit-content !important; - // } - // } } } @@ -1418,4 +1538,25 @@ b { .ui.small.modal { margin: 0!important; } +} + +.eprtrReportingYears { + color: #fff; + background-color: #4296B3; + border-radius: 10px; + display: grid; + grid-template-columns: repeat(3, 1fr); + > div { + position: relative; + } + p { + color: #fff; + margin-bottom: 0.5em !important; + } + .floating-icon { + position: absolute; + top: 50%; + transform: translateY(-50%); + left: -26px + } } \ No newline at end of file