From 6584b76e5b408052741e4b35ca753a4e53363c86 Mon Sep 17 00:00:00 2001 From: Sachin Date: Fri, 29 Jun 2018 15:50:30 +0530 Subject: [PATCH 1/4] Issue #6 feat: question unit interface with mtf --- editor/controllers/horizontal_controller.js | 270 ---------------- editor/controllers/mtf-controller.js | 305 ++++++++++++++++++ editor/plugin.js | 28 +- ...zontal_template.html => mtf-template.html} | 8 +- .../editor/controllers/mtf-controller.spec.js | 266 +++++++++++++++ test/editor/plugin.spec.js | 19 ++ test/mocks/editor/questionunit.mock.js | 8 +- 7 files changed, 615 insertions(+), 289 deletions(-) delete mode 100644 editor/controllers/horizontal_controller.js create mode 100644 editor/controllers/mtf-controller.js rename editor/templates/{horizontal_template.html => mtf-template.html} (95%) create mode 100644 test/editor/controllers/mtf-controller.spec.js create mode 100644 test/editor/plugin.spec.js diff --git a/editor/controllers/horizontal_controller.js b/editor/controllers/horizontal_controller.js deleted file mode 100644 index dc34055..0000000 --- a/editor/controllers/horizontal_controller.js +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Plugin to create MTF question - * @class org.ekstep.questionunitmcq:mtfQuestionFormController - * Sachin - */ -angular.module('mtfApp', []) - .controller('mtfQuestionFormController', ['$scope', '$rootScope', function($scope, $rootScope) { - $scope.formVaild = false; - $scope.indexCount = 4; - $scope.mtfConfiguartion = { - 'questionConfig': { - 'isText': true, - 'isImage': false, - 'isAudio': false, - 'isHint': false - }, - 'optionsConfig': [{ - 'isText': true, - 'isImage': false, - 'isAudio': false, - 'isHint': false - }, { - 'isText': true, - 'isImage': false, - 'isAudio': false, - 'isHint': false - }] - }; - $scope.mtfFormData = { - 'question': { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '' - }, - 'option': { - 'optionsLHS': [{ - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'index': 1 - }, { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'index': 2 - }, { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'index': 3 - }], - 'optionsRHS': [{ - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'mapIndex': 1 - }, { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'mapIndex': 2 - }, { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'mapIndex': 3 - }], - 'questionCount': 0 - } - }; - $scope.questionMedia = {}; - $scope.optionsMedia = { - 'image': [], - 'audio': [] - }; - $scope.mtfFormData.media = []; - $scope.editMedia = []; - var questionInput = CKEDITOR.replace('mtfQuestion', { - customConfig: CKEDITOR.basePath + "config.js", - skin: 'moono-lisa,' + CKEDITOR.basePath + "skins/moono-lisa/", - contentsCss: CKEDITOR.basePath + "contents.css" - }); - questionInput.on('change', function() { - $scope.mtfFormData.question.text = this.getData(); - }); - questionInput.on('focus', function() { - $scope.generateTelemetry({type: 'TOUCH', id: 'input', target: {id: 'questionunit-mtf-question', ver: '', type: 'input'}}) - }); - angular.element('.innerScroll').on('scroll',function(){ - $scope.generateTelemetry({type: 'SCROLL', id: 'form', target: {id: 'questionunit-mtf-form', ver: '', type: 'form'}}) - }); - $scope.init = function() { - if (!ecEditor._.isUndefined($scope.questionEditData)) { - var data = $scope.questionEditData.data; - $scope.mtfFormData.question = data.question; - $scope.mtfFormData.option = data.option; - $scope.editMedia = $scope.questionEditData.media; - if ($scope.mtfFormData.option.length < 3) { - $scope.mtfFormData.option.splice(3, 1); - } - } - $scope.$parent.$on('question:form:val', function(event) { - if ($scope.formValidation()) { - /*if dynamic question assign how many questions are create that count to $scope.mcqFormData.questionCount - Or else assign 1*/ - $scope.mtfFormData.questionCount = 1; - $scope.$emit('question:form:valid', $scope.mtfFormData); - } else { - $scope.$emit('question:form:inValid', $scope.mtfFormData); - } - }) - } - $scope.addPair = function() { - - var optionLHS = { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'index': $scope.indexCount - }; - var optionRHS = { - 'text': '', - 'image': '', - 'audio': '', - 'hint': '', - 'mapIndex': $scope.indexCount++ - }; - if ($scope.mtfFormData.option.optionsLHS.length < 5) { - $scope.mtfFormData.option.optionsLHS.push(optionLHS); - $scope.mtfFormData.option.optionsRHS.push(optionRHS); - } - } - //on click next the form validation function called - $scope.formValidation = function() { - console.log($scope.mtfFormData); - var opSel = false; - var valid = false; - //check form valid and lhs should be more than 3 - var formValid = $scope.mtfForm.$valid && $scope.mtfFormData.option.optionsLHS.length > 2; - $scope.submitted = true; - if (formValid) { - opSel = true; - $scope.selLbl = 'success'; - } else { - opSel = false; - $scope.selLbl = 'error'; - } - var tempArray = []; - _.isEmpty($scope.questionMedia.image) ? 0 : tempArray.push($scope.questionMedia.image); - _.isEmpty($scope.questionMedia.audio) ? 0 : tempArray.push($scope.questionMedia.audio); - _.each($scope.optionsMedia.image, function(key, val) { - tempArray.push(key); - }); - _.each($scope.optionsMedia.audio, function(key, val) { - tempArray.push(key); - }); - var temp = tempArray.filter(function(element) { - return element !== undefined; - }); - $scope.editMedia = _.union($scope.editMedia, temp); - $scope.mtfFormData.media = $scope.editMedia; - console.log("Form data", $scope.mtfFormData); - return (formValid && opSel) ? true : false; - } - $scope.deletePair = function(id) { - $scope.mtfFormData.option.optionsLHS.splice(id, 1); - $scope.mtfFormData.option.optionsRHS.splice(id, 1); - //} - } - $scope.addImage = function(id, type) { - ecEditor.dispatchEvent('org.ekstep.assetbrowser:show', { - type: 'image', - search_filter: {}, // All composite keys except mediaType - callback: function(data) { - var tempImage = { - "id": Math.floor(Math.random() * 1000000000), // Unique identifier - "src": org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src), // Media URL - "assetId": data.assetMedia.id, // Asset identifier - "type": "image", // Type of asset (image, audio, etc) - "preload": false // true or false - }; - if (id == 'q') { - $scope.mtfFormData.question.image = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); - $scope.questionMedia.image = tempImage; - } else if (type == 'LHS') { - $scope.mtfFormData.option.optionsLHS[id].image = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); - $scope.optionsMedia.image[id] = tempImage; - } else if (type == 'RHS') { - $scope.mtfFormData.option.optionsRHS[id].image = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); - $scope.optionsMedia.image[id] = tempImage; - } - } - }); - } - $scope.addAudio = function(id, type) { - ecEditor.dispatchEvent('org.ekstep.assetbrowser:show', { - type: 'audio', - search_filter: {}, // All composite keys except mediaType - callback: function(data) { - var tempAudio = { - "id": Math.floor(Math.random() * 1000000000), // Unique identifier - "src": org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src), // Media URL - "assetId": data.assetMedia.id, // Asset identifier - "type": "audio", // Type of asset (image, audio, etc) - "preload": false // true or false - }; - if (id == 'q') { - $scope.mtfFormData.question.audio = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); - $scope.questionMedia.audio = tempAudio; - } else if (type == 'LHS') { - $scope.mtfFormData.option.optionsLHS[id].audio = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); - $scope.optionsMedia.audio[id] = tempAudio; - } else if (type == 'RHS') { - $scope.mtfFormData.option.optionsRHS[id].audio = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); - $scope.optionsMedia.audio[id] = tempAudio; - } - } - }); - } - $scope.deleteImage = function(id, type) { - if (id == 'q') { - $scope.mtfFormData.question.image = ''; - delete $scope.questionMedia.image; - } else if (type == 'LHS') { - $scope.mtfFormData.option.optionsLHS[id].image = ''; - delete $scope.optionsMedia.image[id]; - } else if (type == 'RHS') { - $scope.mtfFormData.option.optionsRHS[id].image = ''; - delete $scope.optionsMedia.image[id]; - } - } - $scope.deleteAudio = function(id, type) { - if (id == 'q') { - $scope.isPlayingQ = false; - $scope.mtfFormData.question.audio = ''; - delete $scope.questionMedia.audio; - } else if (type == 'LHS') { - $scope.mtfFormData.option.optionsLHS[id].audio = ''; - delete $scope.optionsMedia.audio[id]; - } else if (type == 'RHS') { - $scope.mtfFormData.option.optionsRHS[id].audio = ''; - delete $scope.optionsMedia.audio[id]; - } - } - $scope.generateTelemetry = function(data) { - if (data) ecEditor.getService('telemetry').interact({ - "type": data.type, - "id": data.id, - "pageid": 'question-creation-mtf-form', - "target": { - "id": data.target.id, - "ver": data.target.ver, - "type": data.target.type - }, - "plugin": { - "id": "org.ekstep.questionunit.mtf", - "ver": "1.0" - } - }) - } - }]); -//# sourceURL=horizontalMtf.js \ No newline at end of file diff --git a/editor/controllers/mtf-controller.js b/editor/controllers/mtf-controller.js new file mode 100644 index 0000000..eb8fc82 --- /dev/null +++ b/editor/controllers/mtf-controller.js @@ -0,0 +1,305 @@ +/* + * Plugin to create MTF question + * @class org.ekstep.questionunitmcq:mtfQuestionFormController + * Sachin + */ +angular.module('mtfApp', []).controller('mtfQuestionFormController', ['$scope', '$rootScope', function($scope, $rootScope) { + $scope.mtfConfiguartion = { + 'questionConfig': { + 'isText': true, + 'isImage': false, + 'isAudio': false, + 'isHint': false + }, + 'optionsConfig': [{ + 'isText': true, + 'isImage': false, + 'isAudio': false, + 'isHint': false + }, { + 'isText': true, + 'isImage': false, + 'isAudio': false, + 'isHint': false + }] + }; + $scope.mtfFormData = { + 'question': { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '' + }, + 'option': { + 'optionsLHS': [{ + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'index': 1 + }, { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'index': 2 + }, { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'index': 3 + }], + 'optionsRHS': [{ + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'mapIndex': 1 + }, { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'mapIndex': 2 + }, { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'mapIndex': 3 + }], + 'questionCount': 0 + } + }; + $scope.indexPair = 4; + $scope.questionMedia = {}; + $scope.optionsMedia = { + 'image': [], + 'audio': [] + }; + $scope.mtfFormData.media = []; + $scope.editMedia = []; + var questionInput = CKEDITOR.replace('mtfQuestion', {// eslint-disable-line no-undef + customConfig: CKEDITOR.basePath + "config.js",// eslint-disable-line no-undef + skin: 'moono-lisa,' + CKEDITOR.basePath + "skins/moono-lisa/",// eslint-disable-line no-undef + contentsCss: CKEDITOR.basePath + "contents.css"// eslint-disable-line no-undef + }); + questionInput.on('change', function() { + $scope.mtfFormData.question.text = this.getData(); + }); + questionInput.on('focus', function() { + $scope.generateTelemetry({ + type: 'TOUCH', + id: 'input', + target: { + id: 'questionunit-mtf-question', + ver: '', + type: 'input' + } + }) + }); + angular.element('.innerScroll').on('scroll', function() { + $scope.generateTelemetry({ + type: 'SCROLL', + id: 'form', + target: { + id: 'questionunit-mtf-form', + ver: '', + type: 'form' + } + }) + }); + $scope.init = function() { + /** + * editor:questionunit.mtf:call form validation. + * @event org.ekstep.questionunit.mtf:validateform + * @memberof org.ekstep.questionunit.mtf.horizontal_controller + */ + $scope.mtfPluginInstance = org.ekstep.pluginframework.pluginManager.getPluginManifest("org.ekstep.questionunit.mtf"); + EventBus.listeners['org.ekstep.questionunit.mtf:validateform'] = []; + ecEditor.addEventListener('org.ekstep.questionunit.mtf:validateform', function(event, callback) { + var validationRes = $scope.formValidation(); + callback(validationRes.isValid, validationRes.formData); + }, $scope); + /** + * editor:questionunit.ftb:call form edit the question. + * @event org.ekstep.questionunit.ftb:editquestion + * @memberof org.ekstep.questionunit.ftb.horizontal_controller + */ + EventBus.listeners['org.ekstep.questionunit.mtf:editquestion'] = []; + ecEditor.addEventListener('org.ekstep.questionunit.mtf:editquestion', $scope.editMtfQuestion, $scope); + ecEditor.dispatchEvent("org.ekstep.questionunit:compiled"); + } + /** + * for edit flow + * @memberof org.ekstep.questionunit.mtf.horizontal_controller + * @param {event} event data. + * @param {question} data data. + */ + $scope.editMtfQuestion = function(event, data) { + var qdata = data.data; + $scope.mtfFormData.question = qdata.question; + $scope.mtfFormData.option = qdata.option; + $scope.editMedia = qdata.media; + } + /** + * add the pair in mtf + * @memberof org.ekstep.questionunit.mtf.horizontal_controller + */ + $scope.addPair = function() { + var optionLHS = { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'index': $scope.indexPair + }; + var optionRHS = { + 'text': '', + 'image': '', + 'audio': '', + 'hint': '', + 'mapIndex': $scope.indexPair++ + }; + if ($scope.mtfFormData.option.optionsLHS.length < 5) { + $scope.mtfFormData.option.optionsLHS.push(optionLHS); + $scope.mtfFormData.option.optionsRHS.push(optionRHS); + } + } + /** + * check form validation + * @memberof org.ekstep.questionunit.mtf.horizontal_controller + * @returns {Object} question data. + */ + $scope.formValidation = function() { + var formConfig = {}, + temp, tempArray = [], + formValid; + //check form valid and lhs should be more than 3 + formValid = $scope.mtfForm.$valid && $scope.mtfFormData.option.optionsLHS.length > 2; + _.isEmpty($scope.questionMedia.image) ? 0 : tempArray.push($scope.questionMedia.image); + _.isEmpty($scope.questionMedia.audio) ? 0 : tempArray.push($scope.questionMedia.audio); + _.each($scope.optionsMedia.image, function(key) { + tempArray.push(key); + }); + _.each($scope.optionsMedia.audio, function(key) { + tempArray.push(key); + }); + temp = tempArray.filter(function(element) { + return element !== undefined; + }); + $scope.editMedia = _.union($scope.editMedia, temp); + $scope.mtfFormData.media = $scope.editMedia; + formConfig.formData = $scope.mtfFormData; + if (formValid) { + formConfig.isValid = true; + } else { + formConfig.isValid = false; + } + return formConfig; + } + /** + * delete the pair in mtf + * @memberof org.ekstep.questionunit.mtf.horizontal_controller + * @param {Integer} id data. + */ + $scope.deletePair = function(id) { + $scope.mtfFormData.option.optionsLHS.splice(id, 1); + $scope.mtfFormData.option.optionsRHS.splice(id, 1); + } + $scope.addImage = function(id, type) { + ecEditor.dispatchEvent('org.ekstep.assetbrowser:show', { + type: 'image', + search_filter: {}, // All composite keys except mediaType + callback: function(data) { + var tempImage = { + "id": Math.floor(Math.random() * 1000000000), // Unique identifier + "src": org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src), // Media URL + "assetId": data.assetMedia.id, // Asset identifier + "type": "image", // Type of asset (image, audio, etc) + "preload": false // true or false + }; + if (type == 'q') { + $scope.mtfFormData.question.image = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); + $scope.questionMedia.image = tempImage; + } else if (type == 'LHS') { + $scope.mtfFormData.option.optionsLHS[id].image = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); + $scope.optionsMedia.image[id] = tempImage; + } else if (type == 'RHS') { + $scope.mtfFormData.option.optionsRHS[id].image = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); + $scope.optionsMedia.image[id] = tempImage; + } + } + }); + } + $scope.addAudio = function(id, type) { + ecEditor.dispatchEvent('org.ekstep.assetbrowser:show', { + type: 'audio', + search_filter: {}, // All composite keys except mediaType + callback: function(data) { + var tempAudio = { + "id": Math.floor(Math.random() * 1000000000), // Unique identifier + "src": org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src), // Media URL + "assetId": data.assetMedia.id, // Asset identifier + "type": "audio", // Type of asset (image, audio, etc) + "preload": false // true or false + }; + if (type == 'q') { + $scope.mtfFormData.question.audio = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); + $scope.questionMedia.audio = tempAudio; + } else if (type == 'LHS') { + $scope.mtfFormData.option.optionsLHS[id].audio = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); + $scope.optionsMedia.audio[id] = tempAudio; + } else if (type == 'RHS') { + $scope.mtfFormData.option.optionsRHS[id].audio = org.ekstep.contenteditor.mediaManager.getMediaOriginURL(data.assetMedia.src); + $scope.optionsMedia.audio[id] = tempAudio; + } + } + }); + } + $scope.deleteImage = function(id, type) { + if (type == 'q') { + $scope.mtfFormData.question.image = ''; + delete $scope.questionMedia.image; + } else if (type == 'LHS') { + $scope.mtfFormData.option.optionsLHS[id].image = ''; + delete $scope.optionsMedia.image[id]; + } else if (type == 'RHS') { + $scope.mtfFormData.option.optionsRHS[id].image = ''; + delete $scope.optionsMedia.image[id]; + } + } + $scope.deleteAudio = function(id, type) { + if (type == 'q') { + $scope.isPlayingQ = false; + $scope.mtfFormData.question.audio = ''; + delete $scope.questionMedia.audio; + } else if (type == 'LHS') { + $scope.mtfFormData.option.optionsLHS[id].audio = ''; + delete $scope.optionsMedia.audio[id]; + } else if (type == 'RHS') { + $scope.mtfFormData.option.optionsRHS[id].audio = ''; + delete $scope.optionsMedia.audio[id]; + } + } + $scope.generateTelemetry = function(data) { + if (data) { + ecEditor.getService('telemetry').interact({ + "type": data.type, + "id": data.id, + "pageid": 'question-creation-mtf-form', + "target": { + "id": data.target.id, + "ver": data.target.ver, + "type": data.target.type + }, + "plugin": { + "id": $scope.mtfPluginInstance.id, + "ver": $scope.mtfPluginInstance.ver + } + }) + } + } +}]); +//# sourceURL=horizontalMtf.js \ No newline at end of file diff --git a/editor/plugin.js b/editor/plugin.js index d21b000..bbc7f8a 100644 --- a/editor/plugin.js +++ b/editor/plugin.js @@ -1,16 +1,16 @@ /** - * - * Plugin to create mcq question - * @extends org.ekstep.contenteditor.questionUnitPlugin - * @author Jagadish P - */ - org.ekstep.contenteditor.questionUnitPlugin.extend({ - - initialize: function() { - ecEditor.addEventListener("org.ekstep.plugins.mcqplugin:showpopup", this.loadHtml, this); - var templatePath = ecEditor.resolvePluginResource(this.manifest.id, this.manifest.ver, 'editor/templates/horizontal_template.html'); - var controllerPath = ecEditor.resolvePluginResource(this.manifest.id, this.manifest.ver, 'editor/controllers/horizontal_controller.js'); - ecEditor.getService(ServiceConstants.POPUP_SERVICE).loadNgModules(templatePath, controllerPath); - } + * + * Plugin to create mcq question + * @extends org.ekstep.contenteditor.questionUnitPlugin + * @author Jagadish P + */ + org.ekstep.questionunitMTF = {}; + org.ekstep.questionunitMTF.EditorPlugin = org.ekstep.contenteditor.questionUnitPlugin.extend({ + initialize: function() { + ecEditor.addEventListener("org.ekstep.plugins.mcqplugin:showpopup", this.loadHtml, this); + var templatePath = ecEditor.resolvePluginResource(this.manifest.id, this.manifest.ver, 'editor/templates/mtf-template.html'); + var controllerPath = ecEditor.resolvePluginResource(this.manifest.id, this.manifest.ver, 'editor/controllers/mtf-controller.js'); + ecEditor.getService(ServiceConstants.POPUP_SERVICE).loadNgModules(templatePath, controllerPath); + } }); -//# sourceURL=mcqpluginEditorPlugin.js + //# sourceURL=mcqpluginEditorPlugin.js \ No newline at end of file diff --git a/editor/templates/horizontal_template.html b/editor/templates/mtf-template.html similarity index 95% rename from editor/templates/horizontal_template.html rename to editor/templates/mtf-template.html index 7b5313b..a21d412 100644 --- a/editor/templates/horizontal_template.html +++ b/editor/templates/mtf-template.html @@ -13,7 +13,7 @@
- +