Skip to content

Commit 080ed69

Browse files
committed
Major React 18 update for the base app and most pages and components.
1 parent 9fb06ac commit 080ed69

21 files changed

+1583
-1936
lines changed

assets/js/Components/AboutModal.js

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,30 @@ import { CloseButton } from '@instructure/ui-buttons'
66
import AboutPage from './AboutPage'
77

88

9-
class AboutModal extends React.Component {
10-
constructor(props) {
11-
super(props)
12-
}
13-
14-
render() {
15-
return (
16-
<Modal
17-
open={true}
18-
size="large"
19-
label={this.props.t('label.about')}>
20-
<Modal.Header padding="0 medium">
21-
<Flex>
22-
<Flex.Item shouldGrow shouldShrink>
23-
<Heading>{this.props.t('label.about')}</Heading>
24-
</Flex.Item>
25-
<Flex.Item>
26-
<CloseButton
27-
placement="end"
28-
offset="small"
29-
screenReaderLabel={this.props.t('srlabel.close')}
30-
onClick={() => this.props.handleModal(null)}
31-
/>
32-
</Flex.Item>
33-
</Flex>
34-
</Modal.Header>
35-
<Modal.Body padding="small medium">
36-
<AboutPage t={this.props.t} settings={this.props.settings} />
37-
</Modal.Body>
38-
</Modal>
39-
)
40-
}
41-
}
42-
43-
export default AboutModal
9+
export default function AboutModel({ t, settings, handleModal }) {
10+
return (
11+
<Modal
12+
open={true}
13+
size="large"
14+
label={t('label.about')}>
15+
<Modal.Header padding="0 medium">
16+
<Flex>
17+
<Flex.Item shouldGrow shouldShrink>
18+
<Heading>{t('label.about')}</Heading>
19+
</Flex.Item>
20+
<Flex.Item>
21+
<CloseButton
22+
placement="end"
23+
offset="small"
24+
screenReaderLabel={t('srlabel.close')}
25+
onClick={() => handleModal(null)}
26+
/>
27+
</Flex.Item>
28+
</Flex>
29+
</Modal.Header>
30+
<Modal.Body padding="small medium">
31+
<AboutPage t={t} settings={settings} />
32+
</Modal.Body>
33+
</Modal>
34+
)
35+
}

assets/js/Components/AboutPage.js

Lines changed: 100 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react'
1+
import React, { useState, useEffect } from 'react'
22
import { Heading } from '@instructure/ui-heading'
33
import { View } from '@instructure/ui-view'
44
import { Text } from '@instructure/ui-text'
@@ -10,133 +10,126 @@ import * as Html from '../Services/Html'
1010
import ReactHtmlParser from 'react-html-parser'
1111
import Classes from '../../css/theme-overrides.css'
1212

