Merge pull request #396 from MITx/feature/ichuang/xqa-and-patches
Provide content QA (quality assessment) interface
@@ -249,7 +249,7 @@ def load_preview_module(request, preview_id, descriptor, instance_state, shared_
|
||||
module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
|
||||
module.get_html = replace_static_urls(
|
||||
wrap_xmodule(module.get_html, module, "xmodule_display.html"),
|
||||
module.metadata['data_dir']
|
||||
module.metadata['data_dir'], module
|
||||
)
|
||||
save_preview_state(request, preview_id, descriptor.location.url(),
|
||||
module.get_instance_state(), module.get_shared_state())
|
||||
|
||||
@@ -297,6 +297,7 @@ def _do_create_account(post_vars):
|
||||
try:
|
||||
user.save()
|
||||
except IntegrityError:
|
||||
js = {'success': False}
|
||||
# Figure out the cause of the integrity error
|
||||
if len(User.objects.filter(username=post_vars['username'])) > 0:
|
||||
js['value'] = "An account with this username already exists."
|
||||
@@ -402,7 +403,10 @@ def create_account(request, post_override=None):
|
||||
return HttpResponse(json.dumps(js))
|
||||
|
||||
# Ok, looks like everything is legit. Create the account.
|
||||
(user, profile, registration) = _do_create_account(post_vars)
|
||||
ret = _do_create_account(post_vars)
|
||||
if isinstance(ret,HttpResponse): # if there was an error then return that
|
||||
return ret
|
||||
(user, profile, registration) = ret
|
||||
|
||||
d = {'name': post_vars['name'],
|
||||
'key': registration.activation_key,
|
||||
|
||||
@@ -34,7 +34,7 @@ def wrap_xmodule(get_html, module, template):
|
||||
return _get_html
|
||||
|
||||
|
||||
def replace_static_urls(get_html, prefix):
|
||||
def replace_static_urls(get_html, prefix, module):
|
||||
"""
|
||||
Updates the supplied module with a new get_html function that wraps
|
||||
the old get_html function and substitutes urls of the form /static/...
|
||||
@@ -69,14 +69,14 @@ def grade_histogram(module_id):
|
||||
return grades
|
||||
|
||||
|
||||
def add_histogram(get_html, module):
|
||||
def add_histogram(get_html, module, user):
|
||||
"""
|
||||
Updates the supplied module with a new get_html function that wraps
|
||||
the output of the old get_html function with additional information
|
||||
for admin users only, including a histogram of student answers and the
|
||||
definition of the xmodule
|
||||
|
||||
Does nothing if module is a SequenceModule
|
||||
Does nothing if module is a SequenceModule or a VerticalModule.
|
||||
"""
|
||||
@wraps(get_html)
|
||||
def _get_html():
|
||||
@@ -97,14 +97,20 @@ def add_histogram(get_html, module):
|
||||
# doesn't like symlinks)
|
||||
filepath = filename
|
||||
data_dir = osfs.root_path.rsplit('/')[-1]
|
||||
edit_link = "https://github.com/MITx/%s/tree/master/%s" % (data_dir,filepath)
|
||||
giturl = module.metadata.get('giturl','https://github.com/MITx')
|
||||
edit_link = "%s/%s/tree/master/%s" % (giturl,data_dir,filepath)
|
||||
else:
|
||||
edit_link = False
|
||||
|
||||
staff_context = {'definition': module.definition.get('data'),
|
||||
'metadata': json.dumps(module.metadata, indent=4),
|
||||
'element_id': module.location.html_id(),
|
||||
'location': module.location,
|
||||
'xqa_key': module.metadata.get('xqa_key',''),
|
||||
'category': str(module.__class__.__name__),
|
||||
'element_id': module.location.html_id().replace('-','_'),
|
||||
'edit_link': edit_link,
|
||||
'user': user,
|
||||
'xqa_server' : settings.MITX_FEATURES.get('USE_XQA_SERVER','http://xqa:server@content-qa.mitx.mit.edu/xqa'),
|
||||
'histogram': json.dumps(histogram),
|
||||
'render_histogram': render_histogram,
|
||||
'module_content': get_html()}
|
||||
|
||||
@@ -393,9 +393,10 @@ class LoncapaProblem(object):
|
||||
context['script_code'] += code # store code source in context
|
||||
try:
|
||||
exec code in context, context # use "context" for global context; thus defs in code are global within code
|
||||
except Exception:
|
||||
except Exception as err:
|
||||
log.exception("Error while execing script code: " + code)
|
||||
raise responsetypes.LoncapaProblemError("Error while executing script code")
|
||||
msg = "Error while executing script code: %s" % str(err).replace('<','<')
|
||||
raise responsetypes.LoncapaProblemError(msg)
|
||||
finally:
|
||||
sys.path = original_path
|
||||
|
||||
|
||||
@@ -319,7 +319,8 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
|
||||
# A list of metadata that this module can inherit from its parent module
|
||||
inheritable_metadata = (
|
||||
'graded', 'start', 'due', 'graceperiod', 'showanswer', 'rerandomize',
|
||||
|
||||
# TODO (ichuang): used for Fall 2012 xqa server access
|
||||
'xqa_key',
|
||||
# TODO: This is used by the XMLModuleStore to provide for locations for
|
||||
# static files, and will need to be removed when that code is removed
|
||||
'data_dir'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from xmodule.x_module import XModuleDescriptor
|
||||
from xmodule.modulestore import Location
|
||||
from lxml import etree
|
||||
import json
|
||||
import copy
|
||||
import logging
|
||||
import traceback
|
||||
@@ -32,7 +33,15 @@ def is_pointer_tag(xml_obj):
|
||||
actual_attr = set(xml_obj.attrib.keys())
|
||||
return len(xml_obj) == 0 and actual_attr == expected_attr
|
||||
|
||||
|
||||
def get_metadata_from_xml(xml_object, remove=True):
|
||||
meta = xml_object.find('meta')
|
||||
if meta is None:
|
||||
return ''
|
||||
dmdata = meta.text
|
||||
log.debug('meta for %s loaded: %s' % (xml_object,dmdata))
|
||||
if remove:
|
||||
xml_object.remove(meta)
|
||||
return dmdata
|
||||
|
||||
_AttrMapBase = namedtuple('_AttrMap', 'from_xml to_xml')
|
||||
|
||||
@@ -71,6 +80,7 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize',
|
||||
'start', 'due', 'graded', 'display_name', 'url_name', 'hide_from_toc',
|
||||
'ispublic', # if True, then course is listed for all users; see
|
||||
'xqa_key', # for xqaa server access
|
||||
# VS[compat] Remove once unused.
|
||||
'name', 'slug')
|
||||
|
||||
@@ -180,8 +190,11 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
|
||||
definition_xml = cls.load_file(filepath, system.resources_fs, location)
|
||||
|
||||
definition_metadata = get_metadata_from_xml(definition_xml)
|
||||
cls.clean_metadata_from_xml(definition_xml)
|
||||
definition = cls.definition_from_xml(definition_xml, system)
|
||||
if definition_metadata:
|
||||
definition['definition_metadata'] = definition_metadata
|
||||
|
||||
# TODO (ichuang): remove this after migration
|
||||
# for Fall 2012 LMS migration: keep filename (and unmangled filename)
|
||||
@@ -236,9 +249,9 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
filepath = cls._format_filepath(xml_object.tag, url_name)
|
||||
definition_xml = cls.load_file(filepath, system.resources_fs, location)
|
||||
else:
|
||||
definition_xml = xml_object
|
||||
definition_xml = xml_object # this is just a pointer, not the real definition content
|
||||
|
||||
definition = cls.load_definition(definition_xml, system, location)
|
||||
definition = cls.load_definition(definition_xml, system, location) # note this removes metadata
|
||||
# VS[compat] -- make Ike's github preview links work in both old and
|
||||
# new file layouts
|
||||
if is_pointer_tag(xml_object):
|
||||
@@ -246,6 +259,17 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
definition['filename'] = [filepath, filepath]
|
||||
|
||||
metadata = cls.load_metadata(definition_xml)
|
||||
|
||||
# move definition metadata into dict
|
||||
dmdata = definition.get('definition_metadata','')
|
||||
if dmdata:
|
||||
metadata['definition_metadata_raw'] = dmdata
|
||||
try:
|
||||
metadata.update(json.loads(dmdata))
|
||||
except Exception as err:
|
||||
log.debug('Error %s in loading metadata %s' % (err,dmdata))
|
||||
metadata['definition_metadata_err'] = str(err)
|
||||
|
||||
return cls(
|
||||
system,
|
||||
definition,
|
||||
|
||||
@@ -199,17 +199,18 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
)
|
||||
# pass position specified in URL to module through ModuleSystem
|
||||
system.set('position', position)
|
||||
system.set('DEBUG',settings.DEBUG)
|
||||
|
||||
module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
|
||||
|
||||
module.get_html = replace_static_urls(
|
||||
wrap_xmodule(module.get_html, module, 'xmodule_display.html'),
|
||||
module.metadata['data_dir']
|
||||
module.metadata['data_dir'], module
|
||||
)
|
||||
|
||||
if settings.MITX_FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF'):
|
||||
if has_staff_access_to_course(user, module.location.course):
|
||||
module.get_html = add_histogram(module.get_html, module)
|
||||
module.get_html = add_histogram(module.get_html, module, user)
|
||||
|
||||
return module
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ MITX_FEATURES = {
|
||||
'ENABLE_SQL_TRACKING_LOGS': False,
|
||||
'ENABLE_LMS_MIGRATION': False,
|
||||
|
||||
'DISABLE_LOGIN_BUTTON': False, # used in systems where login is automatic, eg MIT SSL
|
||||
|
||||
# extrernal access methods
|
||||
'ACCESS_REQUIRE_STAFF_FOR_COURSE': False,
|
||||
'AUTH_USE_OPENID': False,
|
||||
|
||||
@@ -62,6 +62,7 @@ SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
################################ LMS Migration #################################
|
||||
MITX_FEATURES['ENABLE_LMS_MIGRATION'] = True
|
||||
MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = False # require that user be in the staff_* group to be able to enroll
|
||||
MITX_FEATURES['USE_XQA_SERVER'] = 'http://xqa:server@content-qa.mitx.mit.edu/xqa'
|
||||
|
||||
LMS_MIGRATION_ALLOWED_IPS = ['127.0.0.1']
|
||||
|
||||
|
||||
@@ -10,14 +10,27 @@ sessions. Assumes structure:
|
||||
from .common import *
|
||||
from .logsettings import get_logger_config
|
||||
from .dev import *
|
||||
import socket
|
||||
|
||||
WIKI_ENABLED = False
|
||||
MITX_FEATURES['ENABLE_TEXTBOOK'] = False
|
||||
MITX_FEATURES['ENABLE_DISCUSSION'] = False
|
||||
MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = True # require that user be in the staff_* group to be able to enroll
|
||||
|
||||
myhost = socket.gethostname()
|
||||
if ('edxvm' in myhost) or ('ocw' in myhost):
|
||||
MITX_FEATURES['DISABLE_LOGIN_BUTTON'] = True # auto-login with MIT certificate
|
||||
MITX_FEATURES['USE_XQA_SERVER'] = 'https://qisx.mit.edu/xqa' # needs to be ssl or browser blocks it
|
||||
|
||||
if ('domU' in myhost):
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
MITX_FEATURES['REROUTE_ACTIVATION_EMAIL'] = 'ichuang@mitx.mit.edu' # nonempty string = address for all activation emails
|
||||
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') # django 1.4 for nginx ssl proxy
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# disable django debug toolbars
|
||||
|
||||
INSTALLED_APPS = tuple([ app for app in INSTALLED_APPS if not app.startswith('debug_toolbar') ])
|
||||
MIDDLEWARE_CLASSES = tuple([ mcl for mcl in MIDDLEWARE_CLASSES if not mcl.startswith('debug_toolbar') ])
|
||||
TEMPLATE_LOADERS = tuple([ app for app in TEMPLATE_LOADERS if not app.startswith('askbot') ])
|
||||
|
||||
@@ -189,6 +189,10 @@ p.mini {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
img.help-tooltip {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
p img, h1 img, h2 img, h3 img, h4 img, td img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
@@ -259,7 +263,7 @@ tfoot td {
|
||||
color: #666;
|
||||
padding: 2px 5px;
|
||||
font-size: 11px;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x;
|
||||
border-left: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
@@ -305,25 +309,84 @@ tr.alt {
|
||||
|
||||
/* SORTABLE TABLES */
|
||||
|
||||
thead th {
|
||||
padding: 2px 5px;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
thead th a:link, thead th a:visited {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
thead th.sorted {
|
||||
background: #c5c5c5 url(../img/nav-bg-selected.gif) top left repeat-x;
|
||||
}
|
||||
|
||||
table thead th .text span {
|
||||
padding: 2px 5px;
|
||||
display:block;
|
||||
}
|
||||
|
||||
table thead th .text a {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
table thead th.sorted {
|
||||
background-position: bottom left !important;
|
||||
table thead th.sortable:hover {
|
||||
background: white url(../img/nav-bg-reverse.gif) 0 -5px repeat-x;
|
||||
}
|
||||
|
||||
table thead th.sorted a {
|
||||
padding-right: 13px;
|
||||
thead th.sorted a.sortremove {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
table thead th.ascending a {
|
||||
background: url(../img/admin/arrow-up.gif) right .4em no-repeat;
|
||||
table thead th.sorted:hover a.sortremove {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
table thead th.descending a {
|
||||
background: url(../img/admin/arrow-down.gif) right .4em no-repeat;
|
||||
table thead th.sorted .sortoptions {
|
||||
display: block;
|
||||
padding: 4px 5px 0 5px;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortpriority {
|
||||
font-size: .8em;
|
||||
min-width: 12px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a {
|
||||
width: 14px;
|
||||
height: 12px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.sortremove {
|
||||
background: url(../img/sorting-icons.gif) -4px -5px no-repeat;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.sortremove:hover {
|
||||
background: url(../img/sorting-icons.gif) -4px -27px no-repeat;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.ascending {
|
||||
background: url(../img/sorting-icons.gif) -5px -50px no-repeat;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.ascending:hover {
|
||||
background: url(../img/sorting-icons.gif) -5px -72px no-repeat;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.descending {
|
||||
background: url(../img/sorting-icons.gif) -5px -94px no-repeat;
|
||||
}
|
||||
|
||||
table thead th.sorted .sortoptions a.descending:hover {
|
||||
background: url(../img/sorting-icons.gif) -5px -115px no-repeat;
|
||||
}
|
||||
|
||||
/* ORDERABLE TABLES */
|
||||
@@ -334,7 +397,7 @@ table.orderable tbody tr td:hover {
|
||||
|
||||
table.orderable tbody tr td:first-child {
|
||||
padding-left: 14px;
|
||||
background-image: url(../img/admin/nav-bg-grabber.gif);
|
||||
background-image: url(../img/nav-bg-grabber.gif);
|
||||
background-repeat: repeat-y;
|
||||
}
|
||||
|
||||
@@ -364,7 +427,7 @@ input[type=text], input[type=password], textarea, select, .vTextField {
|
||||
/* FORM BUTTONS */
|
||||
|
||||
.button, input[type=submit], input[type=button], .submit-row input {
|
||||
background: white url(../img/admin/nav-bg.gif) bottom repeat-x;
|
||||
background: white url(../img/nav-bg.gif) bottom repeat-x;
|
||||
padding: 3px 5px;
|
||||
color: black;
|
||||
border: 1px solid #bbb;
|
||||
@@ -372,31 +435,31 @@ input[type=text], input[type=password], textarea, select, .vTextField {
|
||||
}
|
||||
|
||||
.button:active, input[type=submit]:active, input[type=button]:active {
|
||||
background-image: url(../img/admin/nav-bg-reverse.gif);
|
||||
background-image: url(../img/nav-bg-reverse.gif);
|
||||
background-position: top;
|
||||
}
|
||||
|
||||
.button[disabled], input[type=submit][disabled], input[type=button][disabled] {
|
||||
background-image: url(../img/admin/nav-bg.gif);
|
||||
background-image: url(../img/nav-bg.gif);
|
||||
background-position: bottom;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.button.default, input[type=submit].default, .submit-row input.default {
|
||||
border: 2px solid #5b80b2;
|
||||
background: #7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x;
|
||||
background: #7CA0C7 url(../img/default-bg.gif) bottom repeat-x;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.button.default:active, input[type=submit].default:active {
|
||||
background-image: url(../img/admin/default-bg-reverse.gif);
|
||||
background-image: url(../img/default-bg-reverse.gif);
|
||||
background-position: top;
|
||||
}
|
||||
|
||||
.button[disabled].default, input[type=submit][disabled].default, input[type=button][disabled].default {
|
||||
background-image: url(../img/admin/default-bg.gif);
|
||||
background-image: url(../img/default-bg.gif);
|
||||
background-position: bottom;
|
||||
opacity: 0.4;
|
||||
}
|
||||
@@ -433,7 +496,7 @@ input[type=text], input[type=password], textarea, select, .vTextField {
|
||||
font-size: 11px;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
background: #7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x;
|
||||
background: #7CA0C7 url(../img/default-bg.gif) top left repeat-x;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -455,15 +518,15 @@ ul.messagelist li {
|
||||
margin: 0 0 3px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
color: #666;
|
||||
background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat;
|
||||
background: #ffc url(../img/icon_success.gif) 5px .3em no-repeat;
|
||||
}
|
||||
|
||||
ul.messagelist li.warning{
|
||||
background-image: url(../img/admin/icon_alert.gif);
|
||||
background-image: url(../img/icon_alert.gif);
|
||||
}
|
||||
|
||||
ul.messagelist li.error{
|
||||
background-image: url(../img/admin/icon_error.gif);
|
||||
background-image: url(../img/icon_error.gif);
|
||||
}
|
||||
|
||||
.errornote {
|
||||
@@ -473,7 +536,7 @@ ul.messagelist li.error{
|
||||
margin: 0 0 3px 0;
|
||||
border: 1px solid red;
|
||||
color: red;
|
||||
background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat;
|
||||
background: #ffc url(../img/icon_error.gif) 5px .3em no-repeat;
|
||||
}
|
||||
|
||||
ul.errorlist {
|
||||
@@ -488,7 +551,7 @@ ul.errorlist {
|
||||
margin: 0 0 3px 0;
|
||||
border: 1px solid red;
|
||||
color: white;
|
||||
background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat;
|
||||
background: red url(../img/icon_alert.gif) 5px .3em no-repeat;
|
||||
}
|
||||
|
||||
.errorlist li a {
|
||||
@@ -524,7 +587,7 @@ div.system-message p.system-message-title {
|
||||
padding: 4px 5px 4px 25px;
|
||||
margin: 0;
|
||||
color: red;
|
||||
background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat;
|
||||
background: #ffc url(../img/icon_error.gif) 5px .3em no-repeat;
|
||||
}
|
||||
|
||||
.description {
|
||||
@@ -535,7 +598,7 @@ div.system-message p.system-message-title {
|
||||
/* BREADCRUMBS */
|
||||
|
||||
div.breadcrumbs {
|
||||
background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
|
||||
background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x;
|
||||
padding: 2px 8px 3px 8px;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
@@ -548,17 +611,17 @@ div.breadcrumbs {
|
||||
|
||||
.addlink {
|
||||
padding-left: 12px;
|
||||
background: url(../img/admin/icon_addlink.gif) 0 .2em no-repeat;
|
||||
background: url(../img/icon_addlink.gif) 0 .2em no-repeat;
|
||||
}
|
||||
|
||||
.changelink {
|
||||
padding-left: 12px;
|
||||
background: url(../img/admin/icon_changelink.gif) 0 .2em no-repeat;
|
||||
background: url(../img/icon_changelink.gif) 0 .2em no-repeat;
|
||||
}
|
||||
|
||||
.deletelink {
|
||||
padding-left: 12px;
|
||||
background: url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat;
|
||||
background: url(../img/icon_deletelink.gif) 0 .25em no-repeat;
|
||||
}
|
||||
|
||||
a.deletelink:link, a.deletelink:visited {
|
||||
@@ -593,14 +656,14 @@ a.deletelink:hover {
|
||||
.object-tools li {
|
||||
display: block;
|
||||
float: left;
|
||||
background: url(../img/admin/tool-left.gif) 0 0 no-repeat;
|
||||
background: url(../img/tool-left.gif) 0 0 no-repeat;
|
||||
padding: 0 0 0 8px;
|
||||
margin-left: 2px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.object-tools li:hover {
|
||||
background: url(../img/admin/tool-left_over.gif) 0 0 no-repeat;
|
||||
background: url(../img/tool-left_over.gif) 0 0 no-repeat;
|
||||
}
|
||||
|
||||
.object-tools a:link, .object-tools a:visited {
|
||||
@@ -609,29 +672,29 @@ a.deletelink:hover {
|
||||
color: white;
|
||||
padding: .1em 14px .1em 8px;
|
||||
height: 14px;
|
||||
background: #999 url(../img/admin/tool-right.gif) 100% 0 no-repeat;
|
||||
background: #999 url(../img/tool-right.gif) 100% 0 no-repeat;
|
||||
}
|
||||
|
||||
.object-tools a:hover, .object-tools li:hover a {
|
||||
background: #5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat;
|
||||
background: #5b80b2 url(../img/tool-right_over.gif) 100% 0 no-repeat;
|
||||
}
|
||||
|
||||
.object-tools a.viewsitelink, .object-tools a.golink {
|
||||
background: #999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat;
|
||||
background: #999 url(../img/tooltag-arrowright.gif) top right no-repeat;
|
||||
padding-right: 28px;
|
||||
}
|
||||
|
||||
.object-tools a.viewsitelink:hover, .object-tools a.golink:hover {
|
||||
background: #5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat;
|
||||
background: #5b80b2 url(../img/tooltag-arrowright_over.gif) top right no-repeat;
|
||||
}
|
||||
|
||||
.object-tools a.addlink {
|
||||
background: #999 url(../img/admin/tooltag-add.gif) top right no-repeat;
|
||||
background: #999 url(../img/tooltag-add.gif) top right no-repeat;
|
||||
padding-right: 28px;
|
||||
}
|
||||
|
||||
.object-tools a.addlink:hover {
|
||||
background: #5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat;
|
||||
background: #5b80b2 url(../img/tooltag-add_over.gif) top right no-repeat;
|
||||
}
|
||||
|
||||
/* OBJECT HISTORY */
|
||||
@@ -766,7 +829,7 @@ table#change-history tbody th {
|
||||
}
|
||||
|
||||
#content-related .module h2 {
|
||||
background: #eee url(../img/admin/nav-bg.gif) bottom left repeat-x;
|
||||
background: #eee url(../img/nav-bg.gif) bottom left repeat-x;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
.change-list .filtered {
|
||||
background: white url(../img/admin/changelist-bg.gif) top right repeat-y !important;
|
||||
background: white url(../img/changelist-bg.gif) top right repeat-y !important;
|
||||
}
|
||||
|
||||
.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
|
||||
@@ -40,7 +40,7 @@
|
||||
color: #666;
|
||||
border-top: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
background: white url(../img/admin/nav-bg.gif) 0 180% repeat-x;
|
||||
background: white url(../img/nav-bg.gif) 0 180% repeat-x;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
/* CHANGELIST TABLES */
|
||||
|
||||
#changelist table thead th {
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
@@ -82,7 +83,7 @@
|
||||
#changelist #toolbar {
|
||||
padding: 3px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@@ -156,7 +157,7 @@
|
||||
|
||||
.change-list ul.toplinks {
|
||||
display: block;
|
||||
background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
|
||||
background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x;
|
||||
border-top: 1px solid white;
|
||||
float: left;
|
||||
padding: 0 !important;
|
||||
@@ -165,11 +166,10 @@
|
||||
}
|
||||
|
||||
.change-list ul.toplinks li {
|
||||
float: left;
|
||||
width: 9em;
|
||||
padding: 3px 6px;
|
||||
font-weight: bold;
|
||||
list-style-type: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.change-list ul.toplinks .date-back a {
|
||||
@@ -246,7 +246,7 @@
|
||||
padding: 3px;
|
||||
border-top: 1px solid #fff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
|
||||
background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x;
|
||||
}
|
||||
|
||||
#changelist .actions.selected {
|
||||
|
||||
@@ -140,7 +140,7 @@ fieldset.collapsed h2, fieldset.collapsed {
|
||||
}
|
||||
|
||||
fieldset.collapsed h2 {
|
||||
background-image: url(../img/admin/nav-bg.gif);
|
||||
background-image: url(../img/nav-bg.gif);
|
||||
background-position: bottom left;
|
||||
color: #999;
|
||||
}
|
||||
@@ -161,12 +161,16 @@ fieldset.monospace textarea {
|
||||
.submit-row {
|
||||
padding: 5px 7px;
|
||||
text-align: right;
|
||||
background: white url(../img/admin/nav-bg.gif) 0 100% repeat-x;
|
||||
background: white url(../img/nav-bg.gif) 0 100% repeat-x;
|
||||
border: 1px solid #ccc;
|
||||
margin: 5px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body.popup .submit-row {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.submit-row input {
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
@@ -180,7 +184,7 @@ fieldset.monospace textarea {
|
||||
}
|
||||
|
||||
.submit-row .deletelink {
|
||||
background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat;
|
||||
background: url(../img/icon_deletelink.gif) 0 50% no-repeat;
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
@@ -247,7 +251,7 @@ fieldset.monospace textarea {
|
||||
color: #666;
|
||||
padding: 3px 5px;
|
||||
font-size: 11px;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
@@ -332,7 +336,7 @@ fieldset.monospace textarea {
|
||||
color: #666;
|
||||
padding: 3px 5px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x;
|
||||
}
|
||||
|
||||
.inline-group .tabular tr.add-row td {
|
||||
@@ -343,7 +347,7 @@ fieldset.monospace textarea {
|
||||
.inline-group ul.tools a.add,
|
||||
.inline-group div.add-row a,
|
||||
.inline-group .tabular tr.add-row td a {
|
||||
background: url(../img/admin/icon_addlink.gif) 0 50% no-repeat;
|
||||
background: url(../img/icon_addlink.gif) 0 50% no-repeat;
|
||||
padding-left: 14px;
|
||||
font-size: 11px;
|
||||
outline: 0; /* Remove dotted border around link */
|
||||
@@ -352,9 +356,3 @@ fieldset.monospace textarea {
|
||||
.empty-form {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* IE7 specific bug fixes */
|
||||
|
||||
.submit-row input {
|
||||
float: right;
|
||||
}
|
||||
@@ -53,5 +53,11 @@
|
||||
/* IE doesn't know alpha transparency in PNGs */
|
||||
|
||||
.inline-deletelink {
|
||||
background: transparent url(../img/admin/inline-delete-8bit.png) no-repeat;
|
||||
background: transparent url(../img/inline-delete-8bit.png) no-repeat;
|
||||
}
|
||||
|
||||
/* IE7 doesn't support inline-block */
|
||||
.change-list ul.toplinks li {
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
}
|
||||
@@ -52,3 +52,6 @@ body.login {
|
||||
padding: 1em 0 0 9.4em;
|
||||
}
|
||||
|
||||
.login .password-reset-link {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -80,15 +80,8 @@ div.breadcrumbs {
|
||||
|
||||
/* SORTABLE TABLES */
|
||||
|
||||
|
||||
table thead th.sorted a {
|
||||
padding-left: 13px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
table thead th.ascending a,
|
||||
table thead th.descending a {
|
||||
background-position: left;
|
||||
table thead th.sorted .sortoptions {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* dashboard styles */
|
||||
@@ -100,12 +93,8 @@ table thead th.descending a {
|
||||
|
||||
/* changelists styles */
|
||||
|
||||
.change-list ul.toplinks li {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.change-list .filtered {
|
||||
background: white url(../img/admin/changelist-bg_rtl.gif) top left repeat-y !important;
|
||||
background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important;
|
||||
}
|
||||
|
||||
.change-list .filtered table {
|
||||
@@ -162,7 +151,7 @@ table thead th.descending a {
|
||||
}
|
||||
|
||||
.submit-row .deletelink {
|
||||
background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat;
|
||||
background: url(../img/icon_deletelink.gif) 0 50% no-repeat;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
@@ -183,6 +172,7 @@ input[type=submit].default, .submit-row input.default {
|
||||
fieldset .field-box {
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.errorlist li {
|
||||
@@ -236,9 +226,20 @@ fieldset .field-box {
|
||||
padding-left: inherit;
|
||||
left: 10px;
|
||||
right: inherit;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.inline-related h3 span.delete label {
|
||||
margin-left: inherit;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
/* IE7 specific bug fixes */
|
||||
|
||||
div.colM {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.submit-row input {
|
||||
float: left;
|
||||
}
|
||||
@@ -17,12 +17,16 @@
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.selector-chosen select {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.selector-available h2, .selector-chosen h2 {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.selector .selector-available h2 {
|
||||
background: white url(../img/admin/nav-bg.gif) bottom left repeat-x;
|
||||
background: white url(../img/nav-bg.gif) bottom left repeat-x;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@@ -37,8 +41,10 @@
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.selector .selector-chosen .selector-filter {
|
||||
padding: 4px 5px;
|
||||
.selector .selector-filter label,
|
||||
.inline-group .aligned .selector .selector-filter label {
|
||||
width: 16px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.selector .selector-available input {
|
||||
@@ -49,8 +55,8 @@
|
||||
float: left;
|
||||
width: 22px;
|
||||
height: 50px;
|
||||
background: url(../img/admin/chooser-bg.gif) top center no-repeat;
|
||||
margin: 8em 3px 0 3px;
|
||||
background: url(../img/chooser-bg.gif) top center no-repeat;
|
||||
margin: 10em 5px 0 5px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -61,7 +67,7 @@
|
||||
}
|
||||
|
||||
.selector select {
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -74,38 +80,66 @@
|
||||
}
|
||||
|
||||
.selector-add {
|
||||
background: url(../img/admin/selector-add.gif) top center no-repeat;
|
||||
background: url(../img/selector-icons.gif) 0 -161px no-repeat;
|
||||
cursor: default;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.active.selector-add {
|
||||
background: url(../img/selector-icons.gif) 0 -187px no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selector-remove {
|
||||
background: url(../img/admin/selector-remove.gif) top center no-repeat;
|
||||
background: url(../img/selector-icons.gif) 0 -109px no-repeat;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.active.selector-remove {
|
||||
background: url(../img/selector-icons.gif) 0 -135px no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.selector-chooseall, a.selector-clearall {
|
||||
display: block;
|
||||
width: 6em;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
a.selector-chooseall {
|
||||
padding: 3px 18px 3px 0;
|
||||
}
|
||||
|
||||
a.selector-clearall {
|
||||
padding: 3px 0 3px 18px;
|
||||
}
|
||||
|
||||
a.selector-chooseall:hover, a.selector-clearall:hover {
|
||||
a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
|
||||
color: #036;
|
||||
}
|
||||
|
||||
a.selector-chooseall {
|
||||
width: 7em;
|
||||
background: url(../img/admin/selector-addall.gif) left center no-repeat;
|
||||
background: url(../img/selector-icons.gif) right -263px no-repeat;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
a.active.selector-chooseall {
|
||||
background: url(../img/selector-icons.gif) right -289px no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.selector-clearall {
|
||||
background: url(../img/admin/selector-removeall.gif) left center no-repeat;
|
||||
background: url(../img/selector-icons.gif) left -211px no-repeat;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
a.active.selector-clearall {
|
||||
background: url(../img/selector-icons.gif) left -237px no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* STACKED SELECTORS */
|
||||
|
||||
@@ -135,7 +169,7 @@ a.selector-clearall {
|
||||
height: 22px;
|
||||
width: 50px;
|
||||
margin: 0 0 3px 40%;
|
||||
background: url(../img/admin/chooser_stacked-bg.gif) top center no-repeat;
|
||||
background: url(../img/chooser_stacked-bg.gif) top center no-repeat;
|
||||
}
|
||||
|
||||
.stacked .selector-chooser li {
|
||||
@@ -148,13 +182,24 @@ a.selector-clearall {
|
||||
}
|
||||
|
||||
.stacked .selector-add {
|
||||
background-image: url(../img/admin/selector_stacked-add.gif);
|
||||
background: url(../img/selector-icons.gif) 0 -57px no-repeat;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.stacked .active.selector-add {
|
||||
background: url(../img/selector-icons.gif) 0 -83px no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.stacked .selector-remove {
|
||||
background-image: url(../img/admin/selector_stacked-remove.gif);
|
||||
background: url(../img/selector-icons.gif) 0 -5px no-repeat;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.stacked .active.selector-remove {
|
||||
background: url(../img/selector-icons.gif) 0 -31px no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* DATE AND TIME */
|
||||
|
||||
@@ -231,7 +276,7 @@ span.clearable-file-input label {
|
||||
padding: 0;
|
||||
border-collapse: collapse;
|
||||
background: white;
|
||||
width: 99%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.calendar caption, .calendarbox h2 {
|
||||
@@ -246,7 +291,7 @@ span.clearable-file-input label {
|
||||
color: #666;
|
||||
padding: 2px 3px;
|
||||
text-align: center;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) 0 50% repeat-x;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
@@ -314,7 +359,7 @@ span.clearable-file-input label {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
background: #C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x;
|
||||
background: #C9DBED url(../img/default-bg.gif) bottom left repeat-x;
|
||||
padding: 1px 4px 2px 4px;
|
||||
color: white;
|
||||
}
|
||||
@@ -335,15 +380,19 @@ span.clearable-file-input label {
|
||||
|
||||
.calendar-cancel {
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
padding: 0 !important;
|
||||
font-size: 10px;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) 0 50% repeat-x;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.calendar-cancel:hover {
|
||||
background: #e1e1e1 url(../img/nav-bg-reverse.gif) 0 50% repeat-x;
|
||||
}
|
||||
|
||||
.calendar-cancel a {
|
||||
padding: 2px;
|
||||
color: #999;
|
||||
color: black;
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.timelist, .timelist li {
|
||||
@@ -374,7 +423,7 @@ ul.orderer li {
|
||||
border-width: 0 1px 1px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
background: #e2e2e2 url(../img/admin/nav-bg-grabber.gif) repeat-y;
|
||||
background: #e2e2e2 url(../img/nav-bg-grabber.gif) repeat-y;
|
||||
}
|
||||
|
||||
ul.orderer li:hover {
|
||||
@@ -406,7 +455,7 @@ ul.orderer li.selected {
|
||||
}
|
||||
|
||||
ul.orderer li.deleted {
|
||||
background: #bbb url(../img/admin/deleted-overlay.gif);
|
||||
background: #bbb url(../img/deleted-overlay.gif);
|
||||
}
|
||||
|
||||
ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited {
|
||||
@@ -414,7 +463,7 @@ ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited {
|
||||
}
|
||||
|
||||
ul.orderer li.deleted .inline-deletelink {
|
||||
background-image: url(../img/admin/inline-restore.png);
|
||||
background-image: url(../img/inline-restore.png);
|
||||
}
|
||||
|
||||
ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover {
|
||||
@@ -426,7 +475,7 @@ ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover {
|
||||
.inline-deletelink {
|
||||
float: right;
|
||||
text-indent: -9999px;
|
||||
background: transparent url(../img/admin/inline-delete.png) no-repeat;
|
||||
background: transparent url(../img/inline-delete.png) no-repeat;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 0px none;
|
||||
@@ -465,11 +514,11 @@ ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover {
|
||||
}
|
||||
|
||||
.editinline tr.deleted {
|
||||
background: #ddd url(../img/admin/deleted-overlay.gif);
|
||||
background: #ddd url(../img/deleted-overlay.gif);
|
||||
}
|
||||
|
||||
.editinline tr.deleted .inline-deletelink {
|
||||
background-image: url(../img/admin/inline-restore.png);
|
||||
background-image: url(../img/inline-restore.png);
|
||||
}
|
||||
|
||||
.editinline tr.deleted td:hover {
|
||||
@@ -500,13 +549,13 @@ ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover {
|
||||
.editinline-stacked .inline-splitter {
|
||||
float: left;
|
||||
width: 9px;
|
||||
background: #f8f8f8 url(../img/admin/inline-splitter-bg.gif) 50% 50% no-repeat;
|
||||
background: #f8f8f8 url(../img/inline-splitter-bg.gif) 50% 50% no-repeat;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.editinline-stacked .controls {
|
||||
clear: both;
|
||||
background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
|
||||
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x;
|
||||
padding: 3px 4px;
|
||||
font-size: 11px;
|
||||
border-top: 1px solid #ddd;
|
||||
|
||||
BIN
lms/static/admin/img/changelist-bg.gif
Normal file
|
After Width: | Height: | Size: 58 B |
BIN
lms/static/admin/img/changelist-bg_rtl.gif
Normal file
|
After Width: | Height: | Size: 75 B |
BIN
lms/static/admin/img/chooser-bg.gif
Normal file
|
After Width: | Height: | Size: 199 B |
BIN
lms/static/admin/img/chooser_stacked-bg.gif
Normal file
|
After Width: | Height: | Size: 212 B |
BIN
lms/static/admin/img/default-bg-reverse.gif
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
lms/static/admin/img/default-bg.gif
Normal file
|
After Width: | Height: | Size: 844 B |
BIN
lms/static/admin/img/deleted-overlay.gif
Normal file
|
After Width: | Height: | Size: 45 B |
BIN
lms/static/admin/img/icon-no.gif
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
lms/static/admin/img/icon-unknown.gif
Normal file
|
After Width: | Height: | Size: 130 B |
BIN
lms/static/admin/img/icon-yes.gif
Normal file
|
After Width: | Height: | Size: 299 B |
BIN
lms/static/admin/img/icon_addlink.gif
Normal file
|
After Width: | Height: | Size: 119 B |
BIN
lms/static/admin/img/icon_alert.gif
Normal file
|
After Width: | Height: | Size: 145 B |
BIN
lms/static/admin/img/icon_calendar.gif
Normal file
|
After Width: | Height: | Size: 192 B |
BIN
lms/static/admin/img/icon_changelink.gif
Normal file
|
After Width: | Height: | Size: 119 B |
BIN
lms/static/admin/img/icon_clock.gif
Normal file
|
After Width: | Height: | Size: 390 B |
BIN
lms/static/admin/img/icon_deletelink.gif
Normal file
|
After Width: | Height: | Size: 181 B |
BIN
lms/static/admin/img/icon_error.gif
Normal file
|
After Width: | Height: | Size: 319 B |
BIN
lms/static/admin/img/icon_searchbox.png
Normal file
|
After Width: | Height: | Size: 667 B |
BIN
lms/static/admin/img/icon_success.gif
Normal file
|
After Width: | Height: | Size: 341 B |
BIN
lms/static/admin/img/inline-delete-8bit.png
Normal file
|
After Width: | Height: | Size: 477 B |
BIN
lms/static/admin/img/inline-delete.png
Normal file
|
After Width: | Height: | Size: 781 B |
BIN
lms/static/admin/img/inline-restore-8bit.png
Normal file
|
After Width: | Height: | Size: 447 B |
BIN
lms/static/admin/img/inline-restore.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
lms/static/admin/img/inline-splitter-bg.gif
Normal file
|
After Width: | Height: | Size: 102 B |
BIN
lms/static/admin/img/nav-bg-grabber.gif
Normal file
|
After Width: | Height: | Size: 116 B |
BIN
lms/static/admin/img/nav-bg-reverse.gif
Normal file
|
After Width: | Height: | Size: 186 B |
BIN
lms/static/admin/img/nav-bg-selected.gif
Normal file
|
After Width: | Height: | Size: 265 B |
BIN
lms/static/admin/img/nav-bg.gif
Normal file
|
After Width: | Height: | Size: 273 B |
BIN
lms/static/admin/img/selector-icons.gif
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
lms/static/admin/img/selector-search.gif
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
lms/static/admin/img/sorting-icons.gif
Normal file
|
After Width: | Height: | Size: 369 B |
BIN
lms/static/admin/img/tool-left.gif
Normal file
|
After Width: | Height: | Size: 197 B |
BIN
lms/static/admin/img/tool-left_over.gif
Normal file
|
After Width: | Height: | Size: 203 B |
BIN
lms/static/admin/img/tool-right.gif
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
lms/static/admin/img/tool-right_over.gif
Normal file
|
After Width: | Height: | Size: 200 B |
BIN
lms/static/admin/img/tooltag-add.gif
Normal file
|
After Width: | Height: | Size: 932 B |
BIN
lms/static/admin/img/tooltag-add_over.gif
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
lms/static/admin/img/tooltag-arrowright.gif
Normal file
|
After Width: | Height: | Size: 351 B |
BIN
lms/static/admin/img/tooltag-arrowright_over.gif
Normal file
|
After Width: | Height: | Size: 354 B |
@@ -1,11 +1,9 @@
|
||||
/*
|
||||
SelectFilter2 - Turns a multiple-select box into a filter interface.
|
||||
|
||||
Different than SelectFilter because this is coupled to the admin framework.
|
||||
|
||||
Requires core.js, SelectBox.js and addevent.js.
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
function findForm(node) {
|
||||
// returns the node of the form containing the given node
|
||||
if (node.tagName.toLowerCase() != 'form') {
|
||||
@@ -14,7 +12,7 @@ function findForm(node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
var SelectFilter = {
|
||||
window.SelectFilter = {
|
||||
init: function(field_id, field_name, is_stacked, admin_media_prefix) {
|
||||
if (field_id.match(/__prefix__/)){
|
||||
// Don't intialize on empty forms.
|
||||
@@ -44,41 +42,42 @@ var SelectFilter = {
|
||||
// <div class="selector-available">
|
||||
var selector_available = quickElement('div', selector_div, '');
|
||||
selector_available.className = 'selector-available';
|
||||
quickElement('h2', selector_available, interpolate(gettext('Available %s'), [field_name]));
|
||||
var filter_p = quickElement('p', selector_available, '');
|
||||
var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
|
||||
quickElement('img', title_available, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name]));
|
||||
|
||||
var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
|
||||
filter_p.className = 'selector-filter';
|
||||
|
||||
var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input", 'style', 'width:16px;padding:2px');
|
||||
var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input");
|
||||
|
||||
var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/admin/selector-search.gif');
|
||||
search_selector_img.alt = gettext("Filter");
|
||||
var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_media_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name]));
|
||||
|
||||
filter_p.appendChild(document.createTextNode(' '));
|
||||
|
||||
var filter_input = quickElement('input', filter_p, '', 'type', 'text');
|
||||
var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
|
||||
filter_input.id = field_id + '_input';
|
||||
|
||||
selector_available.appendChild(from_box);
|
||||
var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); })()');
|
||||
var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link');
|
||||
choose_all.className = 'selector-chooseall';
|
||||
|
||||
// <ul class="selector-chooser">
|
||||
var selector_chooser = quickElement('ul', selector_div, '');
|
||||
selector_chooser.className = 'selector-chooser';
|
||||
var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Add'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to");})()');
|
||||
var add_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link');
|
||||
add_link.className = 'selector-add';
|
||||
var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from");})()');
|
||||
var remove_link = quickElement('a', quickElement('li', selector_chooser, ''), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link');
|
||||
remove_link.className = 'selector-remove';
|
||||
|
||||
// <div class="selector-chosen">
|
||||
var selector_chosen = quickElement('div', selector_div, '');
|
||||
selector_chosen.className = 'selector-chosen';
|
||||
quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
|
||||
var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
|
||||
selector_filter.className = 'selector-filter';
|
||||
quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add');
|
||||
var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
|
||||
quickElement('img', title_chosen, '', 'src', admin_media_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name]));
|
||||
|
||||
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
|
||||
to_box.className = 'filtered';
|
||||
var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
|
||||
var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link');
|
||||
clear_all.className = 'selector-clearall';
|
||||
|
||||
from_box.setAttribute('name', from_box.getAttribute('name') + '_old');
|
||||
@@ -86,16 +85,46 @@ var SelectFilter = {
|
||||
// Set up the JavaScript event handlers for the select box filter interface
|
||||
addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); });
|
||||
addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); });
|
||||
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); });
|
||||
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); });
|
||||
addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
|
||||
addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) });
|
||||
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); });
|
||||
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); });
|
||||
addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); });
|
||||
SelectBox.init(field_id + '_from');
|
||||
SelectBox.init(field_id + '_to');
|
||||
// Move selected from_box options to to_box
|
||||
SelectBox.move(field_id + '_from', field_id + '_to');
|
||||
|
||||
if (!is_stacked) {
|
||||
// In horizontal mode, give the same height to the two boxes.
|
||||
var j_from_box = $(from_box);
|
||||
var j_to_box = $(to_box);
|
||||
var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); }
|
||||
if (j_from_box.outerHeight() > 0) {
|
||||
resize_filters(); // This fieldset is already open. Resize now.
|
||||
} else {
|
||||
// This fieldset is probably collapsed. Wait for its 'show' event.
|
||||
j_to_box.closest('fieldset').one('show.fieldset', resize_filters);
|
||||
}
|
||||
}
|
||||
|
||||
// Initial icon refresh
|
||||
SelectFilter.refresh_icons(field_id);
|
||||
},
|
||||
refresh_icons: function(field_id) {
|
||||
var from = $('#' + field_id + '_from');
|
||||
var to = $('#' + field_id + '_to');
|
||||
var is_from_selected = from.find('option:selected').length > 0;
|
||||
var is_to_selected = to.find('option:selected').length > 0;
|
||||
// Active if at least one item is selected
|
||||
$('#' + field_id + '_add_link').toggleClass('active', is_from_selected);
|
||||
$('#' + field_id + '_remove_link').toggleClass('active', is_to_selected);
|
||||
// Active if the corresponding box isn't empty
|
||||
$('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);
|
||||
$('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);
|
||||
},
|
||||
filter_key_up: function(event, field_id) {
|
||||
from = document.getElementById(field_id + '_from');
|
||||
var from = document.getElementById(field_id + '_from');
|
||||
// don't submit form if user pressed Enter
|
||||
if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
|
||||
from.selectedIndex = 0;
|
||||
@@ -109,7 +138,7 @@ var SelectFilter = {
|
||||
return true;
|
||||
},
|
||||
filter_key_down: function(event, field_id) {
|
||||
from = document.getElementById(field_id + '_from');
|
||||
var from = document.getElementById(field_id + '_from');
|
||||
// right arrow -- move across
|
||||
if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) {
|
||||
var old_index = from.selectedIndex;
|
||||
@@ -128,3 +157,5 @@ var SelectFilter = {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
})(django.jQuery);
|
||||
|
||||
12
lms/static/admin/js/actions.min.js
vendored
@@ -1,7 +1,7 @@
|
||||
(function(a){a.fn.actions=function(h){var b=a.extend({},a.fn.actions.defaults,h),e=a(this),f=false;checker=function(c){c?showQuestion():reset();a(e).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(e).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},true));a(b.allToggle).attr("checked",function(){if(c==e.length){value=true;showQuestion()}else{value=
|
||||
false;clearAcross()}return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};
|
||||
a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();a(b.acrossInput).val()==1&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",false);clearAcross();checker(0);
|
||||
updateCounter()});lastChecked=null;a(e).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&c.shiftKey==true){var g=false;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(e).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))g=g?false:true;g&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,
|
||||
d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){f=true});a('form#changelist-form button[name="index"]').click(function(){if(f)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var c=false;a("div.actions select option:selected").each(function(){if(a(this).val())c=
|
||||
true});if(c)return f?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",
|
||||
(function(a){a.fn.actions=function(g){var b=a.extend({},a.fn.actions.defaults,g),f=a(this),e=!1;checker=function(c){c?showQuestion():reset();a(f).attr("checked",c).parent().parent().toggleClass(b.selectedClass,c)};updateCounter=function(){var c=a(f).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).attr("checked",function(){c==f.length?(value=!0,showQuestion()):(value=
|
||||
!1,clearAcross());return value})};showQuestion=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()};showClear=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()};reset=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()};clearAcross=function(){reset();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};
|
||||
a(b.counterContainer).show();a(this).filter(":checked").each(function(){a(this).parent().parent().toggleClass(b.selectedClass);updateCounter();1==a(b.acrossInput).val()&&showClear()});a(b.allToggle).show().click(function(){checker(a(this).attr("checked"));updateCounter()});a("div.actions span.question a").click(function(c){c.preventDefault();a(b.acrossInput).val(1);showClear()});a("div.actions span.clear a").click(function(c){c.preventDefault();a(b.allToggle).attr("checked",!1);clearAcross();checker(0);
|
||||
updateCounter()});lastChecked=null;a(f).click(function(c){if(!c)c=window.event;var d=c.target?c.target:c.srcElement;if(lastChecked&&a.data(lastChecked)!=a.data(d)&&!0==c.shiftKey){var e=!1;a(lastChecked).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(f).each(function(){if(a.data(this)==a.data(lastChecked)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).attr("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,
|
||||
d.checked);lastChecked=d;updateCounter()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});a('form#changelist-form input[name="_save"]').click(function(){var b=!1;a("div.actions select option:selected").each(function(){a(this).val()&&(b=!0)});
|
||||
if(b)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",
|
||||
acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);
|
||||
|
||||
@@ -50,7 +50,7 @@ var DateTimeShortcuts = {
|
||||
var clock_link = document.createElement('a');
|
||||
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
|
||||
clock_link.id = DateTimeShortcuts.clockLinkName + num;
|
||||
quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_clock.gif', 'alt', gettext('Clock'));
|
||||
quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/icon_clock.gif', 'alt', gettext('Clock'));
|
||||
shortcuts_span.appendChild(document.createTextNode('\240'));
|
||||
shortcuts_span.appendChild(now_link);
|
||||
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
||||
@@ -79,17 +79,24 @@ var DateTimeShortcuts = {
|
||||
addEvent(clock_box, 'click', DateTimeShortcuts.cancelEventPropagation);
|
||||
|
||||
quickElement('h2', clock_box, gettext('Choose a time'));
|
||||
time_list = quickElement('ul', clock_box, '');
|
||||
var time_list = quickElement('ul', clock_box, '');
|
||||
time_list.className = 'timelist';
|
||||
time_format = get_format('TIME_INPUT_FORMATS')[0];
|
||||
var time_format = get_format('TIME_INPUT_FORMATS')[0];
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));");
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));");
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));");
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));");
|
||||
|
||||
cancel_p = quickElement('p', clock_box, '');
|
||||
var cancel_p = quickElement('p', clock_box, '');
|
||||
cancel_p.className = 'calendar-cancel';
|
||||
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');');
|
||||
django.jQuery(document).bind('keyup', function(event) {
|
||||
if (event.which == 27) {
|
||||
// ESC key closes popup
|
||||
DateTimeShortcuts.dismissClock(num);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
openClock: function(num) {
|
||||
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num)
|
||||
@@ -138,7 +145,7 @@ var DateTimeShortcuts = {
|
||||
var cal_link = document.createElement('a');
|
||||
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');');
|
||||
cal_link.id = DateTimeShortcuts.calendarLinkName + num;
|
||||
quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/admin/icon_calendar.gif', 'alt', gettext('Calendar'));
|
||||
quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/icon_calendar.gif', 'alt', gettext('Calendar'));
|
||||
shortcuts_span.appendChild(document.createTextNode('\240'));
|
||||
shortcuts_span.appendChild(today_link);
|
||||
shortcuts_span.appendChild(document.createTextNode('\240|\240'));
|
||||
@@ -195,6 +202,13 @@ var DateTimeShortcuts = {
|
||||
var cancel_p = quickElement('p', cal_box, '');
|
||||
cancel_p.className = 'calendar-cancel';
|
||||
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');');
|
||||
django.jQuery(document).bind('keyup', function(event) {
|
||||
if (event.which == 27) {
|
||||
// ESC key closes popup
|
||||
DateTimeShortcuts.dismissCalendar(num);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
openCalendar: function(num) {
|
||||
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
|
||||
|
||||
@@ -74,11 +74,12 @@ function dismissAddAnotherPopup(win, newId, newRepr) {
|
||||
var name = windowname_to_id(win.name);
|
||||
var elem = document.getElementById(name);
|
||||
if (elem) {
|
||||
if (elem.nodeName == 'SELECT') {
|
||||
var elemName = elem.nodeName.toUpperCase();
|
||||
if (elemName == 'SELECT') {
|
||||
var o = new Option(newRepr, newId);
|
||||
elem.options[elem.options.length] = o;
|
||||
o.selected = true;
|
||||
} else if (elem.nodeName == 'INPUT') {
|
||||
} else if (elemName == 'INPUT') {
|
||||
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
|
||||
elem.value += ',' + newId;
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,7 @@ function reorder_init() {
|
||||
setOrder(input.value.split(','));
|
||||
input.disabled = true;
|
||||
draw();
|
||||
// Now initialise the dragging behaviour
|
||||
// Now initialize the dragging behavior
|
||||
var limit = (lis.length - 1) * height;
|
||||
for (var i = 0; i < lis.length; i++) {
|
||||
var li = lis[i];
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
// Add anchor tag for Show/Hide link
|
||||
$("fieldset.collapse").each(function(i, elem) {
|
||||
// Don't hide if fields in this fieldset have errors
|
||||
if ( $(elem).find("div.errors").length == 0 ) {
|
||||
$(elem).addClass("collapsed");
|
||||
$(elem).find("h2").first().append(' (<a id="fieldsetcollapser' +
|
||||
if ($(elem).find("div.errors").length == 0) {
|
||||
$(elem).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser' +
|
||||
i +'" class="collapse-toggle" href="#">' + gettext("Show") +
|
||||
'</a>)');
|
||||
}
|
||||
@@ -13,13 +12,11 @@
|
||||
// Add toggle to anchor tag
|
||||
$("fieldset.collapse a.collapse-toggle").toggle(
|
||||
function() { // Show
|
||||
$(this).text(gettext("Hide"));
|
||||
$(this).closest("fieldset").removeClass("collapsed");
|
||||
$(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
|
||||
return false;
|
||||
},
|
||||
function() { // Hide
|
||||
$(this).text(gettext("Show"));
|
||||
$(this).closest("fieldset").addClass("collapsed");
|
||||
$(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
4
lms/static/admin/js/collapse.min.js
vendored
@@ -1,2 +1,2 @@
|
||||
(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){if(a(b).find("div.errors").length==0){a(b).addClass("collapsed");a(b).find("h2").first().append(' (<a id="fieldsetcollapser'+c+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")}});a("fieldset.collapse a.collapse-toggle").toggle(function(){a(this).text(gettext("Hide"));a(this).closest("fieldset").removeClass("collapsed");return false},function(){a(this).text(gettext("Show"));a(this).closest("fieldset").addClass("collapsed");
|
||||
return false})})})(django.jQuery);
|
||||
(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){0==a(b).find("div.errors").length&&a(b).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser'+c+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")});a("fieldset.collapse a.collapse-toggle").toggle(function(){a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]);return!1},function(){a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset",
|
||||
[a(this).attr("id")]);return!1})})})(django.jQuery);
|
||||
|
||||
@@ -108,12 +108,6 @@ function findPosY(obj) {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Date object extensions
|
||||
// ----------------------------------------------------------------------------
|
||||
Date.prototype.getCorrectYear = function() {
|
||||
// Date.getYear() is unreliable --
|
||||
// see http://www.quirksmode.org/js/introdate.html#year
|
||||
var y = this.getYear() % 100;
|
||||
return (y < 38) ? y + 2000 : y + 1900;
|
||||
}
|
||||
|
||||
Date.prototype.getTwelveHours = function() {
|
||||
hours = this.getHours();
|
||||
@@ -149,10 +143,6 @@ Date.prototype.getTwoDigitSecond = function() {
|
||||
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
|
||||
}
|
||||
|
||||
Date.prototype.getISODate = function() {
|
||||
return this.getCorrectYear() + '-' + this.getTwoDigitMonth() + '-' + this.getTwoDigitDate();
|
||||
}
|
||||
|
||||
Date.prototype.getHourMinute = function() {
|
||||
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
|
||||
}
|
||||
|
||||
10
lms/static/admin/js/inlines.min.js
vendored
@@ -1,5 +1,5 @@
|
||||
(function(b){b.fn.formset=function(g){var a=b.extend({},b.fn.formset.defaults,g),k=function(c,f,d){var e=new RegExp("("+f+"-(\\d+|__prefix__))");f=f+"-"+d;b(c).attr("for")&&b(c).attr("for",b(c).attr("for").replace(e,f));if(c.id)c.id=c.id.replace(e,f);if(c.name)c.name=c.name.replace(e,f)};g=b("#id_"+a.prefix+"-TOTAL_FORMS").attr("autocomplete","off");var l=parseInt(g.val()),h=b("#id_"+a.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off");g=h.val()==""||h.val()-g.val()>0;b(this).each(function(){b(this).not("."+
|
||||
a.emptyCssClass).addClass(a.formCssClass)});if(b(this).length&&g){var j;if(b(this).attr("tagName")=="TR"){g=this.eq(0).children().length;b(this).parent().append('<tr class="'+a.addCssClass+'"><td colspan="'+g+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>");j=b(this).parent().find("tr:last a")}else{b(this).filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>");j=b(this).filter(":last").next().find("a")}j.click(function(){var c=b("#id_"+
|
||||
a.prefix+"-TOTAL_FORMS"),f=b("#"+a.prefix+"-empty"),d=f.clone(true);d.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);if(d.is("tr"))d.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>");else d.is("ul")||d.is("ol")?d.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):d.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+
|
||||
a.deleteText+"</a></span>");d.find("*").each(function(){k(this,a.prefix,c.val())});d.insertBefore(b(f));b(c).val(parseInt(c.val())+1);l+=1;h.val()!=""&&h.val()-c.val()<=0&&j.parent().hide();d.find("a."+a.deleteCssClass).click(function(){var e=b(this).parents("."+a.formCssClass);e.remove();l-=1;a.removed&&a.removed(e);e=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(e.length);if(h.val()==""||h.val()-e.length>0)j.parent().show();for(var i=0,m=e.length;i<m;i++){k(b(e).get(i),a.prefix,i);
|
||||
b(e.get(i)).find("*").each(function(){k(this,a.prefix,i)})}return false});a.added&&a.added(d);return false})}return this};b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null}})(django.jQuery);
|
||||
(function(b){b.fn.formset=function(c){var a=b.extend({},b.fn.formset.defaults,c),j=function(a,e,d){var i=RegExp("("+e+"-(\\d+|__prefix__))"),e=e+"-"+d;b(a).attr("for")&&b(a).attr("for",b(a).attr("for").replace(i,e));if(a.id)a.id=a.id.replace(i,e);if(a.name)a.name=a.name.replace(i,e)},c=b("#id_"+a.prefix+"-TOTAL_FORMS").attr("autocomplete","off"),g=parseInt(c.val()),f=b("#id_"+a.prefix+"-MAX_NUM_FORMS").attr("autocomplete","off"),c=""==f.val()||0<f.val()-c.val();b(this).each(function(){b(this).not("."+
|
||||
a.emptyCssClass).addClass(a.formCssClass)});if(b(this).length&&c){var h;"TR"==b(this).attr("tagName")?(c=this.eq(0).children().length,b(this).parent().append('<tr class="'+a.addCssClass+'"><td colspan="'+c+'"><a href="javascript:void(0)">'+a.addText+"</a></tr>"),h=b(this).parent().find("tr:last a")):(b(this).filter(":last").after('<div class="'+a.addCssClass+'"><a href="javascript:void(0)">'+a.addText+"</a></div>"),h=b(this).filter(":last").next().find("a"));h.click(function(){var c=b("#id_"+a.prefix+
|
||||
"-TOTAL_FORMS"),e=b("#"+a.prefix+"-empty"),d=e.clone(!0);d.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+g);d.is("tr")?d.children(":last").append('<div><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></div>"):d.is("ul")||d.is("ol")?d.append('<li><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+"</a></li>"):d.children(":first").append('<span><a class="'+a.deleteCssClass+'" href="javascript:void(0)">'+a.deleteText+
|
||||
"</a></span>");d.find("*").each(function(){j(this,a.prefix,c.val())});d.insertBefore(b(e));b(c).val(parseInt(c.val())+1);g+=1;""!=f.val()&&0>=f.val()-c.val()&&h.parent().hide();d.find("a."+a.deleteCssClass).click(function(){var c=b(this).parents("."+a.formCssClass);c.remove();g-=1;a.removed&&a.removed(c);c=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(c.length);(""==f.val()||0<f.val()-c.length)&&h.parent().show();for(var d=0,e=c.length;d<e;d++)j(b(c).get(d),a.prefix,d),b(c.get(d)).find("*").each(function(){j(this,
|
||||
a.prefix,d)});return!1});a.added&&a.added(d);return!1})}return this};b.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null}})(django.jQuery);
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
// Puts the included jQuery into our own namespace
|
||||
/* Puts the included jQuery into our own namespace using noConflict and passing
|
||||
* it 'true'. This ensures that the included jQuery doesn't pollute the global
|
||||
* namespace (i.e. this preserves pre-existing values for both window.$ and
|
||||
* window.jQuery).
|
||||
*/
|
||||
var django = {
|
||||
"jQuery": jQuery.noConflict(true)
|
||||
};
|
||||
|
||||
2
lms/static/admin/js/prepopulate.min.js
vendored
@@ -1 +1 @@
|
||||
(function(a){a.fn.prepopulate=function(d,g){return this.each(function(){var b=a(this);b.data("_changed",false);b.change(function(){b.data("_changed",true)});var c=function(){if(b.data("_changed")!=true){var e=[];a.each(d,function(h,f){a(f).val().length>0&&e.push(a(f).val())});b.val(URLify(e.join(" "),g))}};a(d.join(",")).keyup(c).change(c).focus(c)})}})(django.jQuery);
|
||||
(function(a){a.fn.prepopulate=function(d,e){return this.each(function(){var b=a(this);b.data("_changed",!1);b.change(function(){b.data("_changed",!0)});var c=function(){if(!0!=b.data("_changed")){var c=[];a.each(d,function(b,d){0<a(d).val().length&&c.push(a(d).val())});b.val(URLify(c.join(" "),e))}};a(d.join(",")).keyup(c).change(c).focus(c)})}})(django.jQuery);
|
||||
|
||||
@@ -42,11 +42,15 @@
|
||||
<a href="${reverse('about_edx')}">About</a>
|
||||
<a href="http://edxonline.tumblr.com/">Blog</a>
|
||||
<a href="${reverse('jobs')}">Jobs</a>
|
||||
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
|
||||
<a href="#login-modal" id="login" rel="leanModal">Log In</a>
|
||||
% endif
|
||||
</li>
|
||||
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
|
||||
<li class="primary">
|
||||
<a href="#signup-modal" id="signup" rel="leanModal">Sign Up</a>
|
||||
</li>
|
||||
% endif
|
||||
</ol>
|
||||
</nav>
|
||||
%endif
|
||||
|
||||
@@ -1,15 +1,122 @@
|
||||
${module_content}
|
||||
%if edit_link:
|
||||
<div><a href="${edit_link}">Edit</a></div>
|
||||
<div><a href="${edit_link}">Edit</a> / <a href="#${element_id}_xqa-modal" onclick="getlog_${element_id}()" id="${element_id}_xqa_log">QA</a></div>
|
||||
% endif
|
||||
<div><a href="javascript:void(0)" onclick="javascript:$('#${element_id}_debug').slideToggle()">Staff Debug Info</a></div>
|
||||
<div><a href="#${element_id}_debug" id="${element_id}_trig">Staff Debug Info</a></div>
|
||||
|
||||
<span style="display:none" id="${element_id}_debug">
|
||||
<div class="staff_info">
|
||||
<section id="${element_id}_xqa-modal" class="modal xqa-modal" style="width:80%; left:20%; height:80%; overflow:auto" >
|
||||
<div class="inner-wrapper">
|
||||
<header>
|
||||
<h2>edX Content Quality Assessment</h2>
|
||||
</header>
|
||||
|
||||
<form id="${element_id}_xqa_form" class="xqa_form">
|
||||
<label>Comment</label>
|
||||
<input id="${element_id}_xqa_entry" type="text" placeholder="comment">
|
||||
<label>Tag</label>
|
||||
<span style="color:black;vertical-align: -10pt">Optional tag (eg "done" or "broken"): </span>
|
||||
<input id="${element_id}_xqa_tag" type="text" placeholder="tag" style="width:80px;display:inline">
|
||||
<div class="submit">
|
||||
<button name="submit" type="submit">Add comment</button>
|
||||
</div>
|
||||
<hr>
|
||||
<div id="${element_id}_xqa_log_data"></div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="modal staff-modal" id="${element_id}_debug" style="width:80%; left:20%; height:80%; overflow:auto;" >
|
||||
<div class="inner-wrapper" style="color:black">
|
||||
<header>
|
||||
<h2>Staff Debug</h2>
|
||||
</header>
|
||||
<div class="staff_info">
|
||||
location = ${location | h}
|
||||
github = <a href="${edit_link}">${edit_link | h}</a>
|
||||
definition = <pre>${definition | h}</pre>
|
||||
metadata = ${metadata | h}
|
||||
</div>
|
||||
%if render_histogram:
|
||||
<div id="histogram_${element_id}" class="histogram" data-histogram="${histogram}"></div>
|
||||
%endif
|
||||
</span>
|
||||
category = ${category | h}
|
||||
</div>
|
||||
%if render_histogram:
|
||||
<div id="histogram_${element_id}" class="histogram" data-histogram="${histogram}"></div>
|
||||
%endif
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="${element_id}_setup"></div>
|
||||
|
||||
## leanModal needs to be included here otherwise this breaks when in a <vertical>
|
||||
<script type="text/javascript" src="/static/js/vendor/jquery.leanModal.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function setup_debug_${element_id}(){
|
||||
$('#${element_id}_trig').leanModal();
|
||||
$('#${element_id}_xqa_log').leanModal();
|
||||
$('#${element_id}_xqa_form').submit(sendlog_${element_id});
|
||||
}
|
||||
|
||||
setup_debug_${element_id}();
|
||||
|
||||
function sendlog_${element_id}(){
|
||||
|
||||
var xqaLog = {authkey: '${xqa_key}',
|
||||
location: '${location}',
|
||||
%if edit_link:
|
||||
giturl: '${edit_link}',
|
||||
%endif
|
||||
category : '${category}',
|
||||
username : '${user.username}',
|
||||
return : 'query',
|
||||
format : 'html',
|
||||
email : '${user.email}',
|
||||
tag:$('#${element_id}_xqa_tag').val(),
|
||||
entry: $('#${element_id}_xqa_entry').val()};
|
||||
|
||||
$.ajax({
|
||||
url: '${xqa_server}/log',
|
||||
type: 'GET',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(xqaLog),
|
||||
crossDomain: true,
|
||||
dataType: 'jsonp',
|
||||
beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", "Basic eHFhOmFnYXJ3YWw="); },
|
||||
timeout : 1000,
|
||||
success: function(result) {
|
||||
$('#${element_id}_xqa_log_data').html(result);
|
||||
},
|
||||
error: function() {
|
||||
alert('Error: cannot connect to XQA server');
|
||||
console.log('error!');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
function getlog_${element_id}(){
|
||||
|
||||
var xqaQuery = {authkey: '${xqa_key}',
|
||||
location: '${location}',
|
||||
format: 'html'};
|
||||
|
||||
$.ajax({
|
||||
url: '${xqa_server}/query',
|
||||
type: 'GET',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(xqaQuery),
|
||||
crossDomain: true,
|
||||
dataType: 'jsonp',
|
||||
timeout : 1000,
|
||||
success: function(result) {
|
||||
$('#${element_id}_xqa_log_data').html(result);
|
||||
},
|
||||
error: function() {
|
||||
alert('Error: cannot connect to XQA server');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ except Exception as err:
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User, Group
|
||||
from path import path
|
||||
from lxml import etree
|
||||
|
||||
data_dir = settings.DATA_DIR
|
||||
print "data_dir = %s" % data_dir
|
||||
@@ -26,7 +27,17 @@ for course_dir in os.listdir(data_dir):
|
||||
# print course_dir
|
||||
if not os.path.isdir(path(data_dir) / course_dir):
|
||||
continue
|
||||
gname = 'staff_%s' % course_dir
|
||||
|
||||
cxfn = path(data_dir) / course_dir / 'course.xml'
|
||||
coursexml = etree.parse(cxfn)
|
||||
cxmlroot = coursexml.getroot()
|
||||
course = cxmlroot.get('course')
|
||||
if course is None:
|
||||
print "oops, can't get course id for %s" % course_dir
|
||||
continue
|
||||
print "course=%s for course_dir=%s" % (course,course_dir)
|
||||
|
||||
gname = 'staff_%s' % course
|
||||
if Group.objects.filter(name=gname):
|
||||
print "group exists for %s" % gname
|
||||
continue
|
||||
|
||||