#276 Automatic lesson summary page
- Basic overview of all the assignments needed to be solved in a lesson - Clicking on a link will jump to the correct page with the assignment - Lesson completed also updates lesson overview immediately
This commit is contained in:
@ -18,8 +18,10 @@ define(['jquery',
|
||||
'goatApp/model/LessonInfoModel',
|
||||
'goatApp/view/TitleView',
|
||||
'goatApp/model/LessonProgressModel',
|
||||
'goatApp/view/LessonProgressView'
|
||||
],
|
||||
'goatApp/view/LessonProgressView',
|
||||
'goatApp/view/LessonOverviewView',
|
||||
'goatApp/model/LessonOverviewModel'
|
||||
],
|
||||
function($,
|
||||
_,
|
||||
Backbone,
|
||||
@ -40,19 +42,22 @@ define(['jquery',
|
||||
LessonInfoModel,
|
||||
TitleView,
|
||||
LessonProgressModel,
|
||||
LessonProgressView
|
||||
|
||||
LessonProgressView,
|
||||
LessonOverviewView,
|
||||
LessonOverviewModel
|
||||
) {
|
||||
'use strict'
|
||||
|
||||
|
||||
|
||||
var Controller = function(options) {
|
||||
this.lessonContent = new LessonContentModel();
|
||||
this.lessonProgressModel = new LessonProgressModel();
|
||||
this.lessonProgressView = new LessonProgressView(this.lessonProgressModel);
|
||||
this.lessonOverviewModel = new LessonOverviewModel();
|
||||
this.lessonOverview = new LessonOverviewView(this.lessonOverviewModel);
|
||||
this.lessonContentView = options.lessonContentView;
|
||||
this.developerControlsView = new DeveloperControlsView();
|
||||
|
||||
|
||||
_.extend(Controller.prototype,Backbone.Events);
|
||||
|
||||
this.start = function() {
|
||||
@ -92,16 +97,18 @@ define(['jquery',
|
||||
});
|
||||
|
||||
this.listenTo(this.helpControlsView,'hints:show',this.showHints);
|
||||
this.listenTo(this.helpControlsView,'lessonOverview:show',this.showLessonOverview)
|
||||
this.listenTo(this.helpControlsView,'attack:show',this.hideShowAttack);
|
||||
this.listenTo(this.helpControlsView,'solution:show',this.hideShowHelps);
|
||||
this.listenTo(this.helpControlsView,'source:show',this.hideShowHelps);
|
||||
this.listenTo(this.helpControlsView,'lesson:restart',this.restartLesson);
|
||||
this.listenTo(this.developerControlsView, 'dev:labels', this.restartLesson);
|
||||
this.listenTo(this.lessonContentView, 'lesson:complete', this.updateMenu)
|
||||
|
||||
this.listenTo(this.lessonContentView, 'lesson:complete', this.updateLessonOverview)
|
||||
this.listenTo(this,'hints:show',this.onShowHints);
|
||||
|
||||
this.helpControlsView.render();
|
||||
this.lessonOverviewModel.fetch();
|
||||
|
||||
this.titleView.render(this.lessonInfoModel.get('lessonTitle'));
|
||||
};
|
||||
@ -110,6 +117,10 @@ define(['jquery',
|
||||
this.trigger('menu:reload')
|
||||
};
|
||||
|
||||
this.updateLessonOverview = function() {
|
||||
this.lessonOverviewModel.fetch();
|
||||
}
|
||||
|
||||
this.onContentLoaded = function(loadHelps) {
|
||||
this.lessonInfoModel = new LessonInfoModel();
|
||||
this.listenTo(this.lessonInfoModel,'info:loaded',this.onInfoLoaded);
|
||||
@ -177,6 +188,10 @@ define(['jquery',
|
||||
//this.lessonHintView.
|
||||
};
|
||||
|
||||
this.showLessonOverview = function() {
|
||||
this.lessonOverview.render();
|
||||
};
|
||||
|
||||
this.hideShowAttack = function (options) { // will likely expand this to encompass
|
||||
if (options.show) {
|
||||
$('#attack-container').show();
|
||||
|
@ -0,0 +1,8 @@
|
||||
define([
|
||||
'backbone'],
|
||||
function(
|
||||
Backbone) {
|
||||
return Backbone.Model.extend({
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,10 @@
|
||||
define([
|
||||
'backbone'],
|
||||
function(
|
||||
Backbone) {
|
||||
return Backbone.Collection.extend({
|
||||
tagName: 'ul',
|
||||
url: 'service/lessonoverview.mvc'
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,24 @@
|
||||
define([
|
||||
'backbone'],
|
||||
function(
|
||||
Backbone) {
|
||||
return Backbone.View.extend({
|
||||
tagName: 'li',
|
||||
template: _.template($('#assignmentTemplate').html() ),
|
||||
|
||||
events: {
|
||||
"click a": "clicked"
|
||||
},
|
||||
|
||||
clicked: function(e){
|
||||
e.preventDefault();
|
||||
var id = $(e.currentTarget).data("id");
|
||||
Backbone.trigger('assignment:navTo',{'assignment': id});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
});
|
@ -36,7 +36,7 @@ function($,_,Backbone) {
|
||||
this.$el.find('#show-attack-button').unbind().on('click',_.bind(this.showAttack,this)).show();
|
||||
}
|
||||
|
||||
|
||||
this.$el.find('#show-lesson-overview-button').unbind().on('click', _.bind(this.showLessonOverview, this)).show();
|
||||
this.$el.find('#restart-lesson-button').unbind().on('click',_.bind(this.restartLesson,this)).show();
|
||||
//this.$el.append(this.helpButtons.restartLesson);
|
||||
},
|
||||
@ -59,6 +59,9 @@ function($,_,Backbone) {
|
||||
|
||||
restartLesson: function() {
|
||||
this.trigger('lesson:restart');
|
||||
},
|
||||
showLessonOverview: function() {
|
||||
this.trigger('lessonOverview:show');
|
||||
}
|
||||
});
|
||||
});
|
@ -16,6 +16,25 @@ define(['jquery',
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
new ErrorNotificationView();
|
||||
var self = this;
|
||||
Backbone.on('assignment:navTo', function(assignment){
|
||||
var page = self.findPage(assignment);
|
||||
if (page != -1) {
|
||||
self.navToPage(page);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
findPage: function(assignment) {
|
||||
for (var i = 0; i < this.$contentPages.length; i++) {
|
||||
var contentPage = this.$contentPages[i];
|
||||
var form = $('form.attack-form', contentPage);
|
||||
var action = form.attr('action')
|
||||
if (action !== undefined && action.includes(assignment.assignment)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
/* initial renering */
|
||||
@ -76,7 +95,7 @@ define(['jquery',
|
||||
var submitData = (typeof webgoat.customjs[prepareDataFunctionName] === 'function') ? webgoat.customjs[prepareDataFunctionName]() : this.$form.serialize();
|
||||
// var submitData = this.$form.serialize();
|
||||
this.$curFeedback = $(curForm).closest('.attack-container').find('.attack-feedback');
|
||||
this.$curOutput = $(curForm).closest('.atatck-container').find('.attack-output');
|
||||
this.$curOutput = $(curForm).closest('.attack-container').find('.attack-output');
|
||||
var formUrl = $(curForm).attr('action');
|
||||
var formMethod = $(curForm).attr('method');
|
||||
var contentType = ($(curForm).attr('contentType')) ? $(curForm).attr('contentType') : 'application/x-www-form-urlencoded; charset=UTF-8';
|
||||
|
@ -0,0 +1,48 @@
|
||||
define(['jquery',
|
||||
'underscore',
|
||||
'backbone',
|
||||
'goatApp/model/LessonOverviewModel',
|
||||
'goatApp/view/AssignmentOverview'],
|
||||
function($,
|
||||
_,
|
||||
Backbone,
|
||||
LessonOverviewModel,
|
||||
AssignmentOverview) {
|
||||
return Backbone.View.extend({
|
||||
el:'#lesson-overview',
|
||||
initialize: function (lessonOverviewModel) {
|
||||
this.model = lessonOverviewModel;
|
||||
this.listenTo(this.model, 'change add remove update', this.render);
|
||||
this.hideLessonOverview();
|
||||
},
|
||||
|
||||
showAssignments: function() {
|
||||
this.$el.html('');
|
||||
this.model.each(function(assignment) {
|
||||
var assignmentView = new AssignmentOverview({ model: assignment });
|
||||
this.$el.append(assignmentView.render().el);
|
||||
}, this);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.isVisible()) {
|
||||
this.$el.hide();
|
||||
} else {
|
||||
this.$el.show();
|
||||
}
|
||||
this.showAssignments();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
isVisible: function() {
|
||||
return this.$el.is(':visible');
|
||||
},
|
||||
|
||||
hideLessonOverview: function() {
|
||||
if (this.$el.is(':visible')) {
|
||||
this.$el.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user