diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/DataSetViewer.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/DataSetViewer.js new file mode 100644 index 0000000000000000000000000000000000000000..cfa960a15772f202efee821a482c2348c81dcbaf --- /dev/null +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/DataSetViewer.js @@ -0,0 +1,357 @@ +/* + * Copyright 2014 ETH Zuerich, Scientific IT Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Creates an instance of DataSetViewer. + * + * @constructor + * @this {DataSetViewer} + * @param {String} containerId The container where the DataSetViewer will be atached. + * @param {String} profile Global configuration. + * @param {Sample} sample The sample where to check for the data. + * @param {ServerFacade} serverFacade Point of contact to make calls to the server + * @param {String} datastoreDownloadURL The datastore url in format http://localhost:8889/datastore_server. + * @param {Map} datasets API result with the datasets to show. + * @param {Boolean} enableUpload If true, the button to create datasets is shown, this will require the sample to be present. + */ +function DataSetViewer(containerId, profile, sample, serverFacade, datastoreDownloadURL, datasets, enableUpload) { + this.containerId = containerId; + this.profile = profile; + this.containerIdTitle = containerId + "-title"; + this.containerIdContent = containerId + "-content"; + this.serverFacade = serverFacade; + this.sample = sample; + this.datasets = datasets; + this.enableUpload = enableUpload; + this.sampleDataSets = {}; + this.sampleDataSetsFiles = {}; + this.datastoreDownloadURL = datastoreDownloadURL + + this._isPreviewable = function(file) { + if(!file.isDirectory) { + var haveExtension = file.pathInDataSet.lastIndexOf("."); + if( haveExtension !== -1 && (haveExtension + 1 < file.pathInDataSet.length)) { + var extension = file.pathInDataSet.substring(haveExtension + 1, file.pathInDataSet.length).toLowerCase(); + + return extension === "svg" || + extension === "jpg" || extension === "jpeg" || + extension === "png" || + extension === "gif" || + extension === "html" || + extension === "pdf"; + } + } + return false; + } + + this._isImage = function(file) { + if(!file.isDirectory) { + var haveExtension = file.pathInDataSet.lastIndexOf("."); + if( haveExtension !== -1 && (haveExtension + 1 < file.pathInDataSet.length)) { + var extension = file.pathInDataSet.substring(haveExtension + 1, file.pathInDataSet.length).toLowerCase(); + + return extension === "jpg" || extension === "jpeg" || + extension === "png" || + extension === "gif"; + } + } + return false; + } + + this._init = function(datasets) { + // + // Loading Message + // + var $container = $("#"+this.containerId); + $container.empty(); + + var $containerTitle = $("<div>", {"id" : this.containerIdTitle }); + $container.append($containerTitle); + $container.append($("<div>", {"id" : this.containerIdContent })); + + $containerTitle.append($("<legend>").html("Files")); + $containerTitle.append($("<p>") + .append($("<span>", { class: "glyphicon glyphicon-info-sign" })) + .append(" Loading datasets.")); + + // + // + // + var localReference = this; + var listFilesCallList = []; + + var callback = function() { //Just enqueues the next call + var getCall = listFilesCallList.pop(); + if(getCall) { + getCall(callback); + } else { + //Switch Title + $containerTitle.empty(); + + //Upload Button + var $uploadButton = ""; + if(enableUpload) { + $uploadButton = $("<a>", { class: "btn btn-default" }).append($("<span>", { class: "glyphicon glyphicon-upload" })); + $uploadButton.click(function() { + mainController.changeView('showCreateDataSetPageFromPermId',localReference.sample.permId); //TO-DO Fix Global Access + }); + } + + $containerTitle.append($("<legend>").append("Files ").append($uploadButton)); + + //Switch + $containerTitle.append(localReference._getSwitch()); + + //Repaint + localReference.repaintImages(); + } + } + + for(var i = 0; i < datasets.result.length; i++) { //DataSets for sample + var dataset = datasets.result[i]; + var listFilesForDataSet = function(dataset){ return function() { //Files in dataset + localReference.serverFacade.listFilesForDataSet(dataset.code, "/", true, function(files) { + localReference.sampleDataSets[dataset.code] = dataset; + localReference.sampleDataSetsFiles[dataset.code] = files.result; + callback(); + }); + }} + listFilesCallList.push(listFilesForDataSet(dataset)); + } + + callback(); + } + + this.init = function() { + // + // Loading the datasets + // + var cleanSample = $.extend({}, this.sample); + delete cleanSample.parents; + delete cleanSample.children; + + if(datasets) { + this._init(datasets); + } else { + var localReference = this; + this.serverFacade.listDataSetsForSample(cleanSample, true, function(datasets) { + localReference._init(datasets); + }); + } + } + + this._getSwitch = function() { + var _this = this; + var $switch = $("<div>", {"class" : "switch-toggle well", "style" : "width:33%; margin-left: auto; margin-right: auto; min-height: 38px !important;"}); + $switch.change(function(event) { + var mode = $('input[name=dataSetVieweMode]:checked').val(); + switch(mode) { + case "imageMode": + _this.repaintImages(); + break; + case "fileMode": + _this.repaintFiles(); + break; + } + }); + + $switch + .append($("<input>", {"value" : "imageMode", "id" : "imageMode", "name" : "dataSetVieweMode", "type" : "radio", "checked" : ""})) + .append($("<label>", {"for" : "imageMode", "onclick" : "", "style" : "padding-top:3px;"}).append("Images")) + .append($("<input>", {"value" : "fileMode", "id" : "fileMode","name" : "dataSetVieweMode", "type" : "radio"})) + .append($("<label>", {"for" : "fileMode", "onclick" : "", "style" : "padding-top:3px;"}).append("Files")); + + $switch.append($("<a>", {"class" : "btn btn-primary"})); + return $switch; + } + + this._isDisplayed = function(dataSetTypeCode, fileName) { + var passes = false; + this.profile.dataSetViewerConf["DATA_SET_TYPES"].forEach(function(type) { + var datasetTypePattern = new RegExp(type, "") + passes = passes || datasetTypePattern.test(dataSetTypeCode); + }); + + if (!passes) { + return false; + } + + passes = false; + this.profile.dataSetViewerConf["FILE_NAMES"].forEach(function(name) { + var fileNamePattern = new RegExp(name, "") + passes = passes || fileNamePattern.test(fileName); + }); + + return passes; + } + + this._repaintTestsPassed = function($container) { + // + // No data store URL + // + if(datastoreDownloadURL === null) { + $container.append($("<p>") + .append($("<span>", { class: "glyphicon glyphicon-ban-circle" })) + .append(" Please configure properly your DSS server properly, looks like is not reachable.")); + return false; + } + + // + // Don't paint data sets for entities that don't have + // + var numberOfDatasets = 0; + for(var datasetCode in this.sampleDataSets) { + numberOfDatasets++; + } + + if(numberOfDatasets === 0) { + $container.append($("<p>") + .append($("<span>", { class: "glyphicon glyphicon-info-sign" })) + .append(" No datasets found.")); + return false; + } + + return true; + } + this.repaintImages = function() { + var $container = $("#"+this.containerIdContent); + $container.empty(); + + if(!this._repaintTestsPassed($container)) { + return; + } + + for(var datasetCode in this.sampleDataSets) { + var dataset = this.sampleDataSets[datasetCode]; + var datasetFiles = this.sampleDataSetsFiles[datasetCode]; + + if(!datasetFiles) { + $container.append($("<p>") + .append($("<span>", { class: "glyphicon glyphicon-ban-circle" })) + .append(" Please configure properly trusted-cross-origin-domains for this web app, datasets can't be retrieved from the DSS server.")); + return; + } + } + // + _this = this; + var maxImages = 30; + var numImages = 0; + for(var datasetCode in this.sampleDataSets) { + var dataset = this.sampleDataSets[datasetCode]; + var datasetFiles = this.sampleDataSetsFiles[datasetCode]; + + datasetFiles.forEach( + function(file) { + if (numImages < maxImages && _this._isImage(file) && _this._isDisplayed(dataset.dataSetTypeCode, file.pathInDataSet)) { + var $image = $("<img>", {"class" : "zoomableImage", "style" : "width:300px", "src" : _this.datastoreDownloadURL + '/' + dataset.code + "/" + file.pathInDataSet + "?sessionID=" + _this.serverFacade.getSession()}); + $image.css({ + "margin-right" : "10px" + }); + $image.click(function() { + Util.showImage($image.attr("src")); + }); + $container.append($image); + numImages++ + } + }); + } + + if(numImages === maxImages) { + $container.append($("<p>") + .append($("<span>", { class: "glyphicon glyphicon-info-sign" })) + .append(" You can't see more than " + maxImages + " image at the same time, please use the file browser mode.")); + } + } + + this.repaintFiles = function() { + var $container = $("#"+this.containerIdContent); + $container.empty(); + + if(!this._repaintTestsPassed($container)) { + return; + } + + // + // Simple Files Table + // + var $dataSetsTable = $("<table>", { class: "table"}); + $dataSetsTable.append( + $("<thead>").append( + $("<tr>") + .append($("<th>").html("DataSet Code")) + .append($("<th>").html("DataSet Type")) + .append($("<th>").html("File Name")) + .append($("<th>").html("File Size (Mbyte)")) + .append($("<th>").html("Preview")) + ) + ); + + var $dataSetsTableBody = $("<tbody>"); + + for(var datasetCode in this.sampleDataSets) { + var dataset = this.sampleDataSets[datasetCode]; + var datasetFiles = this.sampleDataSetsFiles[datasetCode]; + + if(!datasetFiles) { + $container.append($("<p>") + .append($("<span>", { class: "glyphicon glyphicon-ban-circle" })) + .append(" Please configure properly trusted-cross-origin-domains for this web app, datasets can't be retrieved from the DSS server.")); + return; + } + + for(var i = 0; i < datasetFiles.length; i++) { + var $tableRow = $("<tr>") + .append($("<td>").html(dataset.code)) + .append($("<td>").html(dataset.dataSetTypeCode)); + + var downloadUrl = datastoreDownloadURL + '/' + dataset.code + "/" + encodeURIComponent(datasetFiles[i].pathInDataSet) + "?sessionID=" + this.serverFacade.getSession(); + if(datasetFiles[i].isDirectory) { + $tableRow.append($("<td>").html(datasetFiles[i].pathInDataSet)); + $tableRow.append($("<td>")); + } else { + $tableRow.append( + $("<td>").append( + $("<a>").attr("href", downloadUrl) + .attr("download", 'download') + .html(datasetFiles[i].pathInDataSet) + ) + ); + + var sizeInMb = parseInt(datasetFiles[i].fileSize) / 1024 / 1024; + var sizeInMbThreeDecimals = Math.floor(sizeInMb * 1000) / 1000; + $tableRow.append($("<td>").html(sizeInMbThreeDecimals)); + } + + if(this._isPreviewable(datasetFiles[i])) { + $tableRow.append($("<td>").append( + $("<a>") + .attr("href", downloadUrl) + .attr("target", "_blank") + .append($("<span>").attr("class", "glyphicon glyphicon-search")) + ) + ); + } else { + $tableRow.append($("<td>")); + } + + $dataSetsTableBody.append($tableRow); + } + } + + $dataSetsTable.append($dataSetsTableBody); + $container.append($dataSetsTable); + } +} \ No newline at end of file diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleLinksWidget.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleLinksWidget.js new file mode 100644 index 0000000000000000000000000000000000000000..fa099a795689950a650ebee8949a6b0a14098bbc --- /dev/null +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SampleLinksWidget.js @@ -0,0 +1,594 @@ +/* + * Copyright 2014 ETH Zuerich, Scientific IT Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Creates an instance of SampleLinksTable. + * + * This component is used to render the parents of a sample in a friendly manner. + * + * @constructor + * @this {SampleLinksTable} + * @param {string} containerId The Container where the Inspector DOM will be attached. + * @param {Profile} profile The profile to be used, typically, the global variable that holds the configuration for the application. + * @param {boolean} isDisabled Disables the component. + */ +function SampleLinksWidget(containerId, profile, serverFacade, title, sampleTypeHints, isDisabled, samplesToEdit) { + this.containerId = containerId; + this.profile = profile; + this.serverFacade = serverFacade; + this.title = title; + this.sampleTypeHints = sampleTypeHints; + this.isDisabled = isDisabled; + this.samplesToEdit = (samplesToEdit)?samplesToEdit:new Array(); //Only used to populate the widget + this.samples = {}; + this.samplesRemoved = {}; + this.stateObj = {}; + + this._lastUsedId = null; + this._lastIndex = 0; + + this._enableAnnotations = function() { + var enableAnnotations = false; + for(var i = 0; i < this.sampleTypeHints.length; i++) { + var sampleTypeHint = this.sampleTypeHints[i]; + if(sampleTypeHint["ANNOTATION_PROPERTIES"].length > 0) { + enableAnnotations = true; + } + } + return enableAnnotations; + } + + this._writeState = function(sample, propertyTypeCode, propertyTypeValue) { + if(!this._enableAnnotations()) { + return; + } + this._readState(); + + var sampleTypeAnnotations = this.stateObj[sample.permId]; + if(!sampleTypeAnnotations) { + sampleTypeAnnotations = {}; + this.stateObj[sample.permId] = sampleTypeAnnotations; + } + + sampleTypeAnnotations["code"] = sample.code; //Adds code to the annotations if not present + + if(propertyTypeValue === null) { + delete this.stateObj[sample.permId]; + } else { + sampleTypeAnnotations[propertyTypeCode] = propertyTypeValue; + } + + var xmlDoc = "<root>"; + + for(var permId in this.stateObj) { + xmlDoc += "<Sample permId=\"" + permId + "\""; + for(var propertyTypeCode in this.stateObj[permId]) { + if(propertyTypeCode == "code") { + var propertyTypeValue = this.stateObj[permId][propertyTypeCode]; + xmlDoc += " " + propertyTypeCode + "=\"" + propertyTypeValue +"\""; + } + } + + for(var propertyTypeCode in this.stateObj[permId]) { + if(propertyTypeCode != "code") { + var propertyTypeValue = this.stateObj[permId][propertyTypeCode]; + xmlDoc += " " + propertyTypeCode + "=\"" + propertyTypeValue +"\""; + } + } + + xmlDoc += " />"; + } + + xmlDoc += "</root>"; + + $("#ANNOTATIONS_STATE").val(xmlDoc); + + //Compatibility mode for refactored sample form + if(mainController.currentView._sampleFormModel) { + mainController.currentView._sampleFormModel.sample.properties["ANNOTATIONS_STATE"] = xmlDoc; + } + } + + this._readState = function() { + if(!this._enableAnnotations()) { + return; + } + var stateField = $("#ANNOTATIONS_STATE"); + if(stateField.length === 0) { + Util.showError("You need a property with code ANNOTATIONS_STATE on this entity to store the state of the annotations."); + } else { + //Hide State Field + var fieldset = stateField.parent().parent().parent(); + fieldset.hide(); + + //Update Values + this.stateObj = {}; + var stateFieldValue = Util.getEmptyIfNull(stateField.val()); + //Hack to fix for new sample form on view mode + if(mainController.currentView._sampleFormModel && mainController.currentView._sampleFormModel.mode === FormMode.VIEW) { + stateFieldValue = Util.getEmptyIfNull(stateField.text()); + } + // + if(stateFieldValue === "") { + return; + } + var xmlDoc = new DOMParser().parseFromString(stateFieldValue, 'text/xml'); + var samples = xmlDoc.getElementsByTagName("Sample"); + for(var i = 0; i < samples.length; i++) { + var sample = samples[i]; + var permId = sample.attributes["permId"].value; + for(var j = 0; j < sample.attributes.length; j++) { + var attribute = sample.attributes[j]; + if(attribute.name !== "permId") { + if(!this.stateObj[permId]) { + this.stateObj[permId] = {}; + } + this.stateObj[permId][attribute.name] = attribute.value; + } + } + } + } + } + + this._getDefaultSampleHint = function(sampleTypeCode) { + var defaultMinCount = 0; + var defaultProperties = []; + + for(var i = 0; i < sampleTypeHints.length; i++) { + if(sampleTypeHints[i]["TYPE"] === sampleTypeCode) { + defaultMinCount = sampleTypeHints[i]["MIN_COUNT"]; + defaultProperties = sampleTypeHints[i]["ANNOTATION_PROPERTIES"]; + } + } + + var typeToAdd = { + "LABEL" : sampleTypeCode, + "TYPE": sampleTypeCode, + "MIN_COUNT" : defaultMinCount, + "ANNOTATION_PROPERTIES" : defaultProperties + }; + + return typeToAdd; + } + this._addAny = function(id, tableId, sampleId) { + var sampleTypes = this.profile.getAllSampleTypes(); + + var component = "<select id='sampleTypeSelector' class='form-control' required>"; + component += "<option disabled=\"disabled\" selected></option>"; + for(var i = 0; i < sampleTypes.length; i++) { + var sampleType = sampleTypes[i]; + var label = Util.getEmptyIfNull(sampleType.description); + if(label === "") { + label = sampleType.code; + } + + component += "<option value='" + sampleType.code + "'>" + label + "</option>"; + } + component += "</select>"; + + Util.blockUI("Select type: <br><br>" + component + "<br> or <a class='btn btn-default' id='sampleTypeSelectorCancel'>Cancel</a>"); + + $("#sampleTypeSelectorCancel").on("click", function(event) { + Util.unblockUI(); + }); + + var _this = this; + $("#sampleTypeSelector").on("change", function(event) { + var sampleTypeCode = $("#sampleTypeSelector")[0].value; + var sampleType = _this.profile.getSampleTypeForSampleTypeCode(sampleTypeCode); + + if(sampleType !== null) { + if(_this._lastUsedId) { + $('#'+_this._lastUsedId + "-table").empty(); + $("#"+_this._lastUsedId).css({"background-color" : "#FFFFFF" }); + } + + var typeToAdd = _this._getDefaultSampleHint(sampleTypeCode); + _this.addOneSlot(typeToAdd); + Util.unblockUI(); + } + }); + } + + this._getButton = function(id, sampleTypeHint) { + var _this = this; + var tableId = id + "-table"; + var sampleId = id + "-sample"; + var $component = $("<div>", {"id" : id , "class" : "form-inline control-group row", "sample-type-code" : sampleTypeHint["TYPE"], "sample-min-count" : sampleTypeHint["MIN_COUNT"] } ); + $component.css({"border-radius" : "10px", "padding-left" : "10px", "margin-top" : "10px"}); + + var requiredText = ""; + if(sampleTypeHint["MIN_COUNT"] > 0) { + requiredText = " (Required at least " + sampleTypeHint["MIN_COUNT"] + ")"; + } + + var labelText = sampleTypeHint["LABEL"] + requiredText + ":"; + if(sampleTypeHint["LABEL"] === null) { + labelText = ""; + } + var $label = $("<label>", { "class" : "control-label " + FormUtil.labelColumnClass }).text(labelText); + var $controls = $("<div>", { "class" : "controls " + FormUtil.controlColumnClass}); + + var $buttonTextField = $("<a>", {"class" : "btn btn-default", "type" : "button", "id" : sampleId}); + $buttonTextField.css({ + "max-width" : "90%", + "text-align" : "left" + }); + + $buttonTextField.append("Select"); + $controls.append($buttonTextField); + $controls.append(" "); + + var annotations = sampleTypeHint["ANNOTATION_PROPERTIES"]; + var annotationComponents = []; + + for(var i = 0; i < annotations.length; i++) { + var propertyType = this.profile.getPropertyType(annotations[i]["TYPE"]); + propertyType.mandatory = annotations[i]["MANDATORY"]; + var $propertyField = FormUtil.getFieldForPropertyType(propertyType); + if (propertyType.dataType === "BOOLEAN") { + $($propertyField.children()[0]).css({ + 'margin-bottom' : '15px' + }); + } + $propertyField.attr("property-type-code" , annotations[i]["TYPE"]); + $propertyField.prop("disabled", true); + $propertyField.change(function() { + var $field = $(this); + var sample = _this.samples[sampleId]; + var propertyTypeCode = $field.attr("property-type-code"); + var propertyType = _this.profile.getPropertyType(propertyTypeCode) + var propertyTypeValue; + if (propertyType.dataType === "BOOLEAN") { + propertyTypeValue = $field.children().is(":checked"); + } else { + propertyTypeValue = $field.val(); + } + _this._writeState(sample, propertyTypeCode, propertyTypeValue); + }); + + $controls.append(propertyType.label + ": "); + $controls.append($propertyField); + $controls.append(" "); + annotationComponents.push($propertyField); + } + + var $buttonPlusOne = $("<a>", {"class" : "btn btn-default"}); + $buttonPlusOne.append($("<span>", { "class" : "glyphicon glyphicon-plus-sign"})); + $controls.append($buttonPlusOne); + $controls.append(" "); + + var $buttonDelete = $("<a>", {"class" : "btn btn-default"}); + $buttonDelete.append($("<span>", { "class" : "glyphicon glyphicon-minus-sign"})); + $controls.append($buttonDelete); + + if(this.isDisabled) { + $buttonTextField.attr("disabled", ""); + for(var i = 0; i < annotationComponents.length; i++) { + annotationComponents[i].attr("disabled", ""); + } + $buttonPlusOne.attr("disabled", ""); + $buttonDelete.attr("disabled", ""); + } else { + $buttonTextField.click(function(elem) { + var $buttonClicked = $(elem); + var sampleTypeCode = sampleTypeHint["TYPE"]; + var sampleType = _this.profile.getSampleTypeForSampleTypeCode(sampleTypeCode); + + if(sampleType !== null) { + //Clear last state + if(_this._lastUsedId) { + $('#'+_this._lastUsedId + "-table").empty(); + $("#"+_this._lastUsedId).css({"background-color" : "#FFFFFF" }); + } + //Put new state + var onClick = function(sample) { + $('#'+_this._lastUsedId + "-table").empty(); + $("#"+_this._lastUsedId).css({"background-color" : "#FFFFFF" }); + _this.removeSample(sampleId); + _this.addSample(sample); + $("#" + id).css({"background-color" : "#FFFFFF" }); + } + $("#" + id).css({"border-radius" : "10px", "padding" : "10px", "background-color" : "#EEEEEE" }); + var sampleTable = new SampleTable(_this.serverFacade,tableId,_this.profile, sampleTypeCode, false, false, onClick, false, true); + sampleTable.init(); + //Store new state + _this._lastUsedId = id; + } else { + _this._addAny(id, tableId, sampleId); + } + }); + + $buttonPlusOne.click(function(elem) { + _this.addOneSlot(sampleTypeHint); + }); + $buttonDelete.click(function(elem) { + _this.removeSample(sampleId); + }); + } + + $component.append($label); + $component.append($controls); + + $component.append($("<div>", { "id" : tableId})); + return $component; + } + + this._getPlus = function() { + var id = this.containerId + "-plus-button"; + var tableId = id + "-table"; + var $component = $("<div>", { "id" : id, "class" : "form-group", "style" : 'padding: 10px 0px 0px 10px'} ); + var $controls = $("<div>", { "class" : "col-md-12"}); + + var $buttonPlus = $("<a>", {"class" : "btn btn-default"}); + $buttonPlus.append($("<span>", { "class" : "glyphicon glyphicon-plus-sign"})); + $controls.append($buttonPlus); + + if(this.isDisabled) { + $buttonPlus.attr("disabled", ""); + } else { + var _this = this; + var onClick = function(elem) { + _this._addAny(id, tableId, null); + }; + $buttonPlus.click(onClick); + } + + $component.append($controls); + $component.append($("<div>", { "id" : tableId})); + return $component; + } + + this.repaint = function() { + $('#'+this.containerId).empty(); + + //Create Component + var $component = $("<fieldset>"); + $component.append($("<legend>").text(this.title)) + $component.append(this._getPlus()); + $('#'+this.containerId).append($component); + + //Add predefined slots + for(var i = 0; i < this.sampleTypeHints.length; i++) { + this.addOneSlot(sampleTypeHints[i]); + } + + //Initialize annotations from property + this._readState(); + + //Add sample links to edit + for(var i = 0; i < this.samplesToEdit.length; i++) { + this.addSample(this.samplesToEdit[i]); + } + } + + this.addOneSlot = function(sampleTypeHint) { + + //Find latest slot from that type + var containerId = null; + for(var i = 0; i < this._lastIndex; i++) { + var containerIdAux = this.containerId + "-" + i; + var freePredefinedTypeCodeAux = $("#" + containerIdAux).attr("sample-type-code"); + if(sampleTypeHint["TYPE"] === freePredefinedTypeCodeAux) { + containerId = containerIdAux; + } + } + + //If the slot exists, empty label + if(containerId) { + sampleTypeHint["LABEL"] = null; + } + + //Create the new slot + var $newSlot = this._getButton(this.containerId + "-" + this._lastIndex, sampleTypeHint); + this._lastIndex++; + + if(containerId) { //Insert after that slot + $("#" + containerId).after($newSlot); + } else { //Insert before plus + $("#" + this.containerId + "-plus-button").before($newSlot); + } + } + + this.addSample = function(sampleToAdd) { + var found = false; + for(sampleObjKey in this.samples) { + var sampleObj = this.samples[sampleObjKey]; + if(sampleObj && sampleObj.identifier === sampleToAdd.identifier) { + found = true; + } + } + + if(!found) { + //Check for a predefined slot that is free + var freePredefinedSampleId = null; + for(var i = 0; i < this._lastIndex; i++) { + var predefinedSampleId = this.containerId + "-" + i + "-sample"; + if(!this.samples[predefinedSampleId]) { + var containerId = this.containerId + "-" + i; + var freePredefinedTypeCodeAux = $("#" + containerId).attr("sample-type-code"); + if(sampleToAdd.sampleTypeCode === freePredefinedTypeCodeAux) { + freePredefinedSampleId = predefinedSampleId; + break; + } + } + } + + //Check for a non predefined slot that is free + if(!freePredefinedSampleId) { + for(var i = 0; i < this._lastIndex; i++) { + var predefinedSampleId = this.containerId + "-" + i + "-sample"; + if(!this.samples[predefinedSampleId]) { + var containerId = this.containerId + "-" + i; + var freePredefinedTypeCodeAux = $("#" + containerId).attr("sample-type-code"); + if("null" === freePredefinedTypeCodeAux) { + freePredefinedSampleId = predefinedSampleId; + break; + } + } + } + } + + //Create a new slot if nothing is found + if(!freePredefinedSampleId) { //Create a new slot if not found + var sampleId = this.containerId + "-" + this._lastIndex + "-sample"; + freePredefinedSampleId = sampleId; + + var typeToAdd = this._getDefaultSampleHint(sampleToAdd.sampleTypeCode); + this.addOneSlot(typeToAdd); + } + + //Finally, add the sample + this.samples[freePredefinedSampleId] = sampleToAdd; + + //Show meaningful information + var propertiesToShow = this.profile.typePropertiesForSmallTable[sampleToAdd.sampleTypeCode]; + if(propertiesToShow === null || propertiesToShow === undefined) { + propertiesToShow = []; + } + + var propertiesToShowDisplayNames = this.profile.getPropertiesDisplayNamesForTypeCode(sampleToAdd.sampleTypeCode, propertiesToShow); + + var meaningfulInfo = "<b>Code: </b>" + sampleToAdd.code + " "; + + + for(var j = 0; j < propertiesToShow.length; j++) { + var propertyToShow = sampleToAdd.properties[propertiesToShow[j]]; + if(!propertyToShow && propertiesToShow[j].charAt(0) === '$') { + propertyToShow = sampleToAdd.properties[propertiesToShow[j].substr(1)]; + } + var propertyToShowDisplayName = propertiesToShowDisplayNames[j]; + + meaningfulInfo += "<b>" + propertyToShowDisplayName + ": </b>" + Util.getEmptyIfNull(propertyToShow) + " "; + } + var $input = $("#" +freePredefinedSampleId); + if(meaningfulInfo.length > 200) { + meaningfulInfo = meaningfulInfo.substring(0, 200) + "..."; + } + $input.empty(); + $input.append(meaningfulInfo); + + //Update annotations when adding an existing sample for updates + var sampleState = this.stateObj[sampleToAdd.permId]; + var items = $input.parent().children(); + for(var i = 0; i < items.length; i++) { + var item = $(items[i]); + var propertyTypeCode = item.attr("property-type-code"); + if(propertyTypeCode && sampleState && sampleState[propertyTypeCode]) { + if (this.profile.getPropertyType(propertyTypeCode).dataType === "BOOLEAN") { + item.children()[0].checked = sampleState[propertyTypeCode] === "true"; + } else { + item.val(sampleState[propertyTypeCode]); + } + } + if(!this.isDisabled) { + item.prop("disabled", false); + } + } + } else { + Util.showError("Item Already selected, choose another."); + } + } + + this.removeSample = function(sampleId) { + var sample = this.samples[sampleId]; + if(sample) { + //Remove Link + var $input = $('#'+sampleId); + $input.empty(); + $input.append("Select"); + + //Remove Link Annotations + var items = $input.parent().children(); + for(var i = 0; i < items.length; i++) { + var item = $(items[i]); + var propertyTypeCode = item.attr("property-type-code"); + if(propertyTypeCode) { + item.val(""); + this._writeState(sample, propertyTypeCode, null); + item.prop("disabled", true); + } + } + + //Update + this.samplesRemoved[sampleId] = this.samples[sampleId]; + this.samples[sampleId] = null; + } + } + + this.getSamples = function() { + var samples = new Array(); + for(sampleObjKey in this.samples) { + var sampleObj = this.samples[sampleObjKey]; + if(sampleObj !== null) { + samples.push(sampleObj); + } + } + return samples; + } + + this.getSamplesIdentifiers = function() { + var sampleIdentifiers = new Array(); + for(sampleObjKey in this.samples) { + var sampleObj = this.samples[sampleObjKey]; + if(sampleObj !== null) { + sampleIdentifiers.push(sampleObj.identifier); + } + } + return sampleIdentifiers; + } + + this.getSampleByIdentifier = function(identifier) { + for(sampleObjKey in this.samples) { + var sampleObj = this.samples[sampleObjKey]; + if(sampleObj !== null && sampleObj.identifier === identifier) { + return sampleObj; + } + } + return null; + } + + this.getSamplesRemovedIdentifiers = function() { + var sampleIdentifiers = new Array(); + for(sampleObjKey in this.samplesRemoved) { + var sampleObj = this.samplesRemoved[sampleObjKey]; + if(sampleObj !== null) { + sampleIdentifiers.push(sampleObj.identifier); + } + } + return sampleIdentifiers; + } + + this.isValid = function() { + var isValid = true; + for(sampleTypeHintKey in this.sampleTypeHints) { + var sampleTypeHint = this.sampleTypeHints[sampleTypeHintKey]; + var minCount = sampleTypeHint["MIN_COUNT"]; + var found = 0; + for(sampleKey in this.samples) { + var sample = this.samples[sampleKey]; + if(sample && sample.sampleTypeCode === sampleTypeHint["TYPE"]) { + found++; + } + } + + if(found < minCount) { + isValid = false; + } + } + return isValid; + } +} \ No newline at end of file diff --git a/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SideMenuWidget.js b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SideMenuWidget.js new file mode 100644 index 0000000000000000000000000000000000000000..cc8b95f999bff4ee8adcb5832b4556999f7815f7 --- /dev/null +++ b/plasmid/source/core-plugins/newbrowser/1/as/webapps/newbrowser/html/js/views/legacy/SideMenuWidget.js @@ -0,0 +1,649 @@ +/* + * Copyright 2014 ETH Zuerich, Scientific IT Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Creates an instance of SideMenuWidget. + * + * @constructor + * @this {SideMenuWidget} + * @param {MainController} mainController Used to control view changes. + * @param {string} containerId The Container where the Inspector DOM will be atached. + * @param {ServerFacade} serverFacade Used to access all server side calls. + */ +function SideMenuWidget(mainController, containerId, serverFacade) { + this._mainController = mainController; + this._containerId = containerId; + this._serverFacade = serverFacade; + this._menuDOMTitle = null; + this._menuDOMBody = null; + this._menuStructure = new SideMenuWidgetComponent(false, true, "Main Menu", "Main Menu", null, { children : [] }, 'showBlancPage', null, ""); + this._pointerToMenuNode = this._menuStructure; + this.isHidden = false; + + this.refreshProject = function(spaceCode, projectCode) { + var menuItemSpace = this._getSpaceNodeForCode(spaceCode); + var newMenuIfSelectedProject = { + children : [] + } + var projectIdentifier = "/" + spaceCode + "/" + projectCode; + var menuItemProject = new SideMenuWidgetComponent(true, false, projectCode, projectCode, menuItemSpace, newMenuIfSelectedProject, "showProjectPageFromIdentifier", projectIdentifier, "(Project)"); + menuItemSpace.newMenuIfSelected.children.push(menuItemProject); + + this.repaint(); + } + + this.refreshExperiment = function(experiment, isInventory) { + var projectNode = this._getProjectNodeForCode(experiment.identifier.split("/")[2]); + var newMenuIfSelectedExperiment = { + children : [] + } + + var displayName = null; + if(this._mainController.profile.hideCodes) { + displayName = experiment.properties[this._mainController.profile.propertyReplacingCode]; + } + if(!displayName) { + displayName = experiment.code; + } + + var menuItemExperiment = null; + if(isInventory) { + menuItemExperiment = new SideMenuWidgetComponent(true, false, displayName, experiment.code, projectNode, null, "showSamplesPage", ":" + experiment.identifier); + } else { + menuItemExperiment = new SideMenuWidgetComponent(true, false, displayName, experiment.code, projectNode, newMenuIfSelectedExperiment, "showExperimentPageFromIdentifier", experiment.identifier, "(Experiment)"); + } + + projectNode.newMenuIfSelected.children.push(menuItemExperiment); + + this.repaint(); + } + + this.refreshSubExperiment = function(experimentIdentifierToAskForSamples) { + var _this = this; + _this._serverFacade.listExperimentsForIdentifiers([experimentIdentifierToAskForSamples], function(data) { + var experimentToAskForSamples = data.result[0]; + _this._serverFacade.listSamplesForExperiments([experimentToAskForSamples], function(subExperiments) { + var nodeCleared = false; + for(var i = 0; i < subExperiments.result.length; i++) { + var subExperiment = subExperiments.result[i]; + if(subExperiment.experimentIdentifierOrNull) { + var projectCode = subExperiment.experimentIdentifierOrNull.split("/")[2]; + var experimentCode = subExperiment.experimentIdentifierOrNull.split("/")[3]; + var experimentNode = _this._getExperimentNodeForCode(projectCode, experimentCode); + var displayName = null; + if(_this._mainController.profile.hideCodes) { + displayName = subExperiment.properties[_this._mainController.profile.propertyReplacingCode]; + } + if(!displayName) { + displayName = subExperiment.code; + } + if(!nodeCleared) { + experimentNode.newMenuIfSelected.children = []; + nodeCleared = true; + } + var menuItemSubExperiment = new SideMenuWidgetComponent(true, false, displayName, subExperiment.code, experimentNode, null, "showViewSamplePageFromPermId", subExperiment.permId, "(Sub Exp.)"); + experimentNode.newMenuIfSelected.children.push(menuItemSubExperiment); + } + } + _this.repaint(); + }); + }); + } + + this._getSpaceNodeForCode = function(spaceCode) { + for(var sIdx = 0; sIdx < this._menuStructure.newMenuIfSelected.children.length; sIdx++) { + var spaceNode = this._menuStructure.newMenuIfSelected.children[sIdx]; + if(spaceNode.isTitle && !spaceNode.isSelectable) { + continue; + } + if(spaceNode.code === spaceCode) { + return spaceNode; + } + } + return null; + } + + this._getProjectNodeForCode = function(projectCode) { + for(var sIdx = 0; sIdx < this._menuStructure.newMenuIfSelected.children.length; sIdx++) { + var spaceNode = this._menuStructure.newMenuIfSelected.children[sIdx]; + if(spaceNode.isTitle && !spaceNode.isSelectable) { + continue; + } + var projectsFromSpace = spaceNode.newMenuIfSelected.children; + for(var pIdx = 0; pIdx < projectsFromSpace.length; pIdx++) { + var projectNode = projectsFromSpace[pIdx]; + if(projectNode.code === projectCode) { + return projectNode; + } + } + } + return null; + } + + this._getExperimentNodeForCode = function(projectCode, experimentCode) { + var projectNode = this._getProjectNodeForCode(projectCode); + var experimentsFromProject = projectNode.newMenuIfSelected.children; + for(var eIdx = 0; eIdx < experimentsFromProject.length; eIdx++) { + var experimentNode = experimentsFromProject[eIdx]; + if(experimentNode.code === experimentCode) { + return experimentNode; + } + } + return null; + } + + this.init = function() { + var _this = this; + + this._menuStructure.newMenuIfSelected.children.push( + new SideMenuWidgetComponent(false, true, "Lab Notebook", "Lab Notebook", this._menuStructure, null, null, null, "") + ); + + this._serverFacade.listSpacesWithProjectsAndRoleAssignments(null, function(dataWithSpacesAndProjects) { + //Fill Spaces + var spaces = dataWithSpacesAndProjects.result; + var projectsToAskForExperiments = []; + for(var i = 0; i < spaces.length; i++) { + var space = spaces[i]; + + if($.inArray(space.code, _this._mainController.profile.inventorySpaces) !== -1 && _this._mainController.profile.inventorySpaces.length > 0) { + continue; + } + + var newMenuIfSelectedSpace = { + children : [] + } + var menuItemSpace = new SideMenuWidgetComponent(true, false, space.code, space.code, _this._menuStructure, newMenuIfSelectedSpace, 'showSpacePage', space.code, "(Space)"); + _this._menuStructure.newMenuIfSelected.children.push(menuItemSpace); + + //Fill Projects + for(var j = 0; j < space.projects.length; j++) { + var project = space.projects[j]; + delete project["@id"]; + delete project["@type"]; + projectsToAskForExperiments.push(project); + + var newMenuIfSelectedProject = { + children : [] + } + var menuItemProject = new SideMenuWidgetComponent(true, false, project.code, project.code, menuItemSpace, newMenuIfSelectedProject, "showProjectPageFromPermId", project.permId, "(Project)"); + newMenuIfSelectedSpace.children.push(menuItemProject); + } + } + + //Fill Experiments + _this._serverFacade.listExperiments(projectsToAskForExperiments, function(experiments) { + var experimentsToAskForSamples = []; + + if(experiments.result) { + for(var i = 0; i < experiments.result.length; i++) { + var experiment = experiments.result[i]; + experimentsToAskForSamples.push(experiment); + var projectCode = experiment.identifier.split("/")[2]; + var projectNode = _this._getProjectNodeForCode(projectCode); + + var newMenuIfSelectedExperiment = { + children : [] + } + + var displayName = null; + if(_this._mainController.profile.hideCodes) { + displayName = experiment.properties[_this._mainController.profile.propertyReplacingCode]; + } + if(!displayName) { + displayName = experiment.code; + } + + var menuItemExperiment = new SideMenuWidgetComponent(true, false, displayName, experiment.code, projectNode, newMenuIfSelectedExperiment, "showExperimentPageFromIdentifier", experiment.identifier, "(Experiment)"); + projectNode.newMenuIfSelected.children.push(menuItemExperiment); + } + } + + //Fill Sub Experiments + _this._serverFacade.listSamplesForExperiments(experimentsToAskForSamples, function(subExperiments) { + if(subExperiments.result) { + for(var i = 0; i < subExperiments.result.length; i++) { + var subExperiment = subExperiments.result[i]; + if(subExperiment.experimentIdentifierOrNull) { + var projectCode = subExperiment.experimentIdentifierOrNull.split("/")[2]; + var experimentCode = subExperiment.experimentIdentifierOrNull.split("/")[3]; + var experimentNode = _this._getExperimentNodeForCode(projectCode, experimentCode); + var displayName = null; + if(_this._mainController.profile.hideCodes) { + displayName = subExperiment.properties[_this._mainController.profile.propertyReplacingCode]; + } + if(!displayName) { + displayName = subExperiment.code; + } + var menuItemSubExperiment = new SideMenuWidgetComponent(true, false, displayName, subExperiment.code, experimentNode, null, "showViewSamplePageFromPermId", subExperiment.permId, "(Sub Exp.)"); + experimentNode.newMenuIfSelected.children.push(menuItemSubExperiment); + } + } + } + + + //Fill Inventory + _this._menuStructure.newMenuIfSelected.children.push( + new SideMenuWidgetComponent(false, true, "Inventory", "Inventory", _this._menuStructure, null, null, null, "") + ); + + //Fill Spaces + var spaces = dataWithSpacesAndProjects.result; + var projectsToAskForExperiments = []; + for(var i = 0; i < spaces.length; i++) { + var space = spaces[i]; + + if($.inArray(space.code, _this._mainController.profile.inventorySpaces) === -1) { + continue; + } + + var newMenuIfSelectedSpace = { + children : [] + } + var menuItemSpace = new SideMenuWidgetComponent(true, false, space.code, space.code, _this._menuStructure, newMenuIfSelectedSpace, 'showSpacePage', space.code, "(Space)"); + _this._menuStructure.newMenuIfSelected.children.push(menuItemSpace); + + //Fill Projects + for(var j = 0; j < space.projects.length; j++) { + var project = space.projects[j]; + delete project["@id"]; + delete project["@type"]; + projectsToAskForExperiments.push(project); + + var newMenuIfSelectedProject = { + children : [] + } + var menuItemProject = new SideMenuWidgetComponent(true, false, project.code, project.code, menuItemSpace, newMenuIfSelectedProject, "showProjectPageFromPermId", project.permId, "(Project)"); + newMenuIfSelectedSpace.children.push(menuItemProject); + } + } + + _this._serverFacade.listExperiments(projectsToAskForExperiments, function(experiments) { + var experimentsToAskForSamples = []; + + if(experiments.result) { + for(var i = 0; i < experiments.result.length; i++) { + var experiment = experiments.result[i]; + experimentsToAskForSamples.push(experiment); + var projectCode = experiment.identifier.split("/")[2]; + var projectNode = _this._getProjectNodeForCode(projectCode); + + var newMenuIfSelectedExperiment = { + children : [] + } + + var displayName = null; + if(_this._mainController.profile.hideCodes) { + displayName = experiment.properties[_this._mainController.profile.propertyReplacingCode]; + } + if(!displayName) { + displayName = experiment.code; + } + + var menuItemExperiment = new SideMenuWidgetComponent(true, false, displayName, experiment.code, projectNode, null, "showSamplesPage", ":" + experiment.identifier, ""); + projectNode.newMenuIfSelected.children.push(menuItemExperiment); + } + } + + + //Fill Utils + var profile = _this._mainController.profile; + if(profile.storagesConfiguration["isEnabled"]) { + _this._menuStructure.newMenuIfSelected.children.push( + new SideMenuWidgetComponent(false, true, "Utils", "Utils", _this._menuStructure, null, null, null, "") + ); + _this._menuStructure.newMenuIfSelected.children.push( + new SideMenuWidgetComponent(true, false, "Storage Manager", "Storage Manager", _this._menuStructure, null, "showStorageManager", null, "") + ); + } + + _this._repaint(); + }); + + }); + + }); + }); + + $(window).scroll(function(event){ + var sideMenuWidth = $("#sideMenu").width(); + var windowWidth = $(window).width(); + var ratio = sideMenuWidth / windowWidth; + if(ratio < 0.9) { //For small screens where the menu takes all the screen, we don't move it + var $element = $("#sideMenu"); + var scrollTop = $(document).scrollTop(); + $element.css('top', scrollTop + "px"); + } + }); + + $(window).resize(function(event){ + //Use all height + var $element = $("#sideMenu"); + var windowHeight = $(window).height(); + $element.css('min-height', windowHeight + "px"); + + //Set the children of the menu scrollable + var $elementHead = $("#sideMenuHeader"); + var sideMenuHeaderHeight = $elementHead.height(); + var $elementBody = $("#sideMenuBody"); + $elementBody.css('overflow-y', 'auto'); + $elementBody.css('overflow-x', 'hidden'); + //TO-DO 17px is a hack to be able to scroll properly to the last item on the iPad + $elementBody.css('max-height', (windowHeight - sideMenuHeaderHeight - 17) + "px"); + }); + } + + this.hideSideMenu = function() { + $("#" + this._containerId).hide(); + $("#mainContainer").removeClass("col-md-10"); + $("#mainContainer").addClass("col-md-12"); + + var $toggleButtonShow = $("<a>", { "class" : "btn btn-default", "id" : "toggleButtonShow", "href" : "javascript:mainController.sideMenu.showSideMenu();", "style" : "position: fixed; top:0px; left:0px;"}) + .append($("<span>", { "class" : "glyphicon glyphicon-resize-horizontal" })); + + $("#main").append($toggleButtonShow); + this.isHidden = true; + } + + this.showSideMenu = function() { + $("#" + this._containerId).show(); + $("#toggleButtonShow").remove(); + $("#mainContainer").removeClass("col-md-12"); + $("#mainContainer").addClass("col-md-10"); + this.isHidden = false; + } + + this._repaint = function() { + var _this = this; + var $container = $("#" + this._containerId); + var $widget = $("<div>"); + + // + // Fix Header + // + var $header = $("<div>", { "id" : "sideMenuHeader"}); + var $headerItemList = $("<ul>", { "class" : "nav navbar-nav"}); + $header + .append( + $("<nav>", { "class" : "navbar navbar-default", "role" : "navigation", "style" : "margin:0px; border-left-width:0px; border-right-width:0px;"}) + .append($headerItemList) + ); + + var $pinButton = $("<li>") + .append($("<a>", { "id" : "pin-button", "href" : "javascript:mainController.changeView(\"showInspectors\",null)" }) + .append($("<img>", { "src" : "./img/pin-icon.png", "style" : "width:16px; height:16px;"})) + .append($("<span>", { "id" : "num-pins" }).append(this._mainController.inspector.inspectedSamples.length)) + ); + + var $toggleButton = $("<li>") + .append($("<a>", { "href" : "javascript:mainController.sideMenu.hideSideMenu();" }) + .append($("<span>", { "class" : "glyphicon glyphicon-resize-horizontal" })) + ); + + var dropDownSearch = ""; + var searchDomains = profile.getSearchDomains(); + + var searchFunction = function() { + var searchText = $("#search").val(); + var searchDomain = $("#prefix-selected-search-domain").attr("selected-name"); + var searchDomainLabel = $("#prefix-selected-search-domain").attr("selected-label"); + if(!searchDomain) { + searchDomain = profile.getSearchDomains()[0].name; + searchDomainLabel = profile.getSearchDomains()[0].label; + } + + var argsMap = { + "searchText" : searchText, + "searchDomain" : searchDomain, + "searchDomainLabel" : searchDomainLabel + } + var argsMapStr = JSON.stringify(argsMap); + + mainController.changeView("showSearchPage", argsMapStr); + } + + if(searchDomains.length > 1) { + //Default Selected for the prefix + var defaultSelected = ""; + if(searchDomains[0].label.length > 3) { + defaultSelected = searchDomains[0].label.substring(0, 2) + "."; + } else { + defaultSelected = searchDomains[0].label.label; + } + + //Prefix function + var selectedFunction = function(selectedSearchDomain) { + return function() { + var $component = $("#prefix-selected-search-domain"); + $component.empty(); + if(selectedSearchDomain.label.length > 3) { + $component.append(selectedSearchDomain.label.substring(0, 2) + "."); + } else { + $component.append(selectedSearchDomain.label); + } + $component.attr('selected-name', selectedSearchDomain.name); + $component.attr('selected-label', selectedSearchDomain.label); + }; + } + + //Dropdown elements + var dropDownComponents = []; + for(var i = 0; i < searchDomains.length; i++) { + dropDownComponents.push({ + href : selectedFunction(searchDomains[i]), + title : searchDomains[i].label, + id : searchDomains[i].name + }); + } + + dropDownSearch = FormUtil.getDropDownToogleWithSelectedFeedback( + $('<span>', { id : 'prefix-selected-search-domain', class : 'btn btn-default disabled', 'selected-name' : searchDomains[0].name } + ).append(defaultSelected),dropDownComponents, true, searchFunction); + dropDownSearch.change(); + } + + + var searchElement = $("<input>", { "id" : "search", "type" : "text", "class" : "form-control search-query", "placeholder" : "Search"}); + searchElement.keyup(searchFunction); + + var $searchForm = $("<li>") + .append($("<form>", { "class" : "navbar-form", "onsubmit" : "return false;"}) + .append(searchElement) + .append(' ') + .append(dropDownSearch) + ); + + var logoutButton = $("<a>", { "id" : "logout-button", "href" : "" }).append($("<span>", { "class" : "glyphicon glyphicon-off"})); + logoutButton.click(function() { + $('body').addClass('bodyLogin'); + _this._serverFacade.logout(function(data) { + $("#login-form-div").show(); + $("#main").hide(); + }); + }); + var $logoutButton = $("<li>").append(logoutButton); + + $headerItemList.append($logoutButton); + $headerItemList.append($pinButton); + $headerItemList.append($toggleButton); + $headerItemList.append($searchForm); + + var $body = $("<div>", { "id" : "sideMenuBody"}); + $widget + .append($header) + .append($body); + + var $title = $("<div>", { "class" : "sideMenuTitle" }); + $header + .append($title); + + $container.empty(); + $container.append($widget); + + // + // Print Menu + // + this._menuDOMTitle = $title; + this._menuDOMBody = $body; + this.repaint(); + } + + this.repaint = function() { + var _this = this; + var menuToPaint = this._pointerToMenuNode; + + // + // Title + // + + // Fix for long names + var cutDisplayNameAtLength = 15; + var titleShowTooltip = (menuToPaint.code + " " + menuToPaint.contextTitle).length > cutDisplayNameAtLength; + if(titleShowTooltip) { + var titleDisplayName = (menuToPaint.code + " " + menuToPaint.contextTitle).substring(0, cutDisplayNameAtLength) + "..."; + } else { + var titleDisplayName = (menuToPaint.code + " " + menuToPaint.contextTitle); + } + // + + this._menuDOMTitle.empty(); + var isBackButtonShown = menuToPaint.parent !== null; + if(isBackButtonShown) { + var backButton = $("<a>", { "id" : "back-button", "href" : "javascript:void(0);", "style" : "float:left; color:black; padding-left:10px;" }).append($("<span>", { "class" : "glyphicon glyphicon-arrow-left"})); + var backButtonClick = function(menuItem) { + return function() { + var parent = menuItem.parent; + _this._pointerToMenuNode = parent; + _this.repaint(); + + if(parent.newViewIfSelected !== null) { + _this._mainController.changeView(parent.newViewIfSelected, parent.newViewIfSelectedData); + } + } + }; + backButton.click(backButtonClick(menuToPaint)); + this._menuDOMTitle.append(backButton); + } + + var $titleAsTextOrLink = null; + if(menuToPaint.newViewIfSelected && menuToPaint.newViewIfSelected != "showBlancPage") { + $titleAsTextOrLink = $("<a>", { "href" : "javascript:void(0);" }).append(titleDisplayName) + + var clickFunction = function(menuToPaint) { + return function() { + _this._mainController.changeView(menuToPaint.newViewIfSelected, menuToPaint.newViewIfSelectedData); + } + }; + + $titleAsTextOrLink.click(clickFunction(menuToPaint)); + } else { + $titleAsTextOrLink = $("<span>").text(titleDisplayName); + } + + if(titleShowTooltip) { + $titleAsTextOrLink.attr("title", menuToPaint.code + " " + menuToPaint.contextTitle); + $titleAsTextOrLink.tooltipster(); + } + + var $mainTitle = $("<span>").append($titleAsTextOrLink); + + if(isBackButtonShown) { + $mainTitle.css({ + "margin-left" : "-24px" + }); + } + + this._menuDOMTitle.append($mainTitle); + + + // + // Body + // + this._menuDOMBody.empty(); + for(var mIdx = 0; mIdx < menuToPaint.newMenuIfSelected.children.length; mIdx++ ) { + var menuItem = menuToPaint.newMenuIfSelected.children[mIdx]; + + + var $menuItem = $("<div>", { "class" : "sideMenuItem" }); + + var menuItemDisplayName = menuItem.displayName; + if(!menuItemDisplayName) { + menuItemDisplayName = menuItem.code; + } + + // + var itemShowTooltip = menuItemDisplayName > cutDisplayNameAtLength; + if(itemShowTooltip) { + var itemDisplayName = menuItemDisplayName.substring(0, cutDisplayNameAtLength) + "..."; + } else { + var itemDisplayName = menuItemDisplayName; + } + // + + var $menuItemTitle = $("<span>").append(itemDisplayName); + + if(itemShowTooltip) { + $menuItem.attr("title", menuItemDisplayName); + $menuItem.tooltipster(); + } + + $menuItem.append($menuItemTitle); + + if(menuItem.isTitle) { + $menuItem.addClass("sideMenuItemTitle"); + } + + if(menuItem.isSelectable) { + $menuItem.addClass("sideMenuItemSelectable"); + if(menuItem.newMenuIfSelected && menuItem.newMenuIfSelected.children.length > 0) { + $menuItem.append("<span class='glyphicon glyphicon-chevron-right put-chevron-right'></span>"); + } + + var clickFunction = function(menuItem) { + return function() { + if(menuItem.newMenuIfSelected && menuItem.newMenuIfSelected.children.length > 0) { + _this._pointerToMenuNode = menuItem; + _this.repaint(); + } + + if(menuItem.newViewIfSelected !== null) { + _this._mainController.changeView(menuItem.newViewIfSelected, menuItem.newViewIfSelectedData); + } + } + }; + + $menuItem.click(clickFunction(menuItem)); + } + + this._menuDOMBody.append($menuItem); + } + + $(window).resize(); + } + +} + +function SideMenuWidgetComponent(isSelectable, isTitle, displayName, code, parent, newMenuIfSelected, newViewIfSelected, newViewIfSelectedData, contextTitle) { + this.isSelectable = isSelectable; + this.isTitle = isTitle; + this.displayName = displayName; + this.code = code; + this.contextTitle = contextTitle; + this.parent = parent; + this.newMenuIfSelected = newMenuIfSelected; + this.newViewIfSelected = newViewIfSelected; + this.newViewIfSelectedData = newViewIfSelectedData; +} \ No newline at end of file