Skip to content

Commit 1766d20

Browse files
author
Martin Krulis
committed
Updating components to the new React API (16.3 and newer).
1 parent 9b4babb commit 1766d20

File tree

65 files changed

+413
-427
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+413
-427
lines changed

src/components/Pipelines/BoxForm/BoxForm.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import { getBoxTypes } from '../../../redux/selectors/boxes';
1818
import { getVariablesTypes } from '../../../helpers/boxes';
1919

2020
class BoxForm extends Component {
21-
componentWillMount = () => this.loadBoxTypes();
21+
componentDidMount = () => this.loadBoxTypes();
22+
2223
loadBoxTypes() {
2324
const { fetchBoxTypes } = this.props;
2425
fetchBoxTypes();

src/components/Pipelines/PipelineVisualEditor/PipelineVisualEditor.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@ class PipelineVisualEditor extends Component {
2121
nodeToEdit: null,
2222
};
2323

24-
componentWillMount = () => {
24+
componentDidMount = () => {
2525
// initialize the graph, if the source is valid
2626
const { source } = this.props;
2727
const graph = createGraphFromNodes(source);
28-
2928
this.setState({ graph });
30-
};
3129

32-
componentDidMount = () => {
3330
const { editorWrapper } = this;
3431
editorWrapper.addEventListener('click', e => this.onClick(e.target));
3532
};

src/components/Solutions/UploadsTable/UploadsTable.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ const UploadsTable = ({
8080
<td className="text-center">
8181
<DeleteIcon className="text-warning" />
8282
</td>
83-
<td>{payload.name}</td>
84-
<td>{prettyPrintBytes(payload.file.size)}</td>
83+
<td className="text-muted">
84+
<strike>{payload.name}</strike>
85+
</td>
86+
<td className="text-muted">{prettyPrintBytes(payload.file.size)}</td>
8587
<td>
8688
<ButtonGroup>
8789
<Button bsSize="xs" bsStyle="default" onClick={() => returnFile(payload)}>

src/components/forms/EditAssignmentForm/EditAssignmentForm.js

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
validateLocalizedTextsFormData,
1919
transformLocalizedTextsFormData,
2020
} from '../../../helpers/localizedData';
21-
import { safeSet } from '../../../helpers/common';
21+
import { safeGet, safeSet, EMPTY_ARRAY } from '../../../helpers/common';
2222

2323
const localizedTextDefaults = {
2424
name: '',
@@ -176,13 +176,32 @@ const SUBMIT_BUTTON_MESSAGES_DEFAULT = {
176176
success: <FormattedMessage id="generic.saved" defaultMessage="Saved" />,
177177
};
178178

179+
const getAllGroups = defaultMemoize((groups, groupsAccessor, locale) =>
180+
groups && groupsAccessor
181+
? groups
182+
.filter(g => !g.organizational && !g.archived)
183+
.sort((a, b) =>
184+
getGroupCanonicalLocalizedName(a, groupsAccessor, locale).localeCompare(
185+
getGroupCanonicalLocalizedName(b, groupsAccessor, locale),
186+
locale
187+
)
188+
)
189+
: EMPTY_ARRAY
190+
);
191+
192+
const getUserGroups = defaultMemoize((groups, userId, groupsAccessor, locale) =>
193+
getAllGroups(groups, groupsAccessor, locale).filter(
194+
g =>
195+
safeGet(g, ['primaryAdminsIds', id => id === userId]) ||
196+
safeGet(g, ['privateData', 'supervisors', id => id === userId])
197+
)
198+
);
199+
179200
class EditAssignmentForm extends Component {
180201
state = {
181202
open: false,
182203
assignedToGroups: null,
183204
};
184-
allGroups = [];
185-
myGroups = [];
186205

187206
toggleOpenState = () => {
188207
this.setState({ open: !this.state.open });
@@ -193,33 +212,6 @@ class EditAssignmentForm extends Component {
193212
this.props.reset();
194213
};
195214

196-
componentWillReceiveProps(newProps) {
197-
if (
198-
this.props.groups !== newProps.groups ||
199-
this.props.userId !== newProps.userId ||
200-
this.props.groupsAccessor !== newProps.groupsAccessor
201-
) {
202-
const {
203-
groupsAccessor,
204-
intl: { locale },
205-
} = newProps;
206-
this.allGroups = newProps.groups
207-
.filter(g => !g.organizational && !g.archived)
208-
.sort((a, b) =>
209-
getGroupCanonicalLocalizedName(a, groupsAccessor, locale).localeCompare(
210-
getGroupCanonicalLocalizedName(b, groupsAccessor, locale),
211-
locale
212-
)
213-
);
214-
215-
this.myGroups = this.allGroups.filter(
216-
g =>
217-
g.primaryAdminsIds.find(id => id === newProps.userId) ||
218-
g.privateData.supervisors.find(id => id === newProps.userId)
219-
);
220-
}
221-
}
222-
223215
/**
224216
* Wraps the onSubmit callback passed from the parent component.
225217
* (note that submitHandler in which this function is used is redux-form internal routine to handle submits)
@@ -238,6 +230,7 @@ class EditAssignmentForm extends Component {
238230

239231
render() {
240232
const {
233+
userId,
241234
groups,
242235
editTexts = false,
243236
groupsAccessor = null,
@@ -257,6 +250,7 @@ class EditAssignmentForm extends Component {
257250
visibility,
258251
assignmentIsPublic,
259252
submitButtonMessages = SUBMIT_BUTTON_MESSAGES_DEFAULT,
253+
intl: { locale },
260254
} = this.props;
261255

262256
return groups && groupsAccessor && this.state.assignedToGroups !== null ? (
@@ -278,10 +272,19 @@ class EditAssignmentForm extends Component {
278272

279273
{groupsAccessor && (
280274
<AssignmentFormGroupsList
281-
groups={this.state.open ? this.allGroups : this.myGroups}
275+
groups={
276+
this.state.open
277+
? getAllGroups(groups, groupsAccessor, locale)
278+
: getUserGroups(groups, userId, groupsAccessor, locale)
279+
}
282280
groupsAccessor={groupsAccessor}
283281
isOpen={this.state.open}
284-
toggleOpenState={this.allGroups.length !== this.myGroups.length ? this.toggleOpenState : null}
282+
toggleOpenState={
283+
getAllGroups(groups, groupsAccessor, locale).length !==
284+
getUserGroups(groups, userId, groupsAccessor, locale).length
285+
? this.toggleOpenState
286+
: null
287+
}
285288
/>
286289
)}
287290

@@ -631,7 +634,7 @@ const warn = ({ groups, canViewJudgeOutputs }, { groupsAccessor, alreadyAssigned
631634
);
632635
}
633636

634-
if (groupsAccessor) {
637+
if (groups && groupsAccessor) {
635638
let alreadyAssigned = false;
636639
alreadyAssignedGroups.forEach(id => {
637640
const key = `id${id}`;

src/components/forms/EditPipelineForm/EditPipelineForm.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ import { createGetPipelineFiles } from '../../../redux/selectors/pipelineFiles';
1717

1818
class EditPipelineForm extends Component {
1919
componentDidMount = () => this.props.loadAsync();
20-
componentWillReceiveProps = props => {
21-
if (this.props.pipeline.id !== props.pipeline.id) {
22-
props.loadAsync();
20+
21+
componentDidUpdate(prevProps) {
22+
if (this.props.pipeline.id !== prevProps.pipeline.id) {
23+
this.props.loadAsync();
2324
}
24-
};
25+
}
2526

2627
static loadAsync = ({ pipeline }, dispatch) => {
2728
Promise.all([dispatch(fetchSupplementaryFilesForPipeline(pipeline.id))]);

src/components/forms/Fields/MarkdownTextAreaField.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ if (canUseDOM) {
1414
}
1515

1616
class MarkdownTextAreaField extends Component {
17-
componentWillMount = () => {
18-
const { showPreview = false } = this.props;
19-
this.setState({
20-
showPreview,
21-
});
17+
state = {
18+
showPreview: this.props.showPreview || false,
2219
};
2320

2421
shouldComponentUpdate() {

src/components/forms/SubmitButton/SubmitButton.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import Button from '../../widgets/FlatButton';
55
import { SendIcon, LoadingIcon, SuccessIcon, WarningIcon } from '../../icons';
66

77
class SubmitButton extends Component {
8-
componentWillMount() {
9-
this.setState({ saved: false });
10-
}
8+
state = { saved: false };
119

1210
componentWillUnmount() {
1311
this.unmounted = true;

src/components/helpers/ResourceRenderer/ResourceRenderer.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,8 @@ const shallowResourcesEqual = (oldResources, newResources) => {
7171
* for the loaded state.
7272
*/
7373
class ResourceRenderer extends Component {
74-
componentWillMount = () => {
75-
// Reset caching variables ...
76-
this.oldResources = null;
77-
this.oldData = null;
78-
};
79-
80-
componentWillUpdate = () => {
81-
// Reset caching variables ...
82-
this.oldResources = null;
83-
this.oldData = null;
84-
};
74+
oldResources = null;
75+
oldData = null;
8576

8677
// Perform rendering of the childs whilst keeping resource data cached ...
8778
renderReady = resources => {

src/components/helpers/SimpleTextSearch/SimpleTextSearch.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,14 @@ import { Button, FormGroup, ControlLabel, FormControl, InputGroup } from 'react-
55
import { LoadingIcon, SearchIcon, WarningIcon } from '../../icons';
66

77
class SimpleTextSearch extends Component {
8-
state = { query: this.props.query };
8+
state = { query: this.props.query, lastPropsQuery: this.props.query };
99

1010
queryChangeHandler = ev => {
1111
this.setState({ query: ev.target.value });
1212
};
1313

14-
componentWillReceiveProps(newProps) {
15-
if (this.props.query !== newProps.query) {
16-
this.setState({ query: newProps.query });
17-
}
14+
static getDerivedStateFromProps(props, state) {
15+
return props.query !== state.lastPropsQuery ? { query: props.query, lastPropsQuery: props.query } : null;
1816
}
1917

2018
render() {

src/components/layout/Sidebar/Sidebar.js

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,45 @@ import styles from './sidebar.less';
2121

2222
const getUserData = defaultMemoize(user => getJsData(user));
2323

24-
const Sidebar = ({
25-
loggedInUser,
26-
studentOf,
27-
supervisorOf,
28-
currentUrl,
29-
instances,
30-
small = false,
31-
links: {
32-
FAQ_URL,
33-
LOGIN_URI,
34-
REGISTRATION_URI,
35-
DASHBOARD_URI,
36-
INSTANCE_URI_FACTORY,
37-
GROUP_DETAIL_URI_FACTORY,
38-
EXERCISES_URI,
39-
PIPELINES_URI,
40-
ARCHIVE_URI,
41-
SIS_INTEGRATION_URI,
24+
const Sidebar = (
25+
{
26+
loggedInUser,
27+
studentOf,
28+
supervisorOf,
29+
currentUrl,
30+
instances,
31+
small = false,
32+
links: {
33+
FAQ_URL,
34+
LOGIN_URI,
35+
REGISTRATION_URI,
36+
DASHBOARD_URI,
37+
INSTANCE_URI_FACTORY,
38+
GROUP_DETAIL_URI_FACTORY,
39+
EXERCISES_URI,
40+
PIPELINES_URI,
41+
ARCHIVE_URI,
42+
SIS_INTEGRATION_URI,
43+
},
44+
intl: { locale },
4245
},
43-
intl: { locale },
44-
}) => {
46+
{ isActive }
47+
) => {
4548
const user = getUserData(loggedInUser);
4649
const role = safeGet(user, ['privateData', 'role']);
50+
const createLink = item => GROUP_DETAIL_URI_FACTORY(getId(item));
51+
const studentOfItems =
52+
studentOf &&
53+
studentOf.size > 0 &&
54+
studentOf
55+
.toList()
56+
.sort((a, b) => getLocalizedResourceName(a, locale).localeCompare(getLocalizedResourceName(b, locale), locale));
57+
const supervisorOfItems =
58+
supervisorOf &&
59+
supervisorOf.size > 0 &&
60+
supervisorOf
61+
.toList()
62+
.sort((a, b) => getLocalizedResourceName(a, locale).localeCompare(getLocalizedResourceName(b, locale), locale));
4763

4864
return (
4965
<aside className={classnames(['main-sidebar', styles.mainSidebar])}>
@@ -95,37 +111,31 @@ const Sidebar = ({
95111
/>
96112
))}
97113

98-
{studentOf && studentOf.size > 0 && (
114+
{studentOfItems && (
99115
<MenuGroup
100116
title={<FormattedMessage id="app.sidebar.menu.memberOfGroups" defaultMessage="Member of Groups" />}
101-
items={studentOf
102-
.toList()
103-
.sort((a, b) =>
104-
getLocalizedResourceName(a, locale).localeCompare(getLocalizedResourceName(b, locale), locale)
105-
)}
117+
items={studentOfItems}
106118
notifications={EMPTY_OBJ}
107119
icon={'user-circle'}
108120
currentPath={currentUrl}
109-
createLink={item => GROUP_DETAIL_URI_FACTORY(getId(item))}
121+
createLink={createLink}
110122
forceOpen={false}
123+
isActive={studentOfItems.find(item => isActive(createLink(item))) !== undefined}
111124
/>
112125
)}
113126

114-
{isSupervisorRole(role) && (
127+
{isSupervisorRole(role) && supervisorOfItems && (
115128
<MenuGroup
116129
title={
117130
<FormattedMessage id="app.sidebar.menu.supervisorOfGroups" defaultMessage="Supervisor of Groups" />
118131
}
119132
notifications={EMPTY_OBJ}
120-
items={supervisorOf
121-
.toList()
122-
.sort((a, b) =>
123-
getLocalizedResourceName(a, locale).localeCompare(getLocalizedResourceName(b, locale), locale)
124-
)}
133+
items={supervisorOfItems}
125134
icon="graduation-cap"
126135
currentPath={currentUrl}
127-
createLink={item => GROUP_DETAIL_URI_FACTORY(getId(item))}
136+
createLink={createLink}
128137
forceOpen={false}
138+
isActive={supervisorOfItems.find(item => isActive(createLink(item))) !== undefined}
129139
/>
130140
)}
131141

@@ -190,4 +200,8 @@ Sidebar.propTypes = {
190200
intl: intlShape,
191201
};
192202

203+
Sidebar.contextTypes = {
204+
isActive: PropTypes.func,
205+
};
206+
193207
export default withLinks(injectIntl(Sidebar));

0 commit comments

Comments
 (0)