{Actions, Store} = require('../smc-react')
misc = require('smc-util/misc')
{defaults, required} = misc
{STEPS, previous_step, step_direction, step_verb, step_ready} = require('./util')
project_upgrades = require('./project-upgrades')
exports.CourseStore = class CourseStore extends Store
any_assignment_uses_peer_grading: =>
has_peer = false
@get_assignments().forEach (assignment, _) =>
if assignment.getIn(['peer_grade', 'enabled']) and not assignment.get('deleted')
has_peer = true
return false
return has_peer
get_peers_that_student_will_grade: (assignment, student) =>
assignment = @get_assignment(assignment)
student = @get_student(student)
return assignment.getIn(['peer_grade', 'map'])?.get(student.get('student_id'))?.toJS()
get_peers_that_graded_student: (assignment, student) =>
assignment = @get_assignment(assignment)
map = assignment.getIn(['peer_grade', 'map'])
if not map?
return
student = @get_student(student)
id = student.get('student_id')
return (student_id for student_id, who_grading of map.toJS() when id in who_grading)
get_shared_project_id: =>
return @getIn(['settings', 'shared_project_id'])
get_pay: =>
return @getIn(['settings', 'pay']) ? ''
get_allow_collabs: =>
return @getIn(['settings', 'allow_collabs']) ? true
get_email_invite: =>
{SITE_NAME, DOMAIN_NAME} = require('smc-util/theme')
@getIn(['settings', 'email_invite']) ? "We will use [#{SITE_NAME}](#{DOMAIN_NAME}) for the course *{title}*. \n\nPlease sign up!\n\n--\n\n{name}"
get_activity: =>
@get('activity')
get_students: =>
@get('students')
get_student_name: (student, include_email=false) =>
student = @get_student(student)
if not student?
return 'student'
email = student.get('email_address')
account_id = student.get('account_id')
first_name = student.get('first_name') ? @redux.getStore('users').get_first_name(account_id)
last_name = student.get('last_name') ? @redux.getStore('users').get_last_name(account_id)
if first_name? and last_name?
full_name = first_name + ' ' + last_name
else if first_name?
full_name = first_name
else if last_name?
full_name = last_name
else
full_name = email ? 'student'
if include_email and full_name? and email?
full = full_name + " <#{email}>"
else
full = full_name
if full_name == 'Unknown User' and email?
full_name = email
if not include_email
return full_name
return {simple:full_name.replace(/\W/g, ' '), full:full}
get_student_email: (student) =>
student = @get_student(student)
if not student?
return 'student'
return student.get('email_address')
get_student_ids: (opts) =>
opts = defaults opts,
deleted : false
if not @get('students')?
return
v = []
@get('students').map (val, student_id) =>
if !!val.get('deleted') == opts.deleted
v.push(student_id)
return v
get_student_project_ids: (opts) =>
{include_deleted, deleted_only, map} = defaults opts,
include_deleted : false
deleted_only : false
map : false
if not @get('students')?
return
if map
v = {}
include = (x) -> v[x] = true
else
v = []
include = (x) -> v.push(x)
@get('students').map (val, student_id) =>
id = val.get('project_id')
if deleted_only
if include_deleted and val.get('deleted')
include(id)
else if include_deleted
include(id)
else if not val.get('deleted')
include(id)
return v
get_student: (student) =>
if typeof(student) != 'string'
student = student?.get('student_id')
return @getIn(['students', student])
get_student_note: (student) =>
return @get_student(student)?.get('note')
get_student_project_id: (student) =>
return @get_student(student)?.get('project_id')
get_sorted_students: =>
v = []
@get('students').map (student, id) =>
if not student.get('deleted')
v.push(student)
v.sort (a,b) => misc.cmp(@get_student_name(a), @get_student_name(b))
return v
get_grade: (assignment, student) =>
return @get_assignment(assignment)?.get('grades')?.get(@get_student(student)?.get('student_id'))
get_due_date: (assignment) =>
due_date = @get_assignment(assignment)?.get('due_date')
if due_date?
return new Date(due_date)
get_assignment_note: (assignment) =>
return @get_assignment(assignment)?.get('note')
get_assignments: =>
return @get('assignments')
get_sorted_assignments: =>
v = []
@get_assignments().map (assignment, id) =>
if not assignment.get('deleted')
v.push(assignment)
f = (a) -> [a.get('due_date') ? 0, a.get('path')?.toLowerCase()]
v.sort (a,b) -> misc.cmp_array(f(a), f(b))
return v
get_assignment: (assignment) =>
if typeof(assignment) != 'string'
assignment = assignment?.get('assignment_id')
return @getIn(['assignments', assignment])
get_assignment_ids: (opts) =>
opts = defaults opts,
deleted : false
if not @get_assignments()
return
v = []
@get_assignments().map (val, assignment_id) =>
if !!val.get('deleted') == opts.deleted
v.push(assignment_id)
return v
_num_nondeleted: (a) =>
if not a?
return
n = 0
a.map (val, key) =>
if not val.get('deleted')
n += 1
return n
num_students: => @_num_nondeleted(@get_students())
num_running_projects: (project_map) =>
n = 0
@get_students()?.map (student, student_id) =>
if not student.get('deleted')
if project_map.getIn([student.get('project_id'), 'state', 'state']) == 'running'
n += 1
return n
num_assignments: => @_num_nondeleted(@get_assignments())
num_handouts: => @_num_nondeleted(@get_handouts())
student_assignment_info: (student, assignment) =>
assignment = @get_assignment(assignment)
student = @get_student(student)
student_id = student.get('student_id')
status = @get_assignment_status(assignment)
info =
last_assignment : assignment.get('last_assignment')?.get(student_id)?.toJS()
last_collect : assignment.get('last_collect')?.get(student_id)?.toJS()
last_peer_assignment : assignment.get('last_peer_assignment')?.get(student_id)?.toJS()
last_peer_collect : assignment.get('last_peer_collect')?.get(student_id)?.toJS()
last_return_graded : assignment.get('last_return_graded')?.get(student_id)?.toJS()
student_id : student_id
assignment_id : assignment.get('assignment_id')
peer_assignment : (status.not_collect + status.not_assignment == 0) and status.collect != 0
peer_collect : status.not_peer_assignment? and status.not_peer_assignment == 0
return info
last_copied: (step, assignment, student_id, no_error) =>
x = @get_assignment(assignment)?.get("last_#{step}")?.get(student_id)
if not x?
return
if no_error and x.get('error')
return
return x.get('time')
has_grade: (assignment, student_id) =>
return @get_assignment(assignment)?.get("grades")?.get(student_id)
get_assignment_status: (assignment) =>
if not @_assignment_status?
@_assignment_status = {}
@on 'change', =>
@_assignment_status = {}
assignment = @get_assignment(assignment)
if not assignment?
return undefined
assignment_id = assignment.get('assignment_id')
if @_assignment_status[assignment_id]?
return @_assignment_status[assignment_id]
students = @get_student_ids(deleted:false)
if not students?
return undefined
peer = assignment.get('peer_grade')?.get('enabled')
info = {}
for t in STEPS(peer)
info[t] = 0
info["not_#{t}"] = 0
for student_id in students
previous = true
for t in STEPS(peer)
x = assignment.get("last_#{t}")?.get(student_id)
if x? and not x.get('error')
previous = true
info[t] += 1
else
if previous and (t!='return_graded' or @has_grade(assignment, student_id))
info["not_#{t}"] += 1
previous = false
@_assignment_status[assignment_id] = info
return info
get_handout_note: (handout) =>
return @get_handout(handout)?.get('note')
get_handouts: =>
return @get('handouts')
get_handout: (handout) =>
if typeof(handout) != 'string'
handout = handout?.get('handout_id')
return @getIn(['handouts', handout])
get_handout_ids: (opts) =>
opts = defaults opts,
deleted : false
if not @get_handouts()
return undefined
v = []
@get_handouts().map (val, handout_id) =>
if !!val.get('deleted') == opts.deleted
v.push(handout_id)
return v
student_handout_info: (student, handout) =>
handout = @get_handout(handout)
student = @get_student(student)
student_id = student.get('student_id')
status = @get_handout_status(handout)
info =
status : handout.get('status')?.get(student_id)?.toJS()
student_id : student_id
handout_id : handout.get('handout_id')
return info
handout_last_copied: (handout, student_id) =>
x = @get_handout(handout)?.get("status")?.get(student_id)
if not x?
return undefined
if x.get('error')
return undefined
return x.get('time')
get_handout_status: (handout) =>
if not @_handout_status?
@_handout_status = {}
@on 'change', =>
@_handout_status = {}
handout = @get_handout(handout)
if not handout?
return undefined
handout_id = handout.get('handout_id')
if @_handout_status[handout_id]?
return @_handout_status[handout_id]
students = @get_student_ids(deleted:false)
if not students?
return undefined
info =
handout : 0
not_handout : 0
for student_id in students
x = handout.get("status")?.get(student_id)
if x? and not x.get('error')
info.handout += 1
else
info.not_handout += 1
@_handout_status[handout_id] = info
return info
get_upgrade_plan: (upgrade_goal) =>
account_store = @redux.getStore('account')
plan = project_upgrades.upgrade_plan
account_id : account_store.get_account_id()
purchased_upgrades : account_store.get_total_upgrades()
project_map : @redux.getStore('projects').get('project_map')
student_project_ids : @get_student_project_ids(include_deleted:true, map:true)
deleted_project_ids : @get_student_project_ids(include_deleted:true, deleted_only:true, map:true)
upgrade_goal : upgrade_goal
return plan