define([ "config", "form_validation_conf", "datatables_conf", "utils", "storage_utils", "constants", "tag_conf", "text!template/changelist.html", "text!conf/domain_tag.txt", "text!conf/unofficial_maps.txt", "branches_for_preflight", "jquery", "underscore", "backbone", "dataTables", "DT_bootstrap", "jquery.validate", "select2", ], function(config, form_validation_conf, datatables_conf, utils, storage_utils, constants, tag_conf, tmpl_changelist, domain_txt, unofficial_map_txt,branches_for_preflight){ /** * Changelist view, manage all the fields of the description, the files and the options. */ var ChangelistView = Backbone.View.extend({ el: "#cl_content", type_SA: "", collection: undefined, model: undefined, domain_tag: [], official_map: [], unofficial_map: [], files_length: 0, selected_files_length: 0, $submit_form: [], $selected_files: [], $files_table: [], events: { "change #check_all_files": "checkAllFiles", "change .validation_field": "validateFields", "keyup .validation_field": "validateFields", "focusout .changelist_field": "saveField", "change #jira_tag": "jiraSelected", }, /** * See Backbone documentation. * * @param type_SA - the type of the SA. * @param model - the changelist model. * @param filesCollection - the files collection. */ initialize: function() { this.type_SA = this.options.type_SA; this.collection = this.options.filesCollection; this.files_length = this.collection.length; this.selected_files_length = this.files_length; if (this.type_SA === constants.type_data) { this.getDataTags(); } this.render(); if (this.type_SA === constants.type_code) { this.model.set("use_preflight_tag",branches_for_preflight.usePreflightTag(this.collection)); this.$(".tooltip_element").tooltip(); this.$submit_form.validate(form_validation_conf.code_description); } else if (this.type_SA === constants.type_data) { this.model.set("use_preflight_tag",true); //select2 selects don't react on focusout, bind change event instead to save them dynamically this.$(".select2").select2() .on("change", $.proxy(this.saveField, this)); this.$submit_form.validate(form_validation_conf.data_description); } this.validateFields(); if (this.type_SA === constants.type_code) { // adding the events to refresh the view as and when the jira data for the user is available this.model.bind('change:jira_id_description', this.modelHasChanged, this); this.model.bind('change:failedToReachTeabuddy', this.jiraDataNotAvailable, this); } if (this.model.get("isDefaultChangelist") == true) this.noPreflightForDefaultChangelist(this.type_SA); }, modelHasChanged: function() { this.render(); if(this.model.get("isDefaultChangelist") == true) this.noPreflightForDefaultChangelist(this.type_SA); if(this.model.get("failedToReachTeabuddy") == true) this.jiraDataNotAvailable(); if(this.type_SA === constants.type_code){ this.$(".tooltip_element").tooltip(); this.$submit_form.validate(form_validation_conf.code_description); } this.validateFields(); }, jiraSelected: function () { var jira_tag = this.model.get("jira_tag"); jira_tag = []; var jira_value = $("#jira_tag").val(); jira_tag = _.union(jira_tag, [jira_value]); this.model.set("jira_tag", jira_tag.sort()); }, jiraDataNotAvailable: function() { $("#jira_tag").hide().fadeOut('fast'); var inforString = "Could not reach TeaBox. To get JIRA information, launch TeaBox, right click on the page and refresh"; document.getElementById("teaBuddyError").innerHTML = "Error! " + inforString; document.getElementById("teaBuddyError").style.display = "block"; }, noPreflightForDefaultChangelist: function (type) { var inforString = "Oops ! You cannot submit 'default' changelist."; if (type === constants.type_code) { inforString = inforString + " No 'Preflight and Submit' possible"; } else if (type === constants.type_data) { inforString = inforString + " Move your changes to another changelist and try submitting"; } document.getElementById("defaultChangelistError").innerHTML = "Error! " + inforString; document.getElementById("defaultChangelistError").style.display = "block"; }, render: function () { var viewModel = this; var template = _.template(tmpl_changelist, { type_SA: this.type_SA, config: config, collection: this.collection.toJSON(), constants: constants, model: this.model.toJSON(), type_tag: tag_conf.type_tag, domain_tag: this.domain_tag, unofficial_map: this.unofficial_map, official_map: this.official_map, }); this.$el.html(template); this.$submit_form = this.$("#submit_form"); this.$selected_files = this.$("#selected_files"); this.$files_table = this.$("#files_table"); if(this.$files_table.length > 0){ var options = datatables_conf.fileOptions(this.collection.toJSON()); var table = this.$files_table.dataTable(options); //set context with fnGetNode to select all checkboxes, even hidden ones (with pagination) this.$files_ck = $(".files_ck", table.fnGetNodes()); //manage change events on files checkboxes this.$files_ck.on("change", $.proxy(this.checkFile, this)); } if (this.type_SA === constants.type_code) { $(".jiratags").select2({ allowClear: true }); $(".scopetag").select2({ tags: true, allowClear: true, tokenSeparators: [','], data: viewModel.model.get("scope_tag_content"), }); $(".reviewerfield").select2({ tags: true, allowClear: true, tokenSeparators: [','], data: viewModel.model.get("reviewer_field_content"), }); // handling scope tag related changes $('.scopetag').on("select2:selecting", function (event) { var originalevent = event.params.args.originalEvent; var selectedElement = event.params.args.data.text; if (originalevent === undefined && !(/\s/.test(selectedElement))){ var elements = viewModel.model.get("scope_tag_content"); var foundElement = _.find(elements, function(item) { return item.text.toLowerCase() == selectedElement.toLowerCase(); }); if (foundElement == undefined) { elements.push({ id: selectedElement, text: selectedElement }); viewModel.model.saveScopeTags(); } } viewModel.model.set("scope_tag", selectedElement); }); $('.scopetag').on("select2:select", function (event) { var selectedElements = JSON.stringify($('.scopetag').val()).replace(/[^A-Z0-9,\s]+/ig, ""); viewModel.model.set("scope_tag", selectedElements); }); $('.scopetag').on("select2:unselect", function (event) { var selectedElements = JSON.stringify($('.scopetag').val()).replace(/[^A-Z0-9,\s]+/ig, ""); viewModel.model.set("scope_tag", selectedElements); }); // handling reviewer tag related changes $('.reviewerfield').on("select2:selecting", function (event) { var originalevent = event.params.args.originalEvent; var selectedElement = event.params.args.data.text; if (originalevent === undefined && !(/\s/.test(selectedElement))) { var elements = viewModel.model.get("reviewer_field_content"); var foundElement = _.find(elements, function (item) { return item.text.toLowerCase() == selectedElement.toLowerCase(); }); if (foundElement == undefined) { elements.push({ id: selectedElement, text: selectedElement }); viewModel.model.saveReviewerFields(); } } viewModel.model.set("reviewer_field", selectedElement); }); $('.reviewerfield').on("select2:select", function (event) { var selectedElements = JSON.stringify($('.reviewerfield').val()).replace(/[^A-Z0-9,\s]+/ig, ""); viewModel.model.set("reviewer_field", selectedElements); }); $('.reviewerfield').on("select2:unselect", function (event) { var selectedElements = JSON.stringify($('.reviewerfield').val()).replace(/[^A-Z0-9,\s]+/ig, ""); viewModel.model.set("reviewer_field", selectedElements); }); } }, /** * Get all the tags for data submit assistant. * Get domain tags and unofficial maps from text configuration files. * Get official maps from server. */ getDataTags: function() { var scope = this; this.domain_tag = utils.parseTags(domain_txt); this.unofficial_map = utils.parseTags(unofficial_map_txt); var official_map_txt = storage_utils.getOfficialMaps(); this.official_map = utils.parseTags(official_map_txt, utils.trimOfficialMap); this.getOfficialMapsFromLocalFile(); }, getOfficialMapsFromLocalFile: function () { var scope = this; var request = jQuery.ajax({ type: "GET", url: "http://127.0.0.1:4242?name=GetMapsInLocalMaplist", }); request.done(function (response) { var official_local_maps = []; var obj = JSON.parse(response); if (obj != null) { for (var index = 0; index < obj.length; index++) { var tag = obj[index]; // check if its a valid tag if (/^[\w,/.]+$/.test(tag)) { var value = utils.trimOfficialMap(tag); if (!value) { continue; } tag = value; } official_local_maps.push(tag); } var earlier_loaded_maps = scope.official_map; var uniondata = _.union(earlier_loaded_maps, official_local_maps); var newlist = _.uniq(uniondata); newlist = _.sortBy(newlist, function (name) { return name; }); scope.official_map = newlist; scope.render(); // hack :S scope.$(".select2").select2().on("change", $.proxy(scope.saveField, scope)); scope.$submit_form.validate(form_validation_conf.data_description); } console.log("Something went wrong, you did not received the newly added"); return null; }); request.fail(function (response) { console.log("Unable to reach TeaBox"); return null; }); }, /** * Collect and return the submit options. * * @return - a string containing the submit options */ getSubmitOptions: function(){ var fileOpt = " -f "; switch (this.$("#on_submit option:selected").val()) { case "submitunchanged": fileOpt += "submitunchanged"; break; case "leaveunchanged": fileOpt += "leaveunchanged"; break; case "revertunchanged": fileOpt += "revertunchanged"; break; } if(this.$("#recheckout").prop("checked")){ fileOpt += "+reopen"; } if(this.$("#donotsubmit").prop("checked")){ fileOpt += " -t"; } return fileOpt; }, /** * Check description validity (onKeyUp and onChange) */ validateFields: function () { if(this.$submit_form.valid()){ this.model.set("is_valid", true); } else { this.model.set("is_valid", false); } }, /** * Save a field (onFocusOut (onChange for select2 selects)) * * @param event - the triggered event */ saveField: function(event){ var $element = this.$(event.target); var name = $element.attr("name"); var value = $.trim($element.val()); this.model.set(name, value); }, // Check to see if the user wants to close the associated JIRA getJIRAToBeClosedStatus : function() { var status = false; var jira_tag = this.model.get("jira_tag"); if (jira_tag.length > 0 && jira_tag[0] != null) status = true; return status; }, /** * Update model and view after a file is checked / unchecked. * * @param event - the triggered event */ checkFile: function(event){ var file_id = event.target.value; var checked = event.target.checked; var file = this.collection.get(file_id) if(checked){ this.selected_files_length++; file.set("is_selected", true); } else{ file.set("is_selected", false); this.selected_files_length--; } this.$selected_files.html(this.selected_files_length); }, /** * Check / Uncheck all files. * * @param event - the triggered event */ checkAllFiles: function(event){ var checked = event.target.checked; this.$files_ck.prop("checked", checked); for(var i = 0, length = this.collection.length ; i < length ; i++){ this.collection.at(i).set("is_selected", checked); } this.selected_files_length = checked ? this.files_length : 0; this.$selected_files.html(this.selected_files_length); }, }); return ChangelistView; });