diff --git a/js/PageLevelProgressIndicatorView.js b/js/PageLevelProgressIndicatorView.js index 35e37e1..9ef37c7 100644 --- a/js/PageLevelProgressIndicatorView.js +++ b/js/PageLevelProgressIndicatorView.js @@ -1,5 +1,9 @@ import Adapt from 'core/js/adapt'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { templates } from 'core/js/reactHelpers'; import ItemsComponentModel from 'core/js/models/itemsComponentModel'; +import completionCalculations from './completionCalculations'; class PageLevelProgressIndicatorView extends Backbone.View { @@ -17,71 +21,59 @@ class PageLevelProgressIndicatorView extends Backbone.View { this.setUpEventListeners(); this.setPercentageComplete(); this.render(); - this.refresh(); } addClasses() { this.$el.addClass([ - 'pagelevelprogress__indicator', + 'pagelevelprogress__indicator-outer', 'is-' + this.type ].join(' ')); } - checkAria() { - if (!this.ariaLabel) { - this.$el.attr('aria-hidden', true); - return; - } - const data = this.getRenderData(); - this.$('.js-indicator-aria-label').html(Handlebars.compile(this.ariaLabel)(data)); - } - setUpEventListeners() { if (this.parent) { this.listenToOnce(this.parent, 'postRemove', this.remove); } else { this.listenTo(Adapt, 'remove', this.remove); } - this.listenTo(Adapt.course, 'bubble:change:_isComplete bubble:change:_isVisited', this.refresh); + this.listenTo(Adapt.course, 'bubble:change:_isComplete bubble:change:_isVisited', this.render); } setPercentageComplete() { const percentage = this.calculatePercentage(); this.model.set('percentageComplete', percentage); + this.$el.css({ + '--adapt-pagelevelprogress-percentage': percentage + '%' + }); return percentage; } calculatePercentage() { - const isPresentationComponentWithItems = (!this.model.isTypeGroup('question') && this.model instanceof ItemsComponentModel); const isComplete = this.model.get('_isComplete'); if (isComplete) return 100; + const isContentObject = this.model.isTypeGroup('contentobject'); + if (isContentObject) { + return completionCalculations.calculatePercentageComplete(this.model); + } + const isPresentationComponentWithItems = (!this.model.isTypeGroup('question') && this.model instanceof ItemsComponentModel); if (isPresentationComponentWithItems) { const children = this.model.getChildren(); const visited = children.filter(child => child.get('_isVisited')); return Math.round(visited.length / children.length * 100); } - return 0 + return 0; } render() { + this.checkCompletion(); + this.checkAriaHidden(); const data = this.getRenderData(); - const template = Handlebars.templates[this.constructor.template]; - this.$el.html(template(data)); - } - - getRenderData() { - const data = this.model.toJSON(); - data.ariaLabel = this.ariaLabel; - data.type = this.type; - return data; + const Component = templates.pageLevelProgressIndicator; + ReactDOM.render(, this.el); } refresh() { - this.checkCompletion(); - this.checkAria(); - this.$('.js-indicator-bar').css({ - width: this.calculatePercentage() + '%' - }); + this.render(); } checkCompletion() { @@ -99,8 +91,20 @@ class PageLevelProgressIndicatorView extends Backbone.View { .toggleClass('is-incorrect', isIncorrect); } + checkAriaHidden() { + if (this.ariaLabel) return; + this.$el.attr('aria-hidden', true); + } + + getRenderData() { + const data = this.model.toJSON(); + data.ariaLabel = this.ariaLabel; + data.type = this.type; + return data; + } + } -PageLevelProgressIndicatorView.template = 'pageLevelProgressIndicator'; +PageLevelProgressIndicatorView.template = 'pageLevelProgressIndicator.jsx'; export default PageLevelProgressIndicatorView; diff --git a/js/PageLevelProgressNavigationView.js b/js/PageLevelProgressNavigationView.js index 85341cc..9801b76 100644 --- a/js/PageLevelProgressNavigationView.js +++ b/js/PageLevelProgressNavigationView.js @@ -39,12 +39,14 @@ export default class PageLevelProgressNavigationView extends NavigationButtonVie this.setUpEventListeners(); this.render(); this.addIndicator(); + this.refreshProgressBar(); this.deferredUpdate(); tooltips.register({ _id: 'pagelevelprogress', ...Adapt.course.get('_globals')?._extensions?._pageLevelProgress?._navTooltip || {} }); + this.tooltip = tooltips.getTooltip('pagelevelprogress'); } setUpEventListeners() { @@ -58,8 +60,13 @@ export default class PageLevelProgressNavigationView extends NavigationButtonVie } addIndicator() { + const { + _useCourseProgressInNavigationButton = false + } = Adapt.course.get('_pageLevelProgress') ?? {}; this.indicatorView = new PageLevelProgressIndicatorView({ - model: this.pageModel, + model: _useCourseProgressInNavigationButton + ? Adapt.course + : this.pageModel, calculatePercentage: this._getPageCompletionPercentage.bind(this), ariaLabel: this.model.get('ariaLabel') }); @@ -68,13 +75,12 @@ export default class PageLevelProgressNavigationView extends NavigationButtonVie } _getPageCompletionPercentage() { - const courseConfig = Adapt.course.get('_pageLevelProgress'); - - if (courseConfig._useCourseProgressInNavigationButton) { - return completionCalculations.calculatePercentageComplete(Adapt.course); - } - - return completionCalculations.calculatePercentageComplete(this.pageModel, true); + const { + _useCourseProgressInNavigationButton = false + } = Adapt.course.get('_pageLevelProgress') ?? {}; + return _useCourseProgressInNavigationButton + ? completionCalculations.calculatePercentageComplete(Adapt.course) + : completionCalculations.calculatePercentageComplete(this.pageModel, true); } deferredUpdate() { @@ -86,6 +92,9 @@ export default class PageLevelProgressNavigationView extends NavigationButtonVie } refreshProgressBar() { + const percentageComplete = this._getPageCompletionPercentage(); + this.model.set('percentageComplete', percentageComplete); + this.tooltip.set('percentageComplete', percentageComplete); this.collection = getPageLevelProgressItemsJSON(this.pageModel); this.updateProgressBar(); } diff --git a/js/adapt-contrib-pageLevelProgress.js b/js/adapt-contrib-pageLevelProgress.js index 73bddd0..24b1203 100644 --- a/js/adapt-contrib-pageLevelProgress.js +++ b/js/adapt-contrib-pageLevelProgress.js @@ -118,15 +118,10 @@ class PageLevelProgress extends Backbone.Controller { parent: view, model: view.model, type: 'menu-item', - calculatePercentage: this._getMenuItemCompletionPercentage.bind(view), ariaLabel: PageLevelProgress.globalsConfig?.pageLevelProgressMenuBar }).$el); } - _getMenuItemCompletionPercentage() { - return completionCalculations.calculatePercentageComplete(this.model); - } - // This should add/update progress on page navigation bar renderNavigationView(pageModel) { // Do not render if _isDefaultNavigationDisabled is set to true diff --git a/less/pageLevelProgressIndicator.less b/less/pageLevelProgressIndicator.less index 6761b3d..51f8938 100644 --- a/less/pageLevelProgressIndicator.less +++ b/less/pageLevelProgressIndicator.less @@ -25,6 +25,7 @@ height: inherit; min-width: 15%; background-color: @black; + width: var(--adapt-pagelevelprogress-percentage); } &__indicator .js-indicator-aria-label { diff --git a/templates/pageLevelProgressIndicator.hbs b/templates/pageLevelProgressIndicator.hbs deleted file mode 100644 index edfa65f..0000000 --- a/templates/pageLevelProgressIndicator.hbs +++ /dev/null @@ -1,14 +0,0 @@ -{{! make the _globals object in course.json available to this template}} -{{import_globals}} - - - - - - {{#if ariaLabel}} - - {{compile ariaLabel}} - - {{/if}} - - diff --git a/templates/pageLevelProgressIndicator.jsx b/templates/pageLevelProgressIndicator.jsx new file mode 100644 index 0000000..3701672 --- /dev/null +++ b/templates/pageLevelProgressIndicator.jsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { compile } from 'core/js/reactHelpers'; + +export default function PageLevelProgressIndicator (props) { + const { + ariaLabel + } = props; + + return ( + + + + + + {ariaLabel && + + {compile(ariaLabel, props)} + + } + + + + ); +};