13-
class AboutPage extends React.Component {
13+
export default function AboutPage({ t, settings }) {
14+
const [expandDetails, setExpandDetails] = useState(false)
15+
const [issues, setIssues] = useState({"error": [], "suggestion": []})
1416

15-
constructor(props) {
16-
super(props)
17-
18-
this.state = {
19-
expandDetails: false
20-
}
21-
22-
this.handleDetailsToggle = this.handleDetailsToggle.bind(this)
17+
const handleDetailsToggle = () => {
18+
setExpandDetails(!expandDetails)
2319
}
2420

25-
handleDetailsToggle() {
26-
this.setState({ expandDetails: !this.state.expandDetails })
27-
}
21+
useEffect(() => {
22+
const suggestionTypes = (settings.suggestionRuleIds != null) ? settings.suggestionRuleIds : ''
2823

29-
render() {
30-
const suggestionTypes = (this.props.settings.suggestionRuleIds != null) ? this.props.settings.suggestionRuleIds : ''
31-
this.issues = {
24+
let currentIssues = {
3225
"error": [],
3326
"suggestion": []
3427
}
3528

3629
issueRuleIds.forEach(issue => {
3730
if (suggestionTypes.includes(issue)) {
38-
this.issues.suggestion.push(issue)
31+
currentIssues.suggestion.push(issue)
3932
} else {
40-
this.issues.error.push(issue)
33+
currentIssues.error.push(issue)
4134
}
4235
})
4336

44-
return (
45-
<View as="div">
46-
<Flex>
47-
<Flex.Item shouldShrink shouldGrow align="start">
37+
setIssues(currentIssues)
38+
}, [])
39+
40+
return (
41+
<View as="div">
42+
<Flex>
43+
<Flex.Item shouldShrink shouldGrow align="start">
44+
<View as="div">
45+
<Text as="p" lineHeight="default">
46+
{ReactHtmlParser(t('about.description'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
47+
</Text>
48+
</View>
49+
<View as="div" margin="large 0">
50+
<Text as="strong">{t('about.disclaimer_title')}</Text>
51+
<Text as="p" weight="normal" lineHeight="default">
52+
{ReactHtmlParser(t('about.disclaimer'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
53+
</Text>
54+
</View>
55+
</Flex.Item>
56+
<Flex.Item size="400px" align="start" padding="small 0 0 large">
57+
<View as="div">
58+
{ReactHtmlParser(t('about.video_embed'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
59+
</View>
60+
<View as="div" textAlign="center">
61+
{ReactHtmlParser(t('about.video_link'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
62+
</View>
63+
64+
<View as="div" margin="large 0">
4865
<View as="div">
49-
<Text as="p" lineHeight="default">
50-
{ReactHtmlParser(this.props.t('about.description'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
51-
</Text>
66+
<Text as="strong">{t('about.resources')}</Text>
5267
</View>
53-
<View as="div" margin="large 0">
54-
<Text as="strong">{this.props.t('about.disclaimer_title')}</Text>
55-
<Text as="p" weight="normal" lineHeight="default">
56-
{ReactHtmlParser(this.props.t('about.disclaimer'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
57-
</Text>
68+
<View as="div" position="relative" textAlign="start" insetBlockStart="1vh">
69+
<View>
70+
{ReactHtmlParser(t('about.user_guide_link'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
71+
</View>
5872
</View>
59-
</Flex.Item>
60-
<Flex.Item size="400px" align="start" padding="small 0 0 large">
73+
</View>
74+
75+
<View as="div" margin="large 0">
6176
<View as="div">
62-
{ReactHtmlParser(this.props.t('about.video_embed'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
77+
<Text as="strong">{t('about.policies')}</Text>
6378
</View>
64-
<View as="div" textAlign="center">
65-
{ReactHtmlParser(this.props.t('about.video_link'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
79+
<View as="div" position="relative" textAlign="start" insetBlockStart="1vh">
80+
{ReactHtmlParser(t('about.youtube_terms'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
81+
</View>
82+
<View as="div" position="relative" textAlign="start" insetBlockStart="1vh">
83+
{ReactHtmlParser(t('about.google_privacy'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
6684
</View>
85+
</View>
86+
</Flex.Item>
87+
</Flex>
88+
<View as="div" margin="medium 0" display="inline-block" width="100vw">
89+
<ToggleDetails
90+
summary={t('label.btn.udoit_details')}
91+
expanded={expandDetails}
92+
fluidWidth={true}
93+
onToggle={handleDetailsToggle}>
6794

68-
<View as="div" margin="large 0">
69-
<View as="div">
70-
<Text as="strong">{this.props.t('about.resources')}</Text>
71-
</View>
72-
<View as="div" position="relative" textAlign="start" insetBlockStart="1vh">
73-
<View>
74-
{ReactHtmlParser(this.props.t('about.user_guide_link'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
95+
{Object.keys(issues).map((issueType) => {
96+
const type = issues[issueType]
97+
return (
98+
<View as="div" margin="small large" key={issueType}>
99+
<View padding="x-small" margin="none">
100+
<Heading level="h3">
101+
{('error' === issueType) ? <IconNoLine className={Classes.error} /> : <IconInfoBorderlessLine className={Classes.suggestion} />}&nbsp;
102+
{t(`label.plural.${issueType}`)}
103+
</Heading><br />
75104
</View>
105+
{type.map((rule) => {
106+
if (!t(`rule.example.${rule}`).includes('rule.example')) {
107+
var showExample = true
108+
}
109+
return (
110+
<ToggleDetails key={rule} summary={
111+
<Heading level="h4">
112+
{t(`rule.label.${rule}`)}
113+
</Heading>}
114+
>
115+
<View as="div" margin="small 0" background="primary" padding="small" shadow="above">
116+
{ReactHtmlParser(t(`rule.desc.${rule}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}
117+
{
118+
(showExample) &&
119+
<View as="div">{ReactHtmlParser(t(`rule.example.${rule}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, settings) })}</View>
120+
}
121+
</View>
122+
</ToggleDetails>
123+
)
124+
})}
76125
</View>
77-
</View>
78-
79-
<View as="div" margin="large 0">
80-
<View as="div">
81-
<Text as="strong">{this.props.t('about.policies')}</Text>
82-
</View>
83-
<View as="div" position="relative" textAlign="start" insetBlockStart="1vh">
84-
{ReactHtmlParser(this.props.t('about.youtube_terms'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
85-
</View>
86-
<View as="div" position="relative" textAlign="start" insetBlockStart="1vh">
87-
{ReactHtmlParser(this.props.t('about.google_privacy'), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
88-
</View>
89-
</View>
90-
</Flex.Item>
91-
</Flex>
92-
<View as="div" margin="medium 0" display="inline-block" width="100vw">
93-
<ToggleDetails
94-
summary={this.props.t('label.btn.udoit_details')}
95-
expanded={this.state.expandDetails}
96-
fluidWidth={true}
97-
onToggle={this.handleDetailsToggle}>
98-
99-
{Object.keys(this.issues).map((issueType) => {
100-
const type = this.issues[issueType]
101-
return (
102-
<View as="div" margin="small large" key={issueType}>
103-
<View padding="x-small" margin="none">
104-
<Heading level="h3">
105-
{('error' === issueType) ? <IconNoLine className={Classes.error} /> : <IconInfoBorderlessLine className={Classes.suggestion} />}&nbsp;
106-
{this.props.t(`label.plural.${issueType}`)}
107-
</Heading><br />
108-
</View>
109-
{type.map((rule) => {
110-
if (!this.props.t(`rule.example.${rule}`).includes('rule.example')) {
111-
var showExample = true
112-
}
113-
return (
114-
<ToggleDetails key={rule} summary={
115-
<Heading level="h4">
116-
{this.props.t(`rule.label.${rule}`)}
117-
</Heading>}
118-
>
119-
<View as="div" margin="small 0" background="primary" padding="small" shadow="above">
120-
{ReactHtmlParser(this.props.t(`rule.desc.${rule}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}
121-
{
122-
(showExample) &&
123-
<View as="div">{ReactHtmlParser(this.props.t(`rule.example.${rule}`), { preprocessNodes: (nodes) => Html.processStaticHtml(nodes, this.props.settings) })}</View>
124-
}
125-
</View>
126-
</ToggleDetails>
127-
)
128-
})}
129-
</View>
130-
)
131-
})}
132-
</ToggleDetails>
133-
</View>
134-
<View as="div" textAlign="end">
135-
<Text weight="light">{this.props.t('label.version')} {this.props.settings.versionNumber}</Text>
136-
</View>
126+
)
127+
})}
128+
</ToggleDetails>
137129
</View>
138-
)
139-
}
140-
}
141-
142-
export default AboutPage
130+
<View as="div" textAlign="end">
131+
<Text weight="light">{t('label.version')} {settings.versionNumber}</Text>
132+
</View>
133+
</View>
134+
)
135+
}

0 commit comments

Comments
 (0)