Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Rex Dri
Rex Dri
Commits
d199d7ab
Commit
d199d7ab
authored
Sep 16, 2018
by
Florent Chehab
Browse files
Bug removed in Module
UniversityScholarship & Country scholarship ready Moved to context provider for univ info
parent
62c55ee1
Changes
17
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/MyComponent.js
View file @
d199d7ab
...
...
@@ -114,14 +114,18 @@ class MyComponent extends Component {
loadPropsIfNeeded
()
{
this
.
propsThatNeedToBeFetch
().
map
((
propKey
)
=>
{
if
(
this
.
__apiAttr
&&
this
.
__apiAttr
[
propKey
])
{
this
.
props
.
fetchData
[
propKey
](
this
.
props
[
this
.
__apiAttr
[
propKey
]]);
}
else
{
this
.
props
.
fetchData
[
propKey
]();
}
this
.
performLoadProp
(
propKey
);
})
}
performLoadProp
(
propKey
)
{
if
(
this
.
__apiAttr
&&
this
.
__apiAttr
[
propKey
])
{
this
.
props
.
fetchData
[
propKey
](
this
.
props
[
this
.
__apiAttr
[
propKey
]]);
}
else
{
this
.
props
.
fetchData
[
propKey
]();
}
}
allFetchedDataAreReady
()
{
return
!
this
.
fetchAbleProps
.
some
((
propKey
)
=>
{
if
(
!
this
.
propIsUsable
(
propKey
))
{
...
...
frontend/src/components/pages/PageUniversity.js
View file @
d199d7ab
...
...
@@ -3,13 +3,14 @@ import PropTypes from 'prop-types';
import
Typography
from
'
@material-ui/core/Typography
'
;
import
Paper
from
'
@material-ui/core/Paper
'
;
import
MyComponent
from
'
../MyComponent
'
;
import
{
connect
}
from
"
react-redux
"
;
import
{
connect
}
from
"
react-redux
"
;
import
Dialog
from
'
@material-ui/core/Dialog
'
;
import
DialogActions
from
'
@material-ui/core/DialogActions
'
;
import
DialogTitle
from
'
@material-ui/core/DialogTitle
'
;
import
Button
from
'
@material-ui/core/Button
'
;
import
UniversityTemplate
from
'
../university/UniversityTemplate
'
;
import
UnivInfoProvider
from
'
../university/shared/UnivInfoProvider
'
;
import
{
NavLink
,
...
...
@@ -61,9 +62,12 @@ function renderFirstTimeHere() {
)
}
function renderDefaultView(univId) {
return (
<UniversityTemplate univId={univId} />
<UnivInfoProvider univId={univId}>
<UniversityTemplate />
</UnivInfoProvider>
);
}
...
...
frontend/src/components/shared/UnivContext.js
0 → 100644
View file @
d199d7ab
import
React
from
'
react
'
;
const
UnivContext
=
React
.
createContext
();
export
default
UnivContext
;
\ No newline at end of file
frontend/src/components/university/UniversityTemplate.js
View file @
d199d7ab
...
...
@@ -58,7 +58,7 @@ class UniversityTemplate extends React.Component {
};
render
()
{
const
{
classes
,
univId
,
width
}
=
this
.
props
;
const
{
classes
,
width
}
=
this
.
props
;
const
{
value
}
=
this
.
state
;
let
scroll
=
true
;
...
...
@@ -91,12 +91,12 @@ class UniversityTemplate extends React.Component {
<
Tab
label
=
"
Autres
"
icon
=
{
<
MoreHorizIcon
/>
}
/
>
<
/Tabs
>
<
/AppBar
>
<
TabContainer
visible
=
{
value
===
0
}
>
<
GeneralInfoTab
univId
=
{
univId
}
visible
=
{
value
===
0
}
/> </
TabContainer
>
{
/* {<TabContainer visible={value === 1}> <UniversityMoreTab
univId={univId}
visible={value === 1} /> </TabContainer>} */
}
{
/* {value === 2 && <TabContainer> <PreviousDeparturesTab
univId={univId}
/> </TabContainer>} */
}
{
<
TabContainer
visible
=
{
value
===
3
}
>
<
ScholarshipsTab
univId
=
{
univId
}
visible
=
{
value
===
3
}
/> </
TabContainer
>
}
{
/* {value === 4 && <TabContainer> <CampusesCitiesTab
univId={univId}
/> </TabContainer>} */
}
{
/* {value === 5 && <TabContainer> <MoreTab
univId={univId}
/> </TabContainer>} */
}
<
TabContainer
visible
=
{
value
===
0
}
>
<
GeneralInfoTab
visible
=
{
value
===
0
}
/> </
TabContainer
>
{
/* {<TabContainer visible={value === 1}> <UniversityMoreTab visible={value === 1} /> </TabContainer>} */
}
{
/* {value === 2 && <TabContainer> <PreviousDeparturesTab /> </TabContainer>} */
}
{
<
TabContainer
visible
=
{
value
===
3
}
>
<
ScholarshipsTab
visible
=
{
value
===
3
}
/> </
TabContainer
>
}
{
/* {value === 4 && <TabContainer> <CampusesCitiesTab /> </TabContainer>} */
}
{
/* {value === 5 && <TabContainer> <MoreTab /> </TabContainer>} */
}
<
/div
>
<
/div
>
...
...
@@ -106,7 +106,6 @@ class UniversityTemplate extends React.Component {
UniversityTemplate
.
propTypes
=
{
classes
:
PropTypes
.
object
.
isRequired
,
univId
:
PropTypes
.
string
.
isRequired
,
};
export
default
compose
(
...
...
frontend/src/components/university/editors/CountryScholarshipsEditor.js
0 → 100644
View file @
d199d7ab
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
compose
from
'
recompose/compose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
ScholarshipsEditor
from
'
../shared/ScholarshipsEditor
'
;
import
editorStyle
from
'
../shared/editorStyle
'
;
import
getMapStateToPropsForEditor
from
'
../shared/editorFunctions/getMapStateToPropsForEditor
'
;
import
getMapDispatchToPropsForEditor
from
'
../shared/editorFunctions/getMapDispatchToPropsForEditor
'
;
import
{
countryScholarshipsElSaveData
,
countryScholarshipsElSavingHasError
}
from
'
../../../generated/actions
'
;
const
styles
=
theme
=>
({
...
editorStyle
(
theme
)
});
class
CountryScholarshipsEditor
extends
ScholarshipsEditor
{
renderLinkedField
()
{
return
this
.
renderCountriesField
();
}
}
CountryScholarshipsEditor
.
propTypes
=
{
modelData
:
PropTypes
.
object
.
isRequired
,
};
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
connect
(
getMapStateToPropsForEditor
(
'
countryScholarshipsEl
'
),
getMapDispatchToPropsForEditor
(
countryScholarshipsElSaveData
,
countryScholarshipsElSavingHasError
)
)
)(
CountryScholarshipsEditor
);
\ No newline at end of file
frontend/src/components/university/editors/UniversityScholarshipsEditor.js
View file @
d199d7ab
...
...
@@ -4,7 +4,7 @@ import withStyles from '@material-ui/core/styles/withStyles';
import
compose
from
'
recompose/compose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
Editor
from
'
../shared/Editor
'
;
import
Scholarships
Editor
from
'
../shared/
Scholarships
Editor
'
;
import
editorStyle
from
'
../shared/editorStyle
'
;
...
...
@@ -20,64 +20,9 @@ const styles = theme => ({
...
editorStyle
(
theme
)
});
const
frequencyOptions
=
[
{
value
:
'
w
'
,
label
:
"
Il s'agit du montant hebdomadaire
"
},
{
value
:
'
m
'
,
label
:
"
Il s'agit du montant mensuel
"
},
{
value
:
'
s
'
,
label
:
"
Il s'agit du montant semestriel
"
},
{
value
:
'
y
'
,
label
:
"
Il s'agit du montant annuel
"
},
{
value
:
'
o
'
,
label
:
"
Il s'agit d'un montant donné une seule fois
"
}
]
class
UniversityScholarshipsEditor
extends
Editor
{
formHasError
()
{
let
messages
=
Array
();
const
formData
=
this
.
getDataFromFields
();
const
{
amount_min
,
amount_max
}
=
formData
;
console
.
log
(
formData
);
if
(
amount_min
!==
null
&&
amount_max
!==
null
&&
amount_max
<
amount_min
)
{
messages
.
push
(
"
La logique voudrait que la borne supérieure de la bourse soit... supérieure à la borne inférieure.
"
)
}
return
this
.
buildError
(
messages
);
}
renderEditor
()
{
return
(
<
div
>
{
this
.
renderObjModerationLevelField
()}
{
this
.
renderTitleField
()}
{
this
.
renderUniversitiesField
()}
{
this
.
renderTextField
({
required
:
true
,
label
:
"
Présentation succincte
"
,
maxLength
:
200
,
fieldMapping
:
'
type
'
,
})}
{
this
.
renderCurrencyField
({
label
:
"
Devise
"
,
required
:
false
,
fieldMapping
:
'
currency
'
})}
{
this
.
renderNumberField
({
label
:
"
Borne inférieure du montant de la bourse
"
,
minValue
:
0
,
fieldMapping
:
'
amount_min
'
,
})}
{
this
.
renderNumberField
({
label
:
"
Borne supérieure du montant de la bourse
"
,
minValue
:
0
,
fieldMapping
:
'
amount_max
'
,
})}
{
this
.
renderSelectField
({
label
:
"
Fréquence de la bourse
"
,
options
:
frequencyOptions
,
fieldMapping
:
'
frequency
'
,
})}
{
this
.
renderMarkdownField
({
label
:
"
Autres avantages
"
,
maxLength
:
500
,
formManager
:
this
,
fieldMapping
:
'
other_advantages
'
,
})}
{
this
.
renderCommentField
()}
{
this
.
renderUsefulLinksField
()}
<
/div
>
)
class
UniversityScholarshipsEditor
extends
ScholarshipsEditor
{
renderLinkedField
()
{
return
this
.
renderUniversitiesField
();
}
}
...
...
@@ -85,7 +30,6 @@ UniversityScholarshipsEditor.propTypes = {
modelData
:
PropTypes
.
object
.
isRequired
,
};
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
connect
(
...
...
frontend/src/components/university/modules/CountryDri.js
View file @
d199d7ab
...
...
@@ -72,7 +72,6 @@ class CountryDri extends Module {
{
countryDriItems
.
map
((
rawModelData
)
=>
(
<
GenericModule
visible
=
{
this
.
props
.
visible
}
buildTitle
=
{(
modelData
)
=>
modelData
.
title
}
rawModelData
=
{
rawModelData
}
parseRawModelData
=
{
parseRawModelData
}
...
...
frontend/src/components/university/modules/CountryScholarships.js
0 → 100644
View file @
d199d7ab
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
compose
from
'
recompose/compose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
__pick
from
'
lodash/pick
'
;
import
Module
from
'
../shared/Module
'
;
import
GenericModule
from
'
../shared/GenericModule
'
;
import
GenericGroupModule
from
'
../shared/GenericGroupModule
'
;
import
Scholarship
from
'
../shared/Scholarship
'
;
import
CountryScholarshipsEditor
from
'
../editors/CountryScholarshipsEditor
'
;
import
{
countryScholarshipsFetchData
,
countryScholarshipsInvalidated
,
}
from
'
../../../generated/actions
'
;
const
styles
=
theme
=>
({
});
function
renderCore
(
rawModelData
,
classes
,
outsideData
)
{
const
{
comment
,
frequency
,
currency
,
type
}
=
rawModelData
;
const
amountMin
=
rawModelData
.
amount_min
,
amountMax
=
rawModelData
.
amount_max
,
otherAdvantages
=
rawModelData
.
other_advantages
;
return
(
<
Scholarship
currency
=
{
currency
}
currencies
=
{
outsideData
.
currencies
}
frequency
=
{
frequency
}
type
=
{
type
}
amountMin
=
{
amountMin
}
amountMax
=
{
amountMax
}
otherAdvantages
=
{
otherAdvantages
}
comment
=
{
comment
}
/
>
)
}
function
parseRawModelData
(
rawModelData
)
{
// reverse serialization
const
modelData
=
__pick
(
rawModelData
,
[
"
id
"
,
"
title
"
,
"
type
"
,
"
currency
"
,
"
frequency
"
,
"
amount_min
"
,
"
amount_max
"
,
// "importance_level",
"
countries
"
,
"
comment
"
,
"
other_advantages
"
,
"
useful_links
"
,
"
obj_moderation_level
"
,
]);
return
modelData
;
}
class
CountryScholarships
extends
Module
{
myRender
()
{
const
countryScholarshipsItems
=
this
.
getFetchedData
(
'
countryScholarships
'
);
const
{
countries
,
currencies
,
classes
}
=
this
.
props
;
const
outsideData
=
{
countries
,
currencies
}
return
(
<
GenericGroupModule
groupTitle
=
{
`Bourses liées au pays (
${
this
.
props
.
country
.
name
}
)`
}
endPoint
=
{
"
countryScholarship
"
}
editor
=
{
CountryScholarshipsEditor
}
invalidateGroup
=
{
this
.
props
.
invalidateData
}
propsForEditor
=
{{
modelData
:
{
countries
:
[
this
.
props
.
countryId
],
importance_level
:
'
-
'
,
currency
:
'
EUR
'
,
obj_moderation_level
:
0
},
parseRawModelData
:
parseRawModelData
,
outsideData
:
outsideData
,
__apiAttr
:
this
.
props
.
countryId
,
}}
>
{
countryScholarshipsItems
.
map
((
rawModelData
)
=>
(
<
GenericModule
buildTitle
=
{(
modelData
)
=>
modelData
.
title
}
rawModelData
=
{
rawModelData
}
parseRawModelData
=
{
parseRawModelData
}
editor
=
{
CountryScholarshipsEditor
}
renderCore
=
{
renderCore
}
coreClasses
=
{
classes
}
outsideData
=
{
outsideData
}
moduleInGroupInfos
=
{{
isInGroup
:
true
,
invalidateGroup
:
()
=>
this
.
props
.
invalidateData
()
}}
__apiAttr
=
{
this
.
props
.
countryId
}
/
>
))
}
<
/GenericGroupModule
>
)
}
__apiAttr
=
{
countryScholarships
:
"
countryId
"
};
}
CountryScholarships
.
propTypes
=
{
classes
:
PropTypes
.
object
.
isRequired
,
theme
:
PropTypes
.
object
.
isRequired
,
countryId
:
PropTypes
.
string
.
isRequired
,
country
:
PropTypes
.
object
.
isRequired
,
countries
:
PropTypes
.
object
.
isRequired
,
currencies
:
PropTypes
.
object
.
isRequired
,
};
const
mapStateToProps
=
(
state
)
=>
{
return
{
countryScholarships
:
state
.
countryScholarships
,
};
};
const
mapDispatchToProps
=
(
dispatch
)
=>
{
return
{
fetchData
:
{
countryScholarships
:
(
countryId
)
=>
dispatch
(
countryScholarshipsFetchData
(
countryId
)),
},
invalidateData
:
(
resetObj
=
false
)
=>
dispatch
(
countryScholarshipsInvalidated
(
true
,
resetObj
))
};
};
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
connect
(
mapStateToProps
,
mapDispatchToProps
)
)(
CountryScholarships
);
\ No newline at end of file
frontend/src/components/university/modules/UniversityDri.js
View file @
d199d7ab
...
...
@@ -75,7 +75,6 @@ class UniversityDri extends Module {
{
univDriItems
.
map
((
rawModelData
)
=>
(
<
GenericModule
visible
=
{
this
.
props
.
visible
}
buildTitle
=
{(
modelData
)
=>
modelData
.
title
}
rawModelData
=
{
rawModelData
}
parseRawModelData
=
{
parseRawModelData
}
...
...
frontend/src/components/university/modules/UniversityGeneral.js
View file @
d199d7ab
...
...
@@ -95,7 +95,6 @@ class UniversityGeneral extends Module {
return
(
<
GenericModule
visible
=
{
this
.
props
.
visible
}
buildTitle
=
{()
=>
"
Présentation
"
}
rawModelData
=
{
univInfos
}
parseRawModelData
=
{
parseRawModelData
}
...
...
frontend/src/components/university/modules/UniversityScholarships.js
View file @
d199d7ab
...
...
@@ -91,7 +91,6 @@ class UniversityScholarships extends Module {
{
univScholarshipsItems
.
map
((
rawModelData
)
=>
(
<
GenericModule
visible
=
{
this
.
props
.
visible
}
buildTitle
=
{(
modelData
)
=>
modelData
.
title
}
rawModelData
=
{
rawModelData
}
parseRawModelData
=
{
parseRawModelData
}
...
...
@@ -117,6 +116,7 @@ UniversityScholarships.propTypes = {
theme
:
PropTypes
.
object
.
isRequired
,
univId
:
PropTypes
.
string
.
isRequired
,
universities
:
PropTypes
.
object
.
isRequired
,
currencies
:
PropTypes
.
object
.
isRequired
,
};
const
mapStateToProps
=
(
state
)
=>
{
...
...
frontend/src/components/university/shared/Module.js
View file @
d199d7ab
...
...
@@ -12,7 +12,7 @@ class Module extends MyComponent {
myComponentDidUpdate
()
{
this
.
fetchAbleProps
.
map
((
propKey
)
=>
{
if
(
this
.
props
[
propKey
].
invalidated
&&
!
this
.
props
[
propKey
].
isLoading
)
{
this
.
p
rops
.
fetchData
[
propKey
](
this
.
props
.
univId
);
this
.
p
erformLoadProp
(
propKey
);
}
})
}
...
...
frontend/src/components/university/shared/ScholarshipsEditor.js
0 → 100644
View file @
d199d7ab
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
Editor
from
'
./Editor
'
;
const
frequencyOptions
=
[
{
value
:
'
w
'
,
label
:
"
Il s'agit du montant hebdomadaire
"
},
{
value
:
'
m
'
,
label
:
"
Il s'agit du montant mensuel
"
},
{
value
:
'
s
'
,
label
:
"
Il s'agit du montant semestriel
"
},
{
value
:
'
y
'
,
label
:
"
Il s'agit du montant annuel
"
},
{
value
:
'
o
'
,
label
:
"
Il s'agit d'un montant donné une seule fois
"
}
]
class
ScholarshipEditor
extends
Editor
{
formHasError
()
{
let
messages
=
Array
();
const
formData
=
this
.
getDataFromFields
();
const
{
amount_min
,
amount_max
}
=
formData
;
console
.
log
(
formData
);
if
(
amount_min
!==
null
&&
amount_max
!==
null
&&
amount_max
<
amount_min
)
{
messages
.
push
(
"
La logique voudrait que la borne supérieure de la bourse soit... supérieure à la borne inférieure.
"
)
}
return
this
.
buildError
(
messages
);
}
renderEditor
()
{
return
(
<
div
>
{
this
.
renderObjModerationLevelField
()}
{
this
.
renderTitleField
()}
{
this
.
renderLinkedField
()}
{
this
.
renderTextField
({
required
:
true
,
label
:
"
Présentation succincte
"
,
maxLength
:
200
,
fieldMapping
:
'
type
'
,
})}
{
this
.
renderCurrencyField
({
label
:
"
Devise
"
,
required
:
false
,
fieldMapping
:
'
currency
'
})}
{
this
.
renderNumberField
({
label
:
"
Borne inférieure du montant de la bourse
"
,
minValue
:
0
,
fieldMapping
:
'
amount_min
'
,
})}
{
this
.
renderNumberField
({
label
:
"
Borne supérieure du montant de la bourse
"
,
minValue
:
0
,
fieldMapping
:
'
amount_max
'
,
})}
{
this
.
renderSelectField
({
label
:
"
Fréquence de la bourse
"
,
options
:
frequencyOptions
,
fieldMapping
:
'
frequency
'
,
})}
{
this
.
renderMarkdownField
({
label
:
"
Autres avantages
"
,
maxLength
:
500
,
formManager
:
this
,
fieldMapping
:
'
other_advantages
'
,
})}
{
this
.
renderCommentField
()}
{
this
.
renderUsefulLinksField
()}
<
/div
>
)
}
}
ScholarshipEditor
.
propTypes
=
{
modelData
:
PropTypes
.
object
.
isRequired
,
};
export
default
ScholarshipEditor
;
\ No newline at end of file
frontend/src/components/university/shared/UnivInfoConsumer.js
0 → 100644
View file @
d199d7ab
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
__pick
from
'
lodash/pick
'
;
import
UnivContext
from
'
../../shared/UnivContext
'
;
class
UnivInfoConsumer
extends
React
.
PureComponent
{
render
()
{
const
{
add
}
=
this
.
props
;
return
(
<
UnivContext
.
Consumer
>
{
value
=>
(
<
this
.
props
.
renderAndAddPropsTo
{...
__pick
(
value
,
add
)}
univId
=
{
value
.
univId
}
/
>
)
}
<
/UnivContext.Consumer
>
)
}
}
UnivInfoConsumer
.
defaultProps
=
{
add
:
[
''
],
}
UnivInfoConsumer
.
propTypes
=
{
add
:
PropTypes
.
arrayOf
(
PropTypes
.
string
).
isRequired
,
};
export
default
UnivInfoConsumer
;
\ No newline at end of file
frontend/src/components/university/shared/InfoProvider.js
→
frontend/src/components/university/shared/
Univ
InfoProvider.js
View file @
d199d7ab
...
...
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import
compose
from
'
recompose/compose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
__pick
from
'
lodash/pick
'
;
import
UnivContext
from
'
../../shared/UnivContext
'
;
import
MyComponent
from
'
../../MyComponent
'
;
...
...
@@ -16,56 +16,26 @@ import {
}
from
'
../../../generated/actions
'
;
class
InfoProvider
extends
MyComponent
{
class
Univ
InfoProvider
extends
MyComponent
{
myRender
()
{
const
{
city
,
country
}
=
this
.
getUnivCityAndCountry
(
this
.
props
.
univId
);
const
universities
=
this
.
getFetchedData
(
'
universities
'
);
const
countries
=
this
.
getFetchedData
(
'
countries
'
);
const
currencies
=
this
.
getFetchedData
(
'
currencies
'
);
const
{
univId
}
=
this
.
props
,
countryId
=
country
.
id
,
cityId
=
city
.
id
;
let
propsToAdd
=
{
univId
:
this
.
props
.
univId
,
visible
:
this
.
props
.
visible
};
if
(
this
.
props
.
add
)
{
this
.
props
.
add
.
map
(
(
key
)
=>
{
switch
(
key
)
{
case
'
universities
'
:
propsToAdd
[
key
]
=
universities
;
break
;
case
'
countries
'
:
propsToAdd
[
key
]
=
countries
;
break
;
case
'
currencies
'
:
propsToAdd
[
key
]
=
currencies
;
break
;
case
'
city
'
:
propsToAdd
[
key
]
=
city
;
break
;
case
'
country
'
:
propsToAdd
[
key
]
=
country
;
break
;
case
'
cityId
'
:
propsToAdd
[
key
]
=
city
.
id
;
break
;
case
'
countryId
'
:
propsToAdd
[
key
]
=
country
.
id
;
break
;
default
:
throw
Error
(
'
Not supported.
'
)
}
}