tailor-teaching-elements
Version:
Tailor teaching elements
1,916 lines (1,695 loc) • 122 kB
JavaScript
import get from 'lodash/get';
import 'quill/dist/quill.core.css';
import 'jodit/build/jodit.min.css';
import VueScrollTo from 'vue-scrollto';
import map from 'lodash/map';
import sortBy from 'lodash/sortBy';
import Draggable from 'vuedraggable';
import includes from 'lodash/includes';
import mapValues from 'lodash/mapValues';
import reduce from 'lodash/reduce';
import shuffle from 'lodash/shuffle';
import camelCase from 'lodash/camelCase';
import isArray from 'lodash/isArray';
import isBoolean from 'lodash/isBoolean';
import isNumber from 'lodash/isNumber';
import find from 'lodash/find';
import zipWith from 'lodash/zipWith';
import every from 'lodash/every';
import isEqual from 'lodash/isEqual';
import toLower from 'lodash/toLower';
import xor from 'lodash/xor';
import _uniqueId from 'lodash/uniqueId';
import APlayer from 'vue-aplayer';
import join from 'url-join';
import { PlyrueComponent } from 'plyrue';
var ASSESSMENT_TYPE = {
MC: 'multiple-choice',
MQ: 'matching-question',
SC: 'single-choice',
TF: 'true-false',
NR: 'numerical-response',
TR: 'text-response',
FB: 'fill-blank',
DD: 'drag-drop'
};
var TE_TYPE = {
AUDIO: 'te-audio',
BREAK: 'te-break',
EMBED: 'te-embed',
HTML: 'te-html',
FILE: 'te-file',
IMAGE: 'te-image',
ASSESSMENT: 'te-assessment',
REFLECTION: 'te-reflection',
VIDEO: 'te-video',
ACCORDION: 'te-accordion',
CAROUSEL: 'te-carousel',
JODIT_HTML: 'te-jodit-html',
MODAL: 'te-modal',
TABLE: 'te-table',
PDF: 'te-pdf',
BRIGHTCOVE_VIDEO: 'te-brightcove-video'
};
var subTypeInfo = {
MC: {
type: 'MC',
title: 'Multiple choice',
class: 'multiple-choice',
helperText: 'Select the choice(s) that best answers the question below.',
feedback: true
},
SC: {
type: 'SC',
title: 'Single choice',
class: 'single-choice',
helperText: 'Select one choice that best answers the question below.',
feedback: true
},
TR: {
type: 'TR',
title: 'Text response',
class: 'text-response',
helperText: 'Enter text into the empty field below and submit your answer to see the suggested answer.',
feedback: true,
allowRetake: false
},
NR: {
type: 'NR',
title: 'Numerical response',
class: 'numerical-response',
helperText: 'Enter a number in the field below.',
feedback: false
},
TF: {
type: 'TF',
title: 'True - false',
class: 'true-false',
helperText: 'Answer the question with true or false.',
feedback: true
},
FB: {
type: 'FB',
title: 'Fill in the blank',
class: 'fill-blank',
helperText: 'Enter text into the empty field(s) below and submit your answer for feedback.'
},
DD: {
type: 'DD',
title: 'Drag & Drop',
class: 'drag-drop',
helperText: 'Group items by dragging them into their corresponding boxes.'
},
MQ: {
type: 'MQ',
title: 'Matching question',
class: 'matching-question',
helperText: 'Match items by dragging and dropping each item into the corresponding box.'
}
};
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var EXPANDED_HEIGHT = '98vh';
var script = {
name: 'te-embed',
props: {
height: {
type: [Number, String],
default: 600
},
url: {
type: String,
required: true
}
},
data: function data() {
return {
expanded: false,
showOverlay: true
};
},
computed: {
embedHeight: function embedHeight() {
return this.expanded ? EXPANDED_HEIGHT : "".concat(this.height, "px");
}
},
methods: {
toggleExpand: function toggleExpand() {
this.expanded = !this.expanded;
if (this.showOverlay) this.showOverlay = false;
}
}
};
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css = ".te-embed{position:relative;overflow:auto}.te-embed .content{width:100%}.te-embed .te-embed-toolbar{opacity:0;position:absolute;top:0;left:0;z-index:1;padding:7px 0 0 7px;font-size:16px;transition:opacity .7s}.te-embed .te-embed-toolbar .tes-icon{padding:3px 6px;background-color:#e0e0e0;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.87);transition:background-color .5s}.te-embed .te-embed-toolbar .tes-icon:hover{background-color:#d0d0d0}.te-embed .te-embed-toolbar .mdi-close{font-size:18px}.te-embed:hover .te-embed-toolbar{opacity:1}.te-embed.expanded{position:fixed;top:50%;left:50%;z-index:10000;transform:translate(-50%,-50%);width:98%;box-shadow:0 2px 4px rgba(0,0,0,.87)}.interactive{position:absolute;top:0;right:0;bottom:0;left:0}";
styleInject(css);
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
const options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
let hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
const originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
const existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
const isOldIE = typeof navigator !== 'undefined' &&
/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());
/* script */
var __vue_script__ = script;
/* template */
var __vue_render__ = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "te-embed",
class: {
expanded: _vm.expanded
}
}, [_c('iframe', {
staticClass: "content",
style: {
height: _vm.embedHeight
},
attrs: {
"src": _vm.url,
"frameborder": "0"
}
}), _vm._v(" "), _c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.showOverlay,
expression: "showOverlay"
}],
staticClass: "interactive",
on: {
"click": function click($event) {
_vm.showOverlay = false;
}
}
}), _vm._v(" "), _c('div', {
staticClass: "te-embed-toolbar"
}, [_c('span', {
staticClass: "mdi tes-icon",
class: _vm.expanded ? 'mdi-close' : 'mdi-arrow-expand-all',
on: {
"click": _vm.toggleExpand
}
})])]);
};
var __vue_staticRenderFns__ = [];
/* style */
var __vue_inject_styles__ = undefined;
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = undefined;
/* functional template */
var __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__ = normalizeComponent({
render: __vue_render__,
staticRenderFns: __vue_staticRenderFns__
}, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, undefined, undefined, undefined);
//
var script$1 = {
name: 'te-html',
props: {
content: {
type: String,
required: true
}
}
};
var css$1 = ".te-html .content{padding:12px 15px}.te-html .blank{display:inline-block;margin:0 5px}.te-html .blank .blank-line{display:inline-block;width:50px;border-bottom:1px solid #000}";
styleInject(css$1);
/* script */
var __vue_script__$1 = script$1;
/* template */
var __vue_render__$1 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "ql-container te-html"
}, [_c('div', {
staticClass: "ql-editor content",
domProps: {
"innerHTML": _vm._s(_vm.content)
}
})]);
};
var __vue_staticRenderFns__$1 = [];
/* style */
var __vue_inject_styles__$1 = undefined;
/* scoped */
var __vue_scope_id__$1 = undefined;
/* module identifier */
var __vue_module_identifier__$1 = undefined;
/* functional template */
var __vue_is_functional_template__$1 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$1 = normalizeComponent({
render: __vue_render__$1,
staticRenderFns: __vue_staticRenderFns__$1
}, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, false, undefined, undefined, undefined);
//
//
//
//
//
//
var script$2 = {
name: 'te-image',
props: {
url: {
type: String,
required: true
}
}
};
var css$2 = ".te-image img{display:block;max-width:100%;height:auto;margin:0 auto}";
styleInject(css$2);
/* script */
var __vue_script__$2 = script$2;
/* template */
var __vue_render__$2 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "te-image"
}, [_c('img', {
attrs: {
"src": _vm.url
}
})]);
};
var __vue_staticRenderFns__$2 = [];
/* style */
var __vue_inject_styles__$2 = undefined;
/* scoped */
var __vue_scope_id__$2 = undefined;
/* module identifier */
var __vue_module_identifier__$2 = undefined;
/* functional template */
var __vue_is_functional_template__$2 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$2 = normalizeComponent({
render: __vue_render__$2,
staticRenderFns: __vue_staticRenderFns__$2
}, __vue_inject_styles__$2, __vue_script__$2, __vue_scope_id__$2, __vue_is_functional_template__$2, __vue_module_identifier__$2, false, undefined, undefined, undefined);
//
var script$3 = {
name: 'te-passage',
props: {
content: {
type: String,
required: true
}
}
};
var css$3 = ".te-jodit-html-content .jodit_wysiwyg{overflow:visible!important}.te-jodit-html-content .tce-jodit-tooltip{display:inline-block;position:relative;background:rgba(205,215,220,.7);text-decoration:underline dotted #455a64;cursor:help}.te-jodit-html-content .tce-jodit-tooltip::before{content:\"\";position:absolute;bottom:100%;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #455a64}.te-jodit-html-content .tce-jodit-tooltip::after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 6px - 1px);left:-10px;min-width:150px;max-width:300px;padding:5px;text-align:center;color:#fff;font-size:.9em;background:#455a64;border-radius:2px}.te-jodit-html-content .tce-jodit-tooltip::after,.te-jodit-html-content .tce-jodit-tooltip::before{visibility:hidden;transition:opacity .1s ease-out,margin .1s ease-out;opacity:0}.te-jodit-html-content .tce-jodit-tooltip:hover::after,.te-jodit-html-content .tce-jodit-tooltip:hover::before{visibility:visible;margin-bottom:3px;opacity:1}";
styleInject(css$3);
/* script */
var __vue_script__$3 = script$3;
/* template */
var __vue_render__$3 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "jodit_container te-jodit-html-content"
}, [_c('div', {
staticClass: "jodit_wysiwyg",
domProps: {
"innerHTML": _vm._s(_vm.content)
}
})]);
};
var __vue_staticRenderFns__$3 = [];
/* style */
var __vue_inject_styles__$3 = undefined;
/* scoped */
var __vue_scope_id__$3 = undefined;
/* module identifier */
var __vue_module_identifier__$3 = undefined;
/* functional template */
var __vue_is_functional_template__$3 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$3 = normalizeComponent({
render: __vue_render__$3,
staticRenderFns: __vue_staticRenderFns__$3
}, __vue_inject_styles__$3, __vue_script__$3, __vue_scope_id__$3, __vue_is_functional_template__$3, __vue_module_identifier__$3, false, undefined, undefined, undefined);
//
var resolveElement = function resolveElement(type) {
return TE_TYPE[type];
};
var script$4 = {
name: 'te-primitive',
inheritAttrs: false,
props: {
type: {
type: String,
required: true
},
width: {
type: Number,
default: 12
}
},
methods: {
resolveElement: resolveElement
},
components: {
TeEmbed: __vue_component__,
TeHtml: __vue_component__$1,
TeImage: __vue_component__$2,
TeJoditHtml: __vue_component__$3
}
};
/* script */
var __vue_script__$4 = script$4;
/* template */
var __vue_render__$4 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "te-container",
class: "col-xs-" + _vm.width
}, [_c('div', {
staticClass: "teaching-element"
}, [_c(_vm.resolveElement(_vm.type), _vm._b({
tag: "component"
}, 'component', _vm.$attrs, false))], 1)]);
};
var __vue_staticRenderFns__$4 = [];
/* style */
var __vue_inject_styles__$4 = undefined;
/* scoped */
var __vue_scope_id__$4 = undefined;
/* module identifier */
var __vue_module_identifier__$4 = undefined;
/* functional template */
var __vue_is_functional_template__$4 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$4 = normalizeComponent({
render: __vue_render__$4,
staticRenderFns: __vue_staticRenderFns__$4
}, __vue_inject_styles__$4, __vue_script__$4, __vue_scope_id__$4, __vue_is_functional_template__$4, __vue_module_identifier__$4, false, undefined, undefined, undefined);
//
var DEFAULT_SCROLL_OPTIONS = {
container: 'body',
easing: 'ease',
cancelable: true,
offset: 0,
onDone: false,
onCancel: false
};
var script$5 = {
name: 'te-accordion-item',
props: {
elements: {
type: Array,
required: true
},
heading: {
type: String,
required: true
},
options: {
type: Object,
default: function _default() {
return {};
}
}
},
data: function data() {
return {
expanded: false
};
},
methods: {
toggle: function toggle() {
this.expanded = !this.expanded;
if (this.expanded) this.scroll();
},
scroll: function scroll() {
var options = Object.assign({}, DEFAULT_SCROLL_OPTIONS, this.options.scroll);
VueScrollTo.scrollTo(this.$el, 500, options);
}
},
components: {
Primitive: __vue_component__$4
}
};
var css$4 = ".accordion-header{position:relative;height:60px;font-size:16px;cursor:pointer;text-align:justify}.accordion-active .accordion-header{font-weight:500}.accordion-header .contents{padding:12px;line-height:34px}.accordion-header .contents .title{display:inline-block;width:90%;max-width:90%;padding-top:1px;line-height:1em;vertical-align:middle}.accordion-header .icon{position:absolute;top:50%;right:25px;transform:translateY(-50%);font-size:16px}.accordion-body{height:auto;padding:32px 8px}.slide-fade-enter-active,.slide-fade-leave-active{overflow:hidden;margin-top:0;margin-bottom:0;transition:all .5s cubic-bezier(.165,.84,.44,1)}.slide-fade-enter,.slide-fade-leave-to{height:0;padding-top:0;padding-bottom:0}";
styleInject(css$4);
/* script */
var __vue_script__$5 = script$5;
/* template */
var __vue_render__$5 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('li', {
class: {
'accordion-active': _vm.expanded
},
on: {
"scroll": _vm.scroll
}
}, [_c('div', {
staticClass: "accordion-header",
on: {
"click": _vm.toggle
}
}, [_c('div', {
staticClass: "contents"
}, [_c('span', {
staticClass: "title"
}, [_vm._v(_vm._s(_vm.heading))])]), _vm._v(" "), _c('span', {
staticClass: "icon"
})]), _vm._v(" "), _c('transition', {
attrs: {
"name": "slide-fade"
}
}, [_c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.expanded,
expression: "expanded"
}],
staticClass: "accordion-body"
}, [_c('div', {
staticClass: "row"
}, _vm._l(_vm.elements, function (ref) {
var id = ref.id;
var type = ref.type;
var data = ref.data;
return _c('primitive', _vm._b({
key: id,
attrs: {
"type": type
}
}, 'primitive', data, false));
}), 1)])])], 1);
};
var __vue_staticRenderFns__$5 = [];
/* style */
var __vue_inject_styles__$5 = undefined;
/* scoped */
var __vue_scope_id__$5 = undefined;
/* module identifier */
var __vue_module_identifier__$5 = undefined;
/* functional template */
var __vue_is_functional_template__$5 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$5 = normalizeComponent({
render: __vue_render__$5,
staticRenderFns: __vue_staticRenderFns__$5
}, __vue_inject_styles__$5, __vue_script__$5, __vue_scope_id__$5, __vue_is_functional_template__$5, __vue_module_identifier__$5, false, undefined, undefined, undefined);
function getElements(item, embeds) {
var elements = map(item.body, function (_, id) {
return embeds[id];
});
return sortBy(elements, 'position');
}
var embedHost = {
props: {
embeds: {
type: Object,
default: function _default() {
return {};
}
},
items: {
type: Object,
required: true
}
},
computed: {
embeddedItems: function embeddedItems() {
var _this = this;
return map(this.items, function (item) {
return {
elements: getElements(item, _this.embeds),
heading: item.header,
id: item.id
};
});
}
}
};
//
var script$6 = {
name: 'te-accordion',
mixins: [embedHost],
props: {
options: {
type: Object,
default: function _default() {
return {};
}
}
},
computed: {
itemOptions: function itemOptions() {
return get(this.options, 'accordion.item');
}
},
components: {
AccordionItem: __vue_component__$5
}
};
var css$5 = ".accordion{margin:0;padding-left:0;list-style-type:none}";
styleInject(css$5);
/* script */
var __vue_script__$6 = script$6;
/* template */
var __vue_render__$6 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('ul', {
staticClass: "accordion"
}, _vm._l(_vm.embeddedItems, function (item) {
return _c('accordion-item', _vm._b({
key: item.id,
attrs: {
"options": _vm.itemOptions
}
}, 'accordion-item', item, false));
}), 1);
};
var __vue_staticRenderFns__$6 = [];
/* style */
var __vue_inject_styles__$6 = undefined;
/* scoped */
var __vue_scope_id__$6 = undefined;
/* module identifier */
var __vue_module_identifier__$6 = undefined;
/* functional template */
var __vue_is_functional_template__$6 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$6 = normalizeComponent({
render: __vue_render__$6,
staticRenderFns: __vue_staticRenderFns__$6
}, __vue_inject_styles__$6, __vue_script__$6, __vue_scope_id__$6, __vue_is_functional_template__$6, __vue_module_identifier__$6, false, undefined, undefined, undefined);
var buildBlankReplacer = (function (counter) {
return function () {
return "<span class='blank'>\n <span>".concat(++counter.val, "</span>\n <span class=\"blank-line\"></span>\n </span>");
};
});
//
//
//
//
//
//
//
//
//
//
//
//
var script$7 = {
props: {
disabled: {
type: Boolean,
default: false
},
retake: {
type: Boolean,
default: false
}
},
computed: {
btnLabel: function btnLabel() {
return this.retake ? 'Retake' : 'Submit';
}
},
methods: {
onClick: function onClick() {
var _this = this;
setTimeout(function () {
return _this.$emit(_this.retake ? 'reset' : 'submit');
}, 0);
}
}
};
var css$6 = ".assessment .controls{width:50%;float:right;text-align:right;cursor:auto}.assessment .controls .btn-submit{min-width:85px;padding:7px 15px}.assessment .controls .btn-submit.retake{pointer-events:all}";
styleInject(css$6);
/* script */
var __vue_script__$7 = script$7;
/* template */
var __vue_render__$7 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "controls"
}, [_c('button', {
staticClass: "btn btn-submit",
class: {
disabled: _vm.disabled && !_vm.retake,
retake: _vm.retake
},
attrs: {
"disabled": _vm.disabled && !_vm.retake
},
on: {
"click": _vm.onClick
}
}, [_vm._v("\n " + _vm._s(_vm.btnLabel) + "\n ")])]);
};
var __vue_staticRenderFns__$7 = [];
/* style */
var __vue_inject_styles__$7 = undefined;
/* scoped */
var __vue_scope_id__$7 = undefined;
/* module identifier */
var __vue_module_identifier__$7 = undefined;
/* functional template */
var __vue_is_functional_template__$7 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$7 = normalizeComponent({
render: __vue_render__$7,
staticRenderFns: __vue_staticRenderFns__$7
}, __vue_inject_styles__$7, __vue_script__$7, __vue_scope_id__$7, __vue_is_functional_template__$7, __vue_module_identifier__$7, false, undefined, undefined, undefined);
//
var formatAnswers = function formatAnswers(answers) {
var grouped = map(answers, function (answer, id) {
return {
id: id,
answer: answer
};
});
return shuffle(grouped);
};
var defaults = {
groupsPerRow: 3,
removeClass: 'mdi mdi-close'
};
var script$8 = {
props: {
answers: {
type: Object,
required: true
},
correct: {
type: Object,
required: true
},
disabled: {
type: Boolean,
default: false
},
groups: {
type: Object,
required: true
},
options: {
type: Object,
default: function _default() {
return {};
}
},
retake: {
type: Boolean,
default: false
},
submission: {
type: Object,
default: function _default() {
return {};
}
}
},
data: function data() {
return {
dragging: false,
userAnswer: mapValues(this.groups, function () {
return [];
}),
answersCollection: formatAnswers(this.answers)
};
},
computed: {
config: function config(vm) {
return Object.assign({}, defaults, {}, vm.options.dragDrop);
},
colWidth: function colWidth(vm) {
return 12 / vm.config.groupsPerRow;
},
draggableOptions: function draggableOptions() {
return {
animation: 150,
disabled: this.disabled,
chosenClass: 'chosen',
dragClass: 'drag',
ghostClass: 'ghost',
group: "tesDragDrop-".concat(this._uid)
};
},
groupsCollection: function groupsCollection() {
return map(this.groups, function (group, id) {
return {
id: id,
group: group
};
});
},
isBoxFull: function isBoxFull() {
return this.answersCollection.length === 0;
},
removeClass: function removeClass() {
return get(this.options.dragDrop, 'removeClass', 'mdi mdi-close');
},
canPartiallyRetake: function canPartiallyRetake() {
return get(this.options.dragDrop, 'partialRetake', false);
}
},
methods: {
answerClasses: function answerClasses(groupId, answerId) {
var correct = this.correct,
disabled = this.disabled;
if (!disabled) return;
return includes(correct[groupId], answerId) ? 'te-correct' : 'te-incorrect';
},
removeFromBox: function removeFromBox(id, answer) {
if (this.disabled) return; // Remove from box and add to answers array
this.userAnswer[id] = this.userAnswer[id].filter(function (a) {
return a.id !== answer.id;
});
this.answersCollection.push(answer);
},
partiallyRetake: function partiallyRetake() {
var correct = this.correct,
userAnswer = this.userAnswer;
var data = reduce(userAnswer, function (acc, group, id) {
acc.userAnswer[id] = [];
group.forEach(function (answer) {
var included = includes(correct[id], answer.id);
if (included) return acc.userAnswer[id].push(answer);
acc.answersCollection.push(answer);
});
return acc;
}, {
userAnswer: {},
answersCollection: []
});
Object.assign(this, data);
},
update: function update(userAnswer) {
this.$emit('update', {
userAnswer: userAnswer
});
},
initializeSubmission: function initializeSubmission(submission) {
var _this = this;
if (!submission) return;
this.answersCollection = formatAnswers(this.answers);
this.userAnswer = mapValues(this.groups, function () {
return [];
});
Object.keys(submission).forEach(function (groupId) {
submission[groupId].forEach(function (answerId) {
var findAnswer = function findAnswer(it) {
return it.id === answerId;
};
var answer = _this.answersCollection.find(findAnswer);
var answerIndex = _this.answersCollection.findIndex(findAnswer);
_this.userAnswer[groupId].push(answer);
_this.answersCollection.splice(answerIndex, 1);
});
});
}
},
watch: {
retake: function retake(val) {
if (!val) return;
if (this.canPartiallyRetake) return this.partiallyRetake();
this.answersCollection = formatAnswers(this.answers);
this.userAnswer = mapValues(this.groups, function () {
return [];
});
},
submission: {
handler: 'initializeSubmission',
immediate: true
},
userAnswer: {
handler: function handler() {
var isBoxFull = this.isBoxFull,
update = this.update,
userAnswer = this.userAnswer;
if (!isBoxFull) return;
update(mapValues(userAnswer, function (answer) {
return map(answer, 'id');
}));
},
deep: true
},
isBoxFull: function isBoxFull(val, oldVal) {
if (!val && oldVal) this.update(null);
}
},
components: {
Draggable: Draggable
}
};
var css$7 = ".ghost{opacity:.5}.answers{min-height:100px}.answers .answer{display:inline-block;margin:0 10px 10px 0;padding:10px 20px;cursor:default}.group>.box .ghost,.group>.box .response{display:inline-block;margin:5px;padding:5px 20px;cursor:default}.group>.box .response{position:relative}.group>.box .response .btn-close{position:absolute;top:0;right:0;margin:0;padding:0;font-size:12px;background-color:transparent;outline:0;box-shadow:none}.group>.box .response .btn-close:active{box-shadow:none}.row.groups{display:flex;flex-wrap:wrap}.row.groups .group-container{display:flex;flex-direction:column;justify-content:space-between}.row.groups .group-container .group-title{display:flex;flex-grow:2;flex-direction:column;justify-content:center}.row.groups .group-container .group{height:250px}.row.groups .group-container .group .box{height:100%;overflow:scroll}";
styleInject(css$7);
/* script */
var __vue_script__$8 = script$8;
/* template */
var __vue_render__$8 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "form-group"
}, [_c('span', {
staticClass: "form-label"
}, [_vm._v("Solution")]), _vm._v(" "), _c('div', {
staticClass: "row answers"
}, [_c('draggable', {
staticClass: "col-xs-12",
attrs: {
"options": _vm.draggableOptions
},
on: {
"start": function start($event) {
_vm.dragging = true;
},
"end": function end($event) {
_vm.dragging = false;
}
},
model: {
value: _vm.answersCollection,
callback: function callback($$v) {
_vm.answersCollection = $$v;
},
expression: "answersCollection"
}
}, _vm._l(_vm.answersCollection, function (ref) {
var id = ref.id;
var answer = ref.answer;
return _c('span', {
key: id,
staticClass: "answer"
}, [_vm._v("\n " + _vm._s(answer) + "\n ")]);
}), 0)], 1), _vm._v(" "), _c('div', {
staticClass: "row groups"
}, _vm._l(_vm.groupsCollection, function (ref) {
var id = ref.id;
var group = ref.group;
return _c('div', {
key: id,
staticClass: "group-container",
class: "col-xs-" + _vm.colWidth
}, [_c('h3', {
staticClass: "group-title"
}, [_vm._v(_vm._s(group))]), _vm._v(" "), _c('div', {
staticClass: "group"
}, [_c('draggable', {
staticClass: "box",
class: {
drop: _vm.dragging
},
attrs: {
"options": _vm.draggableOptions,
"element": "div"
},
model: {
value: _vm.userAnswer[id],
callback: function callback($$v) {
_vm.$set(_vm.userAnswer, id, $$v);
},
expression: "userAnswer[id]"
}
}, _vm._l(_vm.userAnswer[id], function (response) {
return _c('div', {
key: response.id,
staticClass: "response",
class: _vm.answerClasses(id, response.id)
}, [_vm._v("\n " + _vm._s(response.answer) + "\n "), !_vm.disabled ? _c('button', {
staticClass: "btn btn-close",
on: {
"click": function click($event) {
return _vm.removeFromBox(id, response);
}
}
}, [_c('span', {
class: _vm.config.removeClass
})]) : _vm._e()]);
}), 0)], 1)]);
}), 0)]);
};
var __vue_staticRenderFns__$8 = [];
/* style */
var __vue_inject_styles__$8 = undefined;
/* scoped */
var __vue_scope_id__$8 = undefined;
/* module identifier */
var __vue_module_identifier__$8 = undefined;
/* functional template */
var __vue_is_functional_template__$8 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$8 = normalizeComponent({
render: __vue_render__$8,
staticRenderFns: __vue_staticRenderFns__$8
}, __vue_inject_styles__$8, __vue_script__$8, __vue_scope_id__$8, __vue_is_functional_template__$8, __vue_module_identifier__$8, false, undefined, undefined, undefined);
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
var _rules;
var TYPES = {
LATIN: {
UPPER: 'upper-latin',
LOWER: 'lower-latin'
},
DECIMAL: 'decimal',
NONE: 'none'
};
var rules = (_rules = {}, _defineProperty(_rules, TYPES.LATIN.UPPER, function (index) {
return String.fromCharCode(Number(index) + 65);
}), _defineProperty(_rules, TYPES.LATIN.LOWER, function (index) {
return String.fromCharCode(Number(index) + 97);
}), _defineProperty(_rules, TYPES.DECIMAL, function (index) {
return Number(index) + 1;
}), _rules);
//
var toArray = function toArray(arg) {
return isArray(arg) ? arg : [arg];
};
var noFeedback = ['TR', 'NR'];
var defaults$1 = {
multipleChoice: {
type: TYPES.LATIN.UPPER
},
numericalResponse: {
type: TYPES.NONE
},
singleChoice: {
type: TYPES.LATIN.UPPER
},
textResponse: {
type: TYPES.NONE
},
trueFalse: {
type: TYPES.LATIN.UPPER
}
};
var script$9 = {
props: {
correct: {
type: [Number, Array, Object, String, Boolean],
default: null
},
feedback: {
type: Object,
default: function _default() {
return {};
}
},
options: {
type: Object,
default: function _default() {
return {};
}
},
type: {
type: String,
required: true
},
userAnswer: {
type: [Number, String, Array, Object, Boolean],
default: null
},
isRandomizable: {
type: Boolean,
required: true
}
},
computed: {
assessmentType: function assessmentType(vm) {
return camelCase(ASSESSMENT_TYPE[vm.type]);
},
config: function config(vm) {
return Object.assign({}, defaults$1[vm.assessmentType], {}, vm.options[vm.assessmentType]);
},
title: function title() {
return this.type === 'TR' ? 'Suggested Solution' : 'Solution';
},
allFeedback: function allFeedback() {
var config = this.config,
feedback = this.feedback;
var rule = rules[config.type];
return map(feedback, function (content, key) {
return {
prefix: rule(key),
content: content
};
});
},
hasRandomResponses: function hasRandomResponses() {
return this.isRandomizable && this.config.randomize;
},
feedbacks: function feedbacks() {
var _this = this;
if (includes(noFeedback, this.type)) return [{
content: this.correct
}];
if (!this.feedback) return [];
var options = this.options,
hasRandomResponses = this.hasRandomResponses,
allFeedback = this.allFeedback;
if (options.showFeedback && !hasRandomResponses) return allFeedback;
return toArray(this.userAnswer).reduce(function (acc, it) {
var feedback = _this.getData(it);
if (feedback.content) acc.push(feedback);
return acc;
}, []);
},
show: function show() {
return !!this.feedbacks.length;
}
},
methods: {
getPrefix: function getPrefix(answer) {
var index = this.isRandomizable ? answer.index : answer;
return rules[this.config.type](index);
},
getContent: function getContent(answer) {
var index = this.isRandomizable ? answer.key : answer;
return this.feedback[index];
},
getData: function getData(answer) {
answer = isBoolean(answer) ? Number(!answer) : answer;
var prefix = this.getPrefix(answer);
var content = this.getContent(answer);
return {
prefix: prefix,
content: content
};
}
}
};
var css$8 = ".assessment .feedback{position:relative;border:1px dotted #ccc}.assessment .feedback .form-label{margin-top:10px;color:#000}.assessment .feedback .feedback-content,.assessment .feedback .form-label{margin-bottom:10px;padding-left:15px}.assessment .feedback .content-row{white-space:pre-wrap}.assessment .feedback::before{content:\"\";display:inline-block;position:absolute;top:0;left:50%;border:9px dotted #ccc;border-color:#ccc transparent transparent transparent}.assessment .feedback::after{content:\"\";display:inline-block;position:absolute;top:-1px;left:50%;border:9px dotted #ccc;border-color:#fff transparent transparent transparent}";
styleInject(css$8);
/* script */
var __vue_script__$9 = script$9;
/* template */
var __vue_render__$9 = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _vm.show ? _c('div', {
staticClass: "ql-container feedback"
}, [_c('div', {
staticClass: "form-label"
}, [_vm._v(_vm._s(_vm.title))]), _vm._v(" "), _vm._l(_vm.feedbacks, function (ref, index) {
var prefix = ref.prefix;
var content = ref.content;
return _c('div', {
key: index,
staticClass: "ql-editor feedback-content"
}, [prefix ? _c('span', {
staticClass: "prefix"
}, [_vm._v(_vm._s(prefix) + ".")]) : _vm._e(), _vm._v(" "), _c('span', {
staticClass: "content-row",
domProps: {
"innerHTML": _vm._s(content)
}
})]);
})], 2) : _vm._e();
};
var __vue_staticRenderFns__$9 = [];
/* style */
var __vue_inject_styles__$9 = undefined;
/* scoped */
var __vue_scope_id__$9 = undefined;
/* module identifier */
var __vue_module_identifier__$9 = undefined;
/* functional template */
var __vue_is_functional_template__$9 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$9 = normalizeComponent({
render: __vue_render__$9,
staticRenderFns: __vue_staticRenderFns__$9
}, __vue_inject_styles__$9, __vue_script__$9, __vue_scope_id__$9, __vue_is_functional_template__$9, __vue_module_identifier__$9, false, undefined, undefined, undefined);
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var script$a = {
props: {
question: {
type: Array,
required: true
},
disabled: {
type: Boolean,
default: false
},
submission: {
type: Array,
default: function _default() {
return [];
}
},
retake: {
type: Boolean,
default: false
}
},
data: function data() {
return {
userAnswer: this.submission || []
};
},
computed: {
blankCount: function blankCount() {
return this.question.reduce(function (total, _ref) {
var _ref$count = _ref.count,
count = _ref$count === void 0 ? 0 : _ref$count;
return total + count;
}, 0);
}
},
methods: {
update: function update() {
var userAnswer = this.userAnswer.filter(function (it) {
return !!it.trim();
});
if (userAnswer.length !== this.blankCount) userAnswer = null;
this.$emit('update', {
userAnswer: userAnswer
});
}
},
watch: {
retake: function retake(val) {
if (val) this.userAnswer = [];
},
submission: function submission(val) {
this.userAnswer = val || [];
},
userAnswer: 'update'
}
};
var css$9 = ".assessment.fill-blank .answer-group{margin-top:10px}.assessment.fill-blank ul{padding:0 0 0 10px;list-style:none}.assessment.fill-blank ul li{padding:5px 0}";
styleInject(css$9);
/* script */
var __vue_script__$a = script$a;
/* template */
var __vue_render__$a = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "form-group"
}, [_c('span', {
staticClass: "form-label"
}, [_vm._v("Solution")]), _vm._v(" "), _vm._l(_vm.blankCount, function (index) {
return _c('div', {
key: index,
staticClass: "answer-group"
}, [_c('ul', [_c('li', [_c('div', {
staticClass: "input-group"
}, [_c('div', {
staticClass: "input-group-addon"
}, [_vm._v(_vm._s(index))]), _vm._v(" "), _c('input', {
directives: [{
name: "model",
rawName: "v-model",
value: _vm.userAnswer[index - 1],
expression: "userAnswer[index - 1]"
}],
staticClass: "form-control",
attrs: {
"disabled": _vm.disabled,
"type": "text",
"placeholder": "Solution..."
},
domProps: {
"value": _vm.userAnswer[index - 1]
},
on: {
"input": function input($event) {
if ($event.target.composing) {
return;
}
_vm.$set(_vm.userAnswer, index - 1, $event.target.value);
}
}
})])])])]);
})], 2);
};
var __vue_staticRenderFns__$a = [];
/* style */
var __vue_inject_styles__$a = undefined;
/* scoped */
var __vue_scope_id__$a = undefined;
/* module identifier */
var __vue_module_identifier__$a = undefined;
/* functional template */
var __vue_is_functional_template__$a = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$a = normalizeComponent({
render: __vue_render__$a,
staticRenderFns: __vue_staticRenderFns__$a
}, __vue_inject_styles__$a, __vue_script__$a, __vue_scope_id__$a, __vue_is_functional_template__$a, __vue_module_identifier__$a, false, undefined, undefined, undefined);
//
//
//
//
//
//
//
//
//
//
var script$b = {
props: {
content: {
type: String,
required: true
}
},
data: function data() {
return {
show: false
};
},
computed: {
icon: function icon() {
return this.show ? 'up' : 'down';
}
}
};
var css$a = ".assessment .hint-content{margin:10px 0}";
styleInject(css$a);
/* script */
var __vue_script__$b = script$b;
/* template */
var __vue_render__$b = function __vue_render__() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "hint"
}, [_c('button', {
staticClass: "btn btn-hint",
on: {
"click": function click($event) {
_vm.show = !_vm.show;
}
}
}, [_c('span', {
class: "mdi mdi-chevron-" + _vm.icon
}), _vm._v("\n Hint\n ")]), _vm._v(" "), _c('p', {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.show,
expression: "show"
}],
staticClass: "hint-content"
}, [_vm._v(_vm._s(_vm.content))])]);
};
var __vue_staticRenderFns__$b = [];
/* style */
var __vue_inject_styles__$b = undefined;
/* scoped */
var __vue_scope_id__$b = undefined;
/* module identifier */
var __vue_module_identifier__$b = undefined;
/* functional template */
var __vue_is_functional_template__$b = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$b = normalizeComponent({
render: __vue_render__$b,
staticRenderFns: __vue_staticRenderFns__$b
}, __vue_inject_styles__$b, __vue_script__$b, __vue_scope_id__$b, __vue_is_functional_template__$b, __vue_module_identifier__$b, false, undefined, undefined, undefined);
//
var script$c = {
props: {
correct: {
type: Object,
required: true
},
disabled: {
type: Boolean,
default: false
},
headings: {
type: Object,
required: true
},
options: {
type: Object,
default: function _default() {
return {};
}
},
premises: {
type: Array,
required: true
},
responses: {
type: Array,
required: true
},
retake: {
type: Boolean,
default: false
},
submission: {
type: Object,
default: function _default() {
return {};
}
}
},
data: function data() {
return {
dragOptions: {
group: {
name: "match-".concat(this._uid),
pull: 'clone',
put: false,
revertClone: true
},
sort: false
},
source: [],
target: [],
draggingItem: null
};
},
computed: {
premiseHeading: function premiseHeading() {
return get(this.headings, 'premise', 'Premise');
},
responseHeading: function responseHeading() {
return get(this.headings, 'response', 'Response');
},
isDragging: function isDragging() {
return isNumber(this.draggingItem);
},
isValid: function isValid() {
return this.source.every(function (_ref) {
var dragged = _ref.dragged;
return dragged;
});
},
canPartiallyRetake: function canPartiallyRetake() {
return get(this.options.matchingQuestions, 'partialRetake', false);
}
},
methods: {
getOptions: function getOptions(item) {
return {
group: {
name: "match-".concat(this._uid),
put: item.answers.length < 1
},
sort: false,
filter: '.disabled'
};
},
onDragStart: function onDragStart(e) {
e.clone.className += ' cloned';
this.draggingItem = e.oldIndex;
},
onDragEnd: function onDragEnd() {
this.draggingItem = null;
},
onAdd: function onAdd() {
this.source[this.draggingItem].dragged = true;
this.update();
},
answerClasses: function answerClasses(_ref2) {
var key = _ref2.key,
answers = _ref2.answers;
var disabled = this.disabled,
correct = this.correct;
if (!disabled) return;
var isCorrect = key === correct[answers[0].key];
return isCorrect ? 'te-correct' : 'te-incorrect';
},
remove: function remove(item) {
var premise = item.answers[0];
premise.dragged = false;
item.answers = [];
},
draggable: function draggable(item) {
return get(item.answers, '0.value', '');
},
partiallyRetake: function partiallyRetake() {
var _this = this;
var correct = this.correct,
target = this.target;
target.forEach(function (response) {
var key = response.answers[0].key;
if (correct[key] !== response.key) _this.remove(response);
});
},
update: function update() {
var reducer = function reducer(acc, _ref3) {
var answers = _ref3.answers,
key = _ref3.key;
if (answers.length) acc[answers[0].key] = key;
return acc;
};
this.$emit('update', {
userAnswer: reduce(this.target, reducer, {})
});
},
initialize: function initialize() {
var premises = this.premises,
responses = this.responses;
this.source = shuffle(premises.map(function (it) {
return Object.assign({}, it, {
dragged: false
});
}));
this.target = sortBy(responses.map(function (it) {
return Object.assign({}, it, {
answers: []
});
}), 'key');
},
initializeSubmission: function initializeSubmission(submission) {
var _this2 = this;
if (!submission) return;
Object.keys(submission).forEach(function (key) {
var source = _this2.source.find(function (it) {
return it.key === key;
});
var target = _this2.target.find(function (it) {
return it.key === submission[key];
});
target.answers.push(source);
source.dragged = true;
});
}
},
watch: {
retake: function retake(val) {
if (!val) return;
if (this.canPartiallyRetake) return this.partiallyRetake();
this.initialize();
this.update();
},
isValid: function isValid(val) {
this.$emit('validateAnswer', {
isValid: val
});
},
submission: 'initializeSubmission'
},
created: function created() {
this.initialize();
this.initializeSubmission(this.submission);
},
components: {
Draggable: Draggable
}
};
var css$b = ".assessment.matching-question .drag-spot{margin-bottom:10px;cursor:move}.assessment.matching-question .item{display:inline-block;padding:10px 20px 10px 20px;background-color:#f5f5f5;border:1px solid grey}.assessment.matching-question .dragged{visibility:hidden}.assessment.matching-question .drop-spot{margin-bottom:10px;padding:5px 0;border:1px solid grey}.assessment.matching-question .drop-spot .item{display:block;position:relative;margin:5px 0;padding:10px 35px 10px 20px;background-color:transparent;border:none}.assessment.matching-question .drop-spot .item .mdi-close{position:absolute;top:11px;right:17px;cursor:pointer;pointer-events:all}.assessment.matching-question .sortable-drag{display:inline-block}.assessment.matching-question .sortable-drag .item{background-color:#fff}.assessment.matching-question .cloned .item,.assessment.matching-question .drag-container .sortable-ghost .item{border:1px dashed #ccc}.assessment.matching-question .drop-area{background-color:#f4eef3;border:1px dashed #72246c}";
styleInject(css$b);
/* script */
var __vue_script__$c = script$c;
/* template */
var __vue_render__$c = function __vue_render__() {
var _vm = this;
var _h = _vm.$cr