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
Julien Jerphanion
Rex Dri
Commits
8654dc22
Commit
8654dc22
authored
Sep 12, 2018
by
Florent Chehab
Browse files
Fields added need more work
parent
c8eb36a5
Changes
7
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/shared/FullScreenDialog.js
View file @
8654dc22
...
@@ -3,10 +3,7 @@ import PropTypes from 'prop-types';
...
@@ -3,10 +3,7 @@ import PropTypes from 'prop-types';
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
Button
from
'
@material-ui/core/Button
'
;
import
Button
from
'
@material-ui/core/Button
'
;
import
Dialog
from
'
@material-ui/core/Dialog
'
;
import
Dialog
from
'
@material-ui/core/Dialog
'
;
import
ListItemText
from
'
@material-ui/core/ListItemText
'
;
import
Paper
from
'
@material-ui/core/Paper
'
;
import
ListItem
from
'
@material-ui/core/ListItem
'
;
import
List
from
'
@material-ui/core/List
'
;
import
Divider
from
'
@material-ui/core/Divider
'
;
import
AppBar
from
'
@material-ui/core/AppBar
'
;
import
AppBar
from
'
@material-ui/core/AppBar
'
;
import
Toolbar
from
'
@material-ui/core/Toolbar
'
;
import
Toolbar
from
'
@material-ui/core/Toolbar
'
;
import
IconButton
from
'
@material-ui/core/IconButton
'
;
import
IconButton
from
'
@material-ui/core/IconButton
'
;
...
@@ -14,14 +11,20 @@ import Typography from '@material-ui/core/Typography';
...
@@ -14,14 +11,20 @@ import Typography from '@material-ui/core/Typography';
import
CloseIcon
from
'
@material-ui/icons/Close
'
;
import
CloseIcon
from
'
@material-ui/icons/Close
'
;
import
Slide
from
'
@material-ui/core/Slide
'
;
import
Slide
from
'
@material-ui/core/Slide
'
;
const
styles
=
{
import
UniversitySemestersDatesEditor
from
'
../university/modules/editors/UniversitySemestersDatesEditor
'
;
const
styles
=
theme
=>
({
appBar
:
{
appBar
:
{
position
:
'
relative
'
,
position
:
'
relative
'
,
},
},
flex
:
{
flex
:
{
flex
:
1
,
flex
:
1
,
},
},
};
paper
:
{
padding
:
2
*
theme
.
spacing
.
unit
,
margin
:
2
*
theme
.
spacing
.
unit
,
}
});
function
Transition
(
props
)
{
function
Transition
(
props
)
{
return
<
Slide
direction
=
"
up
"
{...
props
}
/>
;
return
<
Slide
direction
=
"
up
"
{...
props
}
/>
;
...
@@ -29,7 +32,7 @@ function Transition(props) {
...
@@ -29,7 +32,7 @@ function Transition(props) {
class
FullScreenDialog
extends
React
.
Component
{
class
FullScreenDialog
extends
React
.
Component
{
render
()
{
render
()
{
const
{
classes
}
=
this
.
props
;
const
{
classes
}
=
this
.
props
;
return
(
return
(
<
div
>
<
div
>
...
@@ -45,22 +48,17 @@ class FullScreenDialog extends React.Component {
...
@@ -45,22 +48,17 @@ class FullScreenDialog extends React.Component {
<
CloseIcon
/>
<
CloseIcon
/>
<
/IconButton
>
<
/IconButton
>
<
Typography
variant
=
"
title
"
color
=
"
inherit
"
className
=
{
classes
.
flex
}
>
<
Typography
variant
=
"
title
"
color
=
"
inherit
"
className
=
{
classes
.
flex
}
>
Sound
Mode
édition
<
/Typography
>
<
/Typography
>
<
Button
color
=
"
inherit
"
onClick
=
{
this
.
props
.
handleClose
}
>
<
Button
color
=
"
inherit
"
onClick
=
{
this
.
props
.
handleClose
}
>
save
Enregistrer
<
/Button
>
<
/Button
>
<
/Toolbar
>
<
/Toolbar
>
<
/AppBar
>
<
/AppBar
>
<
List
>
<
Paper
className
=
{
classes
.
paper
}
>
<
ListItem
button
>
{
/* {this.props.children} */
}
<
ListItemText
primary
=
"
Phone ringtone
"
secondary
=
"
Titania
"
/>
<
UniversitySemestersDatesEditor
/>
<
/ListItem
>
<
/Paper
>
<
Divider
/>
<
ListItem
button
>
<
ListItemText
primary
=
"
Default notification ringtone
"
secondary
=
"
Tethys
"
/>
<
/ListItem
>
<
/List
>
<
/Dialog
>
<
/Dialog
>
<
/div
>
<
/div
>
);
);
...
@@ -72,8 +70,8 @@ FullScreenDialog.propTypes = {
...
@@ -72,8 +70,8 @@ FullScreenDialog.propTypes = {
};
};
FullScreenDialog
.
defaultProps
=
{
FullScreenDialog
.
defaultProps
=
{
open
:
false
,
open
:
false
,
handleClose
:
()
=>
console
.
log
(
"
Dev forgot something...
"
)
handleClose
:
()
=>
console
.
log
(
"
Dev forgot something...
"
)
};
};
export
default
withStyles
(
styles
)(
FullScreenDialog
);
export
default
withStyles
(
styles
,
{
withTheme
:
true
}
)(
FullScreenDialog
);
frontend/src/components/shared/MarkdownField.js
0 → 100644
View file @
8654dc22
import
React
from
'
react
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
Grid
from
'
@material-ui/core/Grid
'
;
import
{
compose
}
from
'
recompose
'
;
import
TextField
from
'
@material-ui/core/TextField
'
;
import
Markdown
from
'
./Markdown
'
;
import
{
Typography
}
from
'
@material-ui/core
'
;
import
LinkText
from
'
../other/TextLink
'
;
const
styles
=
theme
=>
({
})
class
MarkdownField
extends
React
.
Component
{
constructor
()
{
super
();
this
.
state
=
{
value
:
''
};
}
handleChangeValue
=
(
value
)
=>
{
this
.
setState
({
value
});
}
render
()
{
const
{
classes
}
=
this
.
props
;
return
(
<
div
>
<
Grid
container
spacing
=
{
16
}
>
<
Grid
item
xs
=
{
12
}
md
=
{
12
}
lg
=
{
6
}
>
<
Typography
variant
=
'
caption
'
>
<
em
>
Saisie
du
texte
(
ce
champ
supporte
en
grande
partie
la
syntaxe
<
LinkText
href
=
"
https://www.markdownguide.org/basic-syntax
"
>
Markdown
<
/LinkText>
)
<
/em
>
<
/Typography
>
<
TextField
fullWidth
=
{
true
}
multiline
=
{
true
}
onChange
=
{(
e
)
=>
this
.
handleChangeValue
(
e
.
target
.
value
)}
/
>
<
/Grid
>
<
Grid
item
xs
=
{
12
}
md
=
{
12
}
lg
=
{
6
}
>
<
Typography
variant
=
'
caption
'
><
em
>
Prévisualisation
du
texte
<
/em></
Typography
>
{
this
.
state
.
value
==
''
?
(
<
Typography
variant
=
'
caption
'
>
Le
champ
est
vide
<
/Typography>
)
:
(
<
Markdown
source
=
{
this
.
state
.
value
}
/>
)
}
<
/Grid
>
<
/Grid
>
<
/div
>
)
}
}
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
)(
MarkdownField
);
\ No newline at end of file
frontend/src/components/shared/MyDatePicker.js
0 → 100644
View file @
8654dc22
import
React
,
{
PureComponent
}
from
'
react
'
;
import
DatePicker
from
'
material-ui-pickers/DatePicker
'
;
import
DateFnsUtils
from
'
material-ui-pickers/utils/date-fns-utils
'
;
import
MuiPickersUtilsProvider
from
'
material-ui-pickers/utils/MuiPickersUtilsProvider
'
;
import
PropTypes
from
'
prop-types
'
;
import
{
compose
}
from
'
recompose
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
frLocale
from
'
date-fns/locale/fr
'
;
import
format
from
'
date-fns/format
'
;
import
KeyboardArrowLeftIcon
from
'
@material-ui/icons/KeyboardArrowLeft
'
;
import
KeyboardArrowRightIcon
from
'
@material-ui/icons/KeyboardArrowRight
'
;
import
{
Typography
}
from
'
@material-ui/core
'
;
const
styles
=
theme
=>
({
datePicker
:
{
// width: '300px',
},
picker
:
{
marginBottom
:
3
*
theme
.
spacing
.
unit
}
});
class
LocalizedUtils
extends
DateFnsUtils
{
getDatePickerHeaderText
(
date
)
{
return
format
(
date
,
'
d MMM YYYY
'
,
{
locale
:
this
.
locale
});
}
}
class
MyDatePicker
extends
PureComponent
{
state
=
{
selectedDate
:
this
.
props
.
selectedDate
,
}
handleDateChange
=
(
date
)
=>
{
this
.
setState
({
selectedDate
:
date
});
this
.
props
.
handleDateChange
(
date
);
}
render
()
{
const
{
classes
}
=
this
.
props
;
return
(
<
MuiPickersUtilsProvider
utils
=
{
LocalizedUtils
}
locale
=
{
frLocale
}
>
<
div
className
=
{
classes
.
picker
}
>
<
Typography
color
=
'
textSecondary
'
>
{
this
.
props
.
label
}
<
/Typography
>
<
DatePicker
clearable
format
=
"
d MMM YYYY
"
value
=
{
this
.
state
.
selectedDate
}
onChange
=
{
this
.
handleDateChange
}
clearLabel
=
"
vider
"
cancelLabel
=
"
annuler
"
leftArrowIcon
=
{
<
KeyboardArrowLeftIcon
/>
}
rightArrowIcon
=
{
<
KeyboardArrowRightIcon
/>
}
className
=
{
classes
.
datePicker
}
/
>
<
/div
>
<
/MuiPickersUtilsProvider
>
);
}
}
MyDatePicker
.
defaultProps
=
{
selectedDate
:
Date
.
now
(),
handleDateChange
:
(
date
)
=>
console
.
log
(
'
Nouvelle date sélectionnée :
'
,
date
),
label
:
'
LABEL
'
}
MyDatePicker
.
propTypes
=
{
selectedDate
:
PropTypes
.
instanceOf
(
Date
).
isRequired
,
handleDateChange
:
PropTypes
.
func
.
isRequired
,
label
:
PropTypes
.
string
.
isRequired
};
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
)(
MyDatePicker
);
frontend/src/components/shared/UsefulLinksField.js
0 → 100644
View file @
8654dc22
import
React
from
'
react
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
Grid
from
'
@material-ui/core/Grid
'
;
import
{
compose
}
from
'
recompose
'
;
import
TextField
from
'
@material-ui/core/TextField
'
;
import
IconButton
from
'
@material-ui/core/IconButton
'
;
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
'
;
const
styles
=
theme
=>
({
container
:
{
display
:
'
flex
'
,
flexWrap
:
'
wrap
'
,
},
usefulLinkContainer
:
{
display
:
'
flex
'
,
flexWrap
:
'
wrap
'
,
}
})
class
UsefulLinksField
extends
React
.
Component
{
constructor
()
{
super
();
this
.
state
=
{
usefulLinks
:
Array
({
url
:
''
,
description
:
''
}),
};
}
handleUsefulLinkUrlChange
=
(
idx
,
evt
)
=>
{
const
newUsefulLinks
=
this
.
state
.
usefulLinks
.
map
((
usefulLink
,
sidx
)
=>
{
if
(
idx
!==
sidx
)
{
return
usefulLink
;
}
return
{
...
usefulLink
,
url
:
evt
.
target
.
value
};
});
this
.
setState
({
usefulLinks
:
newUsefulLinks
});
}
handleUsefulLinkDescriptionChange
=
(
idx
,
evt
)
=>
{
const
newUsefulLinks
=
this
.
state
.
usefulLinks
.
map
((
usefulLink
,
sidx
)
=>
{
if
(
idx
!==
sidx
)
{
return
usefulLink
;
}
return
{
...
usefulLink
,
description
:
evt
.
target
.
value
};
});
this
.
setState
({
usefulLinks
:
newUsefulLinks
});
}
handleAddUsefulLink
=
()
=>
{
this
.
setState
({
usefulLinks
:
this
.
state
.
usefulLinks
.
concat
([{
url
:
''
,
description
:
''
}])
});
}
handleSwipeUsefulLink
=
(
idx
,
swipeIndexDiff
)
=>
{
const
{
usefulLinks
}
=
this
.
state
;
let
newUsefulLinks
=
usefulLinks
.
slice
();
const
b
=
usefulLinks
[
idx
+
swipeIndexDiff
];
newUsefulLinks
[
idx
+
swipeIndexDiff
]
=
newUsefulLinks
[
idx
];
newUsefulLinks
[
idx
]
=
b
;
this
.
setState
({
usefulLinks
:
newUsefulLinks
});
}
handleRemoveUsefulLink
=
(
idx
)
=>
{
this
.
setState
({
usefulLinks
:
this
.
state
.
usefulLinks
.
filter
((
s
,
sidx
)
=>
idx
!==
sidx
)
});
}
areAllUsefulLinksUsed
=
()
=>
{
const
{
usefulLinks
}
=
this
.
state
;
for
(
let
idx
in
usefulLinks
)
{
const
el
=
usefulLinks
[
idx
];
if
(
el
.
url
==
''
&&
el
.
description
==
''
)
{
return
false
;
}
}
return
true
;
}
render
()
{
const
{
classes
}
=
this
.
props
;
const
nbOfUsefulLinks
=
this
.
state
.
usefulLinks
.
length
;
console
.
log
(
"
all links used
"
,
this
.
areAllUsefulLinksUsed
())
return
(
<
div
>
<
Grid
container
spacing
=
{
16
}
direction
=
"
column
"
justify
=
"
flex-start
"
alignItems
=
"
flex-start
"
>
{
this
.
state
.
usefulLinks
.
map
((
usefulLink
,
idx
)
=>
(
<
Grid
item
>
<
Grid
container
spacing
=
{
8
}
alignItems
=
"
center
"
>
<
Grid
item
>
<
TextField
placeholder
=
{
'
URL
'
}
value
=
{
usefulLink
.
url
}
onChange
=
{(
e
)
=>
this
.
handleUsefulLinkUrlChange
(
idx
,
e
)}
/
>
<
/Grid
>
<
Grid
item
>
<
TextField
placeholder
=
{
"
Description
"
}
value
=
{
usefulLink
.
description
}
onChange
=
{(
e
)
=>
this
.
handleUsefulLinkDescriptionChange
(
idx
,
e
)}
/
>
<
/Grid
>
<
Grid
item
>
<
IconButton
onClick
=
{()
=>
this
.
handleSwipeUsefulLink
(
idx
,
-
1
)}
disabled
=
{
idx
==
0
}
color
=
"
secondary
"
>
<
KeyboardArrowUpIcon
/>
<
/IconButton
>
<
IconButton
onClick
=
{()
=>
this
.
handleSwipeUsefulLink
(
idx
,
1
)}
disabled
=
{
idx
==
nbOfUsefulLinks
-
1
}
color
=
"
secondary
"
>
<
KeyboardArrowDownIcon
/>
<
/IconButton
>
<
IconButton
onClick
=
{()
=>
this
.
handleRemoveUsefulLink
(
idx
)}
color
=
'
secondary
'
>
<
DeleteIcon
/>
<
/IconButton
>
<
/Grid
>
<
/Grid
>
<
/Grid
>
))}
<
Grid
item
>
<
Button
disabled
=
{
!
this
.
areAllUsefulLinksUsed
()}
size
=
"
small
"
variant
=
"
outlined
"
color
=
"
secondary
"
onClick
=
{()
=>
this
.
handleAddUsefulLink
()}
>
Ajouter
un
lien
<
/Button
>
<
/Grid
>
<
/Grid
>
<
/div
>
)
}
}
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
)(
UsefulLinksField
);
\ No newline at end of file
frontend/src/components/university/modules/editors/UniversitySemestersDatesEditor.js
0 → 100644
View file @
8654dc22
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
{
compose
}
from
'
recompose
'
;
import
{
connect
}
from
"
react-redux
"
;
import
TextField
from
'
@material-ui/core/TextField
'
;
import
MyComponent
from
'
../../../MyComponent
'
;
import
MyDatePicker
from
'
../../../shared/MyDatePicker
'
;
import
UsefulLinksField
from
'
../../../shared/UsefulLinksField
'
;
import
MardownField
from
'
../../../shared/MarkdownField
'
;
// import dateToStr from '../../../utils/dateToStr';
// import {
// universitiesSemestersDatesElFetchData,
// } from '../../../generated/actions';
class
UniversitySemestersDatesEditor
extends
MyComponent
{
// idToUse = "univId";
myRender
()
{
return
(
<
div
>
<
MyDatePicker
label
=
{
"
Date de début du semestre de printemps :
"
}
/
>
<
MyDatePicker
label
=
{
"
Date de fin du semestre de printemps :
"
}
/
>
<
MyDatePicker
label
=
{
"
Date de début du semestre d'automne :
"
}
/
>
<
MyDatePicker
label
=
{
"
Date de fin du semestre d'automne :
"
}
/
>
<
MardownField
/>
<
UsefulLinksField
/>
<
/div
>
)
}
}
// UniversitySemestersDatesEditor.propTypes = {
// classes: PropTypes.object.isRequired,
// theme: PropTypes.object.isRequired,
// univId: PropTypes.string.isRequired
// };
// const mapStateToProps = (state) => {
// return {
// universitiesSemestersDatesEl: state.universitiesSemestersDatesEl,
// };
// };
// const mapDispatchToProps = (dispatch) => {
// return {
// fetchData: {
// universitiesSemestersDatesEl: (univId) => dispatch(universitiesSemestersDatesElFetchData(univId)),
// }
// };
// };
export
default
compose
(
// withStyles(styles, { withTheme: true }),
// connect(mapStateToProps, mapDispatchToProps)
)(
UniversitySemestersDatesEditor
);
\ No newline at end of file
package-lock.json
View file @
8654dc22
...
@@ -2637,6 +2637,11 @@
...
@@ -2637,6 +2637,11 @@
"assert-plus"
:
"^1.0.0"
"assert-plus"
:
"^1.0.0"
}
}
},
},
"date-fns"
:
{
"version"
:
"2.0.0-alpha.16"
,
"resolved"
:
"https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.16.tgz"
,
"integrity"
:
"sha1-0kmmybeZJSZS+54/JUYOr53oasc="
},
"date-now"
:
{
"date-now"
:
{
"version"
:
"0.1.4"
,
"version"
:
"0.1.4"
,
"resolved"
:
"https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz"
,
"resolved"
:
"https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz"
,
...
@@ -5340,6 +5345,11 @@
...
@@ -5340,6 +5345,11 @@
"integrity"
:
"sha1-0jM6NtnncXyK0vfKyv7HwytERmQ="
,
"integrity"
:
"sha1-0jM6NtnncXyK0vfKyv7HwytERmQ="
,
"dev"
:
true
"dev"
:
true
},
},
"lodash.throttle"
:
{
"version"
:
"4.1.1"
,
"resolved"
:
"https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz"
,
"integrity"
:
"sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
},
"long"
:
{
"long"
:
{
"version"
:
"3.2.0"
,
"version"
:
"3.2.0"
,
"resolved"
:
"https://registry.npmjs.org/long/-/long-3.2.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/long/-/long-3.2.0.tgz"
,
...
@@ -5437,6 +5447,34 @@
...
@@ -5437,6 +5447,34 @@
"resolved"
:
"https://registry.npmjs.org/marked/-/marked-0.5.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/marked/-/marked-0.5.0.tgz"
,
"integrity"
:
"sha512-UhjmkCWKu1SS/BIePL2a59BMJ7V42EYtTfksodPRXzPEGEph3Inp5dylseqt+KbU9Jglsx8xcMKmlumfJMBXAA=="
"integrity"
:
"sha512-UhjmkCWKu1SS/BIePL2a59BMJ7V42EYtTfksodPRXzPEGEph3Inp5dylseqt+KbU9Jglsx8xcMKmlumfJMBXAA=="
},
},
"material-ui-pickers"
:
{
"version"
:
"1.0.0-rc.14"
,
"resolved"
:
"https://registry.npmjs.org/material-ui-pickers/-/material-ui-pickers-1.0.0-rc.14.tgz"
,
"integrity"
:
"sha512-aOU4juaRst8om8/BTKh54ubX9VoJRLyErTtuvbSR/ON0cQpYLycHjS1v2Jxy+7A9P9ZDrqd231UPs9lZFShUCg=="
,
"requires"
:
{
"@babel/runtime"
:
"^7.0.0"
,
"lodash.throttle"
:
"^4.1.1"
,
"react-event-listener"
:
"^0.6.2"
,
"react-text-mask"
:
"=5.4.1"
,
"react-transition-group"
:
"^2.4.0"
,
"recompose"
:
"^0.28.0"
},
"dependencies"
:
{
"@babel/runtime"
:
{
"version"
:
"7.0.0"
,
"resolved"
:
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz"
,
"integrity"
:
"sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA=="
,
"requires"
:
{
"regenerator-runtime"
:
"^0.12.0"
}
},
"regenerator-runtime"
:
{
"version"
:
"0.12.1"
,
"resolved"
:
"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz"
,
"integrity"
:
"sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"math-expression-evaluator"
:
{
"math-expression-evaluator"
:
{
"version"
:
"1.2.17"
,
"version"
:
"1.2.17"
,
"resolved"
:
"https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz"
,
"resolved"
:
"https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz"
,
...
@@ -6882,6 +6920,14 @@
...
@@ -6882,6 +6920,14 @@
}
}
}
}
},
},
"react-text-mask"
:
{
"version"
:
"5.4.1"
,
"resolved"
:
"https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.4.1.tgz"
,
"integrity"
:
"sha512-mGx1n0x0skktwsKcpgAGnrgExFlXDflbWEHh8PC1UaQP8+EdHkW7JYczTghsBo2rnVwU9/4A9x/2bVt3HY46/w=="
,
"requires"
:
{
"prop-types"
:
"^15.5.6"
}
},
"react-transition-group"
:
{
"react-transition-group"
:
{