1
1
import * as React from 'react' ;
2
2
import classnames from 'classnames' ;
3
3
import { flatten , values } from 'lodash' ;
4
- import LinkModuleCodes from 'views/components/LinkModuleCodes ' ;
4
+ import { connect } from 'react-redux ' ;
5
5
6
- import { ModuleCode , PrereqTree } from 'types/modules ' ;
6
+ import { getModuleCondensed } from 'selectors/moduleBank ' ;
7
7
8
+ import { ModuleCode , PrereqTree , ModuleCondensed } from 'types/modules' ;
9
+ import { State } from 'types/state' ;
8
10
import { notNull } from 'types/utils' ;
11
+
12
+ import LinkModuleCodes from 'views/components/LinkModuleCodes' ;
9
13
import styles from './ModuleTree.scss' ;
10
14
11
15
type Props = {
12
16
moduleCode : ModuleCode ;
13
17
fulfillRequirements ?: readonly ModuleCode [ ] ;
14
18
prereqTree ?: PrereqTree ;
19
+
20
+ getModuleCondensed : ( moduleCode : ModuleCode ) => ModuleCondensed | undefined ;
15
21
} ;
16
22
17
23
interface TreeDisplay {
18
24
layer : number ;
19
25
node : PrereqTree ;
20
26
isPrereq ?: boolean ;
27
+
28
+ getModuleCondensed : ( moduleCode : ModuleCode ) => ModuleCondensed | undefined ;
21
29
}
22
30
23
31
const GRADE_REQUIREMENT_SEPARATOR = ':' ;
@@ -36,7 +44,10 @@ const formatConditional = (node: PrereqTree) => {
36
44
return 'all of' ;
37
45
} ;
38
46
39
- type NodeName = { prefix ?: string ; name : string } ;
47
+ type NodeName = {
48
+ prefix ?: string ;
49
+ name : string ;
50
+ } ;
40
51
const nodeName = ( node : PrereqTree ) : NodeName => {
41
52
if ( typeof node !== 'string' ) {
42
53
return { name : Object . keys ( node ) [ 0 ] } ;
@@ -69,11 +80,15 @@ const unwrapLayer = (node: PrereqTree) => {
69
80
return flatten ( values ( node ) . filter ( notNull ) ) ;
70
81
} ;
71
82
72
- const Branch : React . FC < { nodes : PrereqTree [ ] ; layer : number } > = ( props ) => (
83
+ const Branch : React . FC < {
84
+ nodes : PrereqTree [ ] ;
85
+ layer : number ;
86
+ getModuleCondensed : ( moduleCode : ModuleCode ) => ModuleCondensed | undefined ;
87
+ } > = ( props ) => (
73
88
< ul className = { styles . tree } >
74
89
{ props . nodes . map ( ( child , idx ) => (
75
90
< li className = { styles . branch } key = { typeof child === 'string' ? nodeName ( child ) . name : idx } >
76
- < Tree node = { child } layer = { props . layer } />
91
+ < Tree node = { child } layer = { props . layer } getModuleCondensed = { props . getModuleCondensed } />
77
92
</ li >
78
93
) ) }
79
94
</ ul >
@@ -95,14 +110,24 @@ const Tree: React.FC<TreeDisplay> = (props) => {
95
110
>
96
111
{ formatConditional ( node ) }
97
112
</ div >
98
- < Branch nodes = { unwrapLayer ( node ) } layer = { layer + 1 } />
113
+ < Branch
114
+ nodes = { unwrapLayer ( node ) }
115
+ layer = { layer + 1 }
116
+ getModuleCondensed = { props . getModuleCondensed }
117
+ />
99
118
</ >
100
119
) ;
101
120
}
102
121
122
+ // Check if module name still exists in database
123
+ const moduleActive = props . getModuleCondensed ( name ) ;
124
+
125
+ // If module is deprecated (undefined) then we grey out, remove color classname
126
+
103
127
return (
104
128
< div
105
- className = { classnames ( styles . node , styles . moduleNode , `hoverable color-${ layer } ` , {
129
+ className = { classnames ( styles . node , styles . moduleNode , {
130
+ [ `hoverable color-${ layer } ` ] : ! ! moduleActive ,
106
131
[ styles . prereqNode ] : isPrereq ,
107
132
} ) }
108
133
>
@@ -112,7 +137,7 @@ const Tree: React.FC<TreeDisplay> = (props) => {
112
137
) ;
113
138
} ;
114
139
115
- const ModuleTree : React . FC < Props > = ( props ) => {
140
+ export const ModuleTreeComponent : React . FC < Props > = ( props ) => {
116
141
const { fulfillRequirements, prereqTree, moduleCode } = props ;
117
142
118
143
return (
@@ -126,7 +151,12 @@ const ModuleTree: React.FC<Props> = (props) => {
126
151
key = { fulfilledModule }
127
152
className = { classnames ( styles . branch , styles . prereqBranch ) }
128
153
>
129
- < Tree layer = { 0 } node = { fulfilledModule } isPrereq />
154
+ < Tree
155
+ layer = { 0 }
156
+ node = { fulfilledModule }
157
+ isPrereq
158
+ getModuleCondensed = { props . getModuleCondensed }
159
+ />
130
160
</ li >
131
161
) ) }
132
162
</ ul >
@@ -137,9 +167,15 @@ const ModuleTree: React.FC<Props> = (props) => {
137
167
138
168
< ul className = { classnames ( styles . tree , styles . root ) } >
139
169
< li className = { classnames ( styles . branch ) } >
140
- < Tree layer = { 1 } node = { moduleCode } />
141
-
142
- { prereqTree && < Branch nodes = { [ prereqTree ] } layer = { 2 } /> }
170
+ < Tree layer = { 1 } node = { moduleCode } getModuleCondensed = { props . getModuleCondensed } />
171
+
172
+ { prereqTree && (
173
+ < Branch
174
+ nodes = { [ prereqTree ] }
175
+ layer = { 2 }
176
+ getModuleCondensed = { props . getModuleCondensed }
177
+ />
178
+ ) }
143
179
</ li >
144
180
</ ul >
145
181
</ div >
@@ -170,4 +206,8 @@ const ModuleTree: React.FC<Props> = (props) => {
170
206
) ;
171
207
} ;
172
208
173
- export default ModuleTree ;
209
+ const mapStateToProps = connect ( ( state : State ) => ( {
210
+ getModuleCondensed : getModuleCondensed ( state ) ,
211
+ } ) ) ;
212
+
213
+ export default mapStateToProps ( ModuleTreeComponent ) ;
0 commit comments