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
53b22cbf
Commit
53b22cbf
authored
Oct 08, 2015
by
Amir Qayyum Khan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made dates configuration for CCX schedule same as in studio (Course)
parent
8102bd51
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
291 additions
and
80 deletions
+291
-80
lms/djangoapps/ccx/tests/test_views.py
+31
-6
lms/djangoapps/ccx/views.py
+74
-17
lms/static/js/ccx/schedule.js
+68
-9
lms/static/sass/course/ccx_coach/_dashboard.scss
+48
-0
lms/templates/ccx/schedule.html
+31
-27
lms/templates/ccx/schedule.underscore
+39
-21
No files found.
lms/djangoapps/ccx/tests/test_views.py
View file @
53b22cbf
...
...
@@ -52,6 +52,7 @@ from ccx_keys.locator import CCXLocator
from
lms.djangoapps.ccx.models
import
CustomCourseForEdX
from
lms.djangoapps.ccx.overrides
import
get_override_for_ccx
,
override_field_for_ccx
from
lms.djangoapps.ccx.tests.factories
import
CcxFactory
from
lms.djangoapps.ccx.views
import
get_date
def
intercept_renderer
(
path
,
context
):
...
...
@@ -290,6 +291,21 @@ class TestCoachDashboard(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
role
=
CourseCcxCoachRole
(
course_key
)
self
.
assertTrue
(
role
.
has_user
(
self
.
coach
))
def
test_get_date
(
self
):
"""
Assert that get_date returns valid date.
"""
ccx
=
self
.
make_ccx
()
for
section
in
self
.
course
.
get_children
():
self
.
assertEqual
(
get_date
(
ccx
,
section
,
'start'
),
self
.
mooc_start
)
self
.
assertEqual
(
get_date
(
ccx
,
section
,
'due'
),
None
)
for
subsection
in
section
.
get_children
():
self
.
assertEqual
(
get_date
(
ccx
,
subsection
,
'start'
),
self
.
mooc_start
)
self
.
assertEqual
(
get_date
(
ccx
,
subsection
,
'due'
),
self
.
mooc_due
)
for
unit
in
subsection
.
get_children
():
self
.
assertEqual
(
get_date
(
ccx
,
unit
,
'start'
,
parent_node
=
subsection
),
self
.
mooc_start
)
self
.
assertEqual
(
get_date
(
ccx
,
unit
,
'due'
,
parent_node
=
subsection
),
self
.
mooc_due
)
@SharedModuleStoreTestCase.modifies_courseware
@patch
(
'ccx.views.render_to_response'
,
intercept_renderer
)
@patch
(
'ccx.views.TODAY'
)
...
...
@@ -341,15 +357,24 @@ class TestCoachDashboard(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
kwargs
=
{
'course_id'
:
CCXLocator
.
from_course_locator
(
self
.
course
.
id
,
ccx
.
id
)})
response
=
self
.
client
.
get
(
url
)
schedule
=
json
.
loads
(
response
.
mako_context
[
'schedule'
])
# pylint: disable=no-member
self
.
assertEqual
(
len
(
schedule
),
2
)
self
.
assertEqual
(
schedule
[
0
][
'hidden'
],
False
)
self
.
assertEqual
(
schedule
[
0
][
'start'
],
None
)
self
.
assertEqual
(
schedule
[
0
][
'children'
][
0
][
'start'
],
None
)
self
.
assertEqual
(
schedule
[
0
][
'due'
],
None
)
self
.
assertEqual
(
schedule
[
0
][
'children'
][
0
][
'due'
],
None
)
# If a coach does not override dates, then dates will be imported from master course.
self
.
assertEqual
(
schedule
[
0
][
'children'
][
0
][
'children'
][
0
][
'due'
],
None
schedule
[
0
][
'start'
],
self
.
chapters
[
0
]
.
start
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M'
)
)
self
.
assertEqual
(
schedule
[
0
][
'children'
][
0
][
'start'
],
self
.
sequentials
[
0
]
.
start
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M'
)
)
if
self
.
sequentials
[
0
]
.
due
:
expected_due
=
self
.
sequentials
[
0
]
.
due
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M'
)
else
:
expected_due
=
None
self
.
assertEqual
(
schedule
[
0
][
'children'
][
0
][
'due'
],
expected_due
)
url
=
reverse
(
'save_ccx'
,
...
...
@@ -392,7 +417,7 @@ class TestCoachDashboard(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
# scheduled chapter
ccx
=
CustomCourseForEdX
.
objects
.
get
()
course_start
=
get_override_for_ccx
(
ccx
,
self
.
course
,
'start'
)
self
.
assertEqual
(
str
(
course_start
)[:
-
9
],
u'2014-11-20 00:00'
)
self
.
assertEqual
(
str
(
course_start
)[:
-
9
],
self
.
chapters
[
0
]
.
start
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M'
)
)
# Make sure grading policy adjusted
policy
=
get_override_for_ccx
(
ccx
,
self
.
course
,
'grading_policy'
,
...
...
lms/djangoapps/ccx/views.py
View file @
53b22cbf
...
...
@@ -274,10 +274,16 @@ def save_ccx(request, course, ccx=None):
ccx_ids_to_delete
.
append
(
get_override_for_ccx
(
ccx
,
block
,
'start_id'
))
clear_ccx_field_info_from_ccx_map
(
ccx
,
block
,
'start'
)
due
=
parse_date
(
unit
[
'due'
])
if
due
:
override_field_for_ccx
(
ccx
,
block
,
'due'
,
due
)
# Only subsection (aka sequential) and unit (aka vertical) have due dates.
if
'due'
in
unit
:
# checking that the key (due) exist in dict (unit).
due
=
parse_date
(
unit
[
'due'
])
if
due
:
override_field_for_ccx
(
ccx
,
block
,
'due'
,
due
)
else
:
ccx_ids_to_delete
.
append
(
get_override_for_ccx
(
ccx
,
block
,
'due_id'
))
clear_ccx_field_info_from_ccx_map
(
ccx
,
block
,
'due'
)
else
:
# In case of section aka chapter we do not have due date.
ccx_ids_to_delete
.
append
(
get_override_for_ccx
(
ccx
,
block
,
'due_id'
))
clear_ccx_field_info_from_ccx_map
(
ccx
,
block
,
'due'
)
...
...
@@ -398,6 +404,35 @@ def get_ccx_for_coach(course, coach):
return
None
def
get_date
(
ccx
,
node
,
date_type
=
None
,
parent_node
=
None
):
"""
This returns override or master date for section, subsection or a unit.
:param ccx: ccx instance
:param node: chapter, subsection or unit
:param date_type: start or due
:param parent_node: parent of node
:return: start or due date
"""
date
=
get_override_for_ccx
(
ccx
,
node
,
date_type
,
None
)
if
date_type
==
"start"
:
master_date
=
node
.
start
else
:
master_date
=
node
.
due
if
date
is
not
None
:
# Setting override date [start or due]
date
=
date
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M'
)
elif
not
parent_node
and
master_date
is
not
None
:
# Setting date from master course
date
=
master_date
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M'
)
elif
parent_node
is
not
None
:
# Set parent date (vertical has same dates as subsections)
date
=
get_date
(
ccx
,
node
=
parent_node
,
date_type
=
date_type
)
return
date
def
get_ccx_schedule
(
course
,
ccx
):
"""
Generate a JSON serializable CCX schedule.
...
...
@@ -409,28 +444,50 @@ def get_ccx_schedule(course, ccx):
widgets, which use text inputs.
Visits students visible nodes only; nodes children of hidden ones
are skipped as well.
Dates:
Only start date is applicable to a section. If ccx coach did not override start date then
getting it from the master course.
Both start and due dates are applicable to a subsection (aka sequential). If ccx coach did not override
these dates then getting these dates from corresponding subsection in master course.
Unit inherits start date and due date from its subsection. If ccx coach did not override these dates
then getting them from corresponding subsection in master course.
"""
for
child
in
node
.
get_children
():
# in case the children are visible to staff only, skip them
if
child
.
visible_to_staff_only
:
continue
start
=
get_override_for_ccx
(
ccx
,
child
,
'start'
,
None
)
if
start
:
start
=
str
(
start
)[:
-
9
]
due
=
get_override_for_ccx
(
ccx
,
child
,
'due'
,
None
)
if
due
:
due
=
str
(
due
)[:
-
9
]
hidden
=
get_override_for_ccx
(
ccx
,
child
,
'visible_to_staff_only'
,
child
.
visible_to_staff_only
)
visited
=
{
'location'
:
str
(
child
.
location
),
'display_name'
:
child
.
display_name
,
'category'
:
child
.
category
,
'start'
:
start
,
'due'
:
due
,
'hidden'
:
hidden
,
}
start
=
get_date
(
ccx
,
child
,
'start'
)
if
depth
>
1
:
# Subsection has both start and due dates and unit inherit dates from their subsections
if
depth
==
2
:
due
=
get_date
(
ccx
,
child
,
'due'
)
elif
depth
==
3
:
# Get start and due date of subsection in case unit has not override dates.
due
=
get_date
(
ccx
,
child
,
'due'
,
node
)
start
=
get_date
(
ccx
,
child
,
'start'
,
node
)
visited
=
{
'location'
:
str
(
child
.
location
),
'display_name'
:
child
.
display_name
,
'category'
:
child
.
category
,
'start'
:
start
,
'due'
:
due
,
'hidden'
:
hidden
,
}
else
:
visited
=
{
'location'
:
str
(
child
.
location
),
'display_name'
:
child
.
display_name
,
'category'
:
child
.
category
,
'start'
:
start
,
'hidden'
:
hidden
,
}
if
depth
<
3
:
children
=
tuple
(
visit
(
child
,
depth
+
1
))
if
children
:
...
...
lms/static/js/ccx/schedule.js
View file @
53b22cbf
...
...
@@ -49,6 +49,9 @@ var edx = edx || {};
self
.
render
();
});
// By default input date and time fileds are disable.
self
.
disableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
disableFields
(
$
(
'.ccx_start_date_time_fields'
));
// Add unit handlers
this
.
chapter_select
.
on
(
'change'
,
function
()
{
var
chapter_location
=
self
.
chapter_select
.
val
();
...
...
@@ -60,10 +63,15 @@ var edx = edx || {};
.
append
(
self
.
schedule_options
(
chapter
.
children
));
self
.
sequential_select
.
prop
(
'disabled'
,
false
);
$
(
'#add-unit-button'
).
prop
(
'disabled'
,
false
);
self
.
set_datetime
(
'start'
,
chapter
.
start
);
self
.
set_datetime
(
'due'
,
chapter
.
due
);
// When a chapter is selected, start date fields are enabled and due date
// fields are disabled because due dates are not applicable on a chapter.
self
.
disableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
enableFields
(
$
(
'.ccx_start_date_time_fields'
));
}
else
{
self
.
sequential_select
.
html
(
''
).
prop
(
'disabled'
,
true
);
// When no chapter is selected, all date fields are disabled.
self
.
disableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
disableFields
(
$
(
'.ccx_start_date_time_fields'
));
}
});
...
...
@@ -78,8 +86,15 @@ var edx = edx || {};
self
.
vertical_select
.
prop
(
'disabled'
,
false
);
self
.
set_datetime
(
'start'
,
sequential
.
start
);
self
.
set_datetime
(
'due'
,
sequential
.
due
);
// When a subsection (aka sequential) is selected,
// both start and due date fields are enabled.
self
.
enableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
enableFields
(
$
(
'.ccx_start_date_time_fields'
));
}
else
{
// When "All subsections" is selected, all date fields are disabled.
self
.
vertical_select
.
html
(
''
).
prop
(
'disabled'
,
true
);
self
.
disableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
enableFields
(
$
(
'.ccx_start_date_time_fields'
));
}
});
...
...
@@ -90,8 +105,16 @@ var edx = edx || {};
sequential
=
self
.
sequential_select
.
val
();
var
vertical
=
self
.
find_unit
(
self
.
hidden
,
chapter
,
sequential
,
vertical_location
);
self
.
set_datetime
(
'start'
,
vertical
.
start
);
self
.
set_datetime
(
'due'
,
vertical
.
due
);
// When a unit (aka vertical) is selected, all date fields are disabled because units
// inherit dates from subsection
self
.
disableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
disableFields
(
$
(
'.ccx_start_date_time_fields'
));
}
else
{
// When "All units" is selected, all date fields are enabled,
// because units inherit dates from subsections and we
// are showing dates from the selected subsection.
self
.
enableFields
(
$
(
'.ccx_due_date_time_fields'
));
self
.
enableFields
(
$
(
'.ccx_start_date_time_fields'
));
}
});
...
...
@@ -330,6 +353,14 @@ var edx = edx || {};
});
},
disableFields
:
function
(
$selector
)
{
$selector
.
find
(
'select,input,button'
).
prop
(
'disabled'
,
true
);
},
enableFields
:
function
(
$selector
)
{
$selector
.
find
(
'select,input,button'
).
prop
(
'disabled'
,
false
);
},
toggle_collapse
:
function
(
event
)
{
event
.
preventDefault
();
var
row
=
$
(
this
).
closest
(
'tr'
);
...
...
@@ -344,10 +375,19 @@ var edx = edx || {};
$
(
this
).
attr
(
'aria-expanded'
,
'true'
);
$
(
this
).
find
(
".fa-caret-right"
).
removeClass
(
'fa-caret-right'
).
addClass
(
'fa-caret-down'
);
row
.
removeClass
(
'collapsed'
).
addClass
(
'expanded'
);
children
.
filter
(
'.collapsed'
).
each
(
function
()
{
children
=
children
.
not
(
self
.
get_children
(
this
));
});
children
.
show
();
var
depth
=
$
(
row
).
data
(
'depth'
);
var
$childNodes
=
children
.
filter
(
'.collapsed'
);
if
(
$childNodes
.
length
<=
0
)
{
children
.
show
();
}
else
{
// this will expand units.
$childNodes
.
each
(
function
()
{
var
depthChild
=
$
(
this
).
data
(
'depth'
);
if
(
depth
===
(
depthChild
-
1
))
{
$
(
this
).
show
();
}
});
}
}
},
...
...
@@ -374,9 +414,9 @@ var edx = edx || {};
$
(
row
).
find
(
'.ccx_sr_alert'
).
attr
(
'aria-expanded'
,
'false'
);
$
(
row
).
find
(
'.fa-caret-down'
).
removeClass
(
'fa-caret-down'
).
addClass
(
'fa-caret-right'
);
row
.
removeClass
(
'expanded'
).
addClass
(
'collapsed'
);
$
(
'table.ccx-schedule .sequential,.vertical'
).
hide
();
}
});
$
(
'table.ccx-schedule .sequential,.vertical'
).
hide
();
},
enterNewDate
:
function
(
what
)
{
...
...
@@ -429,8 +469,14 @@ var edx = edx || {};
}
if
(
what
===
'start'
)
{
unit
.
start
=
date
+
' '
+
time
;
if
(
unit
.
category
===
"sequential"
)
{
self
.
updateChildrenDates
(
unit
,
what
,
unit
.
start
);
}
}
else
{
unit
.
due
=
date
+
' '
+
time
;
if
(
unit
.
category
===
"sequential"
)
{
self
.
updateChildrenDates
(
unit
,
what
,
unit
.
due
);
}
}
modal
.
find
(
'.close-modal'
).
click
();
self
.
dirty
=
true
;
...
...
@@ -440,6 +486,19 @@ var edx = edx || {};
};
},
updateChildrenDates
:
function
(
sequential
,
date_type
,
date
)
{
// This code iterates the children (aka verticals) of a sequential.
// It updates start and due dates to corresponding dates
// of sequential (parent).
_
.
forEach
(
sequential
.
children
,
function
(
unit
)
{
if
(
date_type
===
'start'
)
{
unit
.
start
=
date
;
}
else
{
unit
.
due
=
date
;
}
});
},
find_unit
:
function
(
tree
,
chapter
,
sequential
,
vertical
)
{
var
units
=
self
.
find_lineage
(
tree
,
chapter
,
sequential
,
vertical
);
return
units
[
units
.
length
-
1
];
...
...
lms/static/sass/course/ccx_coach/_dashboard.scss
View file @
53b22cbf
...
...
@@ -18,6 +18,11 @@ table.ccx-schedule {
th
,
td
{
padding
:
10px
;
}
td
.no-link
{
font-size
:
13px
;
text-shadow
:
0
1px
0
#fcfbfb
;
text-decoration
:
none
;
}
.sequential
.unit
{
padding-left
:
25px
;
}
...
...
@@ -40,6 +45,7 @@ table.ccx-schedule {
margin-left
:
20px
;
}
.ccx-sidebar-panel
{
border
:
1px
solid
#cbcbcb
;
padding
:
15px
;
...
...
@@ -48,8 +54,46 @@ table.ccx-schedule {
form
.ccx-form
{
line-height
:
1
.5
;
// inspiration was taken from https://github.com/edx/ux-pattern-library
select
{
@include
font-size
(
16
);
background
:
#fcfcfc
;
border
:
1px
solid
#e9e8e8
;
box-sizing
:
padding-box
;
color
:
#282c2e
;
display
:
inline-block
;
font-size
:
(
$baseline
*.
9
.5
);
height
:
40px
;
line-height
:
20px
;
padding
:
10px
;
transition
:
all
125ms
ease-in-out
0s
;
width
:
100%
;
&
:disabled
{
border-color
:
#cfd8dc
;
background
:
#e7ecee
;
cursor
:
not
-
allowed
;
}
}
input
{
@include
font-size
(
15
);
background
:
#FCFCFC
none
repeat
scroll
0%
0%
;
border
:
1px
solid
#E7E6E6
;
box-sizing
:
border-box
;
color
:
#34383A
;
display
:
inline-block
;
line-height
:
normal
;
transition
:
all
0
.125s
ease-in-out
0s
;
padding
:
5px
10px
5px
10px
;
&
:focus
{
border-color
:
#0ea6ec
;
color
:
#282c2e
;
outline
:
0
;
}
&
:disabled
{
border-color
:
#cfd8dc
;
background
:
#e7ecee
;
cursor
:
not
-
allowed
;
}
}
.field
{
margin
:
5px
0
5px
0
;
...
...
@@ -72,6 +116,10 @@ button.ccx-button-link {
}
&
:hover
{
color
:
brown
;
background
:
none
;
}
&
:focus
{
background
:
none
;
}
}
...
...
lms/templates/ccx/schedule.html
View file @
53b22cbf
...
...
@@ -39,14 +39,14 @@
<header>
<h2
id=
"ccx_schedule_set_date_heading"
></h2>
</header>
<form>
<form
class=
"ccx-form"
>
<div
class=
"field datepair"
>
## Translators: This explains to people using a screen reader how to interpret the format of YYYY-MM-DD
<label
class=
"sr form-label"
for=
"ccx_dialog_date"
>
${_('Date format four digit year dash two digit month dash two digit day')}
</label>
<input
placeholder=
"
Date
"
class=
"date"
type=
"text"
name=
"date"
id=
"ccx_dialog_date"
size=
"11"
/>
<input
placeholder=
"
${_('Date')}
"
class=
"date"
type=
"text"
name=
"date"
id=
"ccx_dialog_date"
size=
"11"
/>
## Translators: This explains to people using a screen reader how to interpret the format of HH:MM
<label
class=
"sr form-label"
for=
"ccx_dialog_time"
>
${_('Time format two digit hours colon two digit minutes')}
</label>
<input
placeholder=
"
Time
"
class=
"time"
type=
"text"
name=
"time"
id=
"ccx_dialog_time"
size=
"6"
/>
<input
placeholder=
"
${_('Time')}
"
class=
"time"
type=
"text"
name=
"time"
id=
"ccx_dialog_time"
size=
"6"
/>
</div>
<div
class=
"field"
>
<button
type=
"submit"
class=
"btn btn-primary"
>
${_('Set date')}
</button>
...
...
@@ -63,7 +63,7 @@
<p
id=
"message_save"
class=
"text-helper"
>
${_("You have unsaved changes.")}
</p>
<div
class=
"field"
>
<br/>
<button
id=
"save-changes"
aria-describedby=
"message_save"
>
${_("Save changes")}
</button>
<button
id=
"save-changes"
aria-describedby=
"message_save"
class=
"ccx-schedule-save-changes"
>
${_("Save changes")}
</button>
</div>
</form>
</div>
...
...
@@ -87,31 +87,35 @@
<label
for=
"ccx_vertical"
class=
"form-label"
><b>
${_('Unit')}
</b></label>
<select
name=
"vertical"
id=
"ccx_vertical"
></select>
</div>
<div
class=
"field datepair"
>
<label
for=
"ccx_start_date"
class=
"form-label"
>
<b>
${_('Start Date')}
</b>
<span
class=
"sr"
>
## Translators: This explains to people using a screen reader how to interpret the format of YYYY-MM-DD
${_('format four digit year dash two digit month dash two digit day')}
</span>
</label>
<input
placeholder=
"yyyy-mm-dd"
type=
"text"
class=
"date"
name=
"start_date"
id=
"ccx_start_date"
/>
## Translators: This explains to people using a screen reader how to interpret the format of HH:MM
<label
for=
"ccx_start_time"
class=
"sr form-label"
>
${_('Start time format two digit hours colon two digit minutes')}
</label>
<input
placeholder=
"time"
type=
"text"
class=
"time"
name=
"start_time"
id=
"ccx_start_time"
/>
</div>
<div
class=
"field datepair"
>
<label
for=
"ccx_due_date"
class=
"form-label"
>
<b>
${_('Due Date')}
</b>
${_('(Optional)')}
<span
class=
"sr"
>
<div
class=
"ccx_start_date_time_fields"
>
<div
class=
"field datepair"
>
<label
for=
"ccx_start_date"
class=
"form-label"
>
<b>
${_('Start Date')}
</b>
<span
class=
"sr"
>
## Translators: This explains to people using a screen reader how to interpret the format of YYYY-MM-DD
${_('format four digit year dash two digit month dash two digit day')}
</span>
</label>
<input
placeholder=
"yyyy-mm-dd"
type=
"text"
class=
"date"
name=
"due_date"
id=
"ccx_due_date"
/>
## Translators: This explains to people using a screen reader how to interpret the format of HH:MM
<label
for=
"ccx_due_time"
class=
"sr form-label"
>
${_('Due Time format two digit hours colon two digit minutes')}
</label>
<input
placeholder=
"time"
type=
"text"
class=
"time"
name=
"due_time"
id=
"ccx_due_time"
/>
</span>
</label>
<input
placeholder=
"${_('yyyy-mm-dd')}"
type=
"text"
class=
"date"
name=
"start_date"
id=
"ccx_start_date"
/>
## Translators: This explains to people using a screen reader how to interpret the format of HH:MM
<label
for=
"ccx_start_time"
class=
"sr form-label"
>
${_('Start time format two digit hours colon two digit minutes')}
</label>
<input
placeholder=
"${_('time')}"
type=
"text"
class=
"time"
name=
"start_time"
id=
"ccx_start_time"
/>
</div>
</div>
<div
class=
"ccx_due_date_time_fields"
>
<div
class=
"field datepair"
>
<label
for=
"ccx_due_date"
class=
"form-label"
>
<b>
${_('Due Date')}
</b>
${_('(Optional)')}
<span
class=
"sr"
>
## Translators: This explains to people using a screen reader how to interpret the format of YYYY-MM-DD
${_('format four digit year dash two digit month dash two digit day')}
</span>
</label>
<input
placeholder=
"${_('yyyy-mm-dd')}"
type=
"text"
class=
"date"
name=
"due_date"
id=
"ccx_due_date"
/>
## Translators: This explains to people using a screen reader how to interpret the format of HH:MM
<label
for=
"ccx_due_time"
class=
"sr form-label"
>
${_('Due Time format two digit hours colon two digit minutes')}
</label>
<input
placeholder=
"${_('time')}"
type=
"text"
class=
"time"
name=
"due_time"
id=
"ccx_due_time"
/>
</div>
</div>
<div
class=
"field"
>
<br/>
...
...
lms/templates/ccx/schedule.underscore
View file @
53b22cbf
...
...
@@ -24,9 +24,13 @@
<td class="unit">
<button class="toggle-collapse ccx-button-link" aria-expanded="false">
<i class="fa fa-caret-right"></i>
<span class="sr"><%- gettext('toggle chapter') %> <%= chapter.display_name %></span>
<span class="sr">
<%- interpolate(gettext('toggle chapter %(displayName)s'),
{displayName: chapter.display_name}, true) %>
</span>
</button>
<span class="sr"><%- gettext('Section') %> </span><%= chapter.display_name %>
<span class="sr">
<%- gettext('Section') %> </span><%= chapter.display_name %>
</td>
<td class="date start-date">
<button class="ccx-button-link">
...
...
@@ -34,13 +38,11 @@
<span class="sr"><%- gettext('Click to change') %></span>
</button>
</td>
<td class="date due-date">
<button class="ccx-button-link">
<%= chapter.due %>
<span class="sr"><%- gettext('Click to change') %></span>
</button>
<td class="date due-date no-link">
<%- gettext('N/A') %>
</td>
<td><button class="remove-unit ccx-button-link" aria-label="Remove chapter <%= chapter.display_name %>">
<td><button class="remove-unit ccx-button-link" aria-label="<%- interpolate(
gettext('Remove chapter %(chapterDisplayName)s'), {chapterDisplayName: chapter.display_name}, true) %>">
<i class="fa fa-remove" aria-hidden="true"></i> <%- gettext('remove') %>
</button></td>
</tr>
...
...
@@ -50,7 +52,10 @@
<td class="unit">
<button class="toggle-collapse ccx-button-link" aria-expanded="false">
<i class="fa fa-caret-right"></i>
<span class="sr"><%- gettext('toggle subsection') %> <%= child.display_name %></span>
<span class="sr">
<%- interpolate(gettext('toggle subsection %(displayName)s'),
{displayName: child.display_name}, true) %>
</span>
</button>
<span class="sr"><%- gettext('Subsection') %> </span><%= child.display_name %>
</td>
...
...
@@ -66,32 +71,45 @@
<span class="sr"><%- gettext('Click to change') %></span>
</button>
</td>
<td><button class="remove-unit ccx-button-link" aria-label="Remove subsection <%= child.display_name %>">
<td><button class="remove-unit ccx-button-link" aria-label="<%- interpolate(
gettext('Remove subsection %(subsectionDisplayName)s'), {subsectionDisplayName: child.display_name}, true) %>">
<i class="fa fa-remove" aria-hidden="true"></i> <%- gettext('remove') %>
</button></td>
</tr>
<% _.each(child.children, function(subchild) { %>
<tr class="vertical" data-d
a
pth="3"
<tr class="vertical" data-d
e
pth="3"
data-location="<%= chapter.location %> <%= child.location %> <%= subchild.location %>">
<td class="unit">
<span class="sr"><%- gettext('Unit') %> </span>
<%= subchild.display_name %>
</td>
<td class="date start-date">
<
button class="ccx-button-link"
>
<td class="date start-date
no-link
">
<
% if (subchild.start) { %
>
<%= subchild.start %>
<span class="sr"><%- gettext('Click to change') %></span>
</button>
<% } else { %>
<%
// Translators: Unit's aka vertical start date is set to Unscheduled when user has not set start date on corresponding subsection aka sequential.
%>
<%- gettext('Unscheduled') %>
<% } %>
</td>
<td class="date due-date">
<
button class="ccx-button-link"
>
<td class="date due-date
no-link
">
<
% if (subchild.due) { %
>
<%= subchild.due %>
<span class="sr"><%- gettext('Click to change') %></span>
<% } else { %>
<%
// Translators: Unit's aka vertical due date is set to Unscheduled when user has not set due date on corresponding subsection aka sequential.
%>
<%- gettext('Unscheduled') %>
<% } %>
</td>
<td>
<button class="remove-unit ccx-button-link" aria-label="<%- interpolate(
gettext('Remove unit %(unitName)s'), {unitName: subchild.display_name}, true) %>">
<i class="fa fa-remove" aria-hidden="true"></i> <%- gettext('remove') %>
</button>
</td>
<td><button class="remove-unit ccx-button-link" aria-label="Remove unit <%= subchild.display_name %>">
<i class="fa fa-remove" aria-hidden="true"></i> <%- gettext('remove') %>
</button></td>
</tr>
<% }); %>
<% }); %>
<% }); %>
...
...
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