Skip to content

Commit a290149

Browse files
Merge pull request #1391 from creative-commoners/pulls/6/convert-func
Convert some class components to functional
2 parents 8c896e2 + 42ff70e commit a290149

13 files changed

Lines changed: 1382 additions & 306 deletions

client/dist/js/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/src/components/ElementEditor/AddElementPopover.js

Lines changed: 69 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* global window */
22

3-
import React, { Component } from 'react';
3+
import React, { useContext } from 'react';
44
import PropTypes from 'prop-types';
55
import { connect } from 'react-redux';
66
import { bindActionCreators, compose } from 'redux';
@@ -18,93 +18,85 @@ import getJsonErrorMessage from 'lib/getJsonErrorMessage';
1818
* The AddElementPopover component used in the context of an ElementEditor shows the
1919
* available elements that can be added to an ElementalArea.
2020
*/
21-
class AddElementPopover extends Component {
22-
constructor(props) {
23-
super(props);
24-
25-
this.handleToggle = this.handleToggle.bind(this);
26-
AddElementPopover.contextType = ElementEditorContext;
27-
}
28-
29-
/**
30-
* - Call add element to area endpoint (areaID, elementType, insertAfterElementID)
31-
* - Then call read blocks from area endpoint (areaID)
32-
* - Then update the preview via jquery/entwine
33-
*/
34-
getElementButtonClickHandler(elementType) {
35-
return (event) => {
36-
event.preventDefault();
37-
const sectionConfigKey = 'DNADesign\\Elemental\\Controllers\\ElementalAreaController';
38-
const url = `${Config.getSection(sectionConfigKey).controllerLink}/api/create`;
39-
backend.post(url, {
40-
elementClass: elementType.class,
41-
elementalAreaID: this.props.areaId,
42-
insertAfterElementID: this.props.insertAfterElement,
43-
}, {
44-
'X-SecurityID': Config.get('SecurityID')
45-
})
46-
.then(() => {
47-
const { fetchElements } = this.context;
48-
return fetchElements();
49-
})
50-
.then(() => {
51-
const preview = window.jQuery('.cms-preview');
52-
preview.entwine('ss.preview')._loadUrl(preview.find('iframe').attr('src'));
53-
})
54-
.catch(async (err) => {
55-
const message = await getJsonErrorMessage(err);
56-
this.props.actions.toasts.error(message);
57-
});
58-
this.handleToggle();
59-
};
60-
}
21+
const AddElementPopover = ({
22+
PopoverOptionSetComponent,
23+
elementTypes,
24+
container,
25+
extraClass,
26+
isOpen,
27+
placement,
28+
target,
29+
toggle,
30+
areaId,
31+
insertAfterElement,
32+
actions,
33+
}) => {
34+
const context = useContext(ElementEditorContext);
6135

6236
/**
6337
* Pass toggle to parent and clear the search input
6438
*/
65-
handleToggle() {
66-
const { toggle } = this.props;
67-
39+
const handleToggle = () => {
6840
toggle();
69-
}
41+
};
7042

7143
/**
72-
* Render the add element popover
73-
* @returns {DOMElement}
44+
* - Call add element to area endpoint (areaID, elementType, insertAfterElementID)
45+
* - Then call read blocks from area endpoint (areaID)
46+
* - Then update the preview via jquery/entwine
7447
*/
75-
render() {
76-
const {
77-
PopoverOptionSetComponent, elementTypes,
78-
container, extraClass, isOpen, placement, target
79-
} = this.props;
48+
const getElementButtonClickHandler = (elementType) => (event) => {
49+
event.preventDefault();
50+
const sectionConfigKey = 'DNADesign\\Elemental\\Controllers\\ElementalAreaController';
51+
const url = `${Config.getSection(sectionConfigKey).controllerLink}/api/create`;
52+
backend.post(url, {
53+
elementClass: elementType.class,
54+
elementalAreaID: areaId,
55+
insertAfterElementID: insertAfterElement,
56+
}, {
57+
'X-SecurityID': Config.get('SecurityID')
58+
})
59+
.then(() => {
60+
const { fetchElements } = context;
61+
return fetchElements();
62+
})
63+
.then(() => {
64+
const preview = window.jQuery('.cms-preview');
65+
preview.entwine('ss.preview')._loadUrl(preview.find('iframe').attr('src'));
66+
})
67+
.catch(async (err) => {
68+
const message = await getJsonErrorMessage(err);
69+
actions.toasts.error(message);
70+
});
71+
handleToggle();
72+
};
8073

81-
const popoverClassNames = classNames(
82-
'element-editor-add-element',
83-
extraClass
84-
);
74+
const popoverClassNames = classNames(
75+
'element-editor-add-element',
76+
extraClass
77+
);
8578

86-
const buttons = elementTypes.map((elementType) => ({
87-
content: <span className="btn__title">{elementType.title}</span>,
88-
key: elementType.name,
89-
className: classNames('btn--icon-xl', 'element-editor-add-element__button'),
90-
icon: elementType.icon.replace(/^(font-icon-)/g, ''),
91-
onClick: this.getElementButtonClickHandler(elementType),
92-
}));
79+
const buttons = elementTypes.map((elementType) => ({
80+
content: <span className="btn__title">{elementType.title}</span>,
81+
key: elementType.name,
82+
className: classNames('btn--icon-xl', 'element-editor-add-element__button'),
83+
icon: elementType.icon.replace(/^(font-icon-)/g, ''),
84+
onClick: getElementButtonClickHandler(elementType),
85+
}));
9386

94-
return (
95-
<PopoverOptionSetComponent
96-
buttons={buttons}
97-
searchPlaceholder={i18n._t('ElementAddElementPopover.SEARCH_BLOCKS', 'Search blocks')}
98-
extraClass={popoverClassNames}
99-
container={container}
100-
isOpen={isOpen}
101-
placement={placement}
102-
target={target}
103-
toggle={this.handleToggle}
104-
/>
105-
);
106-
}
107-
}
87+
return (
88+
<PopoverOptionSetComponent
89+
buttons={buttons}
90+
searchPlaceholder={i18n._t('ElementAddElementPopover.SEARCH_BLOCKS', 'Search blocks')}
91+
extraClass={popoverClassNames}
92+
container={container}
93+
isOpen={isOpen}
94+
placement={placement}
95+
target={target}
96+
toggle={handleToggle}
97+
/>
98+
);
99+
};
108100

109101
AddElementPopover.propTypes = {
110102
container: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]),

client/src/components/ElementEditor/AddNewButton.js

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,50 @@
1-
import React, { Component } from 'react';
1+
import React, { useState } from 'react';
22
import PropTypes from 'prop-types';
33
import Button from 'components/Button/Button';
44
import i18n from 'i18n';
55
import { elementTypeType } from 'types/elementTypeType';
66
import { inject } from 'lib/Injector';
77

8-
class AddNewButton extends Component {
9-
constructor(props) {
10-
super(props);
8+
const AddNewButton = ({
9+
AddElementPopoverComponent,
10+
elementTypes,
11+
areaId,
12+
}) => {
13+
const [popoverOpen, setPopoverOpen] = useState(false);
1114

12-
this.toggle = this.toggle.bind(this);
13-
14-
this.state = {
15-
popoverOpen: false
16-
};
17-
}
18-
19-
toggle() {
20-
this.setState((prevState) => ({
21-
popoverOpen: !prevState.popoverOpen,
22-
}));
23-
}
15+
const toggle = () => {
16+
setPopoverOpen((prevState) => !prevState);
17+
};
2418

2519
/**
2620
* Render the add button for block types
2721
* @returns {DOMElement}
2822
*/
29-
render() {
30-
const { AddElementPopoverComponent, elementTypes, areaId } = this.props;
31-
const buttonAttributes = {
32-
id: `ElementalArea${areaId}_AddButton`,
33-
color: 'primary',
34-
onClick: this.toggle,
35-
icon: 'plus',
36-
};
37-
38-
return (
39-
<div>
40-
<Button {...buttonAttributes}>
41-
{i18n._t('ElementAddNewButton.ADD_NEW_BLOCK', 'Add new block')}
42-
</Button>
43-
<AddElementPopoverComponent
44-
placement="bottom-start"
45-
target={buttonAttributes.id}
46-
isOpen={this.state.popoverOpen}
47-
elementTypes={elementTypes}
48-
toggle={this.toggle}
49-
areaId={areaId}
50-
insertAfterElement={0}
51-
/>
52-
</div>
53-
);
54-
}
55-
}
23+
const buttonAttributes = {
24+
id: `ElementalArea${areaId}_AddButton`,
25+
color: 'primary',
26+
onClick: toggle,
27+
icon: 'plus',
28+
};
29+
30+
return (
31+
<div>
32+
<Button {...buttonAttributes}>
33+
{i18n._t('ElementAddNewButton.ADD_NEW_BLOCK', 'Add new block')}
34+
</Button>
35+
<AddElementPopoverComponent
36+
placement="bottom-start"
37+
target={buttonAttributes.id}
38+
isOpen={popoverOpen}
39+
elementTypes={elementTypes}
40+
toggle={toggle}
41+
areaId={areaId}
42+
insertAfterElement={0}
43+
/>
44+
</div>
45+
);
46+
};
5647

57-
AddNewButton.defaultProps = {};
5848
AddNewButton.propTypes = {
5949
elementTypes: PropTypes.arrayOf(elementTypeType).isRequired,
6050
areaId: PropTypes.number.isRequired,
Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
import React, { PureComponent } from 'react';
1+
import React, { memo } from 'react';
22

3-
// eslint-disable-next-line react/prefer-stateless-function
4-
class DragPositionIndicator extends PureComponent {
5-
render() {
6-
return (
7-
<div className="elemental-editor-drag-indicator">
8-
<div className="elemental-editor-drag-indicator__ball" />
9-
</div>
10-
);
11-
}
12-
}
3+
const DragPositionIndicator = () => (
4+
<div className="elemental-editor-drag-indicator">
5+
<div className="elemental-editor-drag-indicator__ball" />
6+
</div>
7+
);
138

14-
export default DragPositionIndicator;
9+
// Wrapping export in React.memo() because the old class component extended React.PureComponent
10+
export default memo(DragPositionIndicator);

0 commit comments

Comments
 (0)