3 lines
No EOL
111 KiB
JavaScript
3 lines
No EOL
111 KiB
JavaScript
define("local_treestudyplan/studyplan-editor-components",["exports","./simpleline/simpleline","core/ajax","core/notification","core/str","./util/string-helper","./util/date-helper","./studyplan-processor","./util/debugger","./downloader","./treestudyplan-components"],(function(_exports,_simpleline,_ajax,_notification,_str,_stringHelper,_dateHelper,_studyplanProcessor,_debugger,_downloader,_treestudyplanComponents){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _createForOfIteratorHelper(o,allowArrayLike){var it="undefined"!=typeof Symbol&&o[Symbol.iterator]||o["@@iterator"];if(!it){if(Array.isArray(o)||(it=function(o,minLen){if(!o)return;if("string"==typeof o)return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);"Object"===n&&o.constructor&&(n=o.constructor.name);if("Map"===n||"Set"===n)return Array.from(o);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen)}(o))||allowArrayLike&&o&&"number"==typeof o.length){it&&(o=it);var i=0,F=function(){};return{s:F,n:function(){return i>=o.length?{done:!0}:{done:!1,value:o[i++]}},e:function(_e){throw _e},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var err,normalCompletion=!0,didErr=!1;return{s:function(){it=it.call(o)},n:function(){var step=it.next();return normalCompletion=step.done,step},e:function(_e2){didErr=!0,err=_e2},f:function(){try{normalCompletion||null==it.return||it.return()}finally{if(didErr)throw err}}}}function _arrayLikeToArray(arr,len){(null==len||len>arr.length)&&(len=arr.length);for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_notification=_interopRequireDefault(_notification),_debugger=_interopRequireDefault(_debugger),_treestudyplanComponents=_interopRequireDefault(_treestudyplanComponents);var STUDYPLAN_EDITOR_FIELDS=["name","shortname","description","idnumber","context_id","aggregation","aggregation_config"],STUDYPLAN_EDITOR_PAGE_FIELDS=["context_id","periods","startdate","enddate"],PERIOD_EDITOR_FIELDS=["fullname","shortname","startdate","enddate"],datechanger_globals={default:!1,defaultchoice:!1,hidewarn:!1},_default2={STUDYPLAN_EDITOR_FIELDS:STUDYPLAN_EDITOR_FIELDS,install:function(Vue){Vue.use(_treestudyplanComponents.default);var debug=new _debugger.default("treestudyplan-editor");function isVisible(elem){return!!(elem.offsetWidth||elem.offsetHeight||elem.getClientRects().length)}var ItemEventBus=new Vue,string_keys=(0,_stringHelper.load_stringkeys)({conditions:[{value:"ALL",textkey:"condition_all"},{value:"ANY",textkey:"condition_any"}]}),strings=(0,_stringHelper.load_strings)({studyplan_text:{studyline_editmode:"studyline_editmode",toolbox_toggle:"toolbox_toggle",editmode_modules_hidden:"editmode_modules_hidden",studyline_add:"studyline_add",add$core:"add$core",edit$core:"edit$core",studyline_name:"studyline_name",studyline_name_ph:"studyline_name_ph",studyline_shortname:"studyline_shortname",studyline_shortname_ph:"studyline_shortname_ph",studyline_color:"studyline_color",associations:"associations",associated_cohorts:"associated_cohorts",associated_users:"associated_users",studyline_edit:"studyline_edit",studyplan_name:"studyplan_name",studyplan_name_ph:"studyplan_name_ph",studyplan_shortname:"studyplan_shortname",studyplan_shortname_ph:"studyplan_shortname_ph",studyplan_description:"studyplan_description",studyplan_description_ph:"studyplan_description_ph",studyplan_idnumber:"studyplan_idnumber",studyplan_idnumber_ph:"studyplan_idnumber_ph",studyplan_slots:"studyplan_slots",studyplan_startdate:"studyplan_startdate",studyplan_enddate:"studyplan_enddate"},studyplan_advanced:{advanced_tools:"advanced_tools",confirm_cancel:"confirm_cancel",confirm_ok:"confirm_ok",success$core:"success$core",error$core:"failed$core",advanced_converted:"advanced_converted",advanced_skipped:"advanced_skipped",advanced_failed:"advanced_failed",advanced_locked:"advanced_locked",advanced_multiple:"advanced_multiple",advanced_error:"advanced_error",advanced_tools_heading:"advanced_tools_heading",advanced_warning_title:"advanced_warning_title",advanced_warning:"advanced_warning",advanced_pick_scale:"advanced_pick_scale",advanced_course_manipulation_title:"advanced_course_manipulation_title",advanced_force_scale_title:"advanced_force_scale_title",advanced_force_scale_desc:"advanced_force_scale_desc",advanced_force_scale_button:"advanced_force_scale_button",advanced_disable_autoenddate_title:"advanced_disable_autoenddate_title",advanced_disable_autoenddate_desc:"advanced_disable_autoenddate_desc",advanced_disable_autoenddate_button:"advanced_disable_autoenddate_button",advanced_confirm_header:"advanced_confirm_header",advanced_force_scale_confirm:"advanced_force_scale_confirm",advanced_import:"advanced_import",advanced_export:"advanced_export",advanced_export_csv:"advanced_export_csv",advanced_import_from_file:"advanced_import_from_file",advanced_purge:"advanced_purge",advanced_purge_expl:"advanced_purge_expl",advanced_cascade_cohortsync_title:"advanced_cascade_cohortsync_title",advanced_cascade_cohortsync_desc:"advanced_cascade_cohortsync_desc",advanced_cascade_cohortsync:"advanced_cascade_cohortsync"},studyplan_edit:{studyplan_edit:"studyplan_edit",studyplan_name:"studyplan_name",studyplan_name_ph:"studyplan_name_ph",studyplan_shortname:"studyplan_shortname",studyplan_shortname_ph:"studyplan_shortname_ph",studyplan_description:"studyplan_description",studyplan_description_ph:"studyplan_description_ph",studyplan_idnumber:"studyplan_idnumber",studyplan_idnumber_ph:"studyplan_idnumber_ph",studyplan_context:"studyplan_context",studyplan_slots:"studyplan_slots",studyplan_startdate:"studyplan_startdate",studyplan_enddate:"studyplan_enddate",choose_aggregation_style:"choose_aggregation_style",setting_bistate_thresh_excellent:"setting_bistate_thresh_excellent",settingdesc_bistate_thresh_excellent:"settingdesc_bistate_thresh_excellent",setting_bistate_thresh_good:"setting_bistate_thresh_good",settingdesc_bistate_thresh_good:"settingdesc_bistate_thresh_good",setting_bistate_thresh_completed:"setting_bistate_thresh_completed",settingdesc_bistate_thresh_completed:"settingdesc_bistate_thresh_completed",setting_bistate_support_failed:"setting_bistate_support_failed",settingdesc_bistate_support_failed:"settingdesc_bistate_support_failed",setting_bistate_thresh_progress:"setting_bistate_thresh_progress",settingdesc_bistate_thresh_progress:"settingdesc_bistate_thresh_progress",setting_bistate_accept_pending_submitted:"setting_bistate_accept_pending_submitted",settingdesc_bistate_accept_pending_submitted:"settingdesc_bistate_accept_pending_submitted"},period_edit:{edit:"period_edit",fullname:"studyplan_name",shortname:"studyplan_shortname",startdate:"studyplan_startdate",enddate:"studyplan_enddate"},course_timing:{title:"course_timing_title",desc:"course_timing_desc",question:"course_timing_question",warning:"course_timing_warning",timing_ok:"course_timing_ok",timing_off:"course_timing_off",course:"course@core",period:"period",yes:"yes$core",no:"no$core",duration:"duration",years:"years$core",year:"year$core",weeks:"weeks$core",week:"week$core",days:"days$core",day:"day$core",rememberchoice:"course_timing_rememberchoice",hidewarning:"course_timing_hidewarning",periodspan:"course_period_span",periods:"periods",periodspan_desc:"course_period_span_desc"},studyplan_associate:{associations:"associations",associated_cohorts:"associated_cohorts",associated_users:"associated_users",associate_cohorts:"associate_cohorts",associate_users:"associate_users",add_association:"add_association",delete_association:"delete_association",associations_empty:"associations_empty",associations_search:"associations_search",cohorts:"cohorts",users:"users",selected:"selected",name:"name",context:"context"},item_text:{select_conditions:"select_conditions",item_configuration:"item_configuration",ok:"ok@core",delete:"delete@core",item_delete_message:"item_delete_message",type_course:"course@core",type_junction:"tool-junction",type_start:"tool-start",type_finish:"tool-finish",type_badge:"tool-badge",type_invalid:"course-invalid"},item_course_text:{select_conditions:"select_conditions",select_grades:"select_grades",coursetiming_past:"coursetiming_past",coursetiming_present:"coursetiming_present",coursetiming_future:"coursetiming_future",grade_include:"grade_include",grade_require:"grade_require",ok:"ok@core",cancel:"cancel@core",delete:"delete@core"},invalid:{error:"error"},completion:{completion_completed:"completion_completed",completion_incomplete:"completion_incomplete",aggregation_all:"aggregation_all",aggregation_any:"aggregation_any",aggregation_overall_all:"aggregation_overall_all",aggregation_overall_any:"aggregation_overall_any",completion_not_configured:"completion_not_configured",configure_completion:"configure_completion"},badge:{share_badge:"share_badge",dateissued:"dateissued",dateexpire:"dateexpire",badgeinfo:"badgeinfo"}});Vue.component("t-studyplan-advanced",{props:{value:{type:Object,default:function(){return null}}},data:function(){return{force_scales:{selected_scale:null,result:[]},text:strings.studyplan_advanced}},created:function(){},mounted:function(){},updated:function(){},computed:{scales:function(){return[{id:null,disabled:!0,name:this.text.advanced_pick_scale}].concat(this.value.advanced.force_scales.scales)}},methods:{disable_autoenddate:function(){var self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_disable_autoenddate",args:{studyplan_id:this.value.id}}])[0].done((function(response){self.$bvModal.msgBoxConfirm((response.success?self.text.success$core:self.text.error$core)+"\n"+response.msg)})).fail(_notification.default.exception)},force_scales_start:function(){var _this=this,self=this;this.$bvModal.msgBoxConfirm(this.text.advanced_force_scale_confirm,{title:this.text.advanced_force_scale_confirm,okVariant:"danger",okTitle:this.text.confirm_ok,cancelTitle:this.text.confirm_cancel}).then((function(value){1==value&&(0,_ajax.call)([{methodname:"local_treestudyplan_force_studyplan_scale",args:{studyplan_id:_this.value.id,scale_id:_this.force_scales.selected_scale}}])[0].done((function(response){self.force_scales.result=response})).fail(_notification.default.exception)}))},export_plan:function(format){var self=this;null!=format&&["json","csv"].includes(format)||(format="json"),(0,_ajax.call)([{methodname:"local_treestudyplan_export_plan",args:{studyplan_id:this.value.id,format:format}}])[0].done((function(response){(0,_downloader.download)(self.value.shortname+"."+format,response.content,response.format)})).fail(_notification.default.exception)},import_studylines:function(){var _this2=this;(0,_downloader.upload)((function(filename,content){(0,_ajax.call)([{methodname:"local_treestudyplan_import_studylines",args:{studyplan_id:_this2.value.id,content:content,format:"application/json"}}])[0].done((function(response){response.success?location.reload():debug.error("Import failed: ",response.msg)})).fail(_notification.default.exception)}),"application/json")},purge_studyline:function(){(0,_ajax.call)([{methodname:"local_treestudyplan_delete_studyplan",args:{id:this.value.id,force:!0}}])[0].done((function(response){response.success?location.reload():debug.error("Could not delete plan: ",response.msg)})).fail(_notification.default.exception)},cascade_cohortsync:function(){var self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_cascade_cohortsync",args:{studyplan_id:this.value.id}}])[0].done((function(response){self.$bvModal.msgBoxOk(response.success?self.text.success$core:self.text.error$core,{title:self.text.advanced_cascade_cohortsync})})).fail(_notification.default.exception)},modal_close:function(){this.force_scales.result=[]}},template:'\n <span>\n <a v-if="value.advanced"\n href=\'#\'\n @click.prevent=\'\'\n class=\'text-danger\'\n v-b-modal="\'t-studyplan-\'+value.id+\'-advanced\'"\n ><i class=\'fa fa-wrench\'></i> {{text.advanced_tools}}</a>\n <b-modal v-if="value.advanced"\n :id="\'t-studyplan-\'+value.id+\'-advanced\'"\n size="lg"\n :title="text.advanced_tools_heading"\n ok-only\n @hide="modal_close"\n >\n <b-card no-body>\n <b-tabs card>\n <b-tab :title="text.advanced_warning_title" active>\n {{ text.advanced_warning}}\n </b-tab>\n <b-tab :title="text.advanced_course_manipulation_title" >\n <b-container>\n <b-row><b-col cols="*">\n <h3>{{ text.advanced_cascade_cohortsync_title}}</h3>\n {{ text.advanced_cascade_cohortsync_desc}}\n </b-col></b-row>\n <b-row><b-col cols="*">\n <b-button\n variant="info"\n @click="cascade_cohortsync"\n >{{ text.advanced_cascade_cohortsync}}</b-button>\n </b-col></b-row>\n <b-row class="mt-3"><b-col cols="*">\n <h3>{{ text.advanced_force_scale_title}}</h3>\n {{ text.advanced_force_scale_desc}}\n </b-col></b-row>\n <b-row>\n <b-col>\n <b-form-select v-model="force_scales.selected_scale"\n :options="scales" text-field="name" value-field="id"\n ></b-form-select>\n </b-col>\n <b-col cols="4">\n <b-button\n variant="danger"\n :disabled="force_scales.selected_scale == null"\n @click="force_scales_start"\n >{{ text.advanced_force_scale_button}}</b-button>\n </b-col>\n\n </b-row>\n <b-row class="mt-3"><b-col cols="*">\n <ul class=\'t-advanced-scrollable\' v-if="force_scales.result.length > 0">\n <li v-for="c in force_scales.result">\n <span class=\'t-advanced-coursename\'>{{c.course.fullname}}</span>\n <ul v-if="c.grades.length > 0">\n <li v-for=\'g in c.grades\'>\n <span class=\'t-advanced-gradename\'><span v-html="g.name"></span></span>\n <span v-if="g.changed == \'converted\'" class=\'t-advanced-status changed\'\n >{{text.advanced_converted}}</span\n ><span v-else-if="g.changed == \'skipped\'" class=\'t-advanced-status skipped\'\n >{{text.advanced_skipped}}</span\n >\n <span v-else class=\'t-advanced-status skipped\'\n >{{text.advanced_error}}</span\n >\n </li>\n </ul>\n </li>\n </ul>\n </b-col></b-row>\n <b-row><b-col cols="*">\n <h3>{{ text.advanced_disable_autoenddate_title}}</h3>\n {{ text.advanced_disable_autoenddate_desc}}\n </b-col></b-row>\n <b-row><b-col cols="*">\n <b-button\n variant="danger"\n @click="disable_autoenddate"\n >{{ text.advanced_disable_autoenddate_button}}</b-button>\n </b-col></b-row>\n </b-container>\n </b-tab>\n <b-tab :title=\'text.advanced_export\'>\n <b-button\n variant="primary"\n @click="export_plan"\n >{{ text.advanced_export}}</b-button>\n <b-button\n variant="danger"\n @click="import_studylines"\n >{{ text.advanced_import}}</b-button>\n <b-button\n variant="primary"\n @click="export_plan(\'csv\')"\n >{{ text.advanced_export_csv}}</b-button>\n </b-tab>\n <b-tab :title=\'text.advanced_purge\'>\n <p>{{text.advanced_purge_expl}}</p>\n <p><b-button\n variant="danger"\n @click="purge_studyline"\n >{{ text.advanced_purge}}</b-button></p>\n </b-tab> </b-tabs>\n </b-card>\n </b-modal>\n </span>\n '}),Vue.component("t-studyplan-edit",{props:{value:{type:Object,default:function(){return null}},mode:{type:String,default:function(){return"edit"}},type:{type:String,default:function(){return"link"}},variant:{type:String,default:function(){return""}},contextid:{type:Number,default:1},defaultAggregation:{type:String,default:"core"}},data:function(){return{show:!1,config:{userfields:[{key:"selected"},{key:"firstname",sortable:!0},{key:"lastname",sortable:!0}],cohortfields:[{key:"selected"},{key:"name",sortable:!0},{key:"context",sortable:!0}]},editdata:{name:"",shortname:"",description:"",idnumber:"",context_id:this.contextid,periods:4,startdate:(new Date).getFullYear()+"-08-01",enddate:(new Date).getFullYear()+1+"-08-01",aggregation:this.defaultAggregation,aggregation_config:""},aggregation_parsed:{},aggregators:[],categories:[{context_id:1,category:{path:"System"}}],text:strings.studyplan_edit}},created:function(){var self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_list_aggregators",args:[]}])[0].done((function(response){for(var ix in self.aggregators=response,self.aggregators){var ag=self.aggregators[ix];try{ag.defaultconfig&&ag.defaultconfig.length>0&&(self.aggregation_parsed[ag.id]=JSON.parse(ag.defaultconfig))}catch(e){debug.warn(e)}}})).fail(_notification.default.exception),(0,_ajax.call)([{methodname:"local_treestudyplan_list_accessible_categories",args:{operation:"edit"}}])[0].done((function(response){for(var ix in response){var cat=response[ix];cat.category.pathname=cat.category.path.join(" / ")}self.categories=response})).fail(_notification.default.exception)},mounted:function(){},updated:function(){},computed:{},methods:{editPlanStart:function(){if("create"!=this.mode&&((0,_studyplanProcessor.objCopy)(this.editdata,this.value.pages[0],STUDYPLAN_EDITOR_PAGE_FIELDS),(0,_studyplanProcessor.objCopy)(this.editdata,this.value,STUDYPLAN_EDITOR_FIELDS)),this.editdata.aggregation_config&&this.editdata.aggregation_config.length>0)try{this.aggregation_parsed[this.editdata.aggregation]=JSON.parse(this.editdata.aggregation_config)}catch(e){debug.warn(e)}this.show=!0},editPlanFinish:function(){var self=this,args={},method="local_treestudyplan_edit_studyplan";"create"==this.mode?method="local_treestudyplan_add_studyplan":args.id=this.value.id,this.aggregation_parsed[this.editdata.aggregation]&&(this.editdata.aggregation_config=JSON.stringify(this.aggregation_parsed[this.editdata.aggregation])),(0,_studyplanProcessor.objCopy)(args,this.editdata,STUDYPLAN_EDITOR_FIELDS),(0,_studyplanProcessor.objCopy)(args,this.editdata,STUDYPLAN_EDITOR_PAGE_FIELDS),(0,_ajax.call)([{methodname:method,args:args}])[0].done((function(response){if("create"==self.mode)self.$emit("created",response),self.editdata={name:"",shortname:"",description:"",context_id:1,periods:4,startdate:(new Date).getFullYear()+"-08-01",enddate:(new Date).getFullYear()+1+"-08-01",aggregation:"bistate",aggregation_config:""};else{var moved_from=self.value.context_id,moved_to=response.context_id,moved=moved_from!=moved_to;response.pages[0].periods!=self.value.pages[0].periods?(0,_ajax.call)([{methodname:"local_treestudyplan_get_studyplan_map",args:{id:self.value.id}}])[0].done((function(response){self.value=(0,_studyplanProcessor.ProcessStudyplan)(response,!0),debug.info("studyplan processed"),self.$emit("input",self.value)})).fail((function(error){_notification.default.exception(error)})):((0,_studyplanProcessor.objCopy)(self.value,response,STUDYPLAN_EDITOR_FIELDS),self.$emit("input",self.value),moved&&self.$emit("moved",self.value,moved_from,moved_to))}})).fail(_notification.default.exception)},numberFilter:function(value){return value}},template:'\n <span class=\'s-studyplan-edit\'>\n <b-button :variant="variant" v-if=\'type == "button"\' @click.prevent=\'editPlanStart()\'\n ><slot><i class=\'fa fa-gear\'></i></slot></b-button>\n <a variant="variant" v-else href=\'#\' @click.prevent=\'editPlanStart()\'\n ><slot><i class=\'fa fa-gear\'></i></slot></a>\n <b-modal\n v-model="show"\n size="lg"\n ok-variant="primary"\n :title="text.studyplan_edit"\n @ok="editPlanFinish()"\n :ok-disabled="Math.min(editdata.name.length,editdata.shortname.length) == 0"\n >\n <b-container>\n <b-row>\n <b-col cols="4">{{ text.studyplan_name}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="editdata.name"\n :state=\'editdata.name.length>0\'\n :placeholder="text.studyplan_name_ph"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_shortname}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="editdata.shortname"\n :state=\'editdata.shortname.length>0\'\n :placeholder="text.studyplan_shortname_ph"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_idnumber}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="editdata.idnumber"\n :placeholder="text.studyplan_idnumber_ph"></b-form-input>\n </b-col>\n </b-row> <b-row>\n <b-col cols="4">{{ text.studyplan_description}}</b-col>\n <b-col cols="8">\n <b-form-textarea v-model="editdata.description"\n rows="4"\n max-rows="5"\n :placeholder="text.studyplan_description_ph"></b-form-textarea>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_context}}</b-col>\n <b-col cols="8">\n <b-form-select v-model="editdata.context_id"\n :options="categories" text-field="category.pathname" value-field="context_id"\n ></b-form-select>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_slots}}</b-col>\n <b-col cols="8">\n <b-form-input \n min="1"\n type="number"\n no-wheel\n v-model="editdata.periods"\n ></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_startdate}}</b-col>\n <b-col cols="8">\n <b-form-datepicker start-weekday="1" v-model="editdata.startdate"></b-form-datepicker>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_enddate}}</b-col>\n <b-col cols="8">\n <b-form-datepicker start-weekday="1" v-model="editdata.enddate" ></b-form-datepicker>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.choose_aggregation_style}}</b-col>\n <b-col cols="8">\n <b-form-select v-model="editdata.aggregation"\n :options="aggregators" text-field="name" value-field="id"\n ></b-form-select>\n </b-col>\n </b-row>\n <template v-if="aggregation_parsed.bistate && editdata.aggregation == \'bistate\'">\n <b-row >\n <b-col cols="4">{{ text.setting_bistate_thresh_excellent}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="aggregation_parsed.bistate.thresh_excellent"\n type="number" number :formatter="numberFilter"\n ></b-form-input>\n </b-col>\n </b-row>\n <b-row >\n <b-col cols="4">{{ text.setting_bistate_thresh_good}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="aggregation_parsed.bistate.thresh_good"\n type="number" number :formatter="numberFilter"\n ></b-form-input>\n </b-col>\n </b-row>\n <b-row >\n <b-col cols="4">{{ text.setting_bistate_thresh_completed}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="aggregation_parsed.bistate.thresh_completed"\n type="number" number :formatter="numberFilter"\n ></b-form-input>\n </b-col>\n </b-row>\n <b-row><b-col cols="*"> </b-col></b-row>\n <b-row>\n <b-col cols="7">{{ text.setting_bistate_support_failed}}</b-col>\n <b-col cols="3">\n <b-form-checkbox v-model="aggregation_parsed.bistate.use_failed"\n ></b-form-checkbox>\n </b-col>\n </b-row>\n <b-row><b-col cols="*"> </b-col></b-row>\n <b-row >\n <b-col cols="7">{{ text.setting_bistate_accept_pending_submitted}}</b-col>\n <b-col cols="3">\n <b-form-checkbox v-model="aggregation_parsed.bistate.accept_pending_as_submitted"\n ></b-form-checkbox>\n </b-col>\n </b-row>\n </template>\n </b-container>\n </b-modal>\n </span>\n '}),Vue.component("t-studyplan-associate",{props:["value"],data:function(){return{show:!1,config:{userfields:[{key:"selected"},{key:"firstname",sortable:!0},{key:"lastname",sortable:!0}],cohortfields:[{key:"selected"},{key:"name",sortable:!0},{key:"context",sortable:!0}]},association:{cohorts:[],users:[]},loading:{cohorts:!1,users:!1},search:{users:[],cohorts:[]},selected:{search:{users:[],cohorts:[]},associated:{users:[],cohorts:[]}},text:strings.studyplan_associate}},created:function(){},mounted:function(){},updated:function(){},methods:{showModal:function(){this.show=!0,this.loadAssociations()},cohortOptionModel:function(c){return{value:c.id,text:c.name+" ("+c.context.path.join(" / ")+")"}},userOptionModel:function(u){return{value:u.id,text:u.firstname+" "+u.lastname}},loadAssociations:function(){var self=this;self.loading.cohorts=!0,self.loading.users=!0,(0,_ajax.call)([{methodname:"local_treestudyplan_associated_users",args:{studyplan_id:self.value.id}}])[0].done((function(response){self.association.users=response.map(self.userOptionModel),self.loading.users=!1})).fail(_notification.default.exception),(0,_ajax.call)([{methodname:"local_treestudyplan_associated_cohorts",args:{studyplan_id:self.value.id}}])[0].done((function(response){self.association.cohorts=response.map(self.cohortOptionModel),self.loading.cohorts=!1})).fail(_notification.default.exception)},searchCohorts:function(searchtext){var self=this;searchtext.length>0?(0,_ajax.call)([{methodname:"local_treestudyplan_list_cohort",args:{like:searchtext,exclude_id:self.value.id}}])[0].done((function(response){self.search.cohorts=response.map(self.cohortOptionModel)})).fail(_notification.default.exception):self.search.cohorts=[]},cohortAssociate:function(){var self=this,requests=[],associated=self.association.cohorts,search=self.search.cohorts,searchselected=self.selected.search.cohorts,_loop=function(i){var r=searchselected[i];requests.push({methodname:"local_treestudyplan_connect_cohort",args:{studyplan_id:self.value.id,cohort_id:r},fail:_notification.default.exception,done:function(response){response.success&&(0,_studyplanProcessor.transportItem)(associated,search,r)}})};for(var i in searchselected)_loop(i);(0,_ajax.call)(requests)},cohortDisassociate:function(){var self=this,requests=[],associatedselected=self.selected.associated.cohorts,associated=self.association.cohorts,search=self.search.cohorts,_loop2=function(i){var r=associatedselected[i];requests.push({methodname:"local_treestudyplan_disconnect_cohort",args:{studyplan_id:self.value.id,cohort_id:r},fail:_notification.default.exception,done:function(response){response.success&&(0,_studyplanProcessor.transportItem)(search,associated,r)}})};for(var i in associatedselected)_loop2(i);(0,_ajax.call)(requests)},searchUsers:function(searchtext){var self=this;searchtext.length>0?(0,_ajax.call)([{methodname:"local_treestudyplan_find_user",args:{like:searchtext,exclude_id:self.value.id}}])[0].done((function(response){self.search.users=response.map(self.userOptionModel)})).fail(_notification.default.exception):self.search.users=[]},userAssociate:function(){var self=this,requests=[],associated=self.association.users,search=self.search.users,searchselected=self.selected.search.users,_loop3=function(i){var r=searchselected[i];requests.push({methodname:"local_treestudyplan_connect_user",args:{studyplan_id:self.value.id,user_id:r},fail:_notification.default.exception,done:function(response){response.success&&(0,_studyplanProcessor.transportItem)(associated,search,r)}})};for(var i in searchselected)_loop3(i);(0,_ajax.call)(requests)},userDisassociate:function(){var self=this,requests=[],associated=self.association.users,associatedselected=self.selected.associated.users,search=self.search.users,_loop4=function(i){var r=associatedselected[i];requests.push({methodname:"local_treestudyplan_disconnect_user",args:{studyplan_id:self.value.id,user_id:r},fail:_notification.default.exception,done:function(response){response.success&&(0,_studyplanProcessor.transportItem)(search,associated,r)}})};for(var i in associatedselected)_loop4(i);(0,_ajax.call)(requests)}},template:'\n<span class=\'s-studyplan-associate\'\n ><a href=\'#\' @click.prevent="showModal" ><slot><i class=\'fa fa-users\'></i></slot></a>\n <b-modal\n v-model="show"\n size="lg"\n ok-variant="primary"\n :title="text.associations + \' - \' + value.name"\n ok-only>\n <b-tabs class=\'s-studyplan-associate-window\'>\n <b-tab :title="text.cohorts">\n <b-container>\n <b-row class=\'mb-2 mt-2\'>\n <b-col>{{text.associated_cohorts}}</b-col>\n <b-col>{{text.associate_cohorts}}</b-col>\n </b-row>\n <b-row class=\'mb-2\'>\n <b-col>\n </b-col>\n <b-col>\n <b-form-input\n type="text" @input="searchCohorts($event)"\n :placeholder="text.search"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col>\n <b-form-select\n multiple\n v-model="selected.associated.cohorts"\n :options="association.cohorts"\n :select-size="10"\n ></b-form-select>\n </b-col>\n <b-col>\n <b-form-select\n multiple\n v-model="selected.search.cohorts"\n :options="search.cohorts"\n :select-size="10"\n ></b-form-select>\n </b-col>\n </b-row>\n <b-row class=\'mt-2\'>\n <b-col>\n <b-button variant=\'danger\' @click="cohortDisassociate()"\n ><i class=\'fa fa-chain-broken\'></i> {{text.delete_association}}</b-button>\n </b-col>\n <b-col>\n <b-button variant=\'success\' @click="cohortAssociate()"\n ><i class=\'fa fa-link\'></i> {{text.add_association}}</b-button>\n </b-col>\n </b-row>\n </b-container>\n </b-tab>\n <b-tab :title="text.users">\n <b-container>\n <b-row class=\'mb-2 mt-2\'>\n <b-col>{{text.associated_users}}</b-col>\n <b-col>{{text.associate_users}}</b-col>\n </b-row>\n <b-row class=\'mb-2\'>\n <b-col>\n </b-col>\n <b-col>\n <b-form-input\n type="text"\n @input="searchUsers($event)"\n placeholder="Search users"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col>\n <b-form-select\n multiple\n v-model="selected.associated.users"\n :options="association.users"\n :select-size="10"\n ></b-form-select>\n </b-col>\n <b-col>\n <b-form-select\n multiple\n v-model="selected.search.users"\n :options="search.users"\n :select-size="10"\n ></b-form-select>\n </b-col>\n </b-row>\n <b-row class=\'mt-2\'>\n <b-col>\n <b-button variant=\'danger\' @click="userDisassociate()"\n ><i class=\'fa fa-chain-broken\'></i> {{text.delete_association}}</b-button>\n </b-col>\n <b-col>\n <b-button variant=\'success\' @click="userAssociate()"\n ><i class=\'fa fa-link\'></i> {{text.add_association}}</b-button>\n </b-col>\n </b-row>\n </b-container>\n </b-tab>\n </b-tabs>\n </b-modal>\n</span>\n'}),Vue.component("t-period-edit",{props:{value:{type:Object,default:function(){return null}},type:{type:String,default:function(){return"link"}},variant:{type:String,default:function(){return""}},minstart:{type:String,default:function(){return null}},maxend:{type:String,default:function(){return null}}},data:function(){return{show:!1,editdata:{fullname:"",shortname:"",startdate:(new Date).getFullYear()+"-08-01",enddate:(new Date).getFullYear()+1+"-08-01"},text:strings.period_edit}},created:function(){},mounted:function(){},updated:function(){},computed:{},methods:{editStart:function(){(0,_studyplanProcessor.objCopy)(this.editdata,this.value,PERIOD_EDITOR_FIELDS),this.show=!0},editFinish:function(){var self=this,args={id:this.value.id};(0,_studyplanProcessor.objCopy)(args,this.editdata,PERIOD_EDITOR_FIELDS),(0,_ajax.call)([{methodname:"local_treestudyplan_edit_period",args:args}])[0].done((function(response){(0,_studyplanProcessor.objCopy)(self.value,response,PERIOD_EDITOR_FIELDS),self.$emit("input",self.value),self.$emit("edited",self.value)})).fail(_notification.default.exception)},refresh:function(){var self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_get_period",args:{id:this.value.id}}])[0].done((function(response){(0,_studyplanProcessor.objCopy)(self.value,response,PERIOD_EDITOR_FIELDS),self.$emit("input",self.value)})).fail(_notification.default.exception)},add_day:function(date,days){return void 0===days&&(days=1),(0,_dateHelper.add_days)(date,days)},sub_day:function(date,days){return void 0===days&&(days=1),(0,_dateHelper.add_days)(date,0-days)}},template:'\n <span class=\'t-period-edit\'>\n <b-button :variant="variant" v-if=\'type == "button"\' @click.prevent=\'editStart()\'\n ><slot><i class=\'fa fa-gear\'></i></slot></b-button>\n <a variant="variant" v-else href=\'#\' @click.prevent=\'editStart()\'\n ><slot><i class=\'fa fa-gear\'></i></slot></a>\n <b-modal\n v-model="show"\n size="lg"\n ok-variant="primary"\n :title="text.edit"\n @ok="editFinish()"\n :ok-disabled="Math.min(editdata.fullname.length,editdata.shortname.length) == 0"\n >\n <b-container>\n <b-row>\n <b-col cols="4">{{ text.fullname}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="editdata.fullname"\n :state=\'editdata.fullname.length>0\'\n ></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.shortname}}</b-col>\n <b-col cols="8">\n <b-form-input v-model="editdata.shortname"\n :state=\'editdata.shortname.length>0\'\n ></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_startdate}}</b-col>\n <b-col cols="8">\n <b-form-datepicker\n start-weekday="1"\n v-model="editdata.startdate"\n :min="(minstart ? minstart : \'\')"\n :max="sub_day(value.enddate)"\n ></b-form-datepicker>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="4">{{ text.studyplan_enddate}}</b-col>\n <b-col cols="8">\n <b-form-datepicker\n start-weekday="1"\n v-model="editdata.enddate"\n :min="add_day(value.startdate)"\n :max="(maxend ? maxend : \'\')"\n ></b-form-datepicker>\n </b-col>\n </b-row>\n </b-container>\n </b-modal>\n </span>\n '}),Vue.component("t-studyplan",{props:["value","index"],data:function(){return{config:{userfields:[{key:"selected"},{key:"firstname",sortable:!0},{key:"lastname",sortable:!0}],cohortfields:[{key:"selected"},{key:"name",sortable:!0},{key:"context",sortable:!0}]},create:{studyline:{name:"",shortname:"",color:"#DDDDDD"}},edit:{toolbox_shown:!1,studyline:{editmode:!1,data:{name:"",shortname:"",color:"#DDDDDD"},original:{}},studyplan:{data:{name:"",shortname:"",description:"",slots:4,startdate:"2020-08-01",enddate:"",aggregation:"",aggregation_config:"",aggregation_info:{useRequiredGrades:!0,useItemCondition:!1}},original:{}}},text:strings.studyplan_text,cache:{linelayers:{}}}},created:function(){},mounted:function(){0==this.page.studylines.length&&(this.edit.studyline.editmode=!0),this.$root.$emit("redrawLines")},updated:function(){this.$root.$emit("redrawLines"),ItemEventBus.$emit("redrawLines")},computed:{columns:function(){return 1+2*this.page.periods},columns_stylerule:function(){for(var s="grid-template-columns: var(--studyplan-filter-width)",i=0;i<this.page.periods;i++)s+=" var(--studyplan-course-width) var(--studyplan-filter-width)";return s+";"},page:function(){return this.value.pages[0]}},methods:{trashbin_accepts:function(type){return!!type.item},countLineLayers:function(line){if(this.cache.linelayers[line.id]&&new Date-this.cache.linelayers[line.id].timestamp<1e3)return this.cache.linelayers[line.id].value;for(var maxLayer=-1,i=0;i<=this.page.periods;i++)if(line.slots[i]){line.slots[i];for(var ix in line.slots[i].courses){var item=line.slots[i].courses[ix];item.layer>maxLayer&&(maxLayer=item.layer)}for(var _ix in line.slots[i].filters){var _item=line.slots[i].filters[_ix];_item.layer>maxLayer&&(maxLayer=_item.layer)}}return this.cache.linelayers[line.id]={value:maxLayer+1,timestamp:new Date},maxLayer+1},slotsempty:function(slots){if(Array.isArray(slots)){for(var count=0,i=0;i<slots.length;i++)Array.isArray(slots[i].courses)&&(count+=slots[i].courses.length),Array.isArray(slots[i].filters)&&(count+=slots[i].filters.length);return 0==count}return!1},movedStudyplan:function(plan,from,to){this.$emit("moved",plan,from,to)},addStudyLine:function(page,newlineinfo){(0,_ajax.call)([{methodname:"local_treestudyplan_add_studyline",args:{page_id:page.id,name:newlineinfo.name,shortname:newlineinfo.shortname,color:newlineinfo.color,sequence:page.studylines.length}}])[0].done((function(response){page.studylines.push(response),newlineinfo.name="",newlineinfo.shortname="",newlineinfo.color="#dddddd"})).fail(_notification.default.exception)},editLineStart:function(line){Object.assign(this.edit.studyline.data,line),this.edit.studyline.original=line,this.$bvModal.show("modal-edit-studyline-"+this.value.id)},editLineFinish:function(){var editedline=this.edit.studyline.data,originalline=this.edit.studyline.original;(0,_ajax.call)([{methodname:"local_treestudyplan_edit_studyline",args:{id:editedline.id,name:editedline.name,shortname:editedline.shortname,color:editedline.color}}])[0].done((function(response){originalline.name=response.name,originalline.shortname=response.shortname,originalline.color=response.color})).fail(_notification.default.exception)},deleteLine:function(page,line){var self=this;(0,_str.get_strings)([{key:"studyline_confirm_remove",param:line.name,component:"local_treestudyplan"},{key:"delete",component:"core"}]).then((function(s){self.$bvModal.msgBoxConfirm(s[0],{okTitle:s[1],okVariant:"danger"}).then((function(modalresponse){modalresponse&&(0,_ajax.call)([{methodname:"local_treestudyplan_delete_studyline",args:{id:line.id}}])[0].done((function(response){if(1==response.success){var index=page.studylines.indexOf(line);page.studylines.splice(index,1)}})).fail(_notification.default.exception)}))}))},reorderLines:function(event,lines){event.apply(lines);var sequence=[];for(var idx in lines)sequence.push({id:lines[idx].id,sequence:idx});(0,_ajax.call)([{methodname:"local_treestudyplan_reorder_studylines",args:{sequence:sequence}}])[0].done((function(response){})).fail(_notification.default.exception)},deletePlan:function(studyplan){var self=this;(0,_str.get_strings)([{key:"studyplan_confirm_remove",param:studyplan.name,component:"local_treestudyplan"},{key:"delete",component:"core"}]).then((function(s){self.$bvModal.msgBoxConfirm(s[0],{okTitle:s[1],okVariant:"danger"}).then((function(modalresponse){modalresponse&&(0,_ajax.call)([{methodname:"local_treestudyplan_delete_studyplan",args:{id:studyplan.id,force:!0}}])[0].done((function(response){1==response.success&&self.$root.$emit("studyplanRemoved",studyplan)})).fail(_notification.default.exception)}))}))},deleteStudyItem:function(event){var item=event.data;(0,_ajax.call)([{methodname:"local_treestudyplan_delete_studyitem",args:{id:item.id}}])[0].done((function(response){1==response.success&&event.source.$emit("cut",event)})).fail(_notification.default.exception)},showslot:function(line,index,layeridx,type){for(var forGradable="gradable"==type,periods=this.page.periods,show=!0,i=0;i<periods;i++)if(line.slots[index-i]&&line.slots[index-i].courses){var list=line.slots[index-i].courses;for(var ix in list){var item=list[ix];item.layer==layeridx&&(forGradable?i>0&&item.span-i>0&&(show=!1):item.span-i>1&&(show=!1))}}return show},periodEdited:function(pi){var prev=this.$refs["periodeditor-"+(pi.period-1)][0];prev&&prev.refresh();var next=this.$refs["periodeditor-"+(pi.period+1)][0];next&&next.refresh()},add_day:function(date,days){return void 0===days&&(days=1),(0,_dateHelper.add_days)(date,days)},sub_day:function(date,days){return void 0===days&&(days=1),(0,_dateHelper.add_days)(date,0-days)},toolbox_switched:function(event){this.$emit("toggletoolbox",event)}},template:'\n <div>\n <div class=\'controlbox t-studyplan-controlbox\'>\n <div class="controlbox-group">\n <b-form-checkbox v-model="edit.studyline.editmode" class="sw-studyplan-toolbar" switch\n @change="toolbox_switched(edit.toolbox_shown && !edit.studyline.editmode); "\n >{{ text.studyline_editmode }}</b-form-checkbox>\n <b-form-checkbox v-if="!edit.studyline.editmode" v-model="edit.toolbox_shown" class="sw-studyplan-toolbar" switch\n @change="toolbox_switched"\n >{{ text.toolbox_toggle}}</b-form-checkbox>\n <drop\n mode=\'copy\'\n class=\'t-item-deletebox text-danger border-danger\'\n @drop=\'deleteStudyItem\'\n :accepts-type="trashbin_accepts"\n ><i class=\'fa fa-trash\'></i>\n </drop>\n </div>\n <div class="controlbox-group">\n <span class=\'control editable\'>\n <t-studyplan-advanced v-model="value"></t-studyplan-advanced>\n </span>\n <span class=\'control editable\'>\n <t-studyplan-associate\n v-model="value"><i class=\'fa fa-users\'></i> {{text.associations}}</t-studyplan-associate>\n </span>\n <span class=\'control editable\'>\n <t-studyplan-edit v-model="value" @moved="movedStudyplan"\n ><i class=\'fa fa-gear\'></i> {{text.edit$core}}</t-studyplan-edit>\n </span>\n <span class=\'control deletable\'>\n <a v-if=\'page.studylines.length == 0\' href=\'#\' @click=\'deletePlan(value)\'\n ><i class=\'text-danger fa fa-trash\'></i></a>\n </span>\n </div>\n </div>\n <div class=\'t-studyplan-content-edit\' v-if="edit.studyline.editmode">\n <drop-list\n :items="page.studylines"\n class="t-slot-droplist"\n :accepts-type="\'studyline-\'+page.id"\n xreorder="$event.apply(page.studylines)"\n @reorder="reorderLines($event,page.studylines)"\n mode="copy"\n row\n >\n <template v-slot:item="{item}">\n <drag\n :key="item.id"\n class=\'t-studyline-drag\'\n :data="item"\n :type="\'studyline-\'+page.id"\n >\n <template v-slot:drag-image>\n <i class="fa fa-arrows text-primary"></i>\n </template>\n <t-studyline-edit\n v-model="item"\n @edit=\'editLineStart(item)\'\n @delete=\'deleteLine(page,item)\'\n >\n <div v-if="!slotsempty(item.slots)"> {{ text.editmode_modules_hidden}} </div>\n </t-studyline-edit>\n </drag>\n </template>\n </drop-list>\n </div>\n <div class=\'t-studyplan-content\' v-else>\n\n \x3c!-- Now paint the headings column --\x3e\n <div class=\'t-studyplan-headings\'>\n <s-studyline-header-heading></s-studyline-header-heading>\n <t-studyline-heading v-for="(line,lineindex) in page.studylines"\n :key="line.id"\n @resize="headingresized(lineindex,$event)"\n v-model="page.studylines[lineindex]"\n :layers=\'countLineLayers(line)+1\'\n :class=" \'t-studyline\' + ((lineindex%2==0)?\' odd \' :\' even \' )\n + ((lineindex==0)?\' first \':\' \')\n + ((lineindex==page.studylines.length-1)?\' last \':\' \')"\n ></t-studyline-heading>\n </div>\n \x3c!-- Next, paint all the cells in the scrollable --\x3e\n <div class="t-studyplan-scrollable" >\n <div class="t-studyplan-timeline" :style="columns_stylerule">\n \x3c!-- add period information --\x3e\n <template v-for="(n,index) in (page.periods+1)">\n <s-studyline-header-period\n v-if="index > 0"\n v-model="page.perioddesc[index-1]"\n ><t-period-edit\n :ref="\'periodeditor-\'+index"\n @edited="periodEdited"\n v-model="page.perioddesc[index-1]"\n :minstart="(index > 1) ? add_day(page.perioddesc[index-2].startdate,2) : null"\n :maxend="(index < page.periods) ? sub_day(page.perioddesc[index].enddate,2) : null"\n ></t-period-edit\n ></s-studyline-header-period>\n <div class="s-studyline-header-filter"></div>\n </template>\n\n \x3c!-- Line by line add the items --\x3e\n \x3c!-- The grid layout handles putting it in rows and columns --\x3e\n <template v-for="(line,lineindex) in page.studylines"\n ><template v-for="(layernr,layeridx) in countLineLayers(line)+1"\n ><template v-for="(n,index) in (page.periods+1)"\n >\n <t-studyline-slot\n v-if="index > 0 && showslot(line, index, layeridx, \'gradable\')"\n type=\'gradable\'\n v-model="line.slots[index].courses"\n :key="\'c-\'+lineindex+\'-\'+index+\'-\'+layernr"\n :slotindex="index"\n :line="line"\n :plan="value"\n :page="page"\n :period="page.perioddesc[index-1]"\n :layer="layeridx"\n :class="\'t-studyline \' + ((lineindex%2==0)?\' odd \':\' even \')\n + ((lineindex==0 && layernr==1)?\' first \':\' \')\n + ((lineindex==page.studylines.length-1)?\' last \':\' \')\n + ((layernr == countLineLayers(line))?\' lastlyr \':\' \')\n + ((layernr == countLineLayers(line)+1)?\' newlyr \':\' \')"\n ></t-studyline-slot\n ><t-studyline-slot\n type=\'filter\'\n v-if="showslot(line, index, layeridx, \'filter\')"\n v-model="line.slots[index].filters"\n :key="\'f-\'+lineindex+\'-\'+index+\'-\'+layernr"\n :slotindex="index"\n :line="line"\n :plan="value"\n :page="page"\n :layer="layeridx"\n :class="\'t-studyline \' + ((lineindex%2==0)?\' odd \':\' even \')\n + ((lineindex==0 && layernr==1)?\' first \':\'\')\n + ((lineindex==page.studylines.length-1)?\' last \':\' \')\n + ((index==page.periods)?\' rightmost\':\'\')\n + ((layernr == countLineLayers(line))?\' lastlyr \':\' \')\n + ((layernr == countLineLayers(line)+1)?\' newlyr \':\' \')"\n >\n </t-studyline-slot\n ></template\n ></template\n ></template\n ></div>\n </div>\n </div>\n <div v-if="edit.studyline.editmode" class=\'t-studyline-add\'>\n <a href="#" v-b-modal="\'modal-add-studyline-\'+page.id" @click="false;"\n ><i class=\'fa fa-plus\'></i>{{ text.studyline_add }}</a>\n </div>\n <b-modal\n :id="\'modal-add-studyline-\'+page.id"\n size="lg"\n :ok-title="text.add$core"\n ok-variant="primary"\n :title="text.studyline_add"\n @ok="addStudyLine(page,create.studyline)"\n :ok-disabled="Math.min(create.studyline.name.length,create.studyline.shortname.length) == 0"\n >\n <b-container>\n <b-row>\n <b-col cols="3">{{text.studyline_name}}</b-col>\n <b-col>\n <b-form-input v-model="create.studyline.name" :placeholder="text.studyline_name_ph"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="3">{{text.studyline_shortname}}</b-col>\n <b-col>\n <b-form-input\n v-model="create.studyline.shortname"\n :placeholder="text.studyline_shortname_ph"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="3">{{text.studyline_color}}</b-col>\n <b-col>\n <input type="color" v-model="create.studyline.color" />\n \x3c!-- hsluv-picker v-model="create.studyline.color" horizontal displaysize="175" ></hsluv-picker --\x3e\n </b-col>\n </b-row>\n </b-container>\n </b-modal>\n <b-modal\n :id="\'modal-edit-studyline-\'+value.id"\n size="lg"\n ok-variant="primary"\n :title="text.studyline_edit"\n @ok="editLineFinish()"\n :ok-disabled="Math.min(edit.studyline.data.name.length,edit.studyline.data.shortname.length) == 0"\n >\n <b-container>\n <b-row>\n <b-col cols="3">{{ text.studyline_name}}</b-col>\n <b-col>\n <b-form-input\n v-model="edit.studyline.data.name"\n :placeholder="text.studyline_name_ph"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="3">{{ text.studyline_shortname}}</b-col>\n <b-col>\n <b-form-input\n v-model="edit.studyline.data.shortname"\n :placeholder="text.studyline_shortname_ph"></b-form-input>\n </b-col>\n </b-row>\n <b-row>\n <b-col cols="3">{{ text.studyline_color}}</b-col>\n <b-col>\n <input type="color" v-model="edit.studyline.data.color" />\n </b-col>\n </b-row>\n </b-container>\n </b-modal>\n </div>\n '}),Vue.component("t-studyline-heading",{props:{value:{type:Object,default:function(){return{}}},layers:{type:Number,default:1}},data:function(){return{layerHeights:{}}},created:function(){ItemEventBus.$on("lineHeightChange",this.onLineHeightChange)},computed:{},methods:{onLineHeightChange:function(lineid,layerid,newheight){if(this.$refs.main&&lineid==this.value.id){var items=document.querySelectorAll(".t-studyline-slot-0[data-studyline='".concat(this.value.id,"']")),heightSum=0;items.forEach((function(el){var height=el.getBoundingClientRect().height;heightSum+=height}));var heightStyle="".concat(heightSum,"px");this.$refs.main.style.height=heightStyle}}},template:'\n <div class="t-studyline t-studyline-heading "\n :data-studyline="value.id" ref="main"\n ><div class="t-studyline-handle" :style="\'background-color: \' + value.color"></div>\n <div class="t-studyline-title">\n <abbr v-b-tooltip.hover.right :title="value.name">{{ value.shortname }}</abbr>\n </div>\n </div>\n '}),Vue.component("t-studyline-edit",{props:{value:{type:Object,default:function(){return{}}}},data:function(){return{}},computed:{deletable:function(){var slots=this.value.slots;if(Array.isArray(slots)){for(var count=0,i=0;i<slots.length;i++)Array.isArray(slots[i].courses)&&(count+=slots[i].courses.length),Array.isArray(slots[i].filters)&&(count+=slots[i].filters.length);return 0==count}return!1},editable:function(){return!0}},methods:{onEdit:function(){this.$emit("edit",this.value)},onDelete:function(){this.$emit("delete",this.value)}},template:"\n <div :class=\"'t-studyline '\" >\n <div class=\"t-studyline-handle\" :style=\"'background-color: ' + value.color\"></div>\n <div class=\"t-studyline-title\">\n <div>\n <i class='fa fa-arrows text-primary'></i>\n <abbr v-b-tooltip.hover :title=\"value.name\">{{ value.shortname }}</abbr>\n </div>\n </div>\n <div class='t-studyline-editmode-content'>\n <slot></slot>\n </div>\n <div class='controlbox'>\n <template v-if='editable || deletable'>\n <span class='control editable' v-if='editable'>\n <a href='#' @click='onEdit'><i class='fa fa-pencil'></i></a>\n </span>\n <span class='control deletable' v-if='deletable'>\n <a v-if='deletable' href='#' @click='onDelete'><i class='text-danger fa fa-trash'></i></a>\n </span>\n </template>\n </div>\n </div>\n "}),Vue.component("t-studyline-slot",{props:{type:{type:String,default:"gradable"},slotindex:{type:Number,default:""},line:{type:Object,default:function(){return null}},layer:{type:Number},value:{type:Array,default:function(){return[]}},plan:{type:Object,default:function(){return null}},page:{type:Object,default:function(){return null}},period:{type:Object,default:function(){return null}}},mounted:function(){var self=this;"gradable"==self.type&&1==self.slotindex&&(self.resizeListener=new ResizeObserver((function(){if(self.$refs.main){var size=self.$refs.main.getBoundingClientRect();ItemEventBus.$emit("lineHeightChange",self.line.id,self.layer,size.height)}})).observe(self.$refs.main))},unmounted:function(){this.resizeListener&&this.resizeListener.disconnect()},computed:{slotkey:function(){return"".concat(this.type,"'-'").concat(this.line.id,"-").concat(this.slotindex,"-").concat(this.layer)},itemidx:function(){for(var ix in this.value){if(this.value[ix].layer==this.layer)return ix}return null},item:function(){for(var ix in this.value){var itm=this.value[ix];if(itm.layer==this.layer)return itm}return null},listtype:function(){return this.type},dragacceptlist:function(){return"gradable"==this.type?["course","gradable-item"]:["filter","filter-item"]},courseHoverDummy:function(){return{course:this.hover.component}},current:function(){if(this.period&&this.period.startdate&&this.period.enddate){var now=new Date,pstart=new Date(this.period.startdate),pend=new Date(this.period.enddate);return now>=pstart&&now<pend}return!1},spanCss:function(){if(this.item&&this.item.span>1){var span=2*this.item.span-1;return"width: 100%; grid-column: span ".concat(span,";")}return""}},data:function(){return{text:strings.course_timing,resizeListener:null,hover:{component:null,type:null},datechanger:{coursespan:null,periodspan:null,default:!1,defaultchoice:!1,hidewarn:!1}}},methods:{onDrop:function(event){var _this3=this;this.hover.component=null,this.hover.type=null,debug.info(event);var self=this;if(event.type.item){var item=event.data;item.layer=this.layer,item.slot=this.slotindex,self.value.push(item),self.$emit("input",self.value),self.relocateStudyItem(item).done((function(){_this3.$refs.timingChecker&&_this3.$refs.timingChecker.validate_course_period()}))}else event.type.component&&(debug.info("Adding new component"),"gradable"==event.type.type?(0,_ajax.call)([{methodname:"local_treestudyplan_add_studyitem",args:{line_id:self.line.id,slot:self.slotindex,layer:self.layer,type:"course",details:{competency_id:null,conditions:"",course_id:event.data.id,badge_id:null,continuation_id:null}}}])[0].done((function(response){var item=response;self.relocateStudyItem(item).done((function(){self.value.push(item),self.$emit("input",self.value),_this3.$nextTick((function(){_this3.$refs.timingChecker&&_this3.$refs.timingChecker.validate_course_period()}))}))})).fail(_notification.default.exception):"filter"==event.type.type&&(debug.info("Adding new filter compenent"),(0,_ajax.call)([{methodname:"local_treestudyplan_add_studyitem",args:{line_id:self.line.id,slot:self.slotindex,type:event.data.type,details:{badge_id:event.data.badge?event.data.badge.id:void 0}}}])[0].done((function(response){var item=response;self.relocateStudyItem(item).done((function(){item.layer=_this3.layer,self.value.push(item),self.$emit("input",self.value)}))})).fail(_notification.default.exception)))},onCut:function(event){for(var id=event.data.id,i=0;i<this.value.length;i++)if(this.value[i].id==id){this.value.splice(i,1),i--;break}this.$emit("input",this.value)},relocateStudyItem:function(item){var iteminfo={id:item.id,layer:this.layer,slot:this.slotindex,line_id:this.line.id};return(0,_ajax.call)([{methodname:"local_treestudyplan_reorder_studyitems",args:{items:[iteminfo]}}])[0].fail(_notification.default.exception)},onDragEnter:function(event){this.hover.component=event.data,this.hover.type=event.type},onDragLeave:function(){this.hover.component=null,this.hover.type=null},maxSpan:function(){for(var freeIndex=this.slotindex,i=this.slotindex+1;i<=this.page.periods&&(this.line.slots&&this.line.slots[i]&&this.line.slots[i].courses);i++){var clist=this.line.slots[i].courses,flist=this.line.slots[i-1].filters,busy=!1;for(var ix in clist)if(clist[ix].layer==this.layer){busy=!0;break}for(var _ix2 in flist)if(flist[_ix2].layer==this.layer){busy=!0;break}if(busy)break;freeIndex=i}return freeIndex-this.slotindex+1},makeType:function(item){return{item:!0,component:!1,span:item.span,type:this.type}},checkType:function(type){return type.type==this.type&&("filter"==type||type.span<=this.maxSpan())}},template:'\n <div :class="\'t-studyline-slot \'+type + \' t-studyline-slot-\'+slotindex + \' \' + ((slotindex==0)?\' t-studyline-firstcolumn \':\' \')\n + (current?\'current \':\' \')"\n :data-studyline="line.id" ref="main"\n :style=\'spanCss\'\n ><drag v-if="item"\n\n :key="item.id"\n class="t-slot-item"\n :data="item"\n :type="makeType(item)"\n @cut="onCut"\n ><t-item\n @deleted="onCut"\n v-model="value[itemidx]"\n :plan="plan"\n :line=\'line\'\n :page=\'page\'\n :period=\'period\'\n :maxspan=\'maxSpan()\'\n ></t-item\n ></drag\n ><drop v-else\n :class="\'t-slot-drop \'+type + (layer > 0?\' secondary\':\' primary\')"\n :accepts-type="checkType"\n @drop="onDrop"\n mode="cut"\n @dragenter="onDragEnter"\n @dragleave="onDragLeave"\n ><template v-if="hover.component">\n <div v-if="hover.type.item"\n class="t-slot-item feedback"\n :key="hover.component.id"\n ><t-item v-model="hover.component" dummy></t-item\n ></div\n ><div v-else-if="hover.type.type == \'gradable\'"\n class="t-slot-item feedback"\n :key="\'course-\'+hover.component.id"\n ><t-item-course v-model="courseHoverDummy"></t-item-course></div\n ><div v-else-if="hover.type.type == \'filter\'"\n class="t-slot-item feedback"\n key="tooldrop"\n ><t-item-junction v-if="hover.component.type == \'junction\'" ></t-item-junction\n ><t-item-start v-else-if="hover.component.type == \'start\'" ></t-item-start\n ><t-item-finish v-else-if="hover.component.type == \'finish\'" ></t-item-finish\n ><t-item-badge v-else-if="hover.component.type == \'badge\'" ></t-item-badge\n ></div\n ><div v-else\n class="t-slot-item feedback"\n :key="hover.type">--{{ hover.type }}--</div\n ></template\n ></drop>\n <t-item-timing-checker hidden\n v-if="value && value[itemidx] && value[itemidx].course"\n ref="timingChecker"\n :maxspan="maxSpan()"\n :page="page"\n :period="period"\n v-model="value[itemidx]"\n ></t-item-timing-checker>\n </div>\n '}),Vue.component("t-item-timing-checker",{props:{value:{type:Object},page:{type:Object},period:{type:Object},maxspan:{type:Number},hidden:{type:Boolean,default:!1}},computed:{endperiod:function(){var endperiodnr=Math.min(this.page.periods,this.period.period+(this.value.span-1));return this.page.perioddesc[endperiodnr-1]},course_period_matches:function(){return this.value&&"course"==this.value.type?(this.datechanger.coursespan=(0,_dateHelper.datespaninfo)(this.value.course.startdate,this.value.course.enddate),this.datechanger.periodspan=(0,_dateHelper.datespaninfo)(this.period.startdate,this.endperiod.enddate),this.datechanger.coursespan.first.getTime()==this.datechanger.periodspan.first.getTime()&&this.datechanger.coursespan.last.getTime()==this.datechanger.periodspan.last.getTime()):(debug.warn("Timing thing not proper configured",this.value,this.period,this.maxspan),!1)}},data:function(){return{id:Math.floor(Math.random()*Date.now()).toString(16),text:strings.course_timing,datechanger:{coursespan:null,periodspan:null,globals:datechanger_globals}}},methods:{validate_course_period:function(force){debug.info("Validating course and period"),this.course_period_matches?debug.info("Course timing matches period",this.datechanger):(debug.info("Course timing does not match period timing"),this.value.course.canupdatecourse?this.hidden&&this.datechanger.globals.default?this.datechanger.globals.defaultvalue&&this.change_course_period():this.$bvModal.show("t-course-timing-matching-"+this.id):this.hidden&&this.datechanger.globals.hidewarn||this.$bvModal.show("t-course-timing-warning-"+this.id))},change_course_period:function(){var self=this;return self.datechanger.globals.default&&(self.datechanger.globals.defaultvalue=!0),(0,_ajax.call)([{methodname:"local_treestudyplan_course_period_timing",args:{period_id:self.period.id,course_id:this.value.course.id,span:this.value.span}}])[0].fail(_notification.default.exception).done((function(response){self.value.course.startdate=response.startdate,self.value.course.enddate=response.enddate,self.value.course.timing=response.timing,self.$emit("input",self.value)}))},change_span:function(span){var self=this;return(0,_ajax.call)([{methodname:"local_treestudyplan_set_studyitem_span",args:{id:self.value.id,span:span}}])[0].fail(_notification.default.exception).done((function(response){self.value.span=response.span,self.$emit("input",self.value),self.$nextTick((function(){self.validate_course_period()}))}))},format_duration:function(dsi){var s="";return 1==dsi.years?s+="1 ".concat(this.text.year,", "):dsi.years>1&&(s+="".concat(dsi.years," ").concat(this.text.years,", ")),1==dsi.weeks?s+="1 ".concat(this.text.week,", "):dsi.weeks>1&&(s+="".concat(dsi.weeks," ").concat(this.text.weeks,", ")),1==dsi.days?s+="1 ".concat(this.text.day,", "):dsi.days>1&&(s+="".concat(dsi.days," ").concat(this.text.days,", ")),s.toLocaleLowerCase()}},template:'\n <div :class="\'t-item-timing-checker\'" :style="hidden?\'display: none \':\'\'">\n <template v-if="!hidden" >\n <span class="mr-1" v-if="course_period_matches">\n <i class="text-success fa fa-calendar-check-o"\n v-b-tooltip.hover.topright :title="text.timing_ok"\n ></i>\n </span>\n <span class="mr-1" v-else>\n <a href=\'#\' @click="validate_course_period()" class="text-warning"\n v-b-tooltip.hover.bottomleft :title="text.timing_off"\n ><i class="fa fa-calendar-times-o"\n ></i\n ><i class="fa fa-question-circle text-black-50"\n style="font-size: 0.8em; top: -0.3em; position: relative;"\n\n ></i\n ></a>\n </span>\n <span class="ml-1" v-b-tooltip.hover.bottomleft :title="text.periodspan_desc"\n >{{ text.periodspan\n }} <b-form-select\n class=""\n size="sm" @change="change_span" v-model="value.span">\n <b-form-select-option v-for="(n,i) in maxspan" :value=\'n\' :key=\'i\'\n >{{ n }}</b-form-select-option>\n </b-form-select\n > {{\n (value.span == 1)?text.period.toLowerCase():text.periods.toLowerCase()\n }}<i\n class="fa fa-question-circle text-black-50"\n style="font-size: 0.8em; top: -0.3em; position: relative;"\n ></i>\n </span>\n </template>\n <b-modal\n :id="\'t-course-timing-matching-\'+this.id"\n size="lg"\n :title="text.title"\n @ok="change_course_period"\n :ok-title="text.yes"\n ok-variant="danger"\n :cancel-title="text.no"\n cancel-variant="primary"\n >\n <b-container v-if="datechanger.coursespan && datechanger.periodspan && value && value.course">\n <b-row><b-col cols="12">{{ text.desc }}</b-col></b-row>\n <b-row><b-col cols="12"><div class="generalbox alert alert-warning">{{ text.question }}</div></b-col></b-row>\n <b-row>\n <b-col cols="6">\n <h3> {{ text.course }} </h3>\n <p class="mb-0"><b>{{ value.course.fullname }}</b></p>\n <p class="mb-1"><b>{{ value.course.shortname }}</b></p>\n <p class="mb-1">{{ datechanger.coursespan.formatted.first}} - {{ datechanger.coursespan.formatted.last}}</p>\n <p class="mb-0"><b>{{ text.duration }}</b><br>\n {{ format_duration(datechanger.coursespan)}}</p>\n </b-col>\n <b-col cols="6">\n <h3> {{ text.period }} </h3>\n <p class="mb-0"><b>{{ period.fullname }}</b><b v-if="value.span > 1"> - {{ endperiod.fullname }}</b></p>\n <p class="mb-1"><b>{{ period.shortname }}</b><b v-if="value.span > 1"> - {{ endperiod.shortname }}</b></p>\n <p class="mb-1">{{ datechanger.periodspan.formatted.first}} - {{ datechanger.periodspan.formatted.last}}</p>\n <p class="mb-0"><b>{{ text.duration }}</b><br>\n {{ format_duration(datechanger.periodspan)}}</p>\n </b-col>\n </b-row>\n <b-row v-if=\'hidden\' class="pt-2"><b-col cols="12">\n <b-form-checkbox type="checkbox" v-model="datechanger.globals.default">{{ text.rememberchoice }}</b-form-checkbox>\n </b-col></b-row>\n </b-container>\n </b-modal>\n <b-modal\n :id="\'t-course-timing-warning-\'+this.id"\n size="lg"\n ok-variant="primary"\n :title="text.title"\n :ok-title="text.yes"\n ok-only\n >\n <b-container v-if="datechanger.coursespan && datechanger.periodspan && value && value.course">\n <b-row><b-col cols="12">{{ text.desc }}</b-col></b-row>\n <b-row><b-col cols="12"><div class="generalbox alert alert-warning">{{ text.warning }}</div></b-col></b-row>\n <b-row>\n <b-col cols="6">\n <h3> {{ text.course }} </h3>\n <p class="mb-0"><b>{{ value.course.fullname }}</b></p>\n <p class="mb-1"><b>{{ value.course.shortname }}</b></p>\n <p class="mb-1">{{ datechanger.coursespan.formatted.first}} - {{ datechanger.coursespan.formatted.last}}</p>\n <p class="mb-0"><b>{{ text.duration }}</b><br>\n {{ format_duration(datechanger.coursespan)}}</p>\n </b-col>\n <b-col cols=>"6">\n <h3> {{ text.period }} </h3>\n <p class="mb-0"><b>{{ period.fullname }}</b><b v-if="value.span > 1"> - {{ endperiod.fullname }}</b></p>\n <p class="mb-1"><b>{{ period.shortname }}</b><b v-if="value.span > 1"> - {{ endperiod.shortname }}</b></p>\n <p class="mb-1">{{ datechanger.periodspan.formatted.first}} - {{ datechanger.periodspan.formatted.last}}</p>\n <p class="mb-0"><b>{{ text.duration }}</b><br>\n {{ format_duration(datechanger.periodspan)}}</p>\n </b-col>\n </b-row>\n <b-row v-if=\'hidden\' class="pt-2"><b-col cols="12">\n <b-form-checkbox type="checkbox" v-model="datechanger.globals.hidewarn">{{ text.hidewarning }}</b-form-checkbox>\n </b-col></b-row>\n </b-container>\n </b-modal>\n </div>\n '}),Vue.component("t-item",{props:{value:{type:Object,default:function(){return null}},dummy:{type:Boolean,default:function(){return!1}},plan:{type:Object,default:function(){return null}},line:{type:Object,default:function(){return null}},page:{type:Object,default:function(){return null}},period:{type:Object,default:function(){return null}},maxspan:{type:Number,default:function(){return 0}}},data:function(){return{dragLine:null,dragEventListener:null,deleteMode:!1,condition_options:string_keys.conditions,text:strings.item_text,showContext:!1,lines:[]}},methods:{dragStart:function(event){this.deleteMode=!1;var start=document.getElementById("studyitem-"+this.value.id),dragelement=document.getElementById("t-item-cdrag-"+this.value.id);dragelement.style.position="fixed",dragelement.style.left=event.position.x+"px",dragelement.style.top=event.position.y+"px",this.dragLine=new _simpleline.SimpleLine(start,dragelement,{color:"#777",gravity:{start:1.3,end:1.3}}),document.addEventListener("mousemove",this.onMouseMove)},dragEnd:function(){null!==this.dragLine&&this.dragLine.remove();var dragelement=document.getElementById("t-item-cdrag-"+this.value.id);dragelement.style.removeProperty("left"),dragelement.style.removeProperty("top"),dragelement.style.removeProperty("position"),document.removeEventListener("mousemove",this.onMouseMove)},onMouseMove:function(event){var dragelement=document.getElementById("t-item-cdrag-"+this.value.id);dragelement.style.position="fixed",dragelement.style.left=event.clientX+"px",dragelement.style.top=event.clientY+"px"},onDrop:function(event){var _this4=this,from_id=event.data.id,to_id=this.value.id;this.redrawLines(),(0,_ajax.call)([{methodname:"local_treestudyplan_connect_studyitems",args:{from_id:from_id,to_id:to_id}}])[0].done((function(response){var conn={id:response.id,from_id:response.from_id,to_id:response.to_id};ItemEventBus.$emit("createdConnection",conn),_this4.value.connections.in.push(conn)})).fail(_notification.default.exception)},redrawLine:function(conn){var start=document.getElementById("studyitem-".concat(conn.from_id)),end=document.getElementById("studyitem-".concat(conn.to_id));this.lines[conn.to_id]&&(this.lines[conn.to_id].remove(),delete this.lines[conn.to_id]),null!==start&&null!==end&&isVisible(start)&&isVisible(end)&&(this.lines[conn.to_id]=new _simpleline.SimpleLine(start,end,{color:"var(--success)",gravity:{start:1.3,end:1.3}}))},deleteLine:function(conn){var _this5=this,self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_disconnect_studyitems",args:{from_id:conn.from_id,to_id:conn.to_id}}])[0].done((function(response){if(response.success){_this5.removeLine(conn),ItemEventBus.$emit("connectionDisconnected",conn);var index=self.value.connections.out.indexOf(conn);self.value.connections.out.splice(index,1)}})).fail(_notification.default.exception)},highlight:function(conn){this.lines[conn.to_id]&&this.lines[conn.to_id].setConfig({color:"var(--danger)"})},normalize:function(conn){this.lines[conn.to_id]&&this.lines[conn.to_id].setConfig({color:"var(--success)"})},updateItem:function(){(0,_ajax.call)([{methodname:"local_treestudyplan_edit_studyitem",args:{id:this.value.id,conditions:this.value.conditions,continuation_id:this.value.continuation_id}}])[0].fail(_notification.default.exception)},doShowContext:function(event){this.hasContext&&(this.showContext=!0,event.preventDefault())},redrawLines:function(){if(this.value.connections&&this.value.connections.out)for(var i in this.value.connections.out){var conn=this.value.connections.out[i];this.redrawLine(conn)}},onCreatedConnection:function(conn){conn.from_id==this.value.id&&(this.value.connections.out.push(conn),this.redrawLine(conn))},onRemovedConnection:function(conn){if(this.value.connections&&this.value.connections.out)for(var i in this.value.connections.in){var c_in=this.value.connections.in[i];conn.id==c_in.id&&self.value.connections.out.splice(i,1)}},onRePositioned:function(){if(this.value.connections&&this.value.connections.out)for(var i in this.value.connections.out){var conn=this.value.connections.out[i];this.redrawLine(conn)}},onDisPositioned:function(re_id){if(this.value.connections&&this.value.connections.out)for(var i in this.value.connections.out){var conn=this.value.connections.out[i];conn.to_id==re_id&&this.removeLine(conn)}},onItemDeleted:function(item_id){if(this.value.connections&&this.value.connections.out)for(var i in this.value.connections.out){var conn=this.value.connections.out[i];conn.to_id==item_id&&(this.removeLine(conn),this.value.connections.out.splice(i,1))}if(this.value.connections&&this.value.connections.in)for(var _i in this.value.connections.in){this.value.connections.in[_i].from_id==item_id&&this.value.connections.out.splice(_i,1)}},onRedrawLines:function(){this.redrawLines()},removeLine:function(conn){this.lines[conn.to_id]&&(this.lines[conn.to_id].remove(),delete this.lines[conn.to_id])},deleteItem:function(){var self=this,msgparams={item:this.text["type_"+this.value.type].toLocaleLowerCase(),name:"course"==this.value.type?this.value.course.displayname:"",line:this.line?this.line.name:"",period:this.period?this.period.fullname:this.plan.name};this.$bvModal.msgBoxConfirm((0,_stringHelper.strformat)(this.text.item_delete_message,msgparams),{okVariant:"danger",okTitle:this.text.ok,cancelTitle:this.text.cancel}).then((function(value){value&&(0,_ajax.call)([{methodname:"local_treestudyplan_delete_studyitem",args:{id:self.value.id}}])[0].done((function(response){1==response.success&&self.$emit("deleted",{data:self.value})})).fail(_notification.default.exception)})).catch((function(err){debug.console.error(err)}))}},computed:{hasConnectionsOut:function(){return!["finish"].includes(this.value.type)},hasConnectionsIn:function(){return!["start"].includes(this.value.type)},hasContext:function(){return["start","junction","finish"].includes(this.value.type)}},created:function(){this.dummy||(ItemEventBus.$on("createdConnection",this.onCreatedConnection),ItemEventBus.$on("removedConnection",this.onRemovedConnection),ItemEventBus.$on("rePositioned",this.onRePositioned),ItemEventBus.$on("disPositioned",this.onDisPositioned),ItemEventBus.$on("itemDeleted",this.onItemDeleted),ItemEventBus.$on("redrawLines",this.onRedrawLines))},mounted:function(){var _this6=this;this.dummy||(this.redrawLines(),setTimeout((function(){ItemEventBus.$emit("rePositioned",_this6.value.id)}),10))},beforeDestroy:function(){if(!this.dummy){for(var i in this.value.connections.out){var conn=this.value.connections.out[i];this.removeLine(conn)}ItemEventBus.$emit("disPositioned",this.value.id),ItemEventBus.$off("createdConnection",this.onCreatedConnection),ItemEventBus.$off("removedConnection",this.onRemovedConnection),ItemEventBus.$off("rePositioned",this.onRePositioned),ItemEventBus.$off("disPositioned",this.onDisPositioned),ItemEventBus.$off("itemDeleted",this.onItemDeleted),ItemEventBus.$off("redrawLines",this.onRedrawLines)}},beforeUpdate:function(){},updated:function(){this.dummy||this.redrawLines()},template:'\n <div class="t-item-base" :id="\'studyitem-\'+value.id">\n <t-item-course\n v-if="value.type == \'course\'"\n @deleterq="deleteItem"\n v-model="value"\n :plan=\'plan\'\n :page=\'page\'\n :period=\'period\'\n :maxspan=\'maxspan\'\n ></t-item-course>\n <t-item-junction\n v-if="value.type == \'junction\'"\n @deleterq="deleteItem"\n v-model="value"\n ></t-item-junction>\n <t-item-start\n v-if="value.type == \'start\'"\n @deleterq="deleteItem"\n v-model="value"\n ></t-item-start>\n <t-item-finish\n v-if="value.type == \'finish\'"\n @deleterq="deleteItem"\n v-model="value"\n ></t-item-finish>\n <t-item-badge\n v-if="value.type == \'badge\'"\n @deleterq="deleteItem"\n v-model="value"\n ></t-item-badge>\n <t-item-invalid\n v-if="value.type == \'invalid\'"\n @deleterq="deleteItem"\n v-model="value"\n ></t-item-invalid>\n <drop v-if=\'!dummy && hasConnectionsIn\' accepts-type="linestart"\n :id="\'t-item-cend-\'+value.id"\n class="t-item-connector-end"\n mode="copy"\n @drop="onDrop"\n ><svg width=\'5px\' height=\'10px\'><rect ry="1px" rx="1px" y="0px" x="0px" height="10px" width="5px"/></svg></drop>\n <drag v-if=\'!dummy && hasConnectionsOut\' type="linestart"\n :id="\'t-item-cstart-\'+value.id"\n :class="\'t-item-connector-start \' + ((deleteMode&&value.connections.out.length)?\'deleteMode\':\'\')"\n :data="value"\n @dragstart="dragStart"\n @dragend="dragEnd"\n @click="deleteMode = (value.connections.out.length)?(!deleteMode):false"\n >\n <svg width=\'5px\' height=\'10px\'><rect ry="1px" rx="1px" y="0px" x="0px" height="10px" width="5px"/></svg>\n <template v-slot:drag-image="{data}"> <i :id="\'t-item-cdrag-\'+value.id" class="fa"></i>\n </template>\n </drag>\n <div class="deletebox" v-if="deleteMode && value.connections.out.length > 0"\n >\n <a v-for="conn in value.connections.out"\n @click="deleteLine(conn)"\n @mouseenter="highlight(conn)"\n @mouseleave="normalize(conn)"\n class="t-connection-delete text-danger"\n :title="conn.id">\n <i class="fa fa-trash"></i>\n </a>\n </div>\n <a v-if="hasContext" class="t-item-config"\n v-b-modal="\'t-item-config-\'+value.id" href="#" @click.prevent=""><i class="fa fa-gear"></i></a>\n <b-modal no-body class=""\n :id="\'t-item-config-\'+value.id"\n :title="text[\'item_configuration\']"\n scrollable\n ok-only\n class="t-item-contextview b-modal-justify-footer-between"\n >\n <b-form-group\n v-if="value.type != \'start\'"\n :label="text.select_conditions"\n >\n <b-form-select size="sm"\n @input="updateItem"\n v-model="value.conditions"\n :options="condition_options"\n ></b-form-select>\n </b-form-group>\n\n <template #modal-footer="{ ok, cancel, hide }" >\n <a href=\'#\' @click=\'deleteItem()\' class="text-danger"\n ><i class="fa fa-trash"></i>\n {{ text.delete }}\n </a>\n <b-button size="sm" variant="primary" @click="ok()">\n {{ text.ok }}\n </b-button>\n </template>\n\n </b-modal>\n </div>\n '}),Vue.component("t-item-invalid",{props:{value:{type:Object,default:function(){return null}}},data:function(){return{text:strings.invalid}},methods:{},template:'\n <div class="t-item-invalid">\n <b-card no-body >\n <b-row no-gutters>\n <b-col md="1">\n <span class="t-timing-indicator timing-invalid"></span>\n </b-col>\n <b-col md="11">\n <b-card-body class="align-items-center">\n <i class="fa fa-exclamation"></i> {{text.error}}\n <a href=\'#\' @click=\'$emit("deleterq")\' class="text-danger"\n ><i class="fa fa-trash"></i></a>\n </b-card-body>\n </b-col>\n </b-row>\n </b-card>\n </div>\n '}),Vue.component("t-item-course",{props:{value:{type:Object,default:function(){return null}},plan:{type:Object,default:function(){return null}},page:{type:Object,default:function(){return null}},period:{type:Object,default:function(){return null}},maxspan:{type:Number,default:function(){return 0}}},data:function(){return{condition_options:string_keys.conditions,text:strings.item_course_text}},computed:{useItemConditions:function(){return!(!this.plan||!this.plan.aggregation_info||void 0===this.plan.aggregation_info.useItemConditions)&&this.plan.aggregation_info.useItemConditions},configurationState:function(){return this.hasGrades()||this.hasCompletions()?"t-configured-ok":"t-configured-alert"},configurationIcon:function(){return this.hasGrades()||this.hasCompletions()?"check":"exclamation-circle"},startdate:function(){return(0,_dateHelper.format_date)(this.value.course.startdate)},enddate:function(){return this.value.course.enddate?(0,_dateHelper.format_date)(this.value.course.enddate):this.text.noenddate}},methods:{hasGrades:function(){if(this.value.course.grades&&this.value.course.grades.length>0){var _step,_iterator=_createForOfIteratorHelper(this.value.course.grades);try{for(_iterator.s();!(_step=_iterator.n()).done;){if(_step.value.selected)return!0}}catch(err){_iterator.e(err)}finally{_iterator.f()}}return!1},hasCompletions:function(){if(this.value.course.completion&&this.value.course.completion.conditions){var _step2,_iterator2=_createForOfIteratorHelper(this.value.course.completion.conditions);try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var cgroup=_step2.value;if(cgroup.items&&cgroup.items.length>0)return!0}}catch(err){_iterator2.e(err)}finally{_iterator2.f()}}return!1},includeChanged:function(newValue,g){(0,_ajax.call)([{methodname:"local_treestudyplan_include_grade",args:{grade_id:g.id,item_id:this.value.id,include:newValue,required:g.required}}])[0].fail(_notification.default.exception)},requiredChanged:function(newValue,g){(0,_ajax.call)([{methodname:"local_treestudyplan_include_grade",args:{grade_id:g.id,item_id:this.value.id,include:g.selected,required:newValue}}])[0].fail(_notification.default.exception)},updateConditions:function(){(0,_ajax.call)([{methodname:"local_treestudyplan_edit_studyitem",args:{id:this.value.id,conditions:this.value.conditions}}])[0].fail(_notification.default.exception)}},created:function(){},template:'\n <div class="t-item-course">\n <b-card no-body >\n <div class=\'d-flex flex-wrap mr-0 ml-0\'>\n <div>\n <span\n :title="text[\'coursetiming_\'+value.course.timing]"\n v-b-popover.hover.top="startdate+\' - \'+enddate"\n :class="\'t-timing-indicator timing-\'+value.course.timing"></span>\n </div>\n <div class="flex-fill align-items-center">\n <b-card-body >\n <a class="t-item-course-config"\n v-b-modal="\'t-item-course-config-\'+value.id"\n href="#" @click.prevent=""\n ><i :class="\'fa fa-\'+configurationIcon+\' \' + configurationState"></i></a>\n <a v-b-modal="\'t-item-course-config-\'+value.id"\n :id="\'t-item-course-details-\'+value.id"\n :href="\'/course/view.php?id=\'+value.course.id"\n @click.prevent.stop="">{{ value.course.displayname }}</a>\n </b-card-body>\n </div>\n </div>\n <b-modal class=""\n :id="\'t-item-course-config-\'+value.id"\n :title="value.course.displayname + \' - \' + value.course.fullname"\n ok-only\n size="lg"\n scrollable\n class="b-modal-justify-footer-between"\n >\n <template #modal-header>\n <div>\n <h1><a :href="\'/course/view.php?id=\'+value.course.id" target="_blank"\n ><i class="fa fa-graduation-cap"></i> {{ value.course.fullname }}</a>\n <a v-if=\'!!value.course.completion\'\n :href="\'/course/completion.php?id=\'+value.course.id" target="_blank"\n :title="text.configure_completion"><i class="fa fa-gear"></i></a>\n </h1>\n {{ value.course.context.path.join(" / ")}} / {{value.course.shortname}}\n </div>\n <div class="r-course-detail-header-right">\n <div :class="\'r-timing-\'+value.course.timing">\n {{text[\'coursetiming_\'+value.course.timing]}}<br>\n {{ startdate }} - {{ enddate }}\n </div>\n <t-item-timing-checker\n class="mt-1"\n :maxspan="maxspan"\n :page="page"\n :period="period"\n v-model="value"\n ></t-item-timing-checker>\n </div>\n </template>\n\n <t-item-course-grades\n v-if=\'!!value.course.grades && value.course.grades.length > 0\'\n v-model=\'value\' :plan="plan"\n ></t-item-course-grades>\n <t-item-course-completion\n v-if=\'!!value.course.completion\'\n v-model=\'value.course.completion\'\n :course=\'value.course\'\n ></t-item-course-completion>\n\n <template #modal-footer="{ ok, cancel, hide }" >\n <a href=\'#\' @click=\'$emit("deleterq")\' class="text-danger"\n ><i class="fa fa-trash"></i>\n {{ text.delete }}\n </a>\n <b-button size="sm" variant="primary" @click="ok()">\n {{ text.ok }}\n </b-button>\n </template>\n </b-modal>\n </b-card></div>\n '}),Vue.component("t-item-course-grades",{props:{value:{type:Object,default:function(){return null}},plan:{type:Object,default:function(){return null}}},data:function(){return{condition_options:string_keys.conditions,text:strings.item_course_text}},computed:{useRequiredGrades:function(){return!(!this.plan||!this.plan.aggregation_info||void 0===this.plan.aggregation_info.useRequiredGrades)&&this.plan.aggregation_info.useRequiredGrades},selectedgrades:function(){var list=[];for(var ix in this.value.course.grades){var g=this.value.course.grades[ix];g.selected&&list.push(g)}return list}},methods:{includeChanged:function(newValue,g){(0,_ajax.call)([{methodname:"local_treestudyplan_include_grade",args:{grade_id:g.id,item_id:this.value.id,include:newValue,required:g.required}}])[0].fail(_notification.default.exception)},requiredChanged:function(newValue,g){(0,_ajax.call)([{methodname:"local_treestudyplan_include_grade",args:{grade_id:g.id,item_id:this.value.id,include:g.selected,required:newValue}}])[0].fail(_notification.default.exception)}},created:function(){},template:'\n <div>\n <b-form-group\n :label="text.select_grades"\n ><ul class="t-item-module-children">\n <li class="t-item-course-gradeinfo">\n <span class=\'t-item-course-chk-lbl\'>{{text.grade_include}}</span\n ><span v-if="useRequiredGrades" class=\'t-item-course-chk-lbl\'>{{text.grade_require}}</span>\n </li>\n <li class="t-item-course-gradeinfo" v-for="g in value.course.grades">\n <b-form-checkbox inline\n @change="includeChanged($event,g)" v-model="g.selected"\n ></b-form-checkbox>\n <b-form-checkbox v-if="useRequiredGrades" inline :disabled="!g.selected"\n @change="requiredChanged($event,g)" v-model="g.required"\n ></b-form-checkbox>\n <span :title="g.typename" v-html="g.icon"></span>\n <s-edit-mod\n :title="value.course.fullname"\n @saved="(fd) => g.name = fd.get(\'name\')"\n v-if="g.cmid > 0"\n :cmid="g.cmid"\n :coursectxid="value.course.ctxid"\n genericonly><span v-html="g.name"></span></s-edit-mod>\n </li>\n </ul>\n </b-form-group>\n </div>\n '}),Vue.component("t-item-course-completion",{props:{value:{type:Object,default:function(){return{}}},guestmode:{type:Boolean,default:!1},course:{type:Object,default:function(){return{}}}},data:function(){return{text:strings.completion}},created:function(){var self=this,stringkeys=[];for(var key in this.text)stringkeys.push({key:key,component:"local_treestudyplan"});(0,_str.get_strings)(stringkeys).then((function(strings){var i=0;for(var _key in self.text)self.text[_key]=strings[i],i++}))},computed:{hasCompletions:function(){if(this.value.conditions){var _step3,_iterator3=_createForOfIteratorHelper(this.value.conditions);try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){var cgroup=_step3.value;if(cgroup.items&&cgroup.items.length>0)return!0}}catch(err){_iterator3.e(err)}finally{_iterator3.f()}}return!1}},methods:{completion_icon:function(completion){switch(completion){case"progress":return"exclamation-circle";case"complete":case"complete-pass":return"check-circle";case"complete-fail":return"times-circle";default:return"circle-o"}},completion_tag:function(cgroup){return cgroup.completion?"completed":"incomplete"}},template:"\n <table class=\"r-item-course-grade-details\">\n <tr v-if=\"hasCompletions\">\n <td colspan='2'><span v-if=\"value.aggregation == 'all'\">{{ text.aggregation_overall_all}}</span\n ><span v-else>{{ text.aggregation_overall_any}}</span></td>\n </tr>\n <tr v-else>\n <td colspan='2'>{{text.completion_not_configured}}!\n <br/><a :href=\"'/course/completion.php?id='+course.id\" target='_blank'>{{text.configure_completion}}</a>\n </td>\n </tr>\n <template v-for='cgroup in value.conditions'>\n <tr>\n <th colspan='2'><span v-if=\"cgroup.items.length > 1\"\n ><span v-if=\"cgroup.aggregation == 'all'\">{{ text.aggregation_all}}</span\n ><span v-else>{{ text.aggregation_any}}</span></span>\n {{cgroup.title}}</th>\n </tr>\n <tr v-for='ci in cgroup.items'>\n <td><span v-html='ci.details.criteria'></span>\n </td>\n <td v-if=\"ci.details.requirement\" class=\"font-italic\">\n {{ci.details.requirement}}\n </td>\n </tr>\n </template>\n </table>\n "}),Vue.component("t-item-junction",{props:{value:{type:Object,default:function(){return{}}}},data:function(){return{condition_options:string_keys.conditions}},methods:{},template:"\n <div class='t-item-junction t-item-filter'>\n <i class=\"fa fa-check-circle\"></i>\n </div>\n "}),Vue.component("t-item-finish",{props:{value:{type:Object,default:function(){return{}}}},data:function(){return{}},methods:{},template:"\n <div class='t-item-finish t-item-filter'>\n <i class=\"fa fa-stop-circle\"></i>\n </div>\n "}),Vue.component("t-item-start",{props:{value:{type:Object,default:function(){return{}}}},data:function(){return{}},created:function(){},methods:{},template:"\n <div class='t-item-start t-item-filter'>\n <i class=\"fa fa-play-circle\"></i>\n </div>\n "}),Vue.component("t-item-badge",{props:{value:{type:Object,default:function(){return{badge:{}}}}},data:function(){return{txt:strings,text:strings.item_text}},methods:{},template:'\n <div class=\'t-item-badge t-item-filter\' v-b-tooltip.hover :title="value.badge.name">\n <svg class="t-badge-backdrop " width=\'50px\' height=\'50px\' viewBox="0 0 100 100">\n <title>{{value.badge.name}}</title>\n <circle cx="50" cy="50" r="46"\n style="stroke: currentcolor; stroke-width: 4; fill: currentcolor; fill-opacity: 0.5;"/>\n <image class="badge-image" clip-path="circle() fill-box"\n :href="value.badge.imageurl" x="12" y="12" width="76" height="76"/>\n </svg>\n <a class="t-item-config badge"\n v-b-modal="\'t-item-badge-details-\'+value.id" href="#" @click.prevent=""><i class="fa fa-gear"></i></a>\n <b-modal class=""\n :id="\'t-item-badge-details-\'+value.id"\n :title="value.badge.name"\n size="lg"\n ok-only\n centered\n scrollable\n class="b-modal-justify-footer-between"\n >\n <template #modal-header>\n <div>\n <h1><i class="fa fa-certificate"></i>\n <a :href="value.badge.infolink" target="_blank"\n >{{ value.badge.name }}</a\n ></h1>\n </div>\n </template>\n <b-container fluid>\n <b-row><b-col cols="3">\n <img :src="value.badge.imageurl"/>\n </b-col><b-col cols="9">\n <p>{{value.badge.description}}</p>\n <ul class="list-unstyled w-100 border-grey border-top border-bottom pt-1 pb-1 mb-1"\n v-if="value.badge.criteria"><li v-for="crit in value.badge.criteria"\n ><span v-html=\'crit\'></span></li></ul>\n <p><strong><i class="fa fa-link"></i>\n <a :href="value.badge.infolink">{{ txt.badge.badgeinfo }}</a></strong></p>\n </b-col></b-row>\n </b-container>\n <template #modal-footer="{ ok, cancel, hide }" >\n <a href=\'#\' @click=\'$emit("deleterq")\' class="text-danger"\n ><i class="fa fa-trash"></i>\n {{ text.delete }}\n </a>\n <b-button size="sm" variant="primary" @click="ok()">\n {{ text.ok }}\n </b-button>\n </template>\n </b-modal>\n\n </div>\n '}),Vue.component("t-coursecat-list",{props:{value:{type:Array,default:function(){return{}}}},data:function(){return{}},methods:{},template:'\n <ul class="t-coursecat-list">\n <t-coursecat-list-item\n v-for="coursecat,idx in value"\n v-model="value[idx]"\n :key="coursecat.id"></t-coursecat-list-item>\n </ul>\n '}),Vue.component("t-coursecat-list-item",{props:{value:{type:Object,default:function(){return{}}}},data:function(){return{loading:!1}},computed:{showSpinner:function(){return this.canLoadMore()},hasDetails:function(){return this.value.haschildren||this.value.hascourses}},methods:{canLoadMore:function(){return this.value.haschildren&&(!this.value.children||0==this.value.children.length)||this.value.hascourses&&(!this.value.courses||0==this.value.courses.length)},onShowDetails:function(){var self=this;this.canLoadMore()&&(0,_ajax.call)([{methodname:"local_treestudyplan_get_category",args:{id:this.value.id}}])[0].done((function(response){self.$emit("input",response)})).fail(_notification.default.exception)}},template:'\n <li class="t-coursecat-list-item">\n <span v-if="hasDetails" v-b-toggle="\'coursecat-\'+value.id">\n <i class="when-closed fa fa-caret-right"></i>\n <i class="when-open fa fa-caret-down"></i>\n <span class="t-coursecat-heading">\n <i class="t-coursecat-list-item fa fa-tasks"></i>\n {{ value.category.name }}\n </span>\n </span>\n <span v-else>\n <span class="t-coursecat-heading">\n <i class="t-coursecat-list-item fa fa-tasks"></i>\n {{ value.category.name }}\n </span>\n </span>\n <b-collapse v-if="hasDetails" :id="\'coursecat-\'+value.id"\n @show="onShowDetails" :visible="!!(value.children) || !!(value.courses)">\n <b-spinner class="ml-4" v-if="showSpinner" small variant="primary"></b-spinner>\n <t-coursecat-list v-if="value.children" v-model="value.children"></t-coursecat-list>\n <t-course-list v-if="value.courses" v-model="value.courses"></t-course-list>\n </b-collapse>\n </li>\n '}),Vue.component("t-course-list",{props:{value:{type:Array,default:function(){return{}}}},data:function(){return{}},methods:{makeType:function(){return{item:!1,component:!0,span:1,type:"gradable"}}},template:'\n <ul class="t-course-list">\n <li class="t-course-list-item" v-for="course in value" :key="course.id">\n <drag\n class="draggable-course"\n :data="course"\n :type="makeType()"\n @cut=""\n >\n <i class="t-course-list-item fa fa-book"></i> {{ course.shortname }} - {{ course.fullname }}\n </drag>\n </li>\n </ul>\n '})}};return _exports.default=_default2,_exports.default}));
|
|
|
|
//# sourceMappingURL=studyplan-editor-components.min.js.map
|