Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Commit

Permalink
fix layouts for new volto
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiggr committed Nov 5, 2022
1 parent eb5bcf9 commit c002349
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 12 deletions.
11 changes: 3 additions & 8 deletions src/constants/Layouts.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import config from '@plone/volto/registry';

export default {
album_view: 'Album view',
event_listing: 'Event listing',
full_view: 'All content',
listing_view: 'Listing view',
summary_view: 'Summary view',
tabular_view: 'Tabular view',
layout_view: 'Mosaic layout',
document_view: 'Document view',
...config.views.layoutViewsNamesMapping,
country_tab_view: 'Country page',
};
6 changes: 3 additions & 3 deletions src/constants/runtime.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const RAZZLE_FRONTEND_VERSION = 'eeacms/forests-frontend:2.4.3';
export const RAZZLE_FRONTEND_VERSION = 'eeacms/forests-frontend:2.26.8';
export const RAZZLE_FRONTEND_VERSION_URL =
'https://github.com/eea/forests-frontend/releases/tag/2.4.3';
export const RAZZLE_FRONTEND_PUBLISHED_AT = '2021-06-18T15:15:04Z';
'https://github.com/eea/forests-frontend/releases/tag/2.26.8';
export const RAZZLE_FRONTEND_PUBLISHED_AT = '2022-11-03T12:36:42Z';
254 changes: 254 additions & 0 deletions src/customizations/volto/components/manage/Display/Display.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';

import { getSchema, updateContent, getContent } from '@plone/volto/actions';
import { getLayoutFieldname } from '@plone/volto/helpers';
import { FormFieldWrapper, Icon } from '@plone/volto/components';
import { defineMessages, injectIntl } from 'react-intl';
import config from '@plone/volto/registry';

import downSVG from '@plone/volto/icons/down-key.svg';
import upSVG from '@plone/volto/icons/up-key.svg';
import checkSVG from '@plone/volto/icons/check.svg';

const messages = defineMessages({
Viewmode: {
id: 'Viewmode',
defaultMessage: 'View',
},
});

const Option = injectLazyLibs('reactSelect')((props) => {
const { Option } = props.reactSelect.components;
return (
<Option {...props}>
<div>{props.label}</div>
{props.isFocused && !props.isSelected && (
<Icon name={checkSVG} size="18px" color="#b8c6c8" />
)}
{props.isSelected && <Icon name={checkSVG} size="18px" color="#007bc1" />}
</Option>
);
});

const DropdownIndicator = injectLazyLibs('reactSelect')((props) => {
const { DropdownIndicator } = props.reactSelect.components;
return (
<DropdownIndicator {...props}>
{props.selectProps.menuIsOpen ? (
<Icon name={upSVG} size="24px" color="#007bc1" />
) : (
<Icon name={downSVG} size="24px" color="#007bc1" />
)}
</DropdownIndicator>
);
});

const selectTheme = (theme) => ({
...theme,
borderRadius: 0,
colors: {
...theme.colors,
primary25: 'hotpink',
primary: '#b8c6c8',
},
});

const customSelectStyles = {
control: (styles, state) => ({
...styles,
border: 'none',
borderBottom: '2px solid #b8c6c8',
boxShadow: 'none',
borderBottomStyle: state.menuIsOpen ? 'dotted' : 'solid',
}),
menu: (styles, state) => ({
...styles,
top: null,
marginTop: 0,
boxShadow: 'none',
borderBottom: '2px solid #b8c6c8',
}),
menuList: (styles, state) => ({
...styles,
maxHeight: '400px',
}),
indicatorSeparator: (styles) => ({
...styles,
width: null,
}),
valueContainer: (styles) => ({
...styles,
padding: 0,
}),
option: (styles, state) => ({
...styles,
backgroundColor: null,
minHeight: '50px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '12px 12px',
color: state.isSelected
? '#007bc1'
: state.isFocused
? '#4a4a4a'
: 'inherit',
':active': {
backgroundColor: null,
},
span: {
flex: '0 0 auto',
},
svg: {
flex: '0 0 auto',
},
}),
};

/**
* Display container class.
* @class Display
* @extends Component
*/
class DisplaySelect extends Component {
/**
* Property types.
* @property {Object} propTypes Property types.
* @static
*/
static propTypes = {
getSchema: PropTypes.func.isRequired,
updateContent: PropTypes.func.isRequired,
getContent: PropTypes.func.isRequired,
loaded: PropTypes.bool.isRequired,
pathname: PropTypes.string.isRequired,
layouts: PropTypes.arrayOf(PropTypes.string),
layout: PropTypes.string,
type: PropTypes.string.isRequired,
};

/**
* Default properties
* @property {Object} defaultProps Default properties.
* @static
*/
static defaultProps = {
layouts: [],
layout: '',
};

state = {
selectedOption: {
value: `${this.props.layout}`,
label: `${this.props?.layout}`,
},
};

componentDidMount() {
this.props.getSchema(this.props.type);
console.log(config?.views?.layoutViewsNamesMapping, 'config');
console.log(this.props.layout, 'config');
}

/**
* Component will receive props
* @method componentWillReceiveProps
* @param {Object} nextProps Next properties
* @returns {undefined}
*/
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.pathname !== this.props.pathname) {
this.props.getSchema(nextProps.type);
}
if (!this.props.loaded && nextProps.loaded) {
this.props.getContent(nextProps.pathname);
}
}

/**
* On set layout handler
* @method setLayout
* @param {Object} event Event object
* @returns {undefined}
*/
setLayout = (selectedOption) => {
this.props.updateContent(this.props.pathname, {
layout: selectedOption.value,
});
this.setState({ selectedOption });
};

selectValue = (option) => (
<Fragment>
<span className="Select-value-label">{option.label}</span>
</Fragment>
);

optionRenderer = (option) => (
<Fragment>
<span style={{ marginRight: 'auto' }}>{option.label}</span>
<Icon name={checkSVG} size="24px" />
</Fragment>
);

render() {
const { selectedOption } = this.state;
const Select = this.props.reactSelect.default;
const layoutsNames = config.views.layoutViewsNamesMapping;
const layoutOptions = this.props.layouts
.filter(
(layout) =>
Object.keys(config.views.contentTypesViews).includes(layout) ||
Object.keys(config.views.layoutViews).includes(layout),
)
.map((item) => ({
value: item,
label: item,
}));

return layoutOptions?.length > 1 ? (
<FormFieldWrapper
id="display-select"
style={{ width: '100%' }}
title={this.props.intl.formatMessage(messages.Viewmode)}
{...this.props}
>
<Select
name="display-select"
className="react-select-container"
classNamePrefix="react-select"
options={layoutOptions}
styles={customSelectStyles}
theme={selectTheme}
components={{ DropdownIndicator, Option }}
onChange={this.setLayout}
defaultValue={selectedOption}
isSearchable={false}
/>
</FormFieldWrapper>
) : null;
}
}

export default compose(
injectIntl,
injectLazyLibs('reactSelect'),
connect(
(state) => ({
loaded: state.content.update.loaded,
layouts: state.schema.schema ? state.schema.schema.layouts : [],
layout: state.content.data
? state.content.data[getLayoutFieldname(state.content.data)]
: '',
layout_fieldname: state.content.data
? getLayoutFieldname(state.content.data)
: '',
type: state.content.data ? state.content.data['@type'] : '',
}),
{ getSchema, updateContent, getContent },
),
)(DisplaySelect);
1 change: 0 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,5 @@ export default function applyConfig(config) {
// { cssClass: 'green-block-text', label: 'Green Text' },
// { cssClass: 'underline-block-text', label: 'Underline Text' },
// ];

return config;
}
7 changes: 7 additions & 0 deletions theme/site/extras/toolbar.less
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,13 @@
flex: 1 0 75%;
}

.field-wrapper-state-select {
width: 100%;
}
.field-wrapper-display-select {
width: 100%;
}

label {
flex: 1 0 25%;
padding-top: 18px;
Expand Down

0 comments on commit c002349

Please sign in to comment.