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
eff80bae
Commit
eff80bae
authored
Jun 30, 2015
by
Diana Huang
Committed by
cahrens
Jul 20, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert cohort JS to use RequireJS.
parent
1ceb8a0d
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1143 additions
and
1234 deletions
+1143
-1234
lms/static/js/groups/collections/cohort.js
+11
-12
lms/static/js/groups/models/cohort.js
+25
-26
lms/static/js/groups/models/cohort_discussions.js
+10
-12
lms/static/js/groups/models/content_group.js
+11
-13
lms/static/js/groups/models/course_cohort_settings.js
+13
-14
lms/static/js/groups/views/cohort_discussions.js
+86
-87
lms/static/js/groups/views/cohort_discussions_course_wide.js
+72
-73
lms/static/js/groups/views/cohort_discussions_inline.js
+142
-143
lms/static/js/groups/views/cohort_editor.js
+247
-248
lms/static/js/groups/views/cohort_form.js
+170
-169
lms/static/js/groups/views/cohorts.js
+303
-301
lms/static/js/groups/views/cohorts_dashboard_factory.js
+14
-7
lms/static/js/groups/views/course_cohort_settings_notification.js
+23
-24
lms/static/js/spec/main.js
+0
-69
lms/static/lms/js/build.js
+1
-0
lms/templates/instructor/instructor_dashboard_2/cohort_management.html
+15
-23
lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html
+0
-13
No files found.
lms/static/js/groups/collections/cohort.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
Backbone
,
CohortModel
)
{
'use strict'
;
'use strict'
;
define
([
'backbone'
,
'js/groups/models/cohort'
],
function
(
Backbone
,
CohortModel
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
CohortCollection
=
Backbone
.
Collection
.
extend
({
model
:
CohortModel
,
edx
.
groups
.
CohortCollection
=
Backbone
.
Collection
.
extend
({
comparator
:
"name"
,
model
:
CohortModel
,
comparator
:
"name"
,
parse
:
function
(
response
)
{
parse
:
function
(
response
)
{
return
response
.
cohorts
;
return
response
.
cohorts
;
}
}
});
return
CohortCollection
;
});
});
}).
call
(
this
,
Backbone
,
edx
.
groups
.
CohortModel
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/groups/models/cohort.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
Backbone
)
{
'use strict'
;
'use strict'
;
define
([
'backbone'
],
function
(
Backbone
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
CohortModel
=
Backbone
.
Model
.
extend
({
idAttribute
:
'id'
,
edx
.
groups
.
CohortModel
=
Backbone
.
Model
.
extend
(
{
defaults
:
{
idAttribute
:
'id
'
,
name
:
'
'
,
defaults
:
{
user_count
:
0
,
name
:
''
,
/**
user_count
:
0
,
* Indicates how students are added to the cohort. Will be "none" (signifying manual assignment) or
/**
* "random" (indicating students are randomly assigned).
* Indicates how students are added to the cohort. Will be "none" (signifying manual assignment) or
*/
* "random" (indicating students are randomly assigned).
assignment_type
:
''
,
*/
/**
assignment_type
:
''
,
* If this cohort is associated with a user partition group, the ID of the user partition.
/**
*/
* If this cohort is associated with a user partition group, the ID of the user partition.
user_partition_id
:
null
,
*/
/**
user_partition_id
:
null
,
* If this cohort is associated with a user partition group, the ID of the group within the
/**
* partition associated with user_partition_id.
* If this cohort is associated with a user partition group, the ID of the group within the
*/
* partition associated with user_partition_id.
group_id
:
null
*/
}
group_id
:
null
});
}
return
CohortModel
;
});
});
}).
call
(
this
,
Backbo
ne
);
}).
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/groups/models/cohort_discussions.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
Backbone
)
{
'use strict'
;
'use strict'
;
define
([
'backbone'
],
function
(
Backbone
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
DiscussionTopicsSettingsModel
=
Backbone
.
Model
.
extend
({
defaults
:
{
edx
.
groups
.
DiscussionTopicsSettingsModel
=
Backbone
.
Model
.
extend
({
course_wide_discussions
:
{},
defaults
:
{
inline_discussions
:
{}
course_wide_discussions
:
{},
}
inline_discussions
:
{}
});
}
return
DiscussionTopicsSettingsModel
;
});
});
}).
call
(
this
,
Backbo
ne
);
}).
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/groups/models/content_group.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
Backbone
)
{
'use strict'
;
'use strict'
;
define
([
'backbone'
],
function
(
Backbone
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
ContentGroupModel
=
Backbone
.
Model
.
extend
({
idAttribute
:
'id'
,
edx
.
groups
.
ContentGroupModel
=
Backbone
.
Model
.
extend
(
{
defaults
:
{
idAttribute
:
'id
'
,
name
:
'
'
,
defaults
:
{
user_partition_id
:
null
name
:
''
,
}
user_partition_id
:
null
});
}
return
ContentGroupModel
;
});
});
}).
call
(
this
,
Backbo
ne
);
}).
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/groups/models/course_cohort_settings.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
Backbone
)
{
'use strict'
;
'use strict'
;
define
([
'backbone'
],
function
(
Backbone
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
CourseCohortSettingsModel
=
Backbone
.
Model
.
extend
({
idAttribute
:
'id'
,
edx
.
groups
.
CourseCohortSettingsModel
=
Backbone
.
Model
.
extend
(
{
defaults
:
{
idAttribute
:
'id'
,
is_cohorted
:
false
,
defaults
:
{
cohorted_inline_discussions
:
[],
is_cohorted
:
false
,
cohorted_course_wide_discussions
:[]
,
cohorted_inline_discussions
:
[],
always_cohort_inline_discussions
:
true
cohorted_course_wide_discussions
:[],
}
always_cohort_inline_discussions
:
true
});
}
return
CourseCohortSettingsModel
;
});
});
}).
call
(
this
,
Backbo
ne
);
}).
call
(
this
,
define
||
RequireJS
.
defi
ne
);
lms/static/js/groups/views/cohort_discussions.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
NotificationModel
,
NotificationView
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'js/models/notification'
,
'js/views/notification'
],
function
(
$
,
_
,
Backbone
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
CohortDiscussionConfigurationView
=
Backbone
.
View
.
extend
({
edx
.
groups
.
CohortDiscussionConfigurationView
=
Backbone
.
View
.
extend
({
/**
* Add/Remove the disabled attribute on given element.
* @param {object} $element - The element to disable/enable.
* @param {bool} disable - The flag to add/remove 'disabled' attribute.
*/
setDisabled
:
function
(
$element
,
disable
)
{
$element
.
prop
(
'disabled'
,
disable
?
'disabled'
:
false
);
},
/**
/**
* Add/Remove the disabled attribute on given elemen
t.
* Returns the cohorted discussions lis
t.
* @param {object} $element - The element to disable/enable
.
* @param {string} selector - To select the discussion elements whose ids to return
.
* @param {bool} disable - The flag to add/remove 'disabled' attribute
.
* @returns {Array} - Cohorted discussions
.
*/
*/
setDisabled
:
function
(
$element
,
disable
)
{
getCohortedDiscussions
:
function
(
selector
)
{
$element
.
prop
(
'disabled'
,
disable
?
'disabled'
:
false
);
var
self
=
this
,
},
cohortedDiscussions
=
[];
/**
_
.
each
(
self
.
$
(
selector
),
function
(
topic
)
{
* Returns the cohorted discussions list.
cohortedDiscussions
.
push
(
$
(
topic
).
data
(
'id'
))
* @param {string} selector - To select the discussion elements whose ids to return.
});
* @returns {Array} - Cohorted discussions.
return
cohortedDiscussions
;
*/
},
getCohortedDiscussions
:
function
(
selector
)
{
var
self
=
this
,
cohortedDiscussions
=
[];
_
.
each
(
self
.
$
(
selector
),
function
(
topic
)
{
/**
cohortedDiscussions
.
push
(
$
(
topic
).
data
(
'id'
))
* Save the cohortSettings' changed attributes to the server via PATCH method.
});
* It shows the error message(s) if any.
return
cohortedDiscussions
;
* @param {object} $element - Messages would be shown before this element.
},
* @param {object} fieldData - Data to update on the server.
*/
saveForm
:
function
(
$element
,
fieldData
)
{
var
self
=
this
,
cohortSettingsModel
=
this
.
cohortSettings
,
saveOperation
=
$
.
Deferred
(),
showErrorMessage
;
/**
showErrorMessage
=
function
(
message
,
$element
)
{
* Save the cohortSettings' changed attributes to the server via PATCH method.
self
.
showMessage
(
message
,
$element
,
'error'
);
* It shows the error message(s) if any.
};
* @param {object} $element - Messages would be shown before this element.
this
.
removeNotification
();
* @param {object} fieldData - Data to update on the server.
*/
saveForm
:
function
(
$element
,
fieldData
)
{
var
self
=
this
,
cohortSettingsModel
=
this
.
cohortSettings
,
saveOperation
=
$
.
Deferred
(),
showErrorMessage
;
showErrorMessage
=
function
(
message
,
$element
)
{
cohortSettingsModel
.
save
(
self
.
showMessage
(
message
,
$element
,
'error'
);
fieldData
,
{
patch
:
true
,
wait
:
true
}
};
).
done
(
function
()
{
this
.
removeNotification
();
saveOperation
.
resolve
();
}).
fail
(
function
(
result
)
{
var
errorMessage
=
null
;
try
{
var
jsonResponse
=
JSON
.
parse
(
result
.
responseText
);
errorMessage
=
jsonResponse
.
error
;
}
catch
(
e
)
{
// Ignore the exception and show the default error message instead.
}
if
(
!
errorMessage
)
{
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
}
showErrorMessage
(
errorMessage
,
$element
);
saveOperation
.
reject
();
});
return
saveOperation
.
promise
();
},
cohortSettingsModel
.
save
(
/**
fieldData
,
{
patch
:
true
,
wait
:
true
}
* Shows the notification messages before given element using the NotificationModel.
).
done
(
function
()
{
* @param {string} message - Text message to show.
saveOperation
.
resolve
();
* @param {object} $element - Message would be shown before this element.
}).
fail
(
function
(
result
)
{
* @param {string} type - Type of message to show e.g. confirmation or error.
var
errorMessage
=
null
;
*/
try
{
showMessage
:
function
(
message
,
$element
,
type
)
{
var
jsonResponse
=
JSON
.
parse
(
result
.
responseText
);
var
model
=
new
NotificationModel
({
type
:
type
||
'confirmation'
,
title
:
message
});
errorMessage
=
jsonResponse
.
error
;
this
.
removeNotification
();
}
catch
(
e
)
{
this
.
notification
=
new
NotificationView
({
// Ignore the exception and show the default error message instead.
model
:
model
}
});
if
(
!
errorMessage
)
{
$element
.
before
(
this
.
notification
.
$el
);
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
this
.
notification
.
render
();
},
/**
*Removes the notification messages.
*/
removeNotification
:
function
()
{
if
(
this
.
notification
)
{
this
.
notification
.
remove
();
}
}
}
showErrorMessage
(
errorMessage
,
$element
);
saveOperation
.
reject
();
});
return
saveOperation
.
promise
();
},
/**
* Shows the notification messages before given element using the NotificationModel.
* @param {string} message - Text message to show.
* @param {object} $element - Message would be shown before this element.
* @param {string} type - Type of message to show e.g. confirmation or error.
*/
showMessage
:
function
(
message
,
$element
,
type
)
{
var
model
=
new
NotificationModel
({
type
:
type
||
'confirmation'
,
title
:
message
});
this
.
removeNotification
();
this
.
notification
=
new
NotificationView
({
model
:
model
});
});
$element
.
before
(
this
.
notification
.
$el
);
return
CohortDiscussionConfigurationView
;
this
.
notification
.
render
();
});
},
}).
call
(
this
,
define
||
RequireJS
.
define
);
/**
*Removes the notification messages.
*/
removeNotification
:
function
()
{
if
(
this
.
notification
)
{
this
.
notification
.
remove
();
}
}
});
}).
call
(
this
,
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
NotificationModel
,
NotificationView
);
lms/static/js/groups/views/cohort_discussions_course_wide.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
CohortDiscussionConfigurationView
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'js/groups/views/cohort_discussions'
],
function
(
$
,
_
,
Backbone
,
gettext
,
CohortDiscussionConfigurationView
)
{
var
CourseWideDiscussionsView
=
CohortDiscussionConfigurationView
.
extend
({
events
:
{
'change .check-discussion-subcategory-course-wide'
:
'discussionCategoryStateChanged'
,
'click .cohort-course-wide-discussions-form .action-save'
:
'saveCourseWideDiscussionsForm'
},
edx
.
groups
=
edx
.
groups
||
{};
initialize
:
function
(
options
)
{
this
.
template
=
_
.
template
(
$
(
'#cohort-discussions-course-wide-tpl'
).
text
());
edx
.
groups
.
CourseWideDiscussionsView
=
CohortDiscussionConfigurationView
.
extend
({
this
.
cohortSettings
=
options
.
cohortSettings
;
events
:
{
},
'change .check-discussion-subcategory-course-wide'
:
'discussionCategoryStateChanged'
,
'click .cohort-course-wide-discussions-form .action-save'
:
'saveCourseWideDiscussionsForm'
},
initialize
:
function
(
options
)
{
render
:
function
()
{
this
.
template
=
_
.
template
(
$
(
'#cohort-discussions-course-wide-tpl'
).
text
());
this
.
$
(
'.cohort-course-wide-discussions-nav'
).
html
(
this
.
template
({
this
.
cohortSettings
=
options
.
cohortSettings
;
courseWideTopics
:
this
.
getCourseWideDiscussionsHtml
(
},
this
.
model
.
get
(
'course_wide_discussions'
)
)
}));
this
.
setDisabled
(
this
.
$
(
'.cohort-course-wide-discussions-form .action-save'
),
true
);
},
render
:
function
()
{
/**
this
.
$
(
'.cohort-course-wide-discussions-nav'
).
html
(
this
.
template
({
* Returns the html list for course-wide discussion topics.
courseWideTopics
:
this
.
getCourseWideDiscussionsHtml
(
* @param {object} courseWideDiscussions - course-wide discussions object from server.
this
.
model
.
get
(
'course_wide_discussions'
)
* @returns {Array} - HTML list for course-wide discussion topics.
)
*/
}));
getCourseWideDiscussionsHtml
:
function
(
courseWideDiscussions
)
{
this
.
setDisabled
(
this
.
$
(
'.cohort-course-wide-discussions-form .action-save'
),
true
);
var
subCategoryTemplate
=
_
.
template
(
$
(
'#cohort-discussions-subcategory-tpl'
).
html
()),
},
entries
=
courseWideDiscussions
.
entries
,
children
=
courseWideDiscussions
.
children
;
/**
return
_
.
map
(
children
,
function
(
name
)
{
* Returns the html list for course-wide discussion topics.
var
entry
=
entries
[
name
];
* @param {object} courseWideDiscussions - course-wide discussions object from server.
return
subCategoryTemplate
({
* @returns {Array} - HTML list for course-wide discussion topics.
name
:
name
,
*/
id
:
entry
.
id
,
getCourseWideDiscussionsHtml
:
function
(
courseWideDiscussions
)
{
is_cohorted
:
entry
.
is_cohorted
,
var
subCategoryTemplate
=
_
.
template
(
$
(
'#cohort-discussions-subcategory-tpl'
).
html
()),
type
:
'course-wide'
entries
=
courseWideDiscussions
.
entries
,
});
children
=
courseWideDiscussions
.
children
;
}).
join
(
''
);
},
return
_
.
map
(
children
,
function
(
name
)
{
/**
var
entry
=
entries
[
name
];
* Enables the save button for course-wide discussions.
return
subCategoryTemplate
({
*/
name
:
name
,
discussionCategoryStateChanged
:
function
(
event
)
{
id
:
entry
.
id
,
event
.
preventDefault
();
is_cohorted
:
entry
.
is_cohorted
,
this
.
setDisabled
(
this
.
$
(
'.cohort-course-wide-discussions-form .action-save'
),
false
);
type
:
'course-wide'
},
});
}).
join
(
''
);
},
/**
/**
* Enables the save button for course-wide discussions.
* Sends the cohorted_course_wide_discussions to the server and renders the view.
*/
*/
discussionCategoryStateChanged
:
function
(
event
)
{
saveCourseWideDiscussionsForm
:
function
(
event
)
{
event
.
preventDefault
();
event
.
preventDefault
();
this
.
setDisabled
(
this
.
$
(
'.cohort-course-wide-discussions-form .action-save'
),
false
);
},
/**
var
self
=
this
,
* Sends the cohorted_course_wide_discussions to the server and renders the view.
courseWideCohortedDiscussions
=
self
.
getCohortedDiscussions
(
*/
'.check-discussion-subcategory-course-wide:checked'
saveCourseWideDiscussionsForm
:
function
(
event
)
{
),
event
.
preventDefault
()
;
fieldData
=
{
cohorted_course_wide_discussions
:
courseWideCohortedDiscussions
}
;
var
self
=
this
,
self
.
saveForm
(
self
.
$
(
'.course-wide-discussion-topics'
),
fieldData
)
courseWideCohortedDiscussions
=
self
.
getCohortedDiscussions
(
.
done
(
function
()
{
'.check-discussion-subcategory-course-wide:checked'
self
.
model
.
fetch
()
),
.
done
(
function
()
{
fieldData
=
{
cohorted_course_wide_discussions
:
courseWideCohortedDiscussions
};
self
.
render
();
self
.
showMessage
(
gettext
(
'Your changes have been saved.'
),
self
.
$
(
'.course-wide-discussion-topics'
));
}).
fail
(
function
()
{
var
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
self
.
showMessage
(
errorMessage
,
self
.
$
(
'.course-wide-discussion-topics'
),
'error'
)
});
});
}
self
.
saveForm
(
self
.
$
(
'.course-wide-discussion-topics'
),
fieldData
)
});
.
done
(
function
()
{
return
CourseWideDiscussionsView
;
self
.
model
.
fetch
()
});
.
done
(
function
()
{
}).
call
(
this
,
define
||
RequireJS
.
define
);
self
.
render
();
self
.
showMessage
(
gettext
(
'Your changes have been saved.'
),
self
.
$
(
'.course-wide-discussion-topics'
));
}).
fail
(
function
()
{
var
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
self
.
showMessage
(
errorMessage
,
self
.
$
(
'.course-wide-discussion-topics'
),
'error'
)
});
});
}
});
}).
call
(
this
,
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
edx
.
groups
.
CohortDiscussionConfigurationView
);
lms/static/js/groups/views/cohort_discussions_inline.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
CohortDiscussionConfigurationView
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'js/groups/views/cohort_discussions'
,
'js/vendor/jquery.qubit'
],
edx
.
groups
=
edx
.
groups
||
{};
function
(
$
,
_
,
Backbone
,
gettext
,
CohortDiscussionConfigurationView
)
{
var
InlineDiscussionsView
=
CohortDiscussionConfigurationView
.
extend
({
edx
.
groups
.
InlineDiscussionsView
=
CohortDiscussionConfigurationView
.
extend
({
events
:
{
events
:
{
'change .check-discussion-category'
:
'setSaveButton'
,
'change .check-discussion-category'
:
'setSaveButton'
,
'change .check-discussion-subcategory-inline'
:
'setSaveButton'
,
'change .check-discussion-subcategory-inline'
:
'setSaveButton'
,
'click .cohort-inline-discussions-form .action-save'
:
'saveInlineDiscussionsForm'
,
'click .cohort-inline-discussions-form .action-save'
:
'saveInlineDiscussionsForm'
,
'change .check-all-inline-discussions'
:
'setAllInlineDiscussions'
,
'change .check-all-inline-discussions'
:
'setAllInlineDiscussions'
,
'change .check-cohort-inline-discussions'
:
'setSomeInlineDiscussions'
'change .check-cohort-inline-discussions'
:
'setSomeInlineDiscussions'
},
},
initialize
:
function
(
options
)
{
initialize
:
function
(
options
)
{
this
.
template
=
_
.
template
(
$
(
'#cohort-discussions-inline-tpl'
).
text
());
this
.
template
=
_
.
template
(
$
(
'#cohort-discussions-inline-tpl'
).
text
());
this
.
cohortSettings
=
options
.
cohortSettings
;
this
.
cohortSettings
=
options
.
cohortSettings
;
},
},
render
:
function
()
{
render
:
function
()
{
var
alwaysCohortInlineDiscussions
=
this
.
cohortSettings
.
get
(
'always_cohort_inline_discussions'
);
var
alwaysCohortInlineDiscussions
=
this
.
cohortSettings
.
get
(
'always_cohort_inline_discussions'
);
this
.
$
(
'.cohort-inline-discussions-nav'
).
html
(
this
.
template
({
this
.
$
(
'.cohort-inline-discussions-nav'
).
html
(
this
.
template
({
inlineDiscussionTopics
:
this
.
getInlineDiscussionsHtml
(
this
.
model
.
get
(
'inline_discussions'
)),
inlineDiscussionTopics
:
this
.
getInlineDiscussionsHtml
(
this
.
model
.
get
(
'inline_discussions'
)),
alwaysCohortInlineDiscussions
:
alwaysCohortInlineDiscussions
alwaysCohortInlineDiscussions
:
alwaysCohortInlineDiscussions
}));
}));
// Provides the semantics for a nested list of tri-state checkboxes.
// Provides the semantics for a nested list of tri-state checkboxes.
// When attached to a jQuery element it listens for change events to
// When attached to a jQuery element it listens for change events to
// input[type=checkbox] elements, and updates the checked and indeterminate
// input[type=checkbox] elements, and updates the checked and indeterminate
// based on the checked values of any checkboxes in child elements of the DOM.
// based on the checked values of any checkboxes in child elements of the DOM.
this
.
$
(
'ul.inline-topics'
).
qubit
();
this
.
$
(
'ul.inline-topics'
).
qubit
();
this
.
setElementsEnabled
(
alwaysCohortInlineDiscussions
,
true
);
this
.
setElementsEnabled
(
alwaysCohortInlineDiscussions
,
true
);
},
},
/**
/**
* Generate html list for inline discussion topics.
* Generate html list for inline discussion topics.
* @params {object} inlineDiscussions - inline discussions object from server.
* @params {object} inlineDiscussions - inline discussions object from server.
* @returns {Array} - HTML for inline discussion topics.
* @returns {Array} - HTML for inline discussion topics.
*/
*/
getInlineDiscussionsHtml
:
function
(
inlineDiscussions
)
{
getInlineDiscussionsHtml
:
function
(
inlineDiscussions
)
{
var
categoryTemplate
=
_
.
template
(
$
(
'#cohort-discussions-category-tpl'
).
html
()),
var
categoryTemplate
=
_
.
template
(
$
(
'#cohort-discussions-category-tpl'
).
html
()),
entryTemplate
=
_
.
template
(
$
(
'#cohort-discussions-subcategory-tpl'
).
html
()),
entryTemplate
=
_
.
template
(
$
(
'#cohort-discussions-subcategory-tpl'
).
html
()),
isCategoryCohorted
=
false
,
isCategoryCohorted
=
false
,
children
=
inlineDiscussions
.
children
,
children
=
inlineDiscussions
.
children
,
entries
=
inlineDiscussions
.
entries
,
entries
=
inlineDiscussions
.
entries
,
subcategories
=
inlineDiscussions
.
subcategories
;
subcategories
=
inlineDiscussions
.
subcategories
;
return
_
.
map
(
children
,
function
(
name
)
{
return
_
.
map
(
children
,
function
(
name
)
{
var
html
=
''
,
entry
;
var
html
=
''
,
entry
;
if
(
entries
&&
_
.
has
(
entries
,
name
))
{
if
(
entries
&&
_
.
has
(
entries
,
name
))
{
entry
=
entries
[
name
];
entry
=
entries
[
name
];
html
=
entryTemplate
({
html
=
entryTemplate
({
name
:
name
,
name
:
name
,
id
:
entry
.
id
,
id
:
entry
.
id
,
is_cohorted
:
entry
.
is_cohorted
,
is_cohorted
:
entry
.
is_cohorted
,
type
:
'inline'
type
:
'inline'
});
});
}
else
{
// subcategory
}
else
{
// subcategory
html
=
categoryTemplate
({
html
=
categoryTemplate
({
name
:
name
,
name
:
name
,
entries
:
this
.
getInlineDiscussionsHtml
(
subcategories
[
name
]),
entries
:
this
.
getInlineDiscussionsHtml
(
subcategories
[
name
]),
isCategoryCohorted
:
isCategoryCohorted
isCategoryCohorted
:
isCategoryCohorted
});
});
}
}
return
html
;
return
html
;
},
this
).
join
(
''
);
},
this
).
join
(
''
);
},
},
/**
/**
* Enable/Disable the inline discussion elements.
* Enable/Disable the inline discussion elements.
*
*
* Disables the category and sub-category checkboxes.
* Disables the category and sub-category checkboxes.
* Enables the save button.
* Enables the save button.
*/
*/
setAllInlineDiscussions
:
function
(
event
)
{
setAllInlineDiscussions
:
function
(
event
)
{
event
.
preventDefault
();
event
.
preventDefault
();
this
.
setElementsEnabled
((
$
(
event
.
currentTarget
).
prop
(
'checked'
)),
false
);
this
.
setElementsEnabled
((
$
(
event
.
currentTarget
).
prop
(
'checked'
)),
false
);
},
},
/**
/**
* Enables the inline discussion elements.
* Enables the inline discussion elements.
*
*
* Enables the category and sub-category checkboxes.
* Enables the category and sub-category checkboxes.
* Enables the save button.
* Enables the save button.
*/
*/
setSomeInlineDiscussions
:
function
(
event
)
{
setSomeInlineDiscussions
:
function
(
event
)
{
event
.
preventDefault
();
event
.
preventDefault
();
this
.
setElementsEnabled
(
!
(
$
(
event
.
currentTarget
).
prop
(
'checked'
)),
false
);
this
.
setElementsEnabled
(
!
(
$
(
event
.
currentTarget
).
prop
(
'checked'
)),
false
);
},
},
/**
/**
* Enable/Disable the inline discussion elements.
* Enable/Disable the inline discussion elements.
*
*
* Enable/Disable the category and sub-category checkboxes.
* Enable/Disable the category and sub-category checkboxes.
* Enable/Disable the save button.
* Enable/Disable the save button.
* @param {bool} enable_checkboxes - The flag to enable/disable the checkboxes.
* @param {bool} enable_checkboxes - The flag to enable/disable the checkboxes.
* @param {bool} enable_save_button - The flag to enable/disable the save button.
* @param {bool} enable_save_button - The flag to enable/disable the save button.
*/
*/
setElementsEnabled
:
function
(
enable_checkboxes
,
enable_save_button
)
{
setElementsEnabled
:
function
(
enable_checkboxes
,
enable_save_button
)
{
this
.
setDisabled
(
this
.
$
(
'.check-discussion-category'
),
enable_checkboxes
);
this
.
setDisabled
(
this
.
$
(
'.check-discussion-category'
),
enable_checkboxes
);
this
.
setDisabled
(
this
.
$
(
'.check-discussion-subcategory-inline'
),
enable_checkboxes
);
this
.
setDisabled
(
this
.
$
(
'.check-discussion-subcategory-inline'
),
enable_checkboxes
);
this
.
setDisabled
(
this
.
$
(
'.cohort-inline-discussions-form .action-save'
),
enable_save_button
);
this
.
setDisabled
(
this
.
$
(
'.cohort-inline-discussions-form .action-save'
),
enable_save_button
);
},
},
/**
/**
* Enables the save button for inline discussions.
* Enables the save button for inline discussions.
*/
*/
setSaveButton
:
function
(
event
)
{
setSaveButton
:
function
(
event
)
{
this
.
setDisabled
(
this
.
$
(
'.cohort-inline-discussions-form .action-save'
),
false
);
this
.
setDisabled
(
this
.
$
(
'.cohort-inline-discussions-form .action-save'
),
false
);
},
},
/**
/**
* Sends the cohorted_inline_discussions to the server and renders the view.
* Sends the cohorted_inline_discussions to the server and renders the view.
*/
*/
saveInlineDiscussionsForm
:
function
(
event
)
{
saveInlineDiscussionsForm
:
function
(
event
)
{
event
.
preventDefault
();
event
.
preventDefault
();
var
self
=
this
,
var
self
=
this
,
cohortedInlineDiscussions
=
self
.
getCohortedDiscussions
(
cohortedInlineDiscussions
=
self
.
getCohortedDiscussions
(
'.check-discussion-subcategory-inline:checked'
'.check-discussion-subcategory-inline:checked'
),
),
fieldData
=
{
fieldData
=
{
cohorted_inline_discussions
:
cohortedInlineDiscussions
,
cohorted_inline_discussions
:
cohortedInlineDiscussions
,
always_cohort_inline_discussions
:
self
.
$
(
'.check-all-inline-discussions'
).
prop
(
'checked'
)
always_cohort_inline_discussions
:
self
.
$
(
'.check-all-inline-discussions'
).
prop
(
'checked'
)
};
};
self
.
saveForm
(
self
.
$
(
'.inline-discussion-topics'
),
fieldData
)
self
.
saveForm
(
self
.
$
(
'.inline-discussion-topics'
),
fieldData
)
.
done
(
function
()
{
.
done
(
function
()
{
self
.
model
.
fetch
()
self
.
model
.
fetch
()
.
done
(
function
()
{
.
done
(
function
()
{
self
.
render
();
self
.
render
();
self
.
showMessage
(
gettext
(
'Your changes have been saved.'
),
self
.
$
(
'.inline-discussion-topics'
));
self
.
showMessage
(
gettext
(
'Your changes have been saved.'
),
self
.
$
(
'.inline-discussion-topics'
));
}).
fail
(
function
()
{
}).
fail
(
function
()
{
var
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
var
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
self
.
showMessage
(
errorMessage
,
self
.
$
(
'.inline-discussion-topics'
),
'error'
)
self
.
showMessage
(
errorMessage
,
self
.
$
(
'.inline-discussion-topics'
),
'error'
)
});
});
});
});
}
}
});
return
InlineDiscussionsView
;
});
});
}).
call
(
this
,
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
edx
.
groups
.
CohortDiscussionConfigurationView
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/groups/views/cohort_editor.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
Backbone
,
_
,
$
,
gettext
,
ngettext
,
interpolate_text
,
CohortFormView
,
NotificationModel
,
NotificationView
)
{
'use strict'
;
'use strict'
;
define
([
'backbone'
,
'underscore'
,
'jquery'
,
'gettext'
,
'js/groups/views/cohort_form'
,
'string_utils'
,
edx
.
groups
=
edx
.
groups
||
{};
'js/models/notification'
,
'js/views/notification'
],
function
(
Backbone
,
_
,
$
,
gettext
,
CohortFormView
)
{
edx
.
groups
.
CohortEditorView
=
Backbone
.
View
.
extend
({
var
CohortEditorView
=
Backbone
.
View
.
extend
({
events
:
{
events
:
{
'click .wrapper-tabs .tab'
:
'selectTab'
,
'click .wrapper-tabs .tab'
:
'selectTab'
,
'click .tab-content-settings .action-save'
:
'saveSettings'
,
'click .tab-content-settings .action-save'
:
'saveSettings'
,
'click .tab-content-settings .action-cancel'
:
'cancelSettings'
,
'click .tab-content-settings .action-cancel'
:
'cancelSettings'
,
'submit .cohort-management-group-add-form'
:
'addStudents'
'submit .cohort-management-group-add-form'
:
'addStudents'
},
},
initialize
:
function
(
options
)
{
initialize
:
function
(
options
)
{
this
.
template
=
_
.
template
(
$
(
'#cohort-editor-tpl'
).
text
());
this
.
template
=
_
.
template
(
$
(
'#cohort-editor-tpl'
).
text
());
this
.
groupHeaderTemplate
=
_
.
template
(
$
(
'#cohort-group-header-tpl'
).
text
());
this
.
groupHeaderTemplate
=
_
.
template
(
$
(
'#cohort-group-header-tpl'
).
text
());
this
.
cohorts
=
options
.
cohorts
;
this
.
cohorts
=
options
.
cohorts
;
this
.
contentGroups
=
options
.
contentGroups
;
this
.
contentGroups
=
options
.
contentGroups
;
this
.
context
=
options
.
context
;
this
.
context
=
options
.
context
;
},
},
// Any errors that are currently being displayed to the instructor (for example, unknown email addresses).
// Any errors that are currently being displayed to the instructor (for example, unknown email addresses).
errorNotifications
:
null
,
errorNotifications
:
null
,
// Any confirmation messages that are currently being displayed (for example, number of students added).
// Any confirmation messages that are currently being displayed (for example, number of students added).
confirmationNotifications
:
null
,
confirmationNotifications
:
null
,
render
:
function
()
{
render
:
function
()
{
this
.
$el
.
html
(
this
.
template
({
this
.
$el
.
html
(
this
.
template
({
cohort
:
this
.
model
cohort
:
this
.
model
}));
}));
this
.
renderGroupHeader
();
this
.
renderGroupHeader
();
this
.
cohortFormView
=
new
CohortFormView
({
this
.
cohortFormView
=
new
CohortFormView
({
model
:
this
.
model
,
model
:
this
.
model
,
contentGroups
:
this
.
contentGroups
,
contentGroups
:
this
.
contentGroups
,
context
:
this
.
context
context
:
this
.
context
});
this
.
cohortFormView
.
render
();
this
.
$
(
'.tab-content-settings'
).
append
(
this
.
cohortFormView
.
$el
);
return
this
;
},
renderGroupHeader
:
function
()
{
this
.
$
(
'.cohort-management-group-header'
).
html
(
this
.
groupHeaderTemplate
({
cohort
:
this
.
model
}));
},
selectTab
:
function
(
event
)
{
var
tabElement
=
$
(
event
.
currentTarget
),
tabName
=
tabElement
.
data
(
'tab'
);
event
.
preventDefault
();
this
.
$
(
'.wrapper-tabs .tab'
).
removeClass
(
'is-selected'
);
this
.
$
(
'.wrapper-tabs .tab'
).
find
(
'span.sr'
).
remove
();
tabElement
.
addClass
(
'is-selected'
);
tabElement
.
find
(
'a'
).
prepend
(
'<span class="sr">'
+
gettext
(
'Selected tab'
)
+
' </span>'
);
this
.
$
(
'.tab-content'
).
addClass
(
'is-hidden'
);
this
.
$
(
'.tab-content-'
+
tabName
).
removeClass
(
'is-hidden'
).
focus
();
},
saveSettings
:
function
(
event
)
{
var
cohortFormView
=
this
.
cohortFormView
;
var
self
=
this
;
event
.
preventDefault
();
cohortFormView
.
saveForm
()
.
done
(
function
()
{
self
.
renderGroupHeader
();
cohortFormView
.
showMessage
(
gettext
(
'Saved cohort'
));
});
},
cancelSettings
:
function
(
event
)
{
event
.
preventDefault
();
this
.
render
();
},
setCohort
:
function
(
cohort
)
{
this
.
model
=
cohort
;
this
.
render
();
},
addStudents
:
function
(
event
)
{
event
.
preventDefault
();
var
self
=
this
,
cohorts
=
this
.
cohorts
,
input
=
this
.
$
(
'.cohort-management-group-add-students'
),
add_url
=
this
.
model
.
url
()
+
'/add'
,
students
=
input
.
val
().
trim
(),
cohortId
=
this
.
model
.
id
;
if
(
students
.
length
>
0
)
{
$
.
post
(
add_url
,
{
'users'
:
students
}
).
done
(
function
(
modifiedUsers
)
{
self
.
refreshCohorts
().
done
(
function
()
{
// Find the equivalent cohort in the new collection and select it
var
cohort
=
cohorts
.
get
(
cohortId
);
self
.
setCohort
(
cohort
);
// Show the notifications
self
.
addNotifications
(
modifiedUsers
);
// If an unknown user was specified then update the new input to have
// the original input's value. This is to allow the user to correct the
// value in case it was a typo.
if
(
modifiedUsers
.
unknown
.
length
>
0
)
{
self
.
$
(
'.cohort-management-group-add-students'
).
val
(
students
);
}
});
});
}).
fail
(
function
()
{
this
.
cohortFormView
.
render
();
self
.
showErrorMessage
(
gettext
(
'Error adding students.'
),
true
);
this
.
$
(
'.tab-content-settings'
).
append
(
this
.
cohortFormView
.
$el
);
});
return
this
;
}
else
{
},
self
.
showErrorMessage
(
gettext
(
'Enter a username or email.'
),
true
);
input
.
val
(
''
);
renderGroupHeader
:
function
()
{
}
this
.
$
(
'.cohort-management-group-header'
).
html
(
this
.
groupHeaderTemplate
({
},
cohort
:
this
.
model
}));
/**
},
* Refresh the cohort collection to get the latest set as well as up-to-date counts.
*/
selectTab
:
function
(
event
)
{
refreshCohorts
:
function
()
{
var
tabElement
=
$
(
event
.
currentTarget
),
return
this
.
cohorts
.
fetch
();
tabName
=
tabElement
.
data
(
'tab'
);
},
event
.
preventDefault
();
this
.
$
(
'.wrapper-tabs .tab'
).
removeClass
(
'is-selected'
);
undelegateViewEvents
:
function
(
view
)
{
this
.
$
(
'.wrapper-tabs .tab'
).
find
(
'span.sr'
).
remove
();
if
(
view
)
{
tabElement
.
addClass
(
'is-selected'
);
view
.
undelegateEvents
();
tabElement
.
find
(
'a'
).
prepend
(
'<span class="sr">'
+
gettext
(
'Selected tab'
)
+
' </span>'
);
}
this
.
$
(
'.tab-content'
).
addClass
(
'is-hidden'
);
},
this
.
$
(
'.tab-content-'
+
tabName
).
removeClass
(
'is-hidden'
).
focus
();
},
showErrorMessage
:
function
(
message
,
removeConfirmations
,
model
)
{
if
(
removeConfirmations
&&
this
.
confirmationNotifications
)
{
saveSettings
:
function
(
event
)
{
this
.
undelegateViewEvents
(
this
.
confirmationNotifications
);
var
cohortFormView
=
this
.
cohortFormView
;
this
.
confirmationNotifications
.
$el
.
html
(
''
);
var
self
=
this
;
this
.
confirmationNotifications
=
null
;
event
.
preventDefault
();
}
cohortFormView
.
saveForm
()
if
(
model
===
undefined
)
{
.
done
(
function
()
{
model
=
new
NotificationModel
();
self
.
renderGroupHeader
();
}
cohortFormView
.
showMessage
(
gettext
(
'Saved cohort'
));
model
.
set
(
'type'
,
'error'
);
});
model
.
set
(
'title'
,
message
);
},
this
.
undelegateViewEvents
(
this
.
errorNotifications
);
cancelSettings
:
function
(
event
)
{
event
.
preventDefault
();
this
.
errorNotifications
=
new
NotificationView
({
this
.
render
();
el
:
this
.
$
(
'.cohort-errors'
),
},
model
:
model
});
setCohort
:
function
(
cohort
)
{
this
.
errorNotifications
.
render
();
this
.
model
=
cohort
;
},
this
.
render
();
},
addNotifications
:
function
(
modifiedUsers
)
{
var
oldCohort
,
title
,
details
,
numPresent
,
numUsersAdded
,
numErrors
,
addStudents
:
function
(
event
)
{
createErrorDetails
,
errorActionCallback
,
errorModel
,
event
.
preventDefault
();
errorLimit
=
5
;
var
self
=
this
,
cohorts
=
this
.
cohorts
,
// Show confirmation messages.
input
=
this
.
$
(
'.cohort-management-group-add-students'
),
this
.
undelegateViewEvents
(
this
.
confirmationNotifications
);
add_url
=
this
.
model
.
url
()
+
'/add'
,
numUsersAdded
=
modifiedUsers
.
added
.
length
+
modifiedUsers
.
changed
.
length
;
students
=
input
.
val
().
trim
(),
numPresent
=
modifiedUsers
.
present
.
length
;
cohortId
=
this
.
model
.
id
;
if
(
numUsersAdded
>
0
||
numPresent
>
0
)
{
title
=
interpolate_text
(
if
(
students
.
length
>
0
)
{
ngettext
(
"{numUsersAdded} student has been added to this cohort"
,
$
.
post
(
"{numUsersAdded} students have been added to this cohort"
,
numUsersAdded
),
add_url
,
{
'users'
:
students
}
{
numUsersAdded
:
numUsersAdded
}
).
done
(
function
(
modifiedUsers
)
{
);
self
.
refreshCohorts
().
done
(
function
()
{
// Find the equivalent cohort in the new collection and select it
var
movedByCohort
=
{};
var
cohort
=
cohorts
.
get
(
cohortId
);
_
.
each
(
modifiedUsers
.
changed
,
function
(
changedInfo
)
{
self
.
setCohort
(
cohort
);
oldCohort
=
changedInfo
.
previous_cohort
;
if
(
oldCohort
in
movedByCohort
)
{
// Show the notifications
movedByCohort
[
oldCohort
]
=
movedByCohort
[
oldCohort
]
+
1
;
self
.
addNotifications
(
modifiedUsers
);
// If an unknown user was specified then update the new input to have
// the original input's value. This is to allow the user to correct the
// value in case it was a typo.
if
(
modifiedUsers
.
unknown
.
length
>
0
)
{
self
.
$
(
'.cohort-management-group-add-students'
).
val
(
students
);
}
});
}).
fail
(
function
()
{
self
.
showErrorMessage
(
gettext
(
'Error adding students.'
),
true
);
});
}
else
{
self
.
showErrorMessage
(
gettext
(
'Enter a username or email.'
),
true
);
input
.
val
(
''
);
}
}
else
{
},
movedByCohort
[
oldCohort
]
=
1
;
/**
* Refresh the cohort collection to get the latest set as well as up-to-date counts.
*/
refreshCohorts
:
function
()
{
return
this
.
cohorts
.
fetch
();
},
undelegateViewEvents
:
function
(
view
)
{
if
(
view
)
{
view
.
undelegateEvents
();
}
}
});
},
details
=
[];
for
(
oldCohort
in
movedByCohort
)
{
details
.
push
(
interpolate_text
(
ngettext
(
"{numMoved} student was removed from {oldCohort}"
,
"{numMoved} students were removed from {oldCohort}"
,
movedByCohort
[
oldCohort
]),
{
numMoved
:
movedByCohort
[
oldCohort
],
oldCohort
:
oldCohort
}
)
);
}
if
(
numPresent
>
0
)
{
details
.
push
(
interpolate_text
(
ngettext
(
"{numPresent} student was already in the cohort"
,
"{numPresent} students were already in the cohort"
,
numPresent
),
{
numPresent
:
numPresent
}
)
);
}
this
.
confirmationNotifications
=
new
NotificationView
({
el
:
this
.
$
(
'.cohort-confirmations'
),
model
:
new
NotificationModel
({
type
:
"confirmation"
,
title
:
title
,
details
:
details
})
});
this
.
confirmationNotifications
.
render
();
}
else
if
(
this
.
confirmationNotifications
)
{
this
.
confirmationNotifications
.
$el
.
html
(
''
);
this
.
confirmationNotifications
=
null
;
}
// Show error messages.
this
.
undelegateViewEvents
(
this
.
errorNotifications
);
numErrors
=
modifiedUsers
.
unknown
.
length
;
if
(
numErrors
>
0
)
{
createErrorDetails
=
function
(
unknownUsers
,
showAllErrors
)
{
var
numErrors
=
unknownUsers
.
length
,
details
=
[];
for
(
var
i
=
0
;
i
<
(
showAllErrors
?
numErrors
:
Math
.
min
(
errorLimit
,
numErrors
));
i
++
)
{
showErrorMessage
:
function
(
message
,
removeConfirmations
,
model
)
{
details
.
push
(
interpolate_text
(
gettext
(
"Unknown user: {user}"
),
{
user
:
unknownUsers
[
i
]}));
if
(
removeConfirmations
&&
this
.
confirmationNotifications
)
{
this
.
undelegateViewEvents
(
this
.
confirmationNotifications
);
this
.
confirmationNotifications
.
$el
.
html
(
''
);
this
.
confirmationNotifications
=
null
;
}
}
return
details
;
if
(
model
===
undefined
)
{
};
model
=
new
NotificationModel
();
}
model
.
set
(
'type'
,
'error'
);
model
.
set
(
'title'
,
message
);
title
=
interpolate_text
(
this
.
undelegateViewEvents
(
this
.
errorNotifications
);
ngettext
(
"There was an error when trying to add students:"
,
"There were {numErrors} errors when trying to add students:"
,
numErrors
),
{
numErrors
:
numErrors
}
);
details
=
createErrorDetails
(
modifiedUsers
.
unknown
,
false
);
errorActionCallback
=
function
(
view
)
{
this
.
errorNotifications
=
new
NotificationView
({
view
.
model
.
set
(
"actionText"
,
null
);
el
:
this
.
$
(
'.cohort-errors'
),
view
.
model
.
set
(
"details"
,
createErrorDetails
(
modifiedUsers
.
unknown
,
true
));
model
:
model
view
.
render
();
});
};
this
.
errorNotifications
.
render
();
},
addNotifications
:
function
(
modifiedUsers
)
{
var
oldCohort
,
title
,
details
,
numPresent
,
numUsersAdded
,
numErrors
,
createErrorDetails
,
errorActionCallback
,
errorModel
,
errorLimit
=
5
;
// Show confirmation messages.
this
.
undelegateViewEvents
(
this
.
confirmationNotifications
);
numUsersAdded
=
modifiedUsers
.
added
.
length
+
modifiedUsers
.
changed
.
length
;
numPresent
=
modifiedUsers
.
present
.
length
;
if
(
numUsersAdded
>
0
||
numPresent
>
0
)
{
title
=
interpolate_text
(
ngettext
(
"{numUsersAdded} student has been added to this cohort"
,
"{numUsersAdded} students have been added to this cohort"
,
numUsersAdded
),
{
numUsersAdded
:
numUsersAdded
}
);
var
movedByCohort
=
{};
_
.
each
(
modifiedUsers
.
changed
,
function
(
changedInfo
)
{
oldCohort
=
changedInfo
.
previous_cohort
;
if
(
oldCohort
in
movedByCohort
)
{
movedByCohort
[
oldCohort
]
=
movedByCohort
[
oldCohort
]
+
1
;
}
else
{
movedByCohort
[
oldCohort
]
=
1
;
}
});
details
=
[];
for
(
oldCohort
in
movedByCohort
)
{
details
.
push
(
interpolate_text
(
ngettext
(
"{numMoved} student was removed from {oldCohort}"
,
"{numMoved} students were removed from {oldCohort}"
,
movedByCohort
[
oldCohort
]),
{
numMoved
:
movedByCohort
[
oldCohort
],
oldCohort
:
oldCohort
}
)
);
}
if
(
numPresent
>
0
)
{
details
.
push
(
interpolate_text
(
ngettext
(
"{numPresent} student was already in the cohort"
,
"{numPresent} students were already in the cohort"
,
numPresent
),
{
numPresent
:
numPresent
}
)
);
}
errorModel
=
new
NotificationModel
({
this
.
confirmationNotifications
=
new
NotificationView
({
details
:
details
,
el
:
this
.
$
(
'.cohort-confirmations'
),
actionText
:
numErrors
>
errorLimit
?
gettext
(
"View all errors"
)
:
null
,
model
:
new
NotificationModel
({
actionCallback
:
errorActionCallback
,
type
:
"confirmation"
,
actionClass
:
'action-expand'
title
:
title
,
});
details
:
details
})
});
this
.
confirmationNotifications
.
render
();
}
else
if
(
this
.
confirmationNotifications
)
{
this
.
confirmationNotifications
.
$el
.
html
(
''
);
this
.
confirmationNotifications
=
null
;
}
this
.
showErrorMessage
(
title
,
false
,
errorModel
);
// Show error messages.
}
this
.
undelegateViewEvents
(
this
.
errorNotifications
);
else
if
(
this
.
errorNotifications
)
{
numErrors
=
modifiedUsers
.
unknown
.
length
;
this
.
errorNotifications
.
$el
.
html
(
''
);
if
(
numErrors
>
0
)
{
this
.
errorNotifications
=
null
;
createErrorDetails
=
function
(
unknownUsers
,
showAllErrors
)
{
}
var
numErrors
=
unknownUsers
.
length
,
details
=
[];
}
for
(
var
i
=
0
;
i
<
(
showAllErrors
?
numErrors
:
Math
.
min
(
errorLimit
,
numErrors
));
i
++
)
{
details
.
push
(
interpolate_text
(
gettext
(
"Unknown user: {user}"
),
{
user
:
unknownUsers
[
i
]}));
}
return
details
;
};
title
=
interpolate_text
(
ngettext
(
"There was an error when trying to add students:"
,
"There were {numErrors} errors when trying to add students:"
,
numErrors
),
{
numErrors
:
numErrors
}
);
details
=
createErrorDetails
(
modifiedUsers
.
unknown
,
false
);
errorActionCallback
=
function
(
view
)
{
view
.
model
.
set
(
"actionText"
,
null
);
view
.
model
.
set
(
"details"
,
createErrorDetails
(
modifiedUsers
.
unknown
,
true
));
view
.
render
();
};
errorModel
=
new
NotificationModel
({
details
:
details
,
actionText
:
numErrors
>
errorLimit
?
gettext
(
"View all errors"
)
:
null
,
actionCallback
:
errorActionCallback
,
actionClass
:
'action-expand'
});
this
.
showErrorMessage
(
title
,
false
,
errorModel
);
}
else
if
(
this
.
errorNotifications
)
{
this
.
errorNotifications
.
$el
.
html
(
''
);
this
.
errorNotifications
=
null
;
}
}
});
return
CohortEditorView
;
});
});
}).
call
(
this
,
Backbone
,
_
,
$
,
gettext
,
ngettext
,
interpolate_text
,
edx
.
groups
.
CohortFormView
,
}).
call
(
this
,
define
||
RequireJS
.
define
);
NotificationModel
,
NotificationView
);
lms/static/js/groups/views/cohort_form.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
CohortModel
,
NotificationModel
,
NotificationView
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'js/groups/models/cohort'
,
edx
.
groups
=
edx
.
groups
||
{};
'js/models/notification'
,
'js/views/notification'
],
function
(
$
,
_
,
Backbone
,
gettext
,
CohortModel
)
{
edx
.
groups
.
CohortFormView
=
Backbone
.
View
.
extend
({
events
:
{
var
CohortFormView
=
Backbone
.
View
.
extend
({
'change .cohort-management-details-association-course input'
:
'onRadioButtonChange'
events
:
{
},
'change .cohort-management-details-association-course input'
:
'onRadioButtonChange'
},
initialize
:
function
(
options
)
{
this
.
template
=
_
.
template
(
$
(
'#cohort-form-tpl'
).
text
());
initialize
:
function
(
options
)
{
this
.
contentGroups
=
options
.
contentGroups
;
this
.
template
=
_
.
template
(
$
(
'#cohort-form-tpl'
).
text
());
this
.
context
=
options
.
context
;
this
.
contentGroups
=
options
.
contentGroups
;
},
this
.
context
=
options
.
context
;
},
showNotification
:
function
(
options
,
beforeElement
)
{
var
model
=
new
NotificationModel
(
options
);
showNotification
:
function
(
options
,
beforeElement
)
{
this
.
removeNotification
();
var
model
=
new
NotificationModel
(
options
);
this
.
notification
=
new
NotificationView
({
this
.
removeNotification
();
model
:
model
this
.
notification
=
new
NotificationView
({
});
model
:
model
beforeElement
.
before
(
this
.
notification
.
$el
);
});
this
.
notification
.
render
();
beforeElement
.
before
(
this
.
notification
.
$el
);
},
this
.
notification
.
render
();
},
removeNotification
:
function
()
{
if
(
this
.
notification
)
{
removeNotification
:
function
()
{
this
.
notification
.
remove
();
if
(
this
.
notification
)
{
}
this
.
notification
.
remove
();
},
}
},
render
:
function
()
{
this
.
$el
.
html
(
this
.
template
({
render
:
function
()
{
cohort
:
this
.
model
,
this
.
$el
.
html
(
this
.
template
({
isDefaultCohort
:
this
.
isDefault
(
this
.
model
.
get
(
'name'
)),
cohort
:
this
.
model
,
contentGroups
:
this
.
contentGroups
,
isDefaultCohort
:
this
.
isDefault
(
this
.
model
.
get
(
'name'
)),
studioGroupConfigurationsUrl
:
this
.
context
.
studioGroupConfigurationsUrl
contentGroups
:
this
.
contentGroups
,
}));
studioGroupConfigurationsUrl
:
this
.
context
.
studioGroupConfigurationsUrl
return
this
;
}));
},
return
this
;
},
isDefault
:
function
(
name
)
{
var
cohorts
=
this
.
model
.
collection
;
isDefault
:
function
(
name
)
{
if
(
_
.
isUndefined
(
cohorts
))
{
var
cohorts
=
this
.
model
.
collection
;
return
false
;
if
(
_
.
isUndefined
(
cohorts
))
{
}
return
false
;
var
randomModels
=
cohorts
.
where
({
assignment_type
:
'random'
});
return
(
randomModels
.
length
===
1
)
&&
(
randomModels
[
0
].
get
(
'name'
)
===
name
);
},
onRadioButtonChange
:
function
(
event
)
{
var
target
=
$
(
event
.
currentTarget
),
groupsEnabled
=
target
.
val
()
===
'yes'
;
if
(
!
groupsEnabled
)
{
// If the user has chosen 'no', then clear the selection by setting
// it to the first option which represents no selection.
this
.
$
(
'.input-cohort-group-association'
).
val
(
'None'
);
}
// Enable the select if the user has chosen groups, else disable it
this
.
$
(
'.input-cohort-group-association'
).
prop
(
'disabled'
,
!
groupsEnabled
);
},
hasAssociatedContentGroup
:
function
()
{
return
this
.
$
(
'.radio-yes'
).
prop
(
'checked'
);
},
getSelectedContentGroup
:
function
()
{
var
selectValue
=
this
.
$
(
'.input-cohort-group-association'
).
val
(),
ids
,
groupId
,
userPartitionId
,
i
,
contentGroup
;
if
(
!
this
.
hasAssociatedContentGroup
()
||
selectValue
===
'None'
)
{
return
null
;
}
ids
=
selectValue
.
split
(
':'
);
groupId
=
parseInt
(
ids
[
0
]);
userPartitionId
=
parseInt
(
ids
[
1
]);
for
(
i
=
0
;
i
<
this
.
contentGroups
.
length
;
i
++
)
{
contentGroup
=
this
.
contentGroups
[
i
];
if
(
contentGroup
.
get
(
'id'
)
===
groupId
&&
contentGroup
.
get
(
'user_partition_id'
)
===
userPartitionId
)
{
return
contentGroup
;
}
}
return
null
;
},
getUpdatedCohortName
:
function
()
{
var
cohortName
=
this
.
$
(
'.cohort-name'
).
val
();
return
cohortName
?
cohortName
.
trim
()
:
''
;
},
getAssignmentType
:
function
()
{
return
this
.
$
(
'input[name="cohort-assignment-type"]:checked'
).
val
();
},
showMessage
:
function
(
message
,
type
,
details
)
{
this
.
showNotification
(
{
type
:
type
||
'confirmation'
,
title
:
message
,
details
:
details
},
this
.
$
(
'.form-fields'
)
);
},
validate
:
function
(
fieldData
)
{
var
errorMessages
;
errorMessages
=
[];
if
(
!
fieldData
.
name
)
{
errorMessages
.
push
(
gettext
(
'You must specify a name for the cohort'
));
}
if
(
this
.
hasAssociatedContentGroup
()
&&
fieldData
.
group_id
===
null
)
{
if
(
this
.
$
(
'.input-cohort-group-association'
).
val
()
===
'None'
)
{
errorMessages
.
push
(
gettext
(
'You did not select a content group'
));
}
else
{
// If a value was selected, then it must be for a non-existent/deleted content group
errorMessages
.
push
(
gettext
(
'The selected content group does not exist'
));
}
}
return
errorMessages
;
},
saveForm
:
function
()
{
var
self
=
this
,
cohort
=
this
.
model
,
saveOperation
=
$
.
Deferred
(),
isUpdate
=
!
_
.
isUndefined
(
this
.
model
.
id
),
fieldData
,
selectedContentGroup
,
selectedAssignmentType
,
errorMessages
,
showErrorMessage
;
showErrorMessage
=
function
(
message
,
details
)
{
self
.
showMessage
(
message
,
'error'
,
details
);
};
this
.
removeNotification
();
selectedContentGroup
=
this
.
getSelectedContentGroup
();
selectedAssignmentType
=
this
.
getAssignmentType
();
fieldData
=
{
name
:
this
.
getUpdatedCohortName
(),
group_id
:
selectedContentGroup
?
selectedContentGroup
.
id
:
null
,
user_partition_id
:
selectedContentGroup
?
selectedContentGroup
.
get
(
'user_partition_id'
)
:
null
,
assignment_type
:
selectedAssignmentType
};
errorMessages
=
this
.
validate
(
fieldData
);
if
(
errorMessages
.
length
>
0
)
{
showErrorMessage
(
isUpdate
?
gettext
(
"The cohort cannot be saved"
)
:
gettext
(
"The cohort cannot be added"
),
errorMessages
);
saveOperation
.
reject
();
}
else
{
cohort
.
save
(
fieldData
,
{
patch
:
isUpdate
,
wait
:
true
}
).
done
(
function
(
result
)
{
cohort
.
id
=
result
.
id
;
self
.
render
();
// re-render to remove any now invalid error messages
saveOperation
.
resolve
();
}).
fail
(
function
(
result
)
{
var
errorMessage
=
null
;
try
{
var
jsonResponse
=
JSON
.
parse
(
result
.
responseText
);
errorMessage
=
jsonResponse
.
error
;
}
catch
(
e
)
{
// Ignore the exception and show the default error message instead.
}
}
if
(
!
errorMessage
)
{
var
randomModels
=
cohorts
.
where
({
assignment_type
:
'random'
});
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
return
(
randomModels
.
length
===
1
)
&&
(
randomModels
[
0
].
get
(
'name'
)
===
name
);
},
onRadioButtonChange
:
function
(
event
)
{
var
target
=
$
(
event
.
currentTarget
),
groupsEnabled
=
target
.
val
()
===
'yes'
;
if
(
!
groupsEnabled
)
{
// If the user has chosen 'no', then clear the selection by setting
// it to the first option which represents no selection.
this
.
$
(
'.input-cohort-group-association'
).
val
(
'None'
);
}
}
showErrorMessage
(
errorMessage
);
// Enable the select if the user has chosen groups, else disable it
saveOperation
.
reject
();
this
.
$
(
'.input-cohort-group-association'
).
prop
(
'disabled'
,
!
groupsEnabled
);
});
},
}
return
saveOperation
.
promise
();
hasAssociatedContentGroup
:
function
()
{
}
return
this
.
$
(
'.radio-yes'
).
prop
(
'checked'
);
});
},
}).
call
(
this
,
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
edx
.
groups
.
CohortModel
,
NotificationModel
,
NotificationView
);
getSelectedContentGroup
:
function
()
{
var
selectValue
=
this
.
$
(
'.input-cohort-group-association'
).
val
(),
ids
,
groupId
,
userPartitionId
,
i
,
contentGroup
;
if
(
!
this
.
hasAssociatedContentGroup
()
||
selectValue
===
'None'
)
{
return
null
;
}
ids
=
selectValue
.
split
(
':'
);
groupId
=
parseInt
(
ids
[
0
]);
userPartitionId
=
parseInt
(
ids
[
1
]);
for
(
i
=
0
;
i
<
this
.
contentGroups
.
length
;
i
++
)
{
contentGroup
=
this
.
contentGroups
[
i
];
if
(
contentGroup
.
get
(
'id'
)
===
groupId
&&
contentGroup
.
get
(
'user_partition_id'
)
===
userPartitionId
)
{
return
contentGroup
;
}
}
return
null
;
},
getUpdatedCohortName
:
function
()
{
var
cohortName
=
this
.
$
(
'.cohort-name'
).
val
();
return
cohortName
?
cohortName
.
trim
()
:
''
;
},
getAssignmentType
:
function
()
{
return
this
.
$
(
'input[name="cohort-assignment-type"]:checked'
).
val
();
},
showMessage
:
function
(
message
,
type
,
details
)
{
this
.
showNotification
(
{
type
:
type
||
'confirmation'
,
title
:
message
,
details
:
details
},
this
.
$
(
'.form-fields'
)
);
},
validate
:
function
(
fieldData
)
{
var
errorMessages
;
errorMessages
=
[];
if
(
!
fieldData
.
name
)
{
errorMessages
.
push
(
gettext
(
'You must specify a name for the cohort'
));
}
if
(
this
.
hasAssociatedContentGroup
()
&&
fieldData
.
group_id
===
null
)
{
if
(
this
.
$
(
'.input-cohort-group-association'
).
val
()
===
'None'
)
{
errorMessages
.
push
(
gettext
(
'You did not select a content group'
));
}
else
{
// If a value was selected, then it must be for a non-existent/deleted content group
errorMessages
.
push
(
gettext
(
'The selected content group does not exist'
));
}
}
return
errorMessages
;
},
saveForm
:
function
()
{
var
self
=
this
,
cohort
=
this
.
model
,
saveOperation
=
$
.
Deferred
(),
isUpdate
=
!
_
.
isUndefined
(
this
.
model
.
id
),
fieldData
,
selectedContentGroup
,
selectedAssignmentType
,
errorMessages
,
showErrorMessage
;
showErrorMessage
=
function
(
message
,
details
)
{
self
.
showMessage
(
message
,
'error'
,
details
);
};
this
.
removeNotification
();
selectedContentGroup
=
this
.
getSelectedContentGroup
();
selectedAssignmentType
=
this
.
getAssignmentType
();
fieldData
=
{
name
:
this
.
getUpdatedCohortName
(),
group_id
:
selectedContentGroup
?
selectedContentGroup
.
id
:
null
,
user_partition_id
:
selectedContentGroup
?
selectedContentGroup
.
get
(
'user_partition_id'
)
:
null
,
assignment_type
:
selectedAssignmentType
};
errorMessages
=
this
.
validate
(
fieldData
);
if
(
errorMessages
.
length
>
0
)
{
showErrorMessage
(
isUpdate
?
gettext
(
"The cohort cannot be saved"
)
:
gettext
(
"The cohort cannot be added"
),
errorMessages
);
saveOperation
.
reject
();
}
else
{
cohort
.
save
(
fieldData
,
{
patch
:
isUpdate
,
wait
:
true
}
).
done
(
function
(
result
)
{
cohort
.
id
=
result
.
id
;
self
.
render
();
// re-render to remove any now invalid error messages
saveOperation
.
resolve
();
}).
fail
(
function
(
result
)
{
var
errorMessage
=
null
;
try
{
var
jsonResponse
=
JSON
.
parse
(
result
.
responseText
);
errorMessage
=
jsonResponse
.
error
;
}
catch
(
e
)
{
// Ignore the exception and show the default error message instead.
}
if
(
!
errorMessage
)
{
errorMessage
=
gettext
(
"We've encountered an error. Refresh your browser and then try again."
);
}
showErrorMessage
(
errorMessage
);
saveOperation
.
reject
();
});
}
return
saveOperation
.
promise
();
}
});
return
CohortFormView
;
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/groups/views/cohorts.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
CohortModel
,
CohortEditorView
,
CohortFormView
,
CourseCohortSettingsNotificationView
,
NotificationModel
,
NotificationView
,
FileUploaderView
,
InlineDiscussionsView
,
CourseWideDiscussionsView
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'js/groups/models/cohort'
,
'js/groups/views/cohort_editor'
,
'js/groups/views/cohort_form'
,
'js/groups/views/course_cohort_settings_notification'
,
'js/groups/views/cohort_discussions_inline'
,
'js/groups/views/cohort_discussions_course_wide'
,
'js/views/file_uploader'
,
'js/models/notification'
,
'js/views/notification'
,
'string_utils'
],
function
(
$
,
_
,
Backbone
,
gettext
,
CohortModel
,
CohortEditorView
,
CohortFormView
,
CourseCohortSettingsNotificationView
,
InlineDiscussionsView
,
CourseWideDiscussionsView
)
{
var
hiddenClass
=
'is-hidden'
,
disabledClass
=
'is-disabled'
;
var
CohortsView
=
Backbone
.
View
.
extend
({
events
:
{
'change .cohort-select'
:
'onCohortSelected'
,
'change .cohorts-state'
:
'onCohortsEnabledChanged'
,
'click .action-create'
:
'showAddCohortForm'
,
'click .cohort-management-add-form .action-save'
:
'saveAddCohortForm'
,
'click .cohort-management-add-form .action-cancel'
:
'cancelAddCohortForm'
,
'click .link-cross-reference'
:
'showSection'
,
'click .toggle-cohort-management-secondary'
:
'showCsvUpload'
,
'click .toggle-cohort-management-discussions'
:
'showDiscussionTopics'
},
initialize
:
function
(
options
)
{
var
model
=
this
.
model
;
this
.
template
=
_
.
template
(
$
(
'#cohorts-tpl'
).
text
());
this
.
selectorTemplate
=
_
.
template
(
$
(
'#cohort-selector-tpl'
).
text
());
this
.
context
=
options
.
context
;
this
.
contentGroups
=
options
.
contentGroups
;
this
.
cohortSettings
=
options
.
cohortSettings
;
model
.
on
(
'sync'
,
this
.
onSync
,
this
);
// Update cohort counts when the user clicks back on the cohort management tab
// (for example, after uploading a csv file of cohort assignments and then
// checking results on data download tab).
$
(
this
.
getSectionCss
(
'cohort_management'
)).
click
(
function
()
{
model
.
fetch
();
});
},
render
:
function
()
{
this
.
$el
.
html
(
this
.
template
({
cohorts
:
this
.
model
.
models
,
cohortsEnabled
:
this
.
cohortSettings
.
get
(
'is_cohorted'
)
}));
this
.
onSync
();
return
this
;
},
renderSelector
:
function
(
selectedCohort
)
{
this
.
$
(
'.cohort-select'
).
html
(
this
.
selectorTemplate
({
cohorts
:
this
.
model
.
models
,
selectedCohort
:
selectedCohort
}));
},
renderCourseCohortSettingsNotificationView
:
function
()
{
var
cohortStateMessageNotificationView
=
new
CourseCohortSettingsNotificationView
({
el
:
$
(
'.cohort-state-message'
),
cohortEnabled
:
this
.
getCohortsEnabled
()
});
cohortStateMessageNotificationView
.
render
();
},
onSync
:
function
(
model
,
response
,
options
)
{
var
selectedCohort
=
this
.
lastSelectedCohortId
&&
this
.
model
.
get
(
this
.
lastSelectedCohortId
),
hasCohorts
=
this
.
model
.
length
>
0
,
cohortNavElement
=
this
.
$
(
'.cohort-management-nav'
),
additionalCohortControlElement
=
this
.
$
(
'.wrapper-cohort-supplemental'
),
isModelUpdate
;
isModelUpdate
=
function
()
{
// Distinguish whether this is a sync event for just one model, or if it is for
// an entire collection.
return
options
&&
options
.
patch
&&
response
.
hasOwnProperty
(
'user_partition_id'
);
};
this
.
hideAddCohortForm
();
if
(
isModelUpdate
())
{
// Refresh the selector in case the model's name changed
this
.
renderSelector
(
selectedCohort
);
}
else
if
(
hasCohorts
)
{
cohortNavElement
.
removeClass
(
hiddenClass
);
additionalCohortControlElement
.
removeClass
(
hiddenClass
);
this
.
renderSelector
(
selectedCohort
);
if
(
selectedCohort
)
{
this
.
showCohortEditor
(
selectedCohort
);
}
}
else
{
cohortNavElement
.
addClass
(
hiddenClass
);
additionalCohortControlElement
.
addClass
(
hiddenClass
);
this
.
showNotification
({
type
:
'warning'
,
title
:
gettext
(
'You currently have no cohorts configured'
),
actionText
:
gettext
(
'Add Cohort'
),
actionClass
:
'action-create'
,
actionIconClass
:
'fa-plus'
});
}
},
var
hiddenClass
=
'is-hidden'
,
getSelectedCohort
:
function
()
{
disabledClass
=
'is-disabled'
;
var
id
=
this
.
$
(
'.cohort-select'
).
val
();
return
id
&&
this
.
model
.
get
(
parseInt
(
id
));
edx
.
groups
=
edx
.
groups
||
{};
},
edx
.
groups
.
CohortsView
=
Backbone
.
View
.
extend
({
events
:
{
'change .cohort-select'
:
'onCohortSelected'
,
'change .cohorts-state'
:
'onCohortsEnabledChanged'
,
'click .action-create'
:
'showAddCohortForm'
,
'click .cohort-management-add-form .action-save'
:
'saveAddCohortForm'
,
'click .cohort-management-add-form .action-cancel'
:
'cancelAddCohortForm'
,
'click .link-cross-reference'
:
'showSection'
,
'click .toggle-cohort-management-secondary'
:
'showCsvUpload'
,
'click .toggle-cohort-management-discussions'
:
'showDiscussionTopics'
},
initialize
:
function
(
options
)
{
var
model
=
this
.
model
;
this
.
template
=
_
.
template
(
$
(
'#cohorts-tpl'
).
text
());
this
.
selectorTemplate
=
_
.
template
(
$
(
'#cohort-selector-tpl'
).
text
());
this
.
context
=
options
.
context
;
this
.
contentGroups
=
options
.
contentGroups
;
this
.
cohortSettings
=
options
.
cohortSettings
;
model
.
on
(
'sync'
,
this
.
onSync
,
this
);
// Update cohort counts when the user clicks back on the cohort management tab
// (for example, after uploading a csv file of cohort assignments and then
// checking results on data download tab).
$
(
this
.
getSectionCss
(
'cohort_management'
)).
click
(
function
()
{
model
.
fetch
();
});
},
render
:
function
()
{
this
.
$el
.
html
(
this
.
template
({
cohorts
:
this
.
model
.
models
,
cohortsEnabled
:
this
.
cohortSettings
.
get
(
'is_cohorted'
)
}));
this
.
onSync
();
return
this
;
},
renderSelector
:
function
(
selectedCohort
)
{
this
.
$
(
'.cohort-select'
).
html
(
this
.
selectorTemplate
({
cohorts
:
this
.
model
.
models
,
selectedCohort
:
selectedCohort
}));
},
renderCourseCohortSettingsNotificationView
:
function
()
{
var
cohortStateMessageNotificationView
=
new
CourseCohortSettingsNotificationView
({
el
:
$
(
'.cohort-state-message'
),
cohortEnabled
:
this
.
getCohortsEnabled
()
});
cohortStateMessageNotificationView
.
render
();
},
onSync
:
function
(
model
,
response
,
options
)
{
var
selectedCohort
=
this
.
lastSelectedCohortId
&&
this
.
model
.
get
(
this
.
lastSelectedCohortId
),
hasCohorts
=
this
.
model
.
length
>
0
,
cohortNavElement
=
this
.
$
(
'.cohort-management-nav'
),
additionalCohortControlElement
=
this
.
$
(
'.wrapper-cohort-supplemental'
),
isModelUpdate
;
isModelUpdate
=
function
()
{
// Distinguish whether this is a sync event for just one model, or if it is for
// an entire collection.
return
options
&&
options
.
patch
&&
response
.
hasOwnProperty
(
'user_partition_id'
);
};
this
.
hideAddCohortForm
();
if
(
isModelUpdate
())
{
// Refresh the selector in case the model's name changed
this
.
renderSelector
(
selectedCohort
);
}
else
if
(
hasCohorts
)
{
cohortNavElement
.
removeClass
(
hiddenClass
);
additionalCohortControlElement
.
removeClass
(
hiddenClass
);
this
.
renderSelector
(
selectedCohort
);
if
(
selectedCohort
)
{
this
.
showCohortEditor
(
selectedCohort
);
}
}
else
{
cohortNavElement
.
addClass
(
hiddenClass
);
additionalCohortControlElement
.
addClass
(
hiddenClass
);
this
.
showNotification
({
type
:
'warning'
,
title
:
gettext
(
'You currently have no cohorts configured'
),
actionText
:
gettext
(
'Add Cohort'
),
actionClass
:
'action-create'
,
actionIconClass
:
'fa-plus'
});
}
},
getSelectedCohort
:
function
()
{
var
id
=
this
.
$
(
'.cohort-select'
).
val
();
return
id
&&
this
.
model
.
get
(
parseInt
(
id
));
},
onCohortSelected
:
function
(
event
)
{
event
.
preventDefault
();
var
selectedCohort
=
this
.
getSelectedCohort
();
this
.
lastSelectedCohortId
=
selectedCohort
.
get
(
'id'
);
this
.
showCohortEditor
(
selectedCohort
);
},
onCohortsEnabledChanged
:
function
(
event
)
{
event
.
preventDefault
();
this
.
saveCohortSettings
();
},
saveCohortSettings
:
function
()
{
var
self
=
this
,
cohortSettings
,
fieldData
=
{
is_cohorted
:
this
.
getCohortsEnabled
()};
cohortSettings
=
this
.
cohortSettings
;
cohortSettings
.
save
(
fieldData
,
{
patch
:
true
,
wait
:
true
}
).
done
(
function
()
{
self
.
render
();
self
.
renderCourseCohortSettingsNotificationView
();
}).
fail
(
function
(
result
)
{
self
.
showNotification
({
type
:
'error'
,
title
:
gettext
(
"We've encountered an error. Refresh your browser and then try again."
)},
self
.
$
(
'.cohorts-state-section'
)
);
});
},
getCohortsEnabled
:
function
()
{
return
this
.
$
(
'.cohorts-state'
).
prop
(
'checked'
);
},
showCohortEditor
:
function
(
cohort
)
{
this
.
removeNotification
();
if
(
this
.
editor
)
{
this
.
editor
.
setCohort
(
cohort
);
$
(
'.cohort-management-group .group-header-title'
).
focus
();
}
else
{
this
.
editor
=
new
CohortEditorView
({
el
:
this
.
$
(
'.cohort-management-group'
),
model
:
cohort
,
cohorts
:
this
.
model
,
contentGroups
:
this
.
contentGroups
,
context
:
this
.
context
});
this
.
editor
.
render
();
$
(
'.cohort-management-group .group-header-title'
).
focus
();
}
},
showNotification
:
function
(
options
,
beforeElement
)
{
var
model
=
new
NotificationModel
(
options
);
this
.
removeNotification
();
this
.
notification
=
new
NotificationView
({
model
:
model
});
if
(
!
beforeElement
)
{
onCohortSelected
:
function
(
event
)
{
beforeElement
=
this
.
$
(
'.cohort-management-group'
);
event
.
preventDefault
();
}
var
selectedCohort
=
this
.
getSelectedCohort
();
beforeElement
.
before
(
this
.
notification
.
$el
);
this
.
lastSelectedCohortId
=
selectedCohort
.
get
(
'id'
);
this
.
showCohortEditor
(
selectedCohort
);
this
.
notification
.
render
();
},
},
onCohortsEnabledChanged
:
function
(
event
)
{
removeNotification
:
function
()
{
event
.
preventDefault
();
if
(
this
.
notification
)
{
this
.
saveCohortSettings
();
this
.
notification
.
remove
();
},
}
if
(
this
.
cohortFormView
)
{
saveCohortSettings
:
function
()
{
this
.
cohortFormView
.
removeNotification
();
var
self
=
this
,
}
cohortSettings
,
},
fieldData
=
{
is_cohorted
:
this
.
getCohortsEnabled
()};
cohortSettings
=
this
.
cohortSettings
;
showAddCohortForm
:
function
(
event
)
{
cohortSettings
.
save
(
var
newCohort
;
fieldData
,
{
patch
:
true
,
wait
:
true
}
event
.
preventDefault
();
).
done
(
function
()
{
this
.
removeNotification
();
self
.
render
();
newCohort
=
new
CohortModel
();
self
.
renderCourseCohortSettingsNotificationView
();
newCohort
.
url
=
this
.
model
.
url
;
}).
fail
(
function
(
result
)
{
this
.
cohortFormView
=
new
CohortFormView
({
model
:
newCohort
,
contentGroups
:
this
.
contentGroups
,
context
:
this
.
context
});
this
.
cohortFormView
.
render
();
this
.
$
(
'.cohort-management-add-form'
).
append
(
this
.
cohortFormView
.
$el
);
this
.
cohortFormView
.
$
(
'.cohort-name'
).
focus
();
this
.
setCohortEditorVisibility
(
false
);
},
hideAddCohortForm
:
function
()
{
this
.
setCohortEditorVisibility
(
true
);
if
(
this
.
cohortFormView
)
{
this
.
cohortFormView
.
remove
();
this
.
cohortFormView
=
null
;
}
},
setCohortEditorVisibility
:
function
(
showEditor
)
{
if
(
showEditor
)
{
this
.
$
(
'.cohorts-state-section'
).
removeClass
(
disabledClass
).
attr
(
'aria-disabled'
,
false
);
this
.
$
(
'.cohort-management-group'
).
removeClass
(
hiddenClass
);
this
.
$
(
'.cohort-management-nav'
).
removeClass
(
disabledClass
).
attr
(
'aria-disabled'
,
false
);
}
else
{
this
.
$
(
'.cohorts-state-section'
).
addClass
(
disabledClass
).
attr
(
'aria-disabled'
,
true
);
this
.
$
(
'.cohort-management-group'
).
addClass
(
hiddenClass
);
this
.
$
(
'.cohort-management-nav'
).
addClass
(
disabledClass
).
attr
(
'aria-disabled'
,
true
);
}
},
saveAddCohortForm
:
function
(
event
)
{
var
self
=
this
,
newCohort
=
this
.
cohortFormView
.
model
;
event
.
preventDefault
();
this
.
removeNotification
();
this
.
cohortFormView
.
saveForm
()
.
done
(
function
()
{
self
.
lastSelectedCohortId
=
newCohort
.
id
;
self
.
model
.
fetch
().
done
(
function
()
{
self
.
showNotification
({
self
.
showNotification
({
type
:
'confirmation'
,
type
:
'error'
,
title
:
interpolate_text
(
title
:
gettext
(
"We've encountered an error. Refresh your browser and then try again."
)},
gettext
(
'The {cohortGroupName} cohort has been created. You can manually add students to this cohort below.'
),
self
.
$
(
'.cohorts-state-section'
)
{
cohortGroupName
:
newCohort
.
get
(
'name'
)}
);
)
});
},
getCohortsEnabled
:
function
()
{
return
this
.
$
(
'.cohorts-state'
).
prop
(
'checked'
);
},
showCohortEditor
:
function
(
cohort
)
{
this
.
removeNotification
();
if
(
this
.
editor
)
{
this
.
editor
.
setCohort
(
cohort
);
$
(
'.cohort-management-group .group-header-title'
).
focus
();
}
else
{
this
.
editor
=
new
CohortEditorView
({
el
:
this
.
$
(
'.cohort-management-group'
),
model
:
cohort
,
cohorts
:
this
.
model
,
contentGroups
:
this
.
contentGroups
,
context
:
this
.
context
});
});
this
.
editor
.
render
();
$
(
'.cohort-management-group .group-header-title'
).
focus
();
}
},
showNotification
:
function
(
options
,
beforeElement
)
{
var
model
=
new
NotificationModel
(
options
);
this
.
removeNotification
();
this
.
notification
=
new
NotificationView
({
model
:
model
});
if
(
!
beforeElement
)
{
beforeElement
=
this
.
$
(
'.cohort-management-group'
);
}
beforeElement
.
before
(
this
.
notification
.
$el
);
this
.
notification
.
render
();
},
removeNotification
:
function
()
{
if
(
this
.
notification
)
{
this
.
notification
.
remove
();
}
if
(
this
.
cohortFormView
)
{
this
.
cohortFormView
.
removeNotification
();
}
},
showAddCohortForm
:
function
(
event
)
{
var
newCohort
;
event
.
preventDefault
();
this
.
removeNotification
();
newCohort
=
new
CohortModel
();
newCohort
.
url
=
this
.
model
.
url
;
this
.
cohortFormView
=
new
CohortFormView
({
model
:
newCohort
,
contentGroups
:
this
.
contentGroups
,
context
:
this
.
context
});
});
});
this
.
cohortFormView
.
render
();
},
this
.
$
(
'.cohort-management-add-form'
).
append
(
this
.
cohortFormView
.
$el
);
this
.
cohortFormView
.
$
(
'.cohort-name'
).
focus
();
cancelAddCohortForm
:
function
(
event
)
{
this
.
setCohortEditorVisibility
(
false
);
event
.
preventDefault
();
},
this
.
removeNotification
();
this
.
onSync
();
hideAddCohortForm
:
function
()
{
},
this
.
setCohortEditorVisibility
(
true
);
if
(
this
.
cohortFormView
)
{
showSection
:
function
(
event
)
{
this
.
cohortFormView
.
remove
();
event
.
preventDefault
();
this
.
cohortFormView
=
null
;
var
section
=
$
(
event
.
currentTarget
).
data
(
"section"
);
}
$
(
this
.
getSectionCss
(
section
)).
click
();
},
$
(
window
).
scrollTop
(
0
);
},
setCohortEditorVisibility
:
function
(
showEditor
)
{
if
(
showEditor
)
{
showCsvUpload
:
function
(
event
)
{
this
.
$
(
'.cohorts-state-section'
).
removeClass
(
disabledClass
).
attr
(
'aria-disabled'
,
false
);
event
.
preventDefault
();
this
.
$
(
'.cohort-management-group'
).
removeClass
(
hiddenClass
);
this
.
$
(
'.cohort-management-nav'
).
removeClass
(
disabledClass
).
attr
(
'aria-disabled'
,
false
);
$
(
event
.
currentTarget
).
addClass
(
hiddenClass
);
}
else
{
var
uploadElement
=
this
.
$
(
'.csv-upload'
).
removeClass
(
hiddenClass
);
this
.
$
(
'.cohorts-state-section'
).
addClass
(
disabledClass
).
attr
(
'aria-disabled'
,
true
);
this
.
$
(
'.cohort-management-group'
).
addClass
(
hiddenClass
);
if
(
!
this
.
fileUploaderView
)
{
this
.
$
(
'.cohort-management-nav'
).
addClass
(
disabledClass
).
attr
(
'aria-disabled'
,
true
);
this
.
fileUploaderView
=
new
FileUploaderView
({
}
el
:
uploadElement
,
},
title
:
gettext
(
"Assign students to cohorts by uploading a CSV file."
),
inputLabel
:
gettext
(
"Choose a .csv file"
),
saveAddCohortForm
:
function
(
event
)
{
inputTip
:
gettext
(
"Only properly formatted .csv files will be accepted."
),
var
self
=
this
,
submitButtonText
:
gettext
(
"Upload File and Assign Students"
),
newCohort
=
this
.
cohortFormView
.
model
;
extensions
:
".csv"
,
event
.
preventDefault
();
url
:
this
.
context
.
uploadCohortsCsvUrl
,
this
.
removeNotification
();
successNotification
:
function
(
file
,
event
,
data
)
{
this
.
cohortFormView
.
saveForm
()
var
message
=
interpolate_text
(
gettext
(
.
done
(
function
()
{
"Your file '{file}' has been uploaded. Allow a few minutes for processing."
self
.
lastSelectedCohortId
=
newCohort
.
id
;
),
{
file
:
file
});
self
.
model
.
fetch
().
done
(
function
()
{
return
new
NotificationModel
({
self
.
showNotification
({
type
:
"confirmation"
,
type
:
'confirmation'
,
title
:
message
title
:
interpolate_text
(
gettext
(
'The {cohortGroupName} cohort has been created. You can manually add students to this cohort below.'
),
{
cohortGroupName
:
newCohort
.
get
(
'name'
)}
)
});
});
});
});
},
cancelAddCohortForm
:
function
(
event
)
{
event
.
preventDefault
();
this
.
removeNotification
();
this
.
onSync
();
},
showSection
:
function
(
event
)
{
event
.
preventDefault
();
var
section
=
$
(
event
.
currentTarget
).
data
(
"section"
);
$
(
this
.
getSectionCss
(
section
)).
click
();
$
(
window
).
scrollTop
(
0
);
},
showCsvUpload
:
function
(
event
)
{
event
.
preventDefault
();
$
(
event
.
currentTarget
).
addClass
(
hiddenClass
);
var
uploadElement
=
this
.
$
(
'.csv-upload'
).
removeClass
(
hiddenClass
);
if
(
!
this
.
fileUploaderView
)
{
this
.
fileUploaderView
=
new
FileUploaderView
({
el
:
uploadElement
,
title
:
gettext
(
"Assign students to cohorts by uploading a CSV file."
),
inputLabel
:
gettext
(
"Choose a .csv file"
),
inputTip
:
gettext
(
"Only properly formatted .csv files will be accepted."
),
submitButtonText
:
gettext
(
"Upload File and Assign Students"
),
extensions
:
".csv"
,
url
:
this
.
context
.
uploadCohortsCsvUrl
,
successNotification
:
function
(
file
,
event
,
data
)
{
var
message
=
interpolate_text
(
gettext
(
"Your file '{file}' has been uploaded. Allow a few minutes for processing."
),
{
file
:
file
});
return
new
NotificationModel
({
type
:
"confirmation"
,
title
:
message
});
}
}).
render
();
this
.
$
(
'#file-upload-form-file'
).
focus
();
}
},
showDiscussionTopics
:
function
(
event
)
{
event
.
preventDefault
();
$
(
event
.
currentTarget
).
addClass
(
hiddenClass
);
var
cohortDiscussionsElement
=
this
.
$
(
'.cohort-discussions-nav'
).
removeClass
(
hiddenClass
);
if
(
!
this
.
CourseWideDiscussionsView
)
{
this
.
CourseWideDiscussionsView
=
new
CourseWideDiscussionsView
({
el
:
cohortDiscussionsElement
,
model
:
this
.
context
.
discussionTopicsSettingsModel
,
cohortSettings
:
this
.
cohortSettings
}).
render
();
}
if
(
!
this
.
InlineDiscussionsView
)
{
this
.
InlineDiscussionsView
=
new
InlineDiscussionsView
({
el
:
cohortDiscussionsElement
,
model
:
this
.
context
.
discussionTopicsSettingsModel
,
cohortSettings
:
this
.
cohortSettings
}).
render
();
}
}
}).
render
();
},
this
.
$
(
'#file-upload-form-file'
).
focus
();
}
getSectionCss
:
function
(
section
)
{
},
return
".instructor-nav .nav-item a[data-section='"
+
section
+
"']"
;
showDiscussionTopics
:
function
(
event
)
{
}
event
.
preventDefault
();
});
return
CohortsView
;
$
(
event
.
currentTarget
).
addClass
(
hiddenClass
);
var
cohortDiscussionsElement
=
this
.
$
(
'.cohort-discussions-nav'
).
removeClass
(
hiddenClass
);
if
(
!
this
.
CourseWideDiscussionsView
)
{
this
.
CourseWideDiscussionsView
=
new
CourseWideDiscussionsView
({
el
:
cohortDiscussionsElement
,
model
:
this
.
context
.
discussionTopicsSettingsModel
,
cohortSettings
:
this
.
cohortSettings
}).
render
();
}
if
(
!
this
.
InlineDiscussionsView
)
{
this
.
InlineDiscussionsView
=
new
InlineDiscussionsView
({
el
:
cohortDiscussionsElement
,
model
:
this
.
context
.
discussionTopicsSettingsModel
,
cohortSettings
:
this
.
cohortSettings
}).
render
();
}
},
getSectionCss
:
function
(
section
)
{
return
".instructor-nav .nav-item a[data-section='"
+
section
+
"']"
;
}
});
});
}).
call
(
this
,
$
,
_
,
Backbone
,
gettext
,
interpolate_text
,
edx
.
groups
.
CohortModel
,
edx
.
groups
.
CohortEditorView
,
}).
call
(
this
,
define
||
RequireJS
.
define
);
edx
.
groups
.
CohortFormView
,
edx
.
groups
.
CourseCohortSettingsNotificationView
,
NotificationModel
,
NotificationView
,
FileUploaderView
,
edx
.
groups
.
InlineDiscussionsView
,
edx
.
groups
.
CourseWideDiscussionsView
);
lms/static/js/groups/views/cohorts_dashboard_factory.js
View file @
eff80bae
;(
function
(
define
,
undefined
)
{
;(
function
(
define
,
undefined
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'js/groups/views/cohorts'
,
'js/groups/collections/cohort'
,
'js/groups/models/course_cohort_settings'
,
define
([
'jquery'
,
'js/groups/views/cohorts'
,
'js/groups/collections/cohort'
,
'js/groups/models/course_cohort_settings'
,
'js/groups/models/cohort_discussions'
],
'js/groups/models/cohort_discussions'
,
'js/groups/models/content_group'
],
function
(
$
)
{
function
(
$
,
CohortsView
,
CohortCollection
,
CourseCohortSettingsModel
,
DiscussionTopicsSettingsModel
,
ContentGroupModel
)
{
return
function
(
contentGroups
,
studioGroupConfigurationsUrl
)
{
return
function
(
contentGroups
,
studioGroupConfigurationsUrl
)
{
var
contentGroupModels
=
$
.
map
(
contentGroups
,
function
(
group
)
{
return
new
ContentGroupModel
({
id
:
group
.
id
,
name
:
group
.
name
,
user_partition_id
:
group
.
user_partition_id
});
});
var
cohorts
=
new
edx
.
groups
.
CohortCollection
(),
var
cohorts
=
new
CohortCollection
(),
courseCohortSettings
=
new
edx
.
groups
.
CourseCohortSettingsModel
(),
courseCohortSettings
=
new
CourseCohortSettingsModel
(),
discussionTopicsSettings
=
new
edx
.
groups
.
DiscussionTopicsSettingsModel
();
discussionTopicsSettings
=
new
DiscussionTopicsSettingsModel
();
var
cohortManagementElement
=
$
(
'.cohort-management'
);
var
cohortManagementElement
=
$
(
'.cohort-management'
);
...
@@ -16,10 +23,10 @@
...
@@ -16,10 +23,10 @@
courseCohortSettings
.
url
=
cohortManagementElement
.
data
(
'course_cohort_settings_url'
);
courseCohortSettings
.
url
=
cohortManagementElement
.
data
(
'course_cohort_settings_url'
);
discussionTopicsSettings
.
url
=
cohortManagementElement
.
data
(
'discussion-topics-url'
);
discussionTopicsSettings
.
url
=
cohortManagementElement
.
data
(
'discussion-topics-url'
);
var
cohortsView
=
new
edx
.
groups
.
CohortsView
({
var
cohortsView
=
new
CohortsView
({
el
:
cohortManagementElement
,
el
:
cohortManagementElement
,
model
:
cohorts
,
model
:
cohorts
,
contentGroups
:
contentGroups
,
contentGroups
:
contentGroup
Model
s
,
cohortSettings
:
courseCohortSettings
,
cohortSettings
:
courseCohortSettings
,
context
:
{
context
:
{
discussionTopicsSettingsModel
:
discussionTopicsSettings
,
discussionTopicsSettingsModel
:
discussionTopicsSettings
,
...
...
lms/static/js/groups/views/course_cohort_settings_notification.js
View file @
eff80bae
var
edx
=
edx
||
{};
;(
function
(
define
)
{
(
function
(
$
,
_
,
Backbone
,
gettext
)
{
'use strict'
;
'use strict'
;
define
([
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
],
function
(
$
,
_
,
Backbone
,
gettext
)
{
edx
.
groups
=
edx
.
groups
||
{};
var
CourseCohortSettingsNotificationView
=
Backbone
.
View
.
extend
({
initialize
:
function
(
options
)
{
edx
.
groups
.
CourseCohortSettingsNotificationView
=
Backbone
.
View
.
extend
({
this
.
template
=
_
.
template
(
$
(
'#cohort-state-tpl'
).
text
());
initialize
:
function
(
options
)
{
this
.
cohortEnabled
=
options
.
cohortEnabled
;
this
.
template
=
_
.
template
(
$
(
'#cohort-state-tpl'
).
text
());
},
this
.
cohortEnabled
=
options
.
cohortEnabled
;
},
render
:
function
()
{
render
:
function
()
{
this
.
$el
.
html
(
this
.
template
({}));
this
.
$el
.
html
(
this
.
template
({}));
this
.
showCohortStateMessage
();
this
.
showCohortStateMessage
();
return
this
;
return
this
;
},
},
showCohortStateMessage
:
function
()
{
showCohortStateMessage
:
function
()
{
var
actionToggleMessage
=
this
.
$
(
'.action-toggle-message'
);
var
actionToggleMessage
=
this
.
$
(
'.action-toggle-message'
);
AnimationUtil
.
triggerAnimation
(
actionToggleMessage
);
AnimationUtil
.
triggerAnimation
(
actionToggleMessage
);
if
(
this
.
cohortEnabled
)
{
if
(
this
.
cohortEnabled
)
{
actionToggleMessage
.
text
(
gettext
(
'Cohorts Enabled'
));
actionToggleMessage
.
text
(
gettext
(
'Cohorts Enabled'
));
}
else
{
}
else
{
actionToggleMessage
.
text
(
gettext
(
'Cohorts Disabled'
));
actionToggleMessage
.
text
(
gettext
(
'Cohorts Disabled'
));
}
}
}
}
});
return
CourseCohortSettingsNotificationView
;
});
});
}).
call
(
this
,
$
,
_
,
Backbone
,
gettext
);
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/static/js/spec/main.js
View file @
eff80bae
...
@@ -67,18 +67,6 @@
...
@@ -67,18 +67,6 @@
'js/models/notification'
:
'js/models/notification'
,
'js/models/notification'
:
'js/models/notification'
,
'js/views/file_uploader'
:
'js/views/file_uploader'
,
'js/views/file_uploader'
:
'js/views/file_uploader'
,
'js/views/notification'
:
'js/views/notification'
,
'js/views/notification'
:
'js/views/notification'
,
'js/groups/models/cohort'
:
'js/groups/models/cohort'
,
'js/groups/models/content_group'
:
'js/groups/models/content_group'
,
'js/groups/models/course_cohort_settings'
:
'js/groups/models/course_cohort_settings'
,
'js/groups/models/cohort_discussions'
:
'js/groups/models/cohort_discussions'
,
'js/groups/views/cohort_discussions'
:
'js/groups/views/cohort_discussions'
,
'js/groups/views/cohort_discussions_course_wide'
:
'js/groups/views/cohort_discussions_course_wide'
,
'js/groups/views/cohort_discussions_inline'
:
'js/groups/views/cohort_discussions_inline'
,
'js/groups/views/course_cohort_settings_notification'
:
'js/groups/views/course_cohort_settings_notification'
,
'js/groups/collections/cohort'
:
'js/groups/collections/cohort'
,
'js/groups/views/cohort_editor'
:
'js/groups/views/cohort_editor'
,
'js/groups/views/cohort_form'
:
'js/groups/views/cohort_form'
,
'js/groups/views/cohorts'
:
'js/groups/views/cohorts'
,
'js/student_account/account'
:
'js/student_account/account'
,
'js/student_account/account'
:
'js/student_account/account'
,
'js/student_account/views/FormView'
:
'js/student_account/views/FormView'
,
'js/student_account/views/FormView'
:
'js/student_account/views/FormView'
,
'js/student_account/models/LoginModel'
:
'js/student_account/models/LoginModel'
,
'js/student_account/models/LoginModel'
:
'js/student_account/models/LoginModel'
,
...
@@ -301,63 +289,6 @@
...
@@ -301,63 +289,6 @@
exports
:
'edx.instructor_dashboard.ecommerce.ExpiryCouponView'
,
exports
:
'edx.instructor_dashboard.ecommerce.ExpiryCouponView'
,
deps
:
[
'backbone'
,
'jquery'
,
'underscore'
]
deps
:
[
'backbone'
,
'jquery'
,
'underscore'
]
},
},
'js/groups/models/cohort'
:
{
exports
:
'edx.groups.CohortModel'
,
deps
:
[
'backbone'
]
},
'js/groups/models/content_group'
:
{
exports
:
'edx.groups.ContentGroupModel'
,
deps
:
[
'backbone'
]
},
'js/groups/models/course_cohort_settings'
:
{
exports
:
'edx.groups.CourseCohortSettingsModel'
,
deps
:
[
'backbone'
]
},
'js/groups/models/cohort_discussions'
:
{
exports
:
'edx.groups.DiscussionTopicsSettingsModel'
,
deps
:
[
'backbone'
]
},
'js/groups/views/cohort_discussions'
:
{
exports
:
'edx.groups.CohortDiscussionConfigurationView'
,
deps
:
[
'backbone'
]
},
'js/groups/views/cohort_discussions_course_wide'
:
{
exports
:
'edx.groups.CourseWideDiscussionsView'
,
deps
:
[
'backbone'
,
'js/groups/views/cohort_discussions'
]
},
'js/groups/views/cohort_discussions_inline'
:
{
exports
:
'edx.groups.InlineDiscussionsView'
,
deps
:
[
'backbone'
,
'js/groups/views/cohort_discussions'
,
'js/vendor/jquery.qubit'
]
},
'js/groups/views/course_cohort_settings_notification'
:
{
exports
:
'edx.groups.CourseCohortSettingsNotificationView'
,
deps
:
[
'backbone'
]
},
'js/groups/collections/cohort'
:
{
exports
:
'edx.groups.CohortCollection'
,
deps
:
[
'backbone'
,
'js/groups/models/cohort'
]
},
'js/groups/views/cohort_form'
:
{
exports
:
'edx.groups.CohortFormView'
,
deps
:
[
'backbone'
,
'jquery'
,
'underscore'
,
'js/views/notification'
,
'js/models/notification'
,
'string_utils'
]
},
'js/groups/views/cohort_editor'
:
{
exports
:
'edx.groups.CohortEditorView'
,
deps
:
[
'backbone'
,
'jquery'
,
'underscore'
,
'js/views/notification'
,
'js/models/notification'
,
'string_utils'
,
'js/groups/views/cohort_form'
]
},
'js/groups/views/cohorts'
:
{
exports
:
'edx.groups.CohortsView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'string_utils'
,
'js/groups/views/cohort_editor'
,
'js/views/notification'
,
'js/models/notification'
,
'js/views/file_uploader'
]
},
'js/models/notification'
:
{
'js/models/notification'
:
{
exports
:
'NotificationModel'
,
exports
:
'NotificationModel'
,
deps
:
[
'backbone'
]
deps
:
[
'backbone'
]
...
...
lms/static/lms/js/build.js
View file @
eff80bae
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
* done.
* done.
*/
*/
modules
:
getModulesList
([
modules
:
getModulesList
([
'js/groups/views/cohorts_dashboard_factory'
,
'js/student_account/views/account_settings_factory'
,
'js/student_account/views/account_settings_factory'
,
'js/student_account/views/finish_auth_factory'
,
'js/student_account/views/finish_auth_factory'
,
'js/student_profile/views/learner_profile_factory'
,
'js/student_profile/views/learner_profile_factory'
,
...
...
lms/templates/instructor/instructor_dashboard_2/cohort_management.html
View file @
eff80bae
<
%
page
args=
"section_data"
/>
<
%
page
args=
"section_data"
/>
<
%
namespace
name=
'static'
file=
'../../static_content.html'
/>
<
%!
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
from
django
.
utils
.
translation
import
ugettext
as
_
from
courseware
.
courses
import
get_studio_url
from
courseware
.
courses
import
get_studio_url
...
@@ -16,32 +17,23 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_
...
@@ -16,32 +17,23 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_
</div>
</div>
<
%
block
name=
"headextra"
>
<
%
block
name=
"js_extra"
>
<
%
static:require_module
module_name=
"js/groups/views/cohorts_dashboard_factory"
class_name=
"CohortsFactory"
>
<
%
<
%
cohorted_user_partition =
get_cohorted_user_partition(course.id)
cohorted_user_partition =
get_cohorted_user_partition(course.id)
content_groups =
cohorted_user_partition.groups
if
cohorted_user_partition
else
[]
content_groups =
cohorted_user_partition.groups
if
cohorted_user_partition
else
[]
%
>
%
>
<script
type=
"text/javascript"
>
var cohortUserPartitionId = ${cohorted_user_partition.id if cohorted_user_partition else 'null'},
$
(
document
).
ready
(
function
()
{
contentGroups = [
% for content_group in content_groups:
var
cohortUserPartitionId
=
$
{
cohorted_user_partition
.
id
if
cohorted_user_partition
else
'null'
},
{
contentGroups
=
[
id: ${content_group.id},
%
for
content_group
in
content_groups
:
name: "${content_group.name | h}",
new
edx
.
groups
.
ContentGroupModel
({
user_partition_id: cohortUserPartitionId
id
:
$
{
content_group
.
id
},
},
name
:
"${content_group.name | h}"
,
% endfor
user_partition_id
:
cohortUserPartitionId
];
}),
CohortsFactory(contentGroups, '${get_studio_url(course, 'group_configurations') | h}');
%
endfor
</
%
static:require
_module
>
];
(
function
(
require
)
{
require
([
'js/groups/views/cohorts_dashboard_factory'
],
function
(
CohortsFactory
)
{
CohortsFactory
(
contentGroups
,
'${get_studio_url(course, '
group_configurations
') | h}'
);
});
}).
call
(
this
,
require
||
RequireJS
.
require
);
});
</script>
</
%
block>
</
%
block>
<div
class=
"cohort-state-message"
></div>
<div
class=
"cohort-state-message"
></div>
lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html
View file @
eff80bae
...
@@ -56,22 +56,9 @@ from django.core.urlresolvers import reverse
...
@@ -56,22 +56,9 @@ from django.core.urlresolvers import reverse
<
%
static:js
group=
'application'
/>
<
%
static:js
group=
'application'
/>
## Backbone classes declared explicitly until RequireJS is supported
## Backbone classes declared explicitly until RequireJS is supported
<script
type=
"text/javascript"
src=
"${static.url('js/instructor_dashboard/cohort_management.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/models/notification.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/models/notification.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/views/notification.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/views/notification.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/views/file_uploader.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/views/file_uploader.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/models/cohort.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/models/content_group.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/models/course_cohort_settings.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/collections/cohort.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/course_cohort_settings_notification.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/models/cohort_discussions.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/cohort_discussions.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/cohort_discussions_course_wide.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/cohort_discussions_inline.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/cohort_form.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/cohort_editor.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/groups/views/cohorts.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/utils/animation.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/utils/animation.js')}"
></script>
</
%
block>
</
%
block>
...
...
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