diff --git a/kadmos/vistoms/templates/VISTOMS.html b/kadmos/vistoms/templates/VISTOMS.html index 573bee8bdafda940af196887c45d58736960d4cb..4b5a4c80f78709d96321fab743879b74d3aebc9d 100644 --- a/kadmos/vistoms/templates/VISTOMS.html +++ b/kadmos/vistoms/templates/VISTOMS.html @@ -402,9 +402,9 @@ { d3.select(this).style("z-index",""); }) - var addButton_div = d3.select(".addButtonDiv") - if (addButton_div) - addButton_div.remove(); + var generalPanel_div = d3.select(".generalPaneDiv") + if (generalPanel_div) + generalPanel_div.remove(); @@ -455,7 +455,7 @@ makeViewButtons(data,"Edge Bundles","edgeBundles"); makeViewButtons(data,"Sankey Diagram","sankeyDiagram"); //aigner: Add special button to open graphs from kdms or cmdows files - addButton(data.graphs); + generalPanel(data.graphs); } }, error: function(result) @@ -473,7 +473,7 @@ makeViewButtons(data,"Edge Bundles","edgeBundles"); makeViewButtons(data,"Sankey Diagram","sankeyDiagram"); //aigner: Add special button to open graphs from kdms or cmdows files - addButton(data.graphs); + generalPanel(data.graphs); } @@ -564,10 +564,12 @@ //########################################################## - //aigner: Add special button to open graphs from kdms or cmdows files + //aigner: Add general panel to open and save graphs and for adding contacts to the organization //########################################################## - function addButton(theGraphs) + function generalPanel(theGraphs) { + var generalPanel_div = d3.select("body").append("div").attr("class","generalPaneDiv") + var newGraphID = '01'; if (theGraphs) { @@ -579,8 +581,7 @@ }) } - var addButton_div = d3.select("body").append("div").attr("class","addButtonDiv") - var addButtonPanel = addButton_div.append("div") + var addButtonPanel = generalPanel_div.append("div") .attr("class","panel panel-default") .attr("id","addButton") .style("display","inline-block") @@ -853,7 +854,7 @@ if (theGraphs) { - var saveButtonPanel = addButton_div.append("div") + var saveButtonPanel = generalPanel_div.append("div") .attr("class","panel panel-default") .attr("id","saveButton") .style("display","inline-block") @@ -20264,8 +20265,6 @@ }) - - //aigner: HIER WEITER!!! function addDesignCompetence(theData, theCurrentGraph=null) { bootbox.hideAll(); @@ -20348,7 +20347,6 @@ }); } - //aigner: HIER WEITER!!! --> Add contacts if not already existing function addDCMetadata(theData, theCurrentGraph, aNode=null) { bootbox.hideAll(); @@ -20383,7 +20381,6 @@ input.append("option").attr("type","select").attr("value","N/A").text("N/A") var contacts = [] if (theCurrentGraph.organization.contacts){contacts=theCurrentGraph.organization.contacts}; - console.log(theCurrentGraph) form_group = form.append("div").attr("class","form-group") form_group.append("text").text("Owner") input = form_group.append("select").attr("id","owner_uid").style("margin-left","5px") @@ -20629,6 +20626,300 @@ } }); }) + + //aigner: View and edit contact information + //##################################################################################################### + function contact_info(contact_uid, theContacts) + { + if (contact_uid=="") + { + var empty_contact = {name:"",function:"",country:"",company:"",telephone:"",address:"",department:"",email:"",attrib:{uID:""}} + theContacts.push(empty_contact) + } + theContacts.forEach(function(contact, index, contacts) + { + if (contact.attrib.uID == contact_uid) + { + //Show contact info + //############################################################ + bootbox.hideAll(); + var html = d3.select("html") + var form_content = html.append("div").attr("class","form-content").attr("style","display:none") + var form = form_content.append("form").attr("class","form").attr("role","form") + var form_group, input; + + form_group = form.append("div").attr("class","form-group") + function form_control(text,value) + { + form_group.append("label").text(text) + input = form_group.append("input") + .attr("id","contact_"+text) + .attr("class","form-control") + .attr("name","contact_"+text) + .attr("placeholder","...") + .attr("value",value) + } + form_control("Name",contact.name) + form_control("uID",contact.attrib.uID) + form_control("Function",contact.function) + form_control("Country",contact.country) + form_control("Company",contact.company) + form_control("Telephone",contact.telephone) + form_control("Address",contact.address) + form_control("Department",contact.department) + form_control("E-Mail",contact.email) + + form_group.append("label").text("Roles") + var input = form_group.append("div").attr("id","contact_roles") + var label1 = input.append("div").append("text").style("margin-top","5pt").attr("for","architect").text("Architect ") + label1.append("input").attr("type","checkbox").attr("id","architect") + var label2 = input.append("div").append("text").style("margin-top","5pt").attr("for","integrator").text("Integrator ") + label2.append("input").attr("type","checkbox").attr("id","integrator") + var label3 = input.append("div").append("text").style("margin-top","5pt").attr("for","toolSpecialist").text("Tool Specialist ") + label3.append("input").attr("type","checkbox").attr("id","toolSpecialist") + currentGraph.organization.organigram.architects.forEach(function(architect) + { + if (contact.attrib.uID==architect.contactUID) + { + $('#architect').attr('checked', true); + } + }); + currentGraph.organization.organigram.integrators.forEach(function(integrator) + { + if (contact.attrib.uID==integrator.contactUID) + { + $('#integrator').attr('checked', true); + } + }); + currentGraph.organization.organigram.toolSpecialists.forEach(function(toolSpecialist) + { + if (contact.attrib.uID==toolSpecialist.contactUID) + { + $('#toolSpecialist').attr('checked', true); + } + }); + //############################################################ + + //Function to save contact information in global organization object + //############################################################ + function update_contact_info() + { + //Save contact information in global contacts object + currentGraph.organization.contacts = theContacts + //Send changes to kadmos and update the graph + var bootboxContent = {title: "Update contact information", message: '<p>Please be patient...</p>'}; + var xhr = $.ajax({ + type: 'POST', + data: {'graphID': graphID, 'currentOrder': nodeOrder, 'organization': JSON.stringify(currentGraph.organization)}, + url: '/kadmos_edit_contact_infos', + success: function(result) + { + if (result.includes("ERROR:")) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + else + { + var updatedData = {}; + updatedData = data; + var graphData = JSON.parse(result); + for (var i = 0; i < updatedData.graphs.length; i++) + { + if (graphID == updatedData.graphs[i].id) + { + updatedData.graphs[i] = graphData.graphs[0]; + } + } + + clearView(); + makeKadmosMenu(updatedData); + + xdsm_script(updatedData,graphID); + + bootboxContent.message = "Success!" + kadmosSuccessMessage(bootboxContent) + } + }, + error: function(result) + { + bootboxContent.message = result + kadmosErrorMessage(bootboxContent); + } + }); + kadmosHavePatience(xhr, bootboxContent) + } + //############################################################ + + + //############################################################ + var modal = bootbox.dialog({ + message: $(".form-content").html(), + title: "Contact information", + size: "large", + buttons: [ + { + label: "Delete contact", + className: "btn btn-danger pull-left", + callback: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + bootbox.hideAll(); + bootbox.confirm("Are you sure you want to delete the contact?", function(sure) + { + if (sure) + { + //remove contact from roles in organigram + currentGraph.organization.organigram.architects.forEach(function(architect, index, architects) + { + if (contact.attrib.uID==architect.contactUID){architects.splice(index,1)} + }); + currentGraph.organization.organigram.integrators.forEach(function(integrator, index, integrators) + { + if (contact.attrib.uID==integrator.contactUID){integrators.splice(index,1)} + }); + currentGraph.organization.organigram.toolSpecialists.forEach(function(toolSpecialist, index, toolSpecialists) + { + if (contact.attrib.uID==toolSpecialist.contactUID){toolSpecialists.splice(index,1)} + }); + + //Delete contact from organization + contacts.splice(index,1); + + //Call function update_contact_info + update_contact_info(); + } + }) + } + }, + { + label: "Apply", + className: "btn btn-primary pull-right", + callback: function() { + contact.name = $('form #contact_Name').val() + contact.attrib.uID = $('form #contact_uID').val() + contact.function = $('form #contact_Function').val() + contact.country = $('form #contact_Country').val() + contact.company = $('form #contact_Company').val() + contact.telephone = $('form #contact_Telephone').val() + contact.address = $('form #contact_Address').val() + contact.department = $('form #contact_Department').val() + contact.email = $('form #contact_E-Mail').val() + + + //aigner: toggle roles of the contact + //############################################################ + var roles = { + architect: document.getElementById("architect").checked, + integrator: document.getElementById("integrator").checked, + toolSpecialist: document.getElementById("toolSpecialist").checked + } + var contact_is_arc = false; + var contact_is_int = false; + var contact_is_ts = false; + currentGraph.organization.organigram.architects.forEach(function(architect, index, architects) + { + if (contact.attrib.uID==architect.contactUID) + { + contact_is_arc = true; + if (!roles.architect){ + architects.splice(index,1) + } + + } + }); + currentGraph.organization.organigram.integrators.forEach(function(integrator, index, integrators) + { + if (contact.attrib.uID==integrator.contactUID) + { + contact_is_int = true; + if (!roles.integrator){ + integrators.splice(index,1) + } + } + }); + currentGraph.organization.organigram.toolSpecialists.forEach(function(toolSpecialist, index, toolSpecialists) + { + if (contact.attrib.uID==toolSpecialist.contactUID) + { + contact_is_ts = true; + if (!roles.toolSpecialist){ + toolSpecialists.splice(index,1) + } + } + }); + if (!contact_is_arc && roles.architect){currentGraph.organization.organigram.architects.push({contactUID: contact.attrib.uID})} + if (!contact_is_int && roles.integrator){currentGraph.organization.organigram.integrators.push({contactUID: contact.attrib.uID})} + if (!contact_is_ts && roles.toolSpecialist){currentGraph.organization.organigram.toolSpecialists.push({contactUID: contact.attrib.uID})} + //############################################################ + + //Call function update_contact_info + update_contact_info(); + + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }, + { + label: "Cancel", + className: "btn btn-default pull-right", + callback: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + } + ], + onEscape: function() { + modal.modal("hide"); + d3.selectAll(".form-content").remove(); + } + }); + //############################################################ + } + }) + } + + var orgaButton = revertDiv.append("button") + .attr("class","btn btn-info") + .attr("data-toggle","tooltip") + .attr("data-placement","top") + .attr("title","Contact options") + .style("margin-left","10px") + .style("margin-bottom","10px") + orgaButton.append("span") + .attr("class","glyphicon glyphicon-user") + .attr("aria-hidden","true") + orgaButton.on("mousedown", function() + { + bootbox.hideAll(); + + var contacts = [] + if (currentGraph.organization.contacts){contacts=JSON.parse(JSON.stringify(currentGraph.organization.contacts))}; + var options = [{text:"Select...",value:"select"},{text:"Add new contact",value:""}]; + contacts.forEach(function(contact){ + options.push({text:contact.name + " (" + contact.company + ")", value:contact.attrib.uID}); + }) + + bootbox.hideAll(); + bootbox.prompt({ + title: "<b>Contact information</b>" + +"<p>Which contact do you want to show or edit?" + +"You can also add a new contact. Just select 'Add new contact'</p>", + inputType: 'select', + value: 'select', + inputOptions: options, + callback: function (result) { + if (result==null || result=="select"){} + else + { + contact_info(result,contacts); + } + } + }); + + + }) + //##################################################################################################### //#################################################################################################################### @@ -24167,7 +24458,7 @@ //d3.select(".legendDiv").moveToBack() d3.select(".dataModelDiv").moveToBack() headerDiv.moveToBack() - d3.select(".addButtonDiv").moveToBack() + d3.select(".generalPaneDiv").moveToBack() d3.select(".navigationBarDiv").moveToBack() d3.select(".visPackDiv").moveToBack() @@ -28486,7 +28777,7 @@ d3.select(".dataModelDiv").moveToBack() headerDiv.moveToBack() - d3.select(".addButtonDiv").moveToBack() + d3.select(".generalPaneDiv").moveToBack() d3.select(".navigationBarDiv").moveToBack() d3.select(".visPackDiv").moveToBack() diff --git a/kadmos/vistoms/vistoms.py b/kadmos/vistoms/vistoms.py index 45ac83d0c91ee12656d24fdac2a59f7dd88a05b0..d9ce80268c198fd4dcc681ef8928fd06fdd6468e 100644 --- a/kadmos/vistoms/vistoms.py +++ b/kadmos/vistoms/vistoms.py @@ -308,7 +308,7 @@ def kadmos_export_graph(): elif fileType == "cmdows": file = fileName + ".xml" # Save as CMDOWS file - graph.save(os.path.join(UPLOAD_FOLDER, fileName), file_type=fileType, graph_check_critical=False, mpg=mpg) + graph.save(os.path.join(UPLOAD_FOLDER, fileName), file_type=fileType,graph_check_critical=False, mpg=mpg) # Copy CMDOWS file from temporary folder to user's download folder copyfile(os.path.join(UPLOAD_FOLDER, file), os.path.join(path, file)) # remove temporary CMDOWS file @@ -949,7 +949,6 @@ def kadmos_add_design_competence(): try: # Get request form graphID = request.form['graphID'] - current_order = request.form['currentOrder'] function_node = request.form['function_node'].replace(" ", "") input_xml = request.files['input_xml'] output_xml = request.files['output_xml'] @@ -1013,6 +1012,49 @@ def kadmos_add_design_competence(): # Logs the error appropriately. +@app.route('/kadmos_edit_contact_infos', methods=['POST']) +def kadmos_edit_contact_infos(): + """ + Function adds a dc to the graph + :param graphID: ID of the current graph + :return: VISTOMS json data with graph information + """ + try: + # Get request form + graphID = request.form['graphID'] + organization = json.loads(request.form['organization']) + if request.form['currentOrder'].split(',') != '': + function_order = request.form['currentOrder'].split(',') + + # Save previous graph as backup before making the changes + savePreviousGraph(graphID) + + path = UPLOAD_FOLDER + graphFileName = TEMP_FILE+'_'+graphID+'.kdms' + mpgFileName = TEMP_FILE+'_'+graphID+'_mpg.kdms' + if os.path.exists(os.path.join(path, mpgFileName)): + return ("ERROR: You cannot change organizational info on an MPG! Please go back to the RCG to do so.") + else: + graph = load(os.path.join(path, graphFileName), file_check_critical=False) + mpg = None + + # Set the new organization from VISTOMS request + graph.graph['organization'] = organization + + # Add the graph with the updated function order to VISTOMS + newVistomsData = graph.vistoms_add_json(graph_id=graphID, mpg=mpg, function_order=function_order) + + # Save the graph in temp/tmp.kdms + graph.save(os.path.join(UPLOAD_FOLDER, TEMP_FILE+'_'+graphID+'.kdms'), file_type='kdms', + graph_check_critical=False, mpg=mpg) + + return newVistomsData + + except Exception as e: + return "ERROR: " + e.message + # Logs the error appropriately. + + @app.route('/kadmos_change_node_pos', methods=['POST']) def kadmos_change_node_pos(): """