diff --git a/src/components/manage/Blocks/SidebarBlock/Edit.jsx b/src/components/manage/Blocks/SidebarBlock/Edit.jsx index 9f7063b..51df1bf 100644 --- a/src/components/manage/Blocks/SidebarBlock/Edit.jsx +++ b/src/components/manage/Blocks/SidebarBlock/Edit.jsx @@ -2,42 +2,101 @@ import React, { useState, useEffect } from 'react'; import { connect } from 'react-redux'; import { compose } from 'redux'; import _uniqueId from 'lodash/uniqueId'; -import RenderFields from 'volto-addons/Widgets/RenderFields'; +import qs from 'query-string'; import View from './View'; +import DiscodataSqlBuilderEdit from 'volto-datablocks/DiscodataSqlBuilder/Edit'; const makeChoices = keys => keys && keys.map(k => [k, k]); const getSchema = props => { - const { search, key, resourceKey } = props.discodata_query.data; - const discodataResources = Object.keys(props.discodata_resources.data) || []; - const selectedDiscodataResource = - props.discodata_resources.data?.[resourceKey]?.[search?.[key]] || null; + const { query } = props; + const { search } = props.discodata_query; + const { data } = props.discodata_resources; + const globalQuery = { ...query, ...search }; + /* ===================== */ + /* ===================== */ + const resourcePackageKey = props.data.resource_package_key?.value; + const key = props.data.key?.value; + const selectedResource = + resourcePackageKey && !key + ? data[resourcePackageKey] + : resourcePackageKey && key + ? data[resourcePackageKey]?.[globalQuery[key]] + : data; return { parent: { type: 'link', title: 'Parent page', }, - multiply_second_level: { + multiply: { type: 'boolean', - title: 'Multiply second level', + title: 'Multiply', }, - discodata_resource: { + depth_of_multiplication: { + type: 'text', + title: 'Depth of multiplication', + }, + resource_package_key: { + title: 'Resource package key', type: 'array', - title: 'Discodata resource', - choices: makeChoices(discodataResources), + choices: data ? makeChoices(Object.keys(data)) : [], }, - discodata_resource_property: { + key: { + title: 'Query to use', type: 'array', + choices: globalQuery ? makeChoices(Object.keys(globalQuery)) : [], + }, + source: { title: 'Source', - // items: { - choices: selectedDiscodataResource - ? makeChoices(Object.keys(selectedDiscodataResource)) + type: 'array', + choices: selectedResource + ? makeChoices(Object.keys(selectedResource)) : [], - // }, }, query_parameter: { type: 'text', - title: 'Query to set', + title: 'Query identifier', + }, + query_parameters: { + title: 'Queries to set', + type: 'schema', + fieldSetTitle: 'Queries metadata', + fieldSetId: 'queries_metadata', + fieldSetSchema: { + fieldsets: [ + { + id: 'default', + title: 'title', + fields: ['title', 'id', 'queryParam'], + }, + ], + properties: { + title: { + title: 'Title', + type: 'text', + }, + id: { + title: 'Id', + type: 'text', + }, + queryParam: { + title: 'Query param', + type: 'text', + // type: formData => (!formData.urlQuery ? 'text' : 'array'), + // choices: formData => { + // if (!formData.urlQuery) return undefined; + // let keys = query ? Object.keys(query) : []; + // Object.keys(search).forEach(key => { + // if (keys.indexOf(key) === -1) keys.push(key); + // }); + // return [...makeChoices(keys)]; + // }, + }, + }, + required: ['id', 'title', 'queryParam'], + }, + editFieldset: false, + deleteFieldset: false, }, }; }; @@ -66,17 +125,21 @@ const Edit = props => { }), }); /* eslint-disable-next-line */ - }, [state.item, props.data, props.discodata_resources, props.discodata_query]) + }, [state.item, props.data, props.discodata_resources, props.discodata_query.search]) return ( -
- - -
+ + + ); }; export default compose( connect((state, props) => ({ + query: qs.parse(state.router.location.search), pathname: state.router.location.pathname, discodata_resources: state.discodata_resources, discodata_query: state.discodata_query, diff --git a/src/components/manage/Blocks/SidebarBlock/View.jsx b/src/components/manage/Blocks/SidebarBlock/View.jsx index 1eb7a84..950e308 100644 --- a/src/components/manage/Blocks/SidebarBlock/View.jsx +++ b/src/components/manage/Blocks/SidebarBlock/View.jsx @@ -14,103 +14,153 @@ import { setQueryParam, deleteQueryParam, } from 'volto-datablocks/actions'; +import DiscodataSqlBuilderView from 'volto-datablocks/DiscodataSqlBuilder/View'; import './style.css'; const sidebarRef = React.createRef(); const View = ({ content, ...props }) => { - const { data } = props; const [state, setState] = useState({ sidebar: [], sidebarOpened: true, + selectedResource: {}, }); + const { query } = props; + const { search } = props.discodata_query; + const { data } = props.discodata_resources; const history = useHistory(); - const parsedQuery = qs.parse(props.location.search); - const { search, key, resourceKey } = props.discodata_query.data; - const parent = data.parent?.value; - const activeItem = parsedQuery?.[props.data.query_parameter?.value] || ''; + const globalQuery = { ...query, ...search }; + const resourcePackageKey = props.data.resource_package_key?.value; + const key = props.data.key?.value; + const source = props.data.source?.value; + const multiply = props.data.multiply?.value; + const depthOfMultiplication = props.data.depth_of_multiplication?.value; + const queryParam = props.data.query_parameter?.value; + const activeItem = globalQuery?.[queryParam] || ''; + const queryParameters = props.data?.query_parameters?.value + ? JSON.parse(props.data.query_parameters.value).properties + : {}; useEffect(() => { - if (props.navigation) { - const sidebar = []; - sidebar.push(...getSidebar(props.navigation, 1)); - setState({ - ...state, - sidebar, - }); + if ( + multiply && + resourcePackageKey && + key && + source && + data[resourcePackageKey]?.[globalQuery[key]]?.[source] && + props.navigation + ) { + const selectedResource = + data[resourcePackageKey][globalQuery[key]][source]; + setState({ ...state, selectedResource }); } /* eslint-disable-next-line */ - }, [ props.data, props.navigation, props.discodata_resources, activeItem]); + }, [resourcePackageKey, key, source, multiply, props.discodata_resources, props.navigation, activeItem]) + + useEffect(() => { + const sidebar = [...getSidebar(props.navigation, 1)]; + setState({ ...state, sidebar }); + /* eslint-disable-next-line */ + }, [state.selectedResource, search]) const getSidebar = (item, depth) => { const sidebar = []; - if (depth === 2 && props.data?.multiply_second_level?.value === true) { - const selectedDiscodataResource = - props.discodata_resources.data?.[resourceKey]?.[search?.[key]] || null; - const selectedDiscodataResourceProperty = - selectedDiscodataResource?.[ - props.data.discodata_resource_property?.value - ]; - selectedDiscodataResourceProperty && + if (multiply && depth === parseInt(depthOfMultiplication)) { + Object.entries(state.selectedResource).forEach(([key, source]) => { + sidebar.push( + , + ); item?.items?.length && - Object.entries(selectedDiscodataResourceProperty).forEach( - ([key, value]) => { + item.items.forEach(nextItem => { sidebar.push( - , + {nextItem.title} + , ); - item?.items?.length && - item.items.forEach(nextItem => { - sidebar.push( - , - ); - sidebar.push(...getSidebar(nextItem, depth + 2)); - }); - }, - ); + sidebar.push(...getSidebar(nextItem, depth + 2)); + }); + }); } else { item?.items?.length && item.items.forEach(nextItem => { sidebar.push( { + let deleteQueries = false; + Object.keys(queryParameters).forEach(key => { + if (globalQuery[key] && !deleteQueries) deleteQueries = true; + }); + if (multiply && deleteQueries) { + props.deleteQueryParam({ + queryParam: Object.keys(queryParameters), + }); + } + }} to={nextItem.url === '' ? `/}` : nextItem.url} exact={ settings.isMultilingual @@ -129,46 +179,29 @@ const View = ({ content, ...props }) => { } return sidebar; }; + return ( -
- {/* */} -
- {props.navigation?.items?.length && parent ? ( + +
+
- ) : ( - '' - )} +
-
+ ); }; export default compose( connect( (state, props) => ({ - router: state.router, location: state.router.location, content: state.prefetch?.[state.router.location.pathname] || state.content.data, - pathname: state.router.location.pathname, lang: state.intl.locale, navigation: getNavigationByParent( state.navigation.items, diff --git a/src/components/theme/View/DiscodataView.jsx b/src/components/theme/View/DiscodataView.jsx index 6de81a8..c0bca1b 100644 --- a/src/components/theme/View/DiscodataView.jsx +++ b/src/components/theme/View/DiscodataView.jsx @@ -1,87 +1,65 @@ /* REACT IMPORTS */ -import React, { useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { connect } from 'react-redux'; import qs from 'query-string'; /* ROOT IMPORTS */ import MosaicView from 'volto-mosaic/components/theme/View'; -import DB from 'volto-datablocks/DataBase/DB'; -// SVGS /* LOCAL IMPORTS */ -import { getDiscodataResource } from 'volto-datablocks/actions'; +import { getDiscodataResource, setQueryParam } from 'volto-datablocks/actions'; +import { Dimmer, Loader } from 'semantic-ui-react'; /* =================================================== */ - const DiscodataView = props => { - const query = qs.parse(props.location.search); + const [state, setState] = useState({ + mounted: false, + }); const history = useHistory(); - const { sql_query, endpoint_url } = props.content; - const { - search, - key, - resourceKey, - where, - groupBy, - } = props.discodata_query.data; - const { deletedQueryParams } = props.discodata_query; - useEffect(() => { - const whereStatements = - where?.length > 0 && - where.map(param => { - return { - discodataKey: param, - value: props.discodata_query.data.search?.[param], - }; - }); - const url = DB.table(sql_query, endpoint_url, { - p: query.p, - nrOfHits: query.nrOfHits, - }) - .where(whereStatements) - .encode() - .get(); - if (!props.discodata_resources.loading) { - const request = { - url, - search: search || {}, - resourceKey: resourceKey || '', - key: key || '', - groupBy: groupBy || [], - }; - if ( - request.url && - !props.discodata_resources.data?.[key]?.[ - props.discodata_query.data.search?.[key] - ] && - !props.discodata_resources.pendingRequests[ - `${resourceKey}_${key}_${search?.[key]}` - ] - ) { - props.getDiscodataResource(request); - } - } - /* eslint-disable-next-line */ - }, [props.discodata_query.data]) + const { search, deletedQueryParams } = props.discodata_query; + const parsedQuery = { ...(qs.parse(props.query) || {}) }; + + // useEffect(() => { + // /* Add query to discodata_query on mount */ + // let updatedSearch = false; + // let newSearch = { ...search }; + // Object.entries(parsedQuery).forEach(([key, value]) => { + // if (!search[key] || search[key] !== value) { + // newSearch[key] = value; + // if (!updatedSearch) updatedSearch = true; + // } + // }); + // if (updatedSearch) props.setQueryParam({ queryParam: newSearch }); + // setState({ + // ...state, + // mounted: true, + // }); + // /* eslint-disable-next-line */ + // }, []) - useEffect(() => { - const query = { ...(qs.parse(props.query) || {}) }; - Object.entries(deletedQueryParams).forEach(([key, value]) => { - if (value && query[key]) delete query[key]; - }); - Object.entries(search).forEach(([key, value], index) => { - if (query) { - query[key] = value; - } - }); - if (props.query !== `?${qs.stringify(query)}`) { - history.push({ - search: `?${qs.stringify(query)}`, - }); - } - /* eslint-disable-next-line */ - }, [props.discodata_query.data?.search, props.query]) + // useEffect(() => { + // if (state.mounted && props.content.layout === 'discodata_view') { + // const newQuery = { ...parsedQuery }; + // Object.entries(deletedQueryParams).forEach(([key, value]) => { + // if (newQuery[key]) delete newQuery[key]; + // }); + // Object.entries(search).forEach(([key, value], index) => { + // if (newQuery[key] !== value) { + // newQuery[key] = value; + // } + // }); + // if (qs.stringify(parsedQuery) !== `${qs.stringify(newQuery)}`) { + // history.push({ + // search: `?${qs.stringify(newQuery)}`, + // }); + // } + // } + // /* eslint-disable-next-line */ + // }, [props.query]) return ( -
+
+ + +
); @@ -96,5 +74,5 @@ export default connect( content: state.prefetch?.[state.router.location.pathname] || state.content.data, }), - { getDiscodataResource }, + { getDiscodataResource, setQueryParam }, )(DiscodataView); diff --git a/src/config.js b/src/config.js index fa80660..734a583 100644 --- a/src/config.js +++ b/src/config.js @@ -4,6 +4,7 @@ import { applyConfig as addonsConfig, installFolderListing, installTableau, + installExpendableList, } from 'volto-addons/config'; import { applyConfig as ckeditorConfig } from 'volto-ckeditor/config'; import { applyConfig as dataBlocksConfig } from 'volto-datablocks/config'; @@ -21,6 +22,7 @@ const config = [ addonsConfig, installFolderListing, installTableau, + installExpendableList, plotlyConfig, // ckeditorConfig, tabsViewConfig, diff --git a/theme/site/globals/site.overrides b/theme/site/globals/site.overrides index 8e87227..35806f2 100644 --- a/theme/site/globals/site.overrides +++ b/theme/site/globals/site.overrides @@ -655,6 +655,7 @@ p { &.hide { td { .table-flex-container { + padding: 0; max-height: 0; opacity: 0; } @@ -664,6 +665,7 @@ p { &.show { td { .table-flex-container { + padding: 20px 30px 40px 30px; max-height: fit-content; opacity: 1; } @@ -1019,6 +1021,32 @@ body.has-sidebar { .ui.menu { border: none; box-shadow: none; + &.red-menu { + .item { + color: #D63D27; + background-color: transparent; + &:before { + width: 0; + background-color: transparent; + } + } + .active.item { + color: #fff; + border-bottom: none; + background-color: #D63D27; + padding: 0 2em !important; + border-radius: 2em; + &:hover { + background: #a32e1c; + color: #fff; + } + &:before { + width: 0; + background: transparent; + background-color: transparent; + } + } + } &.item { text-align: left !important; justify-content: start !important; @@ -1088,10 +1116,31 @@ body.has-sidebar { } } + .facility-block-wrapper { + height: 100%; + > div { + height: 100%; + } + } } } } - + +.ui.dropdown { + display: flex !important; + align-items: center !important; +} + +.ui.dropdown > .dropdown.icon { + font-size: 14px !important; + margin-left: 5px !important; +} + +@media(max-width: 600px) { + .eprtr-box { + width: 100%; + } +} .view-navgation-container { height: 100%; @@ -1125,6 +1174,23 @@ h3 { color: #EC776A; } -.blocks-chooser { - top: -500px !important; +/* Navigation */ +.navigation .ui.menu { + flex-wrap: wrap; +} + +// .react-grid-layout:not(.mosaic-edit-layout) { +// .react-grid-item { +// position: relative !important; +// float: left; +// top: unset !important; +// height: fit-content !important; +// } +// } + +#discodata-mosaic-view { + position: relative; + .ui.dimmer { + background-color: rgba(0, 0, 0, 0.3); + } } \ No newline at end of file