Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
fbd2e3a0
Commit
fbd2e3a0
authored
Feb 27, 2014
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2724 from edx/will/studio-xblock-save
Native XBlock Studio Save UI
parents
8f7497cf
5f099531
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
94 additions
and
2 deletions
+94
-2
cms/djangoapps/contentstore/views/item.py
+4
-0
cms/djangoapps/contentstore/views/tests/test_item.py
+31
-0
cms/envs/test.py
+6
-0
cms/static/coffee/src/xblock/cms.runtime.v1.coffee
+40
-1
cms/templates/component.html
+3
-0
common/static/coffee/src/xblock/runtime.v1.coffee
+9
-0
requirements/edx/base.txt
+1
-1
No files found.
cms/djangoapps/contentstore/views/item.py
View file @
fbd2e3a0
...
...
@@ -210,6 +210,10 @@ def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, v
fragment
.
content
=
render_to_string
(
'component.html'
,
{
'preview'
:
fragment
.
content
,
'label'
:
component
.
display_name
or
component
.
scope_ids
.
block_type
,
# Native XBlocks are responsible for persisting their own data,
# so they are also responsible for providing save/cancel buttons.
'show_save_cancel'
:
isinstance
(
component
,
xmodule
.
x_module
.
XModuleDescriptor
),
})
else
:
raise
Http404
...
...
cms/djangoapps/contentstore/views/tests/test_item.py
View file @
fbd2e3a0
...
...
@@ -626,3 +626,34 @@ class TestComponentHandler(TestCase):
self
.
descriptor
.
handle
=
create_response
self
.
assertEquals
(
component_handler
(
self
.
request
,
self
.
usage_id
,
'dummy_handler'
)
.
status_code
,
status_code
)
@ddt.ddt
class
TestNativeXBlock
(
ItemTest
):
"""
Test a "native" XBlock (not an XModule shim).
"""
@ddt.data
((
'problem'
,
True
),
(
'acid'
,
False
))
@ddt.unpack
def
test_save_cancel_buttons
(
self
,
category
,
include_buttons
):
"""
Native XBlocks handle their own persistence, so Studio
should not render Save/Cancel buttons for them.
"""
# Create the XBlock
resp
=
self
.
create_xblock
(
category
=
category
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
native_loc
=
json
.
loads
(
resp
.
content
)[
'locator'
]
# Render the XBlock
resp_content
=
json
.
loads
(
resp
.
content
)
resp
=
self
.
client
.
get
(
'/xblock/'
+
native_loc
+
'/student_view'
,
HTTP_ACCEPT
=
'application/x-fragment+json'
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
# Check that the save and cancel buttons are hidden for native XBlocks,
# but shown for XModule shim XBlocks
resp_html
=
json
.
loads
(
resp
.
content
)[
'html'
]
assert_func
=
self
.
assertIn
if
include_buttons
else
self
.
assertNotIn
assert_func
(
'save-button'
,
resp_html
)
assert_func
(
'cancel-button'
,
resp_html
)
cms/envs/test.py
View file @
fbd2e3a0
...
...
@@ -156,6 +156,12 @@ INSTALLED_APPS += ('external_auth', )
# hide ratelimit warnings while running tests
filterwarnings
(
'ignore'
,
message
=
'No request passed to the backend, unable to rate-limit'
)
################################# XBLOCK ######################################
from
xmodule.x_module
import
prefer_xmodules
XBLOCK_SELECT_FUNCTION
=
prefer_xmodules
################################# CELERY ######################################
CELERY_ALWAYS_EAGER
=
True
...
...
cms/static/coffee/src/xblock/cms.runtime.v1.coffee
View file @
fbd2e3a0
define
[
"jquery"
,
"xblock/runtime.v1"
,
"URI"
],
(
$
,
XBlock
,
URI
)
->
define
[
"jquery"
,
"xblock/runtime.v1"
,
"URI"
,
"gettext"
,
"js/utils/modal"
,
"js/views/feedback_notification"
],
(
$
,
XBlock
,
URI
,
gettext
,
ModalUtils
,
NotificationView
)
->
@
PreviewRuntime
=
{}
class
PreviewRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
...
...
@@ -13,6 +16,11 @@ define ["jquery", "xblock/runtime.v1", "URI"], ($, XBlock, URI) ->
@
StudioRuntime
=
{}
class
StudioRuntime
.
v1
extends
XBlock
.
Runtime
.
v1
constructor
:
()
->
super
()
@
savingNotification
=
new
NotificationView
.
Mini
title
:
gettext
(
'Saving…'
)
handlerUrl
:
(
element
,
handlerName
,
suffix
,
query
,
thirdparty
)
->
uri
=
URI
(
"/xblock"
).
segment
(
$
(
element
).
data
(
'usage-id'
))
.
segment
(
'handler'
)
...
...
@@ -20,3 +28,34 @@ define ["jquery", "xblock/runtime.v1", "URI"], ($, XBlock, URI) ->
if
suffix
?
then
uri
.
segment
(
suffix
)
if
query
?
then
uri
.
search
(
query
)
uri
.
toString
()
# Notify the Studio client-side runtime so it can update
# the UI in a consistent way. Currently, this is used
# for save / cancel when editing an XBlock.
# Although native XBlocks should handle their own persistence,
# Studio still needs to update the UI in a consistent way
# (showing the "Saving..." notification, closing the modal editing dialog, etc.)
notify
:
(
name
,
data
)
->
if
name
==
'save'
if
'state'
of
data
# Starting to save, so show the "Saving..." notification
if
data
.
state
==
'start'
@
_hide_editor
()
@
savingNotification
.
show
()
# Finished saving, so hide the "Saving..." notification
else
if
data
.
state
==
'end'
$
(
'.component.editing'
).
removeClass
(
'editing'
)
@
savingNotification
.
hide
()
else
if
name
==
'cancel'
@
_hide_editor
()
_hide_editor
:
()
->
# This will close all open component editors, which works
# if we assume that <= 1 are open at a time.
el
=
$
(
'.component.editing'
)
el
.
removeClass
(
'editing'
)
el
.
find
(
'.component-editor'
).
slideUp
(
150
)
ModalUtils
.
hideModalCover
()
cms/templates/component.html
View file @
fbd2e3a0
...
...
@@ -18,10 +18,13 @@
<div
class=
"component-edit-modes"
>
<div
class=
"module-editor"
/>
</div>
## Native XBlocks render their own save/cancel buttons
% if show_save_cancel:
<div
class=
"row module-actions"
>
<a
href=
"#"
class=
"save-button action-primary action"
>
${_("Save")}
</a>
<a
href=
"#"
class=
"cancel-button action-secondary action"
>
${_("Cancel")}
</a>
</div>
<!-- Module Actions-->
% endif
</div>
</div>
<div
class=
"wrapper wrapper-component-action-header"
>
...
...
common/static/coffee/src/xblock/runtime.v1.coffee
View file @
fbd2e3a0
...
...
@@ -3,3 +3,12 @@ class XBlock.Runtime.v1
childMap
:
(
block
,
childName
)
=>
for
child
in
@
children
(
block
)
return
child
if
child
.
name
==
childName
# Notify the client-side runtime that an event has occurred.
# This allows the runtime to update the UI in a consistent way
# for different XBlocks.
# `name` is an arbitrary string (for example, "save")
# `data` is an object (for example, {state: 'starting'})
# The default implementation is a no-op.
# WARNING: This is an interim solution and not officially supported!
notify
:
(
name
,
data
)
->
undefined
requirements/edx/base.txt
View file @
fbd2e3a0
...
...
@@ -106,7 +106,7 @@ django-debug-toolbar-mongo
# Used for testing
chrono==1.0.2
coverage==3.7
ddt==0.
6
.0
ddt==0.
7
.0
django-crum==0.5
django_nose==1.1
factory_boy==2.2.1
...
...
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