-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
1 changed file
with
97 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,149 +1,141 @@ | ||
// duplicate of pagelevelprogress completionCalculations.js v5.1.0 | ||
define([ | ||
'core/js/adapt' | ||
], function(Adapt) { | ||
|
||
var Completion = Backbone.Controller.extend({ | ||
|
||
subProgressCompleted: 0, | ||
subProgressTotal: 0, | ||
nonAssessmentCompleted: 0, | ||
nonAssessmentTotal: 0, | ||
assessmentCompleted: 0, | ||
assessmentTotal: 0 | ||
|
||
}); | ||
import Adapt from 'core/js/adapt'; | ||
import _ from 'underscore'; | ||
|
||
class Completion extends Backbone.Controller { | ||
|
||
initialize() { | ||
_.bindAll(this, 'calculatePercentageComplete'); | ||
this.subProgressCompleted = 0; | ||
this.subProgressTotal = 0; | ||
this.nonAssessmentCompleted = 0; | ||
this.nonAssessmentTotal = 0; | ||
this.assessmentCompleted = 0; | ||
this.assessmentTotal = 0; | ||
} | ||
|
||
// Calculate completion of a contentObject | ||
function calculateCompletion(contentObjectModel) { | ||
|
||
var completion = new Completion(); | ||
|
||
var viewType = contentObjectModel.get('_type'); | ||
var isComplete = contentObjectModel.get('_isComplete') ? 1 : 0; | ||
var children; | ||
|
||
switch (viewType) { | ||
case 'page': | ||
// If it's a page | ||
children = contentObjectModel.getAllDescendantModels().filter(function(model) { | ||
return model.get('_isAvailable') && !model.get('_isOptional'); | ||
}); | ||
|
||
var availableChildren = filterAvailableChildren(children); | ||
var components = getPageLevelProgressEnabledModels(availableChildren); | ||
|
||
var nonAssessmentComponents = getNonAssessmentComponents(components); | ||
|
||
completion.nonAssessmentTotal = nonAssessmentComponents.length; | ||
completion.nonAssessmentCompleted = getComponentsCompleted(nonAssessmentComponents).length; | ||
|
||
var assessmentComponents = getAssessmentComponents(components); | ||
|
||
completion.assessmentTotal = assessmentComponents.length; | ||
completion.assessmentCompleted = getComponentsInteractionCompleted(assessmentComponents).length; | ||
|
||
if (contentObjectModel.get('_pageLevelProgress')._excludeAssessments !== true) { | ||
completion.subProgressCompleted = contentObjectModel.get('_subProgressComplete') || 0; | ||
completion.subProgressTotal = contentObjectModel.get('_subProgressTotal') || 0; | ||
calculateCompletion(contentObjectModel, setGlobal = false) { | ||
const completion = {}; | ||
const perform = contentObjectModel => { | ||
const viewType = contentObjectModel.get('_type'); | ||
const isComplete = contentObjectModel.get('_isComplete') ? 1 : 0; | ||
let children; | ||
switch (viewType) { | ||
case 'page': { | ||
// If it's a page | ||
children = contentObjectModel.getAllDescendantModels().filter(model => { | ||
return model.get('_isAvailable') && !model.get('_isOptional'); | ||
}); | ||
|
||
const availableChildren = this.filterAvailableChildren(children); | ||
const components = this.getPageLevelProgressEnabledModels(availableChildren); | ||
const nonAssessmentComponents = this.getNonAssessmentComponents(components); | ||
|
||
completion.nonAssessmentTotal += nonAssessmentComponents.length; | ||
completion.nonAssessmentCompleted += this.getComponentsCompleted(nonAssessmentComponents).length; | ||
|
||
const assessmentComponents = this.getAssessmentComponents(components); | ||
|
||
completion.assessmentTotal += assessmentComponents.length; | ||
completion.assessmentCompleted += this.getComponentsInteractionCompleted(assessmentComponents).length; | ||
|
||
if (contentObjectModel.get('_pageLevelProgress')?._excludeAssessments !== true) { | ||
completion.subProgressCompleted += contentObjectModel.get('_subProgressComplete') || 0; | ||
completion.subProgressTotal += contentObjectModel.get('_subProgressTotal') || 0; | ||
} | ||
|
||
const showPageCompletionCourse = Adapt.course.get('_pageLevelProgress')?._showPageCompletion !== false; | ||
const showPageCompletionPage = contentObjectModel.get('_pageLevelProgress')?._showPageCompletion !== false; | ||
|
||
if (showPageCompletionCourse && showPageCompletionPage) { | ||
// optionally add one point extra for page completion to eliminate incomplete pages and full progress bars | ||
// if _showPageCompletion is true then the progress bar should also consider it so add 1 to nonAssessmentTotal | ||
completion.nonAssessmentCompleted += isComplete; | ||
completion.nonAssessmentTotal += 1; | ||
} | ||
|
||
break; | ||
} | ||
|
||
var showPageCompletionCourse = Adapt.course.get('_pageLevelProgress') && Adapt.course.get('_pageLevelProgress')._showPageCompletion !== false; | ||
var showPageCompletionPage = contentObjectModel.get('_pageLevelProgress') && contentObjectModel.get('_pageLevelProgress')._showPageCompletion !== false; | ||
|
||
if (showPageCompletionCourse && showPageCompletionPage) { | ||
// optionally add one point extra for page completion to eliminate incomplete pages and full progress bars | ||
// if _showPageCompletion is true then the progress bar should also consider it so add 1 to nonAssessmentTotal | ||
completion.nonAssessmentCompleted += isComplete; | ||
completion.nonAssessmentTotal += 1; | ||
case 'menu': case 'course': { | ||
// If it's a sub-menu | ||
children = contentObjectModel.getChildren().models; | ||
children.forEach(perform); | ||
break; | ||
} | ||
|
||
break; | ||
case 'menu': case 'course': | ||
// If it's a sub-menu | ||
children = contentObjectModel.get('_children').models; | ||
children.forEach(function(contentObject) { | ||
var completionObject = calculateCompletion(contentObject); | ||
completion.subProgressCompleted += completionObject.subProgressCompleted || 0; | ||
completion.subProgressTotal += completionObject.subProgressTotal || 0; | ||
completion.nonAssessmentTotal += completionObject.nonAssessmentTotal; | ||
completion.nonAssessmentCompleted += completionObject.nonAssessmentCompleted; | ||
completion.assessmentTotal += completionObject.assessmentTotal; | ||
completion.assessmentCompleted += completionObject.assessmentCompleted; | ||
}); | ||
break; | ||
|
||
} | ||
|
||
} | ||
}; | ||
completion.subProgressCompleted = 0; | ||
completion.subProgressTotal = 0; | ||
completion.nonAssessmentTotal = 0; | ||
completion.nonAssessmentCompleted = 0; | ||
completion.assessmentTotal = 0; | ||
completion.assessmentCompleted = 0; | ||
perform(contentObjectModel); | ||
if (setGlobal) Object.assign(Adapt.tocCompletion, completion); | ||
return completion; | ||
} | ||
|
||
function getNonAssessmentComponents(models) { | ||
return models.filter(function(model) { | ||
getNonAssessmentComponents(models) { | ||
return models.filter(model => { | ||
return !model.get('_isPartOfAssessment'); | ||
}); | ||
} | ||
|
||
function getAssessmentComponents(models) { | ||
return models.filter(function(model) { | ||
getAssessmentComponents(models) { | ||
return models.filter(model => { | ||
return model.get('_isPartOfAssessment'); | ||
}); | ||
} | ||
|
||
function getComponentsCompleted(models) { | ||
return models.filter(function(item) { | ||
getComponentsCompleted(models) { | ||
return models.filter(item => { | ||
return item.get('_isComplete'); | ||
}); | ||
} | ||
|
||
function getComponentsInteractionCompleted(models) { | ||
return models.filter(function(item) { | ||
getComponentsInteractionCompleted(models) { | ||
return models.filter(item => { | ||
return item.get('_isComplete'); | ||
}); | ||
} | ||
|
||
//Get only those models who were enabled for pageLevelProgress | ||
function getPageLevelProgressEnabledModels(models) { | ||
return models.filter(function(model) { | ||
var config = model.get('_pageLevelProgress'); | ||
return config && config._isEnabled; | ||
// Get only those models who were enabled for pageLevelProgress | ||
getPageLevelProgressEnabledModels(models) { | ||
return models.filter(model => { | ||
const config = model.get('_pageLevelProgress'); | ||
return config?._isEnabled; | ||
}); | ||
} | ||
|
||
function unavailableInHierarchy(parents) { | ||
unavailableInHierarchy(parents) { | ||
if (!parents) return; | ||
return parents.some(function(parent) { | ||
return parents.some(parent => { | ||
return !parent.get('_isAvailable'); | ||
}); | ||
} | ||
|
||
function filterAvailableChildren(children) { | ||
var availableChildren = []; | ||
filterAvailableChildren(children) { | ||
const availableChildren = []; | ||
|
||
for (var i = 0, count = children.length; i < count; i++) { | ||
var parents = children[i].getAncestorModels(); | ||
if (unavailableInHierarchy(parents)) continue; | ||
for (let i = 0, count = children.length; i < count; i++) { | ||
const parents = children[i].getAncestorModels(); | ||
if (this.unavailableInHierarchy(parents)) continue; | ||
availableChildren.push(children[i]); | ||
} | ||
|
||
return availableChildren; | ||
} | ||
|
||
function calculatePercentageComplete(model) { | ||
var completionObject = calculateCompletion(model); | ||
calculatePercentageComplete(model, setGlobal = false) { | ||
const completionObject = this.calculateCompletion(model, setGlobal); | ||
// take all assessment, nonassessment and subprogress into percentage | ||
// this allows the user to see if assessments have been passed, if assessment components can be retaken, and all other component's completion | ||
var completed = completionObject.nonAssessmentCompleted + completionObject.assessmentCompleted + completionObject.subProgressCompleted; | ||
var total = completionObject.nonAssessmentTotal + completionObject.assessmentTotal + completionObject.subProgressTotal; | ||
var percentageComplete = Math.floor((completed / total)*100); | ||
const completed = completionObject.nonAssessmentCompleted + completionObject.assessmentCompleted + completionObject.subProgressCompleted; | ||
const total = completionObject.nonAssessmentTotal + completionObject.assessmentTotal + completionObject.subProgressTotal; | ||
const percentageComplete = Math.floor((completed / total) * 100); | ||
return percentageComplete; | ||
} | ||
|
||
return { | ||
calculateCompletion: calculateCompletion, | ||
calculatePercentageComplete: calculatePercentageComplete, | ||
getPageLevelProgressEnabledModels: getPageLevelProgressEnabledModels, | ||
filterAvailableChildren: filterAvailableChildren | ||
}; | ||
} | ||
|
||
}); | ||
export default (Adapt.tocCompletion = new Completion()); |