Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Julien Jerphanion
Rex Dri
Commits
1c435959
Commit
1c435959
authored
Sep 13, 2018
by
Florent Chehab
Browse files
Better than ever from poo
New fields
parent
ee9a98b3
Changes
8
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/university/modules/editors/Editor.js
View file @
1c435959
...
...
@@ -13,7 +13,6 @@ import Slide from '@material-ui/core/Slide';
import
MyComponent
from
'
../../../MyComponent
'
;
import
Alert
from
'
./Alert
'
;
import
dateToDateStr
from
'
../../../../utils/dateToDateStr
'
;
import
getObjModerationLevel
from
'
../../../../utils/getObjModerationLevels
'
;
import
SelectField
from
'
./fields/SelectField
'
;
...
...
@@ -22,8 +21,15 @@ function Transition(props) {
}
class
Editor
extends
MyComponent
{
formData
=
{};
formError
=
{};
fields
=
Object
();
addField
(
field
,
fieldMapping
)
{
this
.
fields
[
fieldMapping
]
=
field
;
}
removeField
(
fieldMapping
)
{
delete
this
.
fields
[
fieldMapping
];
}
state
=
{
alert
:
{
...
...
@@ -32,6 +38,40 @@ class Editor extends MyComponent {
lastSave
:
this
.
props
.
lastSave
,
}
formIsValid
()
{
// to override if you need to perform some checks at the form level
return
true
;
}
formFieldsHaveError
()
{
for
(
let
fieldKey
in
this
.
fields
)
{
const
field
=
this
.
fields
[
fieldKey
];
if
(
field
.
getHasError
())
{
return
true
;
}
}
return
false
;
}
getDataFromFields
()
{
let
data
=
Object
();
for
(
let
fieldKey
in
this
.
fields
)
{
const
field
=
this
.
fields
[
fieldKey
];
data
[
fieldKey
]
=
field
.
getValue
();
}
return
data
;
}
handleSaveEditor
()
{
if
(
this
.
formIsValid
())
{
const
tmp
=
Object
.
assign
({},
this
.
props
.
modelData
,
this
.
getDataFromFields
())
this
.
props
.
saveData
(
tmp
);
}
else
{
console
.
log
(
"
ici
"
)
}
}
myComponentDidUpdate
()
{
const
{
savingHasError
}
=
this
.
props
;
if
(
savingHasError
.
status
)
{
...
...
@@ -63,15 +103,6 @@ class Editor extends MyComponent {
})
}
setFormDataAndError
(
field
,
data
,
type
=
null
)
{
let
correctData
=
data
.
data
;
if
(
type
==
'
date
'
)
{
correctData
=
dateToDateStr
(
correctData
);
}
this
.
formData
[
field
]
=
correctData
;
this
.
formError
[
field
]
=
data
.
hasError
;
}
renderEditor
()
{
return
(
<
div
>
No
editor
set
<
/div>
)
}
...
...
@@ -85,8 +116,9 @@ class Editor extends MyComponent {
<
SelectField
label
=
{
"
Niveau de modération pour ce module
"
}
required
=
{
true
}
value
=
{
modelData
.
obj_moderation_level
}
fieldMapping
=
{
"
obj_moderation_level
"
}
options
=
{
possibleObjModeration
}
onChan
ge
=
{
(
data
)
=>
this
.
setFormDataAndError
(
'
obj_moderation_level
'
,
data
)
}
formMana
ge
r
=
{
this
}
/
>
)
}
else
{
...
...
@@ -136,6 +168,7 @@ Editor.propTypes = {
classes
:
PropTypes
.
object
.
isRequired
,
clearSaveError
:
PropTypes
.
func
.
isRequired
,
savingHasError
:
PropTypes
.
bool
.
isRequired
,
saveData
:
PropTypes
.
func
.
isRequired
,
};
Editor
.
defaultProps
=
{
...
...
frontend/src/components/university/modules/editors/UniversitySemestersDatesEditor.js
View file @
1c435959
...
...
@@ -24,11 +24,7 @@ const styles = theme => ({
class
UniversitySemestersDatesEditor
extends
Editor
{
handleSaveEditor
()
{
const
tmp
=
Object
.
assign
({},
this
.
props
.
modelData
,
this
.
formData
)
this
.
props
.
saveData
(
tmp
);
}
renderEditor
()
{
const
{
modelData
}
=
this
.
props
;
...
...
@@ -36,28 +32,34 @@ class UniversitySemestersDatesEditor extends Editor {
<
div
>
{
this
.
renderObjModerationLevelField
()}
<
DateField
label
=
{
"
Date de début du semestre de printemps
"
}
selectedDate
=
{
modelData
.
spring_begin
}
onChange
=
{(
data
)
=>
this
.
setFormDataAndError
(
'
spring_begin
'
,
data
,
'
date
'
)}
value
=
{
modelData
.
spring_begin
}
formManager
=
{
this
}
fieldMapping
=
{
'
spring_begin
'
}
/
>
<
DateField
label
=
{
"
Date de fin du semestre de printemps
"
}
selectedDate
=
{
modelData
.
spring_end
}
onChange
=
{(
data
)
=>
this
.
setFormDataAndError
(
'
spring_end
'
,
data
,
'
date
'
)}
value
=
{
modelData
.
spring_end
}
formManager
=
{
this
}
fieldMapping
=
{
'
spring_end
'
}
/
>
<
DateField
label
=
{
"
Date de début du semestre d'automne
"
}
selectedDate
=
{
modelData
.
autumn_begin
}
onChange
=
{(
data
)
=>
this
.
setFormDataAndError
(
'
autumn_begin
'
,
data
,
'
date
'
)}
value
=
{
modelData
.
autumn_begin
}
formManager
=
{
this
}
fieldMapping
=
{
'
autumn_begin
'
}
/
>
<
DateField
label
=
{
"
Date de fin du semestre d'automne
"
}
selectedDate
=
{
modelData
.
autumn_end
}
onChange
=
{(
data
)
=>
this
.
setFormDataAndError
(
'
autumn_end
'
,
data
,
'
date
'
)}
value
=
{
modelData
.
autumn_end
}
formManager
=
{
this
}
fieldMapping
=
{
'
autumn_end
'
}
/
>
<
MarkdownField
label
=
{
"
Éventuel commentaire associé à ces informations
"
}
maxLength
=
{
100
}
value
=
{
modelData
.
comment
}
onChange
=
{(
data
)
=>
this
.
setFormDataAndError
(
'
comment
'
,
data
)}
formManager
=
{
this
}
fieldMapping
=
{
'
comment
'
}
/
>
<
UsefulLinksField
label
=
{
"
Lien(s) utile(s) (ex : vers ces informations)
"
}
value
=
{
modelData
.
UsefulLinksField
}
onChange
=
{(
data
)
=>
this
.
setFormDataAndError
(
'
useful_links
'
,
data
)}
value
=
{
modelData
.
useful_links
}
formManager
=
{
this
}
fieldMapping
=
{
'
useful_links
'
}
/
>
<
/div
>
)
...
...
frontend/src/components/university/modules/editors/fields/DateField.js
View file @
1c435959
...
...
@@ -12,6 +12,9 @@ import format from 'date-fns/format';
import
KeyboardArrowLeftIcon
from
'
@material-ui/icons/KeyboardArrowLeft
'
;
import
KeyboardArrowRightIcon
from
'
@material-ui/icons/KeyboardArrowRight
'
;
import
FieldWrapper
from
'
./FieldWrapper
'
;
import
dateToDateStr
from
'
../../../../../utils/dateToDateStr
'
;
import
Field
from
'
./Field
'
;
const
styles
=
theme
=>
({
});
...
...
@@ -23,31 +26,19 @@ class LocalizedUtils extends DateFnsUtils {
}
}
class
DateField
extends
PureComponent
{
hasError
(
date
)
{
return
this
.
props
.
required
&&
!
date
;
}
class
DateField
extends
Field
{
state
=
{
selectedDate
:
this
.
props
.
selectedDate
,
hasError
:
this
.
hasError
(
this
.
props
.
selectedDate
)
getValue
()
{
return
dateToDateStr
(
this
.
state
.
value
);
}
componentDidMount
(){
// store the data in formData
this
.
handleDateChange
(
this
.
props
.
selectedDate
);
hasError
(
date
)
{
return
this
.
props
.
required
&&
!
date
;
}
handleDateChange
=
(
date
)
=>
{
const
newState
=
{
selectedDate
:
date
,
hasError
:
this
.
hasError
(
date
)
}
this
.
setState
(
newState
);
this
.
props
.
onChange
({
data
:
newState
.
selectedDate
,
hasError
:
newState
.
hasError
this
.
setState
({
value
:
date
,
});
}
...
...
@@ -64,7 +55,7 @@ class DateField extends PureComponent {
<
DatePicker
clearable
format
=
"
d MMM YYYY
"
value
=
{
this
.
state
.
selectedDat
e
}
value
=
{
this
.
state
.
valu
e
}
onChange
=
{
this
.
handleDateChange
}
clearLabel
=
"
vider
"
cancelLabel
=
"
annuler
"
...
...
@@ -78,15 +69,11 @@ class DateField extends PureComponent {
}
DateField
.
defaultProps
=
{
required
:
false
,
label
:
'
mon label
'
,
selectedDate
:
null
,
onChange
:
(
date
)
=>
console
.
log
(
'
Nouvelle date sélectionnée :
'
,
date
),
value
:
null
,
}
DateField
.
propTypes
=
{
selectedDate
:
PropTypes
.
instanceOf
(
Date
),
onChange
:
PropTypes
.
func
.
isRequired
,
value
:
PropTypes
.
instanceOf
(
Date
),
};
...
...
frontend/src/components/university/modules/editors/fields/Field.js
0 → 100644
View file @
1c435959
import
React
,
{
PureComponent
}
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
class
Field
extends
PureComponent
{
state
=
{
value
:
this
.
props
.
value
,
hasError
:
this
.
hasError
(
this
.
props
.
value
)
};
setState
(
newState
)
{
newState
.
hasError
=
this
.
hasError
(
newState
.
value
);
super
.
setState
(
newState
);
}
hasError
()
{
throw
Error
(
'
This methods has to be override in sub classes
'
)
}
getValue
()
{
// function to get the value, ready to send to server
// You might need to override this for weird formats such as Date.
return
this
.
state
.
value
;
}
getHasError
()
{
return
this
.
state
.
hasError
;
}
componentDidMount
()
{
this
.
props
.
formManager
.
addField
(
this
,
this
.
props
.
fieldMapping
);
}
componentWillUnmount
()
{
this
.
props
.
formManager
.
removeField
(
this
.
props
.
fieldMapping
);
}
}
Field
.
defaultProps
=
{
required
:
false
,
label
:
'
mon label
'
,
}
Field
.
propTypes
=
{
required
:
PropTypes
.
bool
.
isRequired
,
label
:
PropTypes
.
string
,
formManager
:
PropTypes
.
object
.
isRequired
,
fieldMapping
:
PropTypes
.
string
.
isRequired
};
export
default
Field
;
frontend/src/components/university/modules/editors/fields/MarkdownField.js
View file @
1c435959
...
...
@@ -12,20 +12,12 @@ import Typography from '@material-ui/core/Typography';
import
Markdown
from
'
../../../../shared/Markdown
'
;
import
LinkText
from
'
../../../../other/TextLink
'
;
import
Field
from
'
./Field
'
;
const
styles
=
theme
=>
({
})
class
MarkdownField
extends
React
.
Component
{
state
=
{
value
:
this
.
props
.
value
,
hasError
:
this
.
hasError
(
this
.
props
.
value
)
};
componentDidMount
()
{
// store the data in formData
this
.
handleChangeValue
(
this
.
props
.
value
);
}
class
MarkdownField
extends
Field
{
hasError
(
value
)
{
if
(
this
.
props
.
required
&&
value
==
''
)
{
...
...
@@ -44,21 +36,12 @@ class MarkdownField extends React.Component {
if
(
maxLength
&&
value
.
length
>
maxLength
+
1
)
{
value
=
value
.
substring
(
0
,
maxLength
+
1
);
}
const
newState
=
{
value
,
hasError
:
this
.
hasError
(
value
)
}
this
.
setState
(
newState
);
this
.
props
.
onChange
({
data
:
newState
.
value
,
hasError
:
newState
.
hasError
});
this
.
setState
({
value
});
}
render
()
{
const
{
classes
}
=
this
.
props
;
return
(
<
FieldWrapper
required
=
{
this
.
props
.
required
}
...
...
@@ -110,16 +93,12 @@ class MarkdownField extends React.Component {
MarkdownField
.
defaultProps
=
{
required
:
false
,
value
:
''
,
label
:
'
mon label
'
,
maxLength
:
0
,
}
MarkdownField
.
propTypes
=
{
required
:
PropTypes
.
bool
,
value
:
PropTypes
.
string
,
label
:
PropTypes
.
string
,
maxLength
:
PropTypes
.
number
};
...
...
frontend/src/components/university/modules/editors/fields/SelectField.js
View file @
1c435959
...
...
@@ -11,36 +11,20 @@ import Select from '@material-ui/core/Select';
import
TextField
from
'
@material-ui/core/TextField
'
;
import
Typography
from
'
@material-ui/core/Typography
'
;
import
Field
from
'
./Field
'
;
const
styles
=
theme
=>
({
})
class
SelectField
extends
React
.
Component
{
state
=
{
value
:
this
.
props
.
value
,
hasError
:
this
.
hasError
(
this
.
props
.
value
)
};
class
SelectField
extends
Field
{
hasError
(
value
)
{
if
(
this
.
props
.
required
&&
!
value
)
{
return
true
;
}
else
{
return
false
;
}
return
this
.
props
.
required
&&
!
value
;
}
handleChangeValue
=
(
value
)
=>
{
const
newState
=
{
value
,
hasError
:
this
.
hasError
(
value
)
}
this
.
setState
(
newState
);
this
.
props
.
onChange
({
data
:
newState
.
value
,
hasError
:
newState
.
hasError
})
this
.
setState
({
value
});
}
render
()
{
const
{
classes
}
=
this
.
props
;
return
(
...
...
@@ -68,22 +52,16 @@ class SelectField extends React.Component {
SelectField
.
defaultProps
=
{
required
:
false
,
value
:
null
,
label
:
'
mon label
'
,
onChange
:
(
data
)
=>
console
.
log
(
'
Nouvelle sélection :
'
,
data
),
}
SelectField
.
propTypes
=
{
required
:
PropTypes
.
bool
,
value
:
PropTypes
.
oneOfType
([
PropTypes
.
number
,
PropTypes
.
string
]),
options
:
PropTypes
.
arrayOf
(
PropTypes
.
shape
({
label
:
PropTypes
.
string
.
isRequired
,
value
:
PropTypes
.
oneOfType
([
PropTypes
.
number
.
isRequired
,
PropTypes
.
string
.
isRequired
]),
disabled
:
PropTypes
.
bool
})),
label
:
PropTypes
.
string
,
onChange
:
PropTypes
.
func
.
isRequired
,
};
...
...
frontend/src/components/university/modules/editors/fields/TextField.js
View file @
1c435959
...
...
@@ -8,16 +8,12 @@ import FieldWrapper from './FieldWrapper';
import
{
TextField
as
MuiTextField
}
from
'
@material-ui/core/TextField
'
;
import
Typography
from
'
@material-ui/core/Typography
'
;
import
Field
from
'
./Field
'
;
const
styles
=
theme
=>
({
})
class
TextField
extends
React
.
Component
{
state
=
{
value
:
this
.
props
.
value
,
hasError
:
this
.
hasError
(
this
.
props
.
value
)
};
class
TextField
extends
Field
{
hasError
(
value
)
{
if
(
this
.
props
.
required
&&
value
==
''
)
{
return
true
;
...
...
@@ -36,15 +32,7 @@ class TextField extends React.Component {
value
=
value
.
substring
(
0
,
maxLength
+
1
);
}
const
newState
=
{
value
,
hasError
:
this
.
hasError
(
value
)
}
this
.
setState
(
newState
);
this
.
props
.
onChange
({
data
:
newState
.
value
,
hasError
:
newState
.
hasError
})
this
.
setState
({
value
});
}
...
...
@@ -78,19 +66,13 @@ class TextField extends React.Component {
TextField
.
defaultProps
=
{
required
:
false
,
value
:
''
,
label
:
'
mon label
'
,
maxLength
:
0
,
onChange
:
(
data
)
=>
console
.
log
(
'
Nouveau texte :
'
,
data
),
}
TextField
.
propTypes
=
{
required
:
PropTypes
.
bool
,
value
:
PropTypes
.
string
,
label
:
PropTypes
.
string
,
maxLength
:
PropTypes
.
number
,
onChange
:
PropTypes
.
func
.
isRequired
,
};
...
...
frontend/src/components/university/modules/editors/fields/UsefulLinksField.js
View file @
1c435959
...
...
@@ -14,6 +14,7 @@ import Button from '@material-ui/core/Button';
import
DeleteIcon
from
'
@material-ui/icons/Delete
'
;
import
KeyboardArrowDownIcon
from
'
@material-ui/icons/KeyboardArrowDown
'
;
import
KeyboardArrowUpIcon
from
'
@material-ui/icons/KeyboardArrowUp
'
;
import
Field
from
'
./Field
'
;
const
styles
=
theme
=>
({
container
:
{
...
...
@@ -26,18 +27,7 @@ const styles = theme => ({
}
})
class
UsefulLinksField
extends
React
.
Component
{
state
=
{
usefulLinks
:
this
.
props
.
usefulLinks
,
hasError
:
this
.
hasError
(
this
.
props
.
usefulLinks
),
errorMessage
:
''
,
}
componentDidMount
()
{
// store the data in formData
this
.
updateUsefulLinks
(
this
.
props
.
usefulLinks
);
}
class
UsefulLinksField
extends
Field
{
hasError
(
usefulLinks
)
{
if
(
this
.
props
.
required
&&
usefulLinks
.
length
==
0
)
{
...
...
@@ -47,21 +37,14 @@ class UsefulLinksField extends React.Component {
// TODO MORE
}
updateUsefulLinks
(
newUsefullLinks
)
{
const
newState
=
{
usefulLinks
:
newUsefullLinks
,
hasError
:
this
.
hasError
(
newUsefullLinks
)
}
this
.
setState
(
newState
);
this
.
props
.
onChange
({
data
:
newState
.
usefulLinks
,
hasError
:
newState
.
hasError
updateUsefulLinks
(
newUsefulLinks
)
{
this
.
setState
({
value
:
newUsefulLinks
,
});
}
handleUsefulLinkUrlChange
=
(
idx
,
evt
)
=>
{
const
newUsefulLinks
=
this
.
state
.
usefulLinks
.
map
((
usefulLink
,
sidx
)
=>
{
const
newUsefulLinks
=
this
.
state
.
value
.
map
((
usefulLink
,
sidx
)
=>
{
if
(
idx
!==
sidx
)
{
return
usefulLink
;
}
return
{
...
usefulLink
,
url
:
evt
.
target
.
value
};
});
...
...
@@ -70,7 +53,7 @@ class UsefulLinksField extends React.Component {
}
handleUsefulLinkDescriptionChange
=
(
idx
,
evt
)
=>
{
const
newUsefulLinks
=
this
.
state
.
usefulLinks
.
map
((
usefulLink
,
sidx
)
=>
{
const
newUsefulLinks
=
this
.
state
.
value
.
map
((
usefulLink
,
sidx
)
=>
{
if
(
idx
!==
sidx
)
{
return
usefulLink
;
}
return
{
...
usefulLink
,
description
:
evt
.
target
.
value
};
});
...
...
@@ -80,27 +63,27 @@ class UsefulLinksField extends React.Component {
handleAddUsefulLink
=
()
=>
{
this
.
updateUsefulLinks
(
this
.
state
.
usefulLinks
.
concat
([{
url
:
''
,
description
:
''
}]));
this
.
updateUsefulLinks
(
this
.
state
.
value
.
concat
([{
url
:
''
,
description
:
''
}]));
}
handleSwipeUsefulLink
=
(
idx
,
swipeIndexDiff
)
=>
{
const
{
usefulLinks
}
=
this
.
state
;
let
newUsefulLinks
=
usefulLinks
.
slice
();
const
{
value
}
=
this
.
state
;
let
newUsefulLinks
=
value
.
slice
();
const
b
=
usefulLinks
[
idx
+
swipeIndexDiff
];
const
b
=
value
[
idx
+
swipeIndexDiff
];
newUsefulLinks
[
idx
+
swipeIndexDiff
]
=
newUsefulLinks
[
idx
];
newUsefulLinks
[
idx
]
=
b
;
this
.
updateUsefulLinks
(
newUsefulLinks
);
}
handleRemoveUsefulLink
=
(
idx
)
=>
{
this
.
updateUsefulLinks
(
this
.
state
.
usefulLinks
.
filter
((
s
,
sidx
)
=>
idx
!==
sidx
));
this
.
updateUsefulLinks
(
this
.
state
.
value
.
filter
((
s
,
sidx
)
=>
idx
!==
sidx
));
}
areAllUsefulLinksUsed
=
()
=>
{
const
{
usefulLinks
}
=
this
.
state
;
for
(
let
idx
in
usefulLinks
)
{
const
el
=
usefulLinks
[
idx
];
const
{
value
}
=
this
.
state
;
for
(
let
idx
in
value
)
{
const
el
=
value
[
idx
];
if
(
el
.
url
==
''
||
el
.
description
==
''
)
{
return
false
;
}
...
...
@@ -111,7 +94,7 @@ class UsefulLinksField extends React.Component {
render
()
{
const
{
classes
}
=
this
.
props
;
const
nbOfUsefulLinks
=
this
.
state
.
usefulLinks
.
length
;
const
nbOfUsefulLinks
=
this
.
state
.
value
.
length
;
return
(
<
FieldWrapper
required
=
{
this
.
props
.
required
}
...
...
@@ -125,7 +108,7 @@ class UsefulLinksField extends React.Component {
justify
=
"
flex-start
"
alignItems
=
"
flex-start
"
>
{
this
.
state
.
usefulLinks
.
map
((
usefulLink
,
idx
)
=>
(
{
this
.
state
.
value
.
map
((
usefulLink
,
idx
)
=>
(