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
dbed16cc
Commit
dbed16cc
authored
Mar 10, 2019
by
Florent Chehab
Browse files
New pendingModeration setup in frontend.
Fixes
#55
parent
9ea5c94b
Pipeline
#36195
failed with stages
in 4 minutes and 58 seconds
Changes
8
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
backend/backend_app/models/abstract/my_model/__init__.py
View file @
dbed16cc
...
...
@@ -5,6 +5,7 @@ from .pendingModeration import (
PendingModeration
,
PendingModerationSerializer
,
PendingModerationViewSet
,
PendingModerationObjViewset
,
)
from
.forTestingModeration
import
(
ForTestingModeration
,
...
...
backend/backend_app/models/abstract/my_model/pendingModeration.py
View file @
dbed16cc
...
...
@@ -6,7 +6,7 @@ from django.db import models
from
backend_app.custom
import
MySerializerWithJSON
from
backend_app.fields
import
JSONField
from
backend_app.utils
import
get_model_config
,
get_viewset_permissions
from
rest_framework
import
serializers
,
viewsets
from
rest_framework
import
serializers
,
viewsets
,
mixins
class
PendingModeration
(
models
.
Model
):
...
...
@@ -56,3 +56,19 @@ class PendingModerationViewSet(viewsets.ModelViewSet):
permission_classes
=
get_viewset_permissions
(
"PendingModerationViewSet"
)
queryset
=
PendingModeration
.
objects
.
all
()
# pylint: disable=E1101
serializer_class
=
PendingModerationSerializer
class
PendingModerationObjViewset
(
mixins
.
ListModelMixin
,
viewsets
.
GenericViewSet
):
"""
Viewset to retrieve the pending moderation data for an object
"""
permission_classes
=
get_viewset_permissions
(
"PendingModerationObjViewset"
)
serializer_class
=
PendingModerationSerializer
def
get_queryset
(
self
):
content_type_id
=
self
.
kwargs
[
"content_type_id"
]
object_pk
=
self
.
kwargs
[
"object_pk"
]
return
PendingModeration
.
objects
.
filter
(
content_type
=
content_type_id
,
object_id
=
object_pk
)
frontend/src/components/university/modules/common/History.js
View file @
dbed16cc
import
React
from
"
react
"
;
import
CustomComponentForAPI
from
"
../../../common/CustomComponentForAPI
"
;
import
{
openFullScreenDialog
,
closeFullScreenDialog
}
from
"
../../../../redux/actions/fullScreenDialog
"
;
import
PropTypes
from
"
prop-types
"
;
...
...
@@ -22,7 +23,6 @@ import Loading from "../../../common/Loading";
import
dateTimeStrToStr
from
"
../../../../utils/dateTimeStrToStr
"
;
import
editorStyle
from
"
../../editors/common/editorStyle
"
;
import
CustomComponentForAPI
from
"
../../../common/CustomComponentForAPI
"
;
import
getActions
from
"
../../../../redux/api/getActions
"
;
...
...
@@ -32,7 +32,7 @@ import getActions from "../../../../redux/api/getActions";
* Component to display the previous versions of module
*
* @class History
* @extends {Component}
* @extends {
Custom
Component
ForAPI
}
*/
class
History
extends
CustomComponentForAPI
{
// Store the version that is being viewed
...
...
@@ -217,10 +217,6 @@ class History extends CustomComponentForAPI {
* @memberof History
*/
render
()
{
if
(
!
this
.
allApiDataIsReady
())
{
return
<><
/>
;
}
return
<><
/>
;
}
}
...
...
frontend/src/components/university/modules/common/ModuleWrapper.js
View file @
dbed16cc
...
...
@@ -54,7 +54,7 @@ class ModuleWrapper extends Component {
* @memberof ModuleWrapper
*/
openEditorPanel
(
ignorePendingModeration
=
false
)
{
if
(
ignorePendingModeration
||
this
.
props
.
rawModelData
.
pending_moderation
.
length
==
0
)
{
if
(
ignorePendingModeration
||
!
this
.
props
.
rawModelData
.
has_
pending_moderation
)
{
this
.
setState
({
editorOpen
:
true
});
}
else
{
this
.
alertThereIsSomethingPendingModeration
();
...
...
@@ -246,6 +246,7 @@ class ModuleWrapper extends Component {
{
this
.
state
.
pendingModerationOpen
?
<
PendingModeration
renderer
=
{
this
}
modelInfo
=
{{
contentTypeId
:
rawModelData
.
content_type_id
,
id
:
rawModelData
.
id
}}
closePendingModerationPanel
=
{()
=>
this
.
closePendingModerationPanel
()}
editFromPendingModeration
=
{(
pendingModelData
)
=>
this
.
editFromPendingModeration
(
pendingModelData
)}
moderatePendingModeration
=
{(
modelData
)
=>
this
.
moderatePendingModeration
(
modelData
)}
...
...
frontend/src/components/university/modules/common/PendingModeration.js
View file @
dbed16cc
import
React
,
{
Component
}
from
"
react
"
;
import
React
from
"
react
"
;
import
CustomComponentForAPI
from
"
../../../common/CustomComponentForAPI
"
;
import
{
connect
}
from
"
react-redux
"
;
import
{
openFullScreenDialog
,
closeFullScreenDialog
}
from
"
../../../../redux/actions/fullScreenDialog
"
;
...
...
@@ -13,35 +14,37 @@ import IconButton from "@material-ui/core/IconButton";
import
Typography
from
"
@material-ui/core/Typography
"
;
import
CloseIcon
from
"
@material-ui/icons/Close
"
;
import
Divider
from
"
@material-ui/core/Divider
"
;
import
getActions
from
"
../../../../redux/api/getActions
"
;
import
editorStyle
from
"
../../editors/common/editorStyle
"
;
import
Loading
from
"
../../../common/Loading
"
;
const
styles
=
theme
=>
({
...
editorStyle
(
theme
),
editButton
:
{
display
:
"
block
"
,
marginLeft
:
"
auto
"
,
marginRight
:
"
auto
"
,
marginTop
:
2
*
theme
.
spacing
.
unit
,
marginBottom
:
2
*
theme
.
spacing
.
unit
}
});
/**
* Class to handle models that are pending moderation.
*
* @class PendingModeration
* @extends {Component}
* @extends {
Custom
Component
ForAPI
}
*/
class
PendingModeration
extends
Component
{
class
PendingModeration
extends
CustomComponentForAPI
{
constructor
(
props
)
{
super
(
props
);
const
{
contentTypeId
,
id
}
=
props
.
modelInfo
;
// set the __apiAttr here so that we can read the correct data
this
.
__apiParam
=
{
pendingModeration
:
{
contentTypeId
,
id
}
};
}
/**
* Force update to force call of componentDidUpdate en mount and force the rendering of the moderation panel.
*
* @memberof PendingModeration
*/
componentDidMount
(){
componentDidMount
()
{
super
.
componentDidMount
();
this
.
forceUpdate
();
}
...
...
@@ -50,8 +53,9 @@ class PendingModeration extends Component {
*
* @memberof PendingModeration
*/
componentDidUpdate
()
{
this
.
props
.
openFullScreenDialog
(
this
.
renderPendingModerationPanel
());
componentDidUpdate
(
prevProps
,
prevState
,
snapshot
)
{
super
.
componentDidUpdate
(
prevProps
,
prevState
,
snapshot
);
this
.
props
.
openFullScreenDialog
(
this
.
renderPanel
());
}
/**
...
...
@@ -61,11 +65,11 @@ class PendingModeration extends Component {
* @memberof PendingModeration
*/
getRawModelDataFromPending
()
{
const
{
renderer
}
=
this
.
props
;
l
et
pendingRawModelData
=
Object
.
assign
({},
renderer
.
props
.
rawModelData
.
pending_moderation
[
0
].
new_object
);
// we have to copy the original ID
pending
RawModelData
.
id
=
renderer
.
props
.
rawModelData
.
id
;
return
pending
RawModelData
;
const
pendingObject
=
this
.
getLatestReadData
(
"
pendingModeration
"
)[
0
]
;
r
et
urn
Object
.
assign
(
{},
pending
Object
.
new_object
,
{
id
:
pending
Object
.
object_id
})
;
}
/**
...
...
@@ -112,6 +116,7 @@ class PendingModeration extends Component {
closePanel
()
{
this
.
props
.
closeFullScreenDialog
();
this
.
props
.
closePendingModerationPanel
();
this
.
props
.
resetPendingModeration
();
}
/**
...
...
@@ -120,7 +125,11 @@ class PendingModeration extends Component {
* @returns
* @memberof PendingModeration
*/
renderPendingModerationPanel
()
{
renderPanel
()
{
if
(
!
this
.
allApiDataIsReady
())
{
return
<
Loading
/>
;
}
const
{
classes
}
=
this
.
props
,
pendingModelData
=
this
.
getRawModelDataFromPending
();
...
...
@@ -146,6 +155,12 @@ class PendingModeration extends Component {
);
}
/**
* @override
*
* @returns
* @memberof PendingModeration
*/
render
()
{
return
<><
/>
;
}
...
...
@@ -153,6 +168,7 @@ class PendingModeration extends Component {
PendingModeration
.
propTypes
=
{
classes
:
PropTypes
.
object
.
isRequired
,
modelInfo
:
PropTypes
.
object
.
isRequired
,
editFromPendingModeration
:
PropTypes
.
func
.
isRequired
,
closePendingModerationPanel
:
PropTypes
.
func
.
isRequired
,
moderatePendingModeration
:
PropTypes
.
func
.
isRequired
,
...
...
@@ -167,15 +183,38 @@ PendingModeration.defaultProps = {
closePendingModerationPanel
:
()
=>
console
.
error
(
"
Dev forgot something...
"
)
};
const
mapStateToProps
=
(
state
)
=>
{
return
{
pendingModeration
:
state
.
api
.
pendingModerationObjSpecific
};
};
const
mapDispatchToProps
=
(
dispatch
)
=>
{
return
{
api
:
{
pendingModeration
:
(
param
)
=>
dispatch
(
getActions
(
"
pendingModerationObj
"
).
readSpecific
(
`
${
param
.
contentTypeId
}
/
${
param
.
id
}
`
)),
},
resetPendingModeration
:
()
=>
dispatch
(
getActions
(
"
pendingModerationObj
"
).
setInvalidatedSpecific
(
true
)),
openFullScreenDialog
:
(
innerNodes
)
=>
dispatch
(
openFullScreenDialog
(
innerNodes
)),
closeFullScreenDialog
:
()
=>
dispatch
(
closeFullScreenDialog
()),
};
};
const
styles
=
theme
=>
({
...
editorStyle
(
theme
),
editButton
:
{
display
:
"
block
"
,
marginLeft
:
"
auto
"
,
marginRight
:
"
auto
"
,
marginTop
:
2
*
theme
.
spacing
.
unit
,
marginBottom
:
2
*
theme
.
spacing
.
unit
}
});
export
default
compose
(
withStyles
(
styles
,
{
withTheme
:
true
}),
connect
(
()
=>
Object
()
,
mapDispatchToProps
)
connect
(
mapStateToProps
,
mapDispatchToProps
)
)(
PendingModeration
);
frontend/src/components/university/modules/common/moduleWrapperFunctions/getModerationTooltipAndClass.js
View file @
dbed16cc
export
default
function
getModerationTooltipAndClass
(
nb
PendingModeration
,
readOnly
)
{
export
default
function
getModerationTooltipAndClass
(
has
PendingModeration
,
readOnly
)
{
if
(
readOnly
)
{
return
{
moderTooltip
:
"
Ce contenu n'est pas concerné par la modération.
"
,
...
...
@@ -6,20 +6,15 @@ export default function getModerationTooltipAndClass(nbPendingModeration, readOn
};
}
if
(
nbPendingModeration
==
0
)
{
return
{
moderTooltip
:
"
Aucune mise-à-jour de ce module est en attente de modération pour ce module.
"
,
moderClass
:
"
green
"
};
}
else
if
(
nbPendingModeration
==
1
)
{
if
(
hasPendingModeration
)
{
return
{
moderTooltip
:
"
Une mise-à-jour de ce modèle est en attente de modération.
"
,
moderClass
:
"
orange
"
};
}
else
{
return
{
moderTooltip
:
"
Plusieurs
mise
s à
jour de ce mod
è
le s
on
t en attente.
"
,
moderClass
:
"
orange
"
moderTooltip
:
"
Aucune
mise
-à-
jour de ce mod
u
le
e
st en attente
de modération pour ce module
.
"
,
moderClass
:
"
green
"
};
}
}
\ No newline at end of file
}
frontend/src/components/university/modules/common/moduleWrapperFunctions/renderFirstRow.js
View file @
dbed16cc
...
...
@@ -19,16 +19,11 @@ import Tooltip from "@material-ui/core/Tooltip";
export
default
function
renderFirstRow
(
userCanModerate
)
{
const
{
classes
,
theme
,
rawModelData
}
=
this
.
props
,
nbVersions
=
Math
.
max
(
0
,
rawModelData
.
nb_versions
),
{
pending_moderation
}
=
rawModelData
;
let
nbPendingModeration
=
0
;
if
(
pending_moderation
)
{
nbPendingModeration
=
pending_moderation
.
length
;
}
hasPendingModeration
=
rawModelData
.
has_pending_moderation
;
const
readOnly
=
rawModelData
.
model_config
.
read_only
,
{
versionTooltip
,
versionClass
}
=
getVersionTooltipAndClass
(
nbVersions
),
{
moderTooltip
,
moderClass
}
=
getModerationTooltipAndClass
(
nb
PendingModeration
,
readOnly
),
{
moderTooltip
,
moderClass
}
=
getModerationTooltipAndClass
(
has
PendingModeration
,
readOnly
),
{
editTooltip
,
editClass
}
=
getEditTooltipAndClass
(
readOnly
,
userCanModerate
);
return
(
...
...
@@ -41,7 +36,7 @@ export default function renderFirstRow(userCanModerate) {
<
Tooltip
title
=
{
moderTooltip
}
placement
=
"
top
"
>
<
div
style
=
{{
display
:
"
inline-block
"
}}
>
{
/* Needed to fire events for the tooltip when below is disabled! when below is disabled!! */
}
<
MyBadge
badgeContent
=
{
nb
PendingModeration
}
color
=
"
secondary
"
minNumber
=
{
1
}
>
<
MyBadge
badgeContent
=
{
has
PendingModeration
?
1
:
0
}
color
=
"
secondary
"
minNumber
=
{
1
}
>
<
IconButton
aria
-
label
=
"
Modération
"
disabled
=
{
moderClass
==
"
disabled
"
||
moderClass
==
"
green
"
}
onClick
=
{()
=>
this
.
openPendingModerationPanel
()}
className
=
{
classes
.
button
}
>
<
VerifiedUserIcon
className
=
{
classes
[
moderClass
]}
/
>
<
/IconButton
>
...
...
shared/api_config.yml
View file @
dbed16cc
...
...
@@ -36,6 +36,8 @@
# - IsOwner : (or )
#
# If you have a custom get_queryset function in your viewset, you need to specify an api_name
#####################################################
## Custom Viewsets that doesn't have a model behind
...
...
@@ -252,6 +254,14 @@
viewset_permission
:
IsStaffOrReadOnly
ignore_in_admin
:
true
-
viewset
:
PendingModerationObjViewset
import_location
:
abstract.my_model
api_end_point
:
pendingModerationObj
api_attr
:
(?P<content_type_id>[0-9]+)/(?P<object_pk>[0-9A-Za-z]+)
api_name
:
pendingModerationObj
read_only
:
true
ignore_in_admin
:
true
-
model
:
ForTestingModeration
viewset
:
ForTestingModerationViewSet
import_location
:
abstract.my_model
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment