| @@ -1,4 +1,5 @@ | |||
| {{template "base/head" .}} | |||
| <link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css"> | |||
| <style> | |||
| .according-panel-heading { | |||
| box-sizing: border-box; | |||
| @@ -200,6 +201,9 @@ | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem; | |||
| } | |||
| .menuContent{ | |||
| background:#ffffff | |||
| } | |||
| </style> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| @@ -236,6 +240,16 @@ | |||
| <i class="dropdown icon"></i> | |||
| <span class="accordion-panel-title-content"> | |||
| <span> | |||
| <div style="float: right;"> | |||
| {{if and ($.canDownload) (eq .Status "COMPLETED") ($.Permission.CanWrite $.UnitTypeModelManage) }} | |||
| <a class="ti-action-menu-item" id="{{.VersionName}}-create-model" | |||
| onclick="showcreate({{.}})">{{$.i18n.Tr "repo.modelarts.create_model"}}</a> | |||
| {{else}} | |||
| <a class="ti-action-menu-item disabled" id="{{.VersionName}}-create-model" | |||
| onclick="showcreate({{.}})">{{$.i18n.Tr "repo.modelarts.create_model"}}</a> | |||
| {{end}} | |||
| </div> | |||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||
| <span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||
| @@ -501,12 +515,268 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div id="menuContent" class="menuContent" style="display:none; position: absolute;z-index:9999"> | |||
| <ul id="treeDemo" class="ztree" style="margin-top:0; width: 83%; height: 100%;"></ul> | |||
| </div> | |||
| <!-- 创建模型 --> | |||
| <div id="newmodel"> | |||
| <div class="ui modal second"> | |||
| <div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||
| <h4 id="model_header">导入新模型</h4> | |||
| </div> | |||
| <div class="content content-padding"> | |||
| <form id="formId" method="POST" class="ui form"> | |||
| <div class="ui error message"> | |||
| </div> | |||
| {{$.CsrfTokenHtml}} | |||
| <input type="hidden" name="trainTaskCreate" value="true"> | |||
| <div class="two inline fields "> | |||
| <div class="required ten wide field"> | |||
| <label style="margin-left: -23px;">选择训练任务</label> | |||
| <input type="hidden" class="width83" id="JobId" name="JobId" readonly required> | |||
| <input class="width83" id="JobName" readonly required> | |||
| </div> | |||
| <div class="required six widde field"> | |||
| <label>版本</label> | |||
| <input class="width70" id="VersionName" name="VersionName" readonly required> | |||
| </div> | |||
| </div> | |||
| <div class="required inline field" id="modelname"> | |||
| <label>模型名称</label> | |||
| <input style="width: 45%;" id="name" name="Name" required maxlength="25" | |||
| onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| </div> | |||
| <div class="required inline field" id="verionname"> | |||
| <label>模型版本</label> | |||
| <input style="width: 45%;" id="version" name="Version" value="" readonly required maxlength="255"> | |||
| </div> | |||
| <div class="unite min_title inline field required"> | |||
| <label>模型框架</label> | |||
| <input type="hidden" id="Engine" name="Engine" required> | |||
| <input style="width: 45%;" id="Engine_name" name="Engine_name" readonly required maxlength="255"> | |||
| </div> | |||
| <div class="unite min_title inline field required"> | |||
| <label>模型文件</label> | |||
| <input id="modelSelectedFile" type="text" style="width: 83%;" readonly required onclick="showMenu();" name="modelSelectedFile" > | |||
| </div> | |||
| <div class="inline field"> | |||
| <label>模型标签</label> | |||
| <input style="width: 83%;margin-left: 7px;" id="label" name="Label" maxlength="255" | |||
| placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
| </div> | |||
| <div class="inline field"> | |||
| <label for="description">模型描述</label> | |||
| <textarea style="width: 83%;margin-left: 7px;" id="Description" name="Description" rows="3" | |||
| maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.new_place"}}' | |||
| onchange="this.value=this.value.substring(0, 255)" | |||
| onkeydown="this.value=this.value.substring(0, 255)" | |||
| onkeyup="this.value=this.value.substring(0, 256)"></textarea> | |||
| </div> | |||
| <div class="inline field" style="margin-left: 75px;"> | |||
| <button onclick="createModel()" type="button" class="ui create_train_job green button" | |||
| style="position: absolute;"> | |||
| {{.i18n.Tr "repo.model.manage.sava_model"}} | |||
| </button> | |||
| </div> | |||
| </form> | |||
| <div class="actions" style="display: inline-block;margin-left: 180px;"> | |||
| <button class="ui button cancel">{{.i18n.Tr "repo.cloudbrain.cancel"}}</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js"></script> | |||
| <script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js"></script> | |||
| <script> | |||
| var setting = { | |||
| check: { | |||
| enable: true, | |||
| chkboxType: {"Y":"ps", "N":"ps"} | |||
| }, | |||
| view: { | |||
| dblClickExpand: false | |||
| }, | |||
| callback: { | |||
| beforeClick: beforeClick, | |||
| onCheck: onCheck | |||
| } | |||
| }; | |||
| function beforeClick(treeId, treeNode) { | |||
| var zTree = $.fn.zTree.getZTreeObj("treeDemo"); | |||
| zTree.checkNode(treeNode, !treeNode.checked, null, true); | |||
| return false; | |||
| } | |||
| function onCheck(e, treeId, treeNode) { | |||
| var zTree = $.fn.zTree.getZTreeObj("treeDemo"), | |||
| nodes = zTree.getCheckedNodes(true), | |||
| v = ""; | |||
| for (var i=0, l=nodes.length; i<l; i++) { | |||
| if(nodes[i].isParent){ | |||
| continue; | |||
| } | |||
| var pathNodes = nodes[i].getPath(); | |||
| var path =""; | |||
| for(var j=0;j<pathNodes.length;j++){ | |||
| if(j ==0){ | |||
| path += pathNodes[j].name; | |||
| }else{ | |||
| path += "/" + pathNodes[j].name; | |||
| } | |||
| } | |||
| v += path + ";"; | |||
| } | |||
| if (v.length > 0 ) v = v.substring(0, v.length-1); | |||
| var cityObj = $("#modelSelectedFile"); | |||
| cityObj.attr("value", v); | |||
| } | |||
| function showMenu() { | |||
| var cityObj = $("#modelSelectedFile"); | |||
| var cityOffset = $("#modelSelectedFile").offset(); | |||
| $("#menuContent").css({left:cityOffset.left + "px", top:cityOffset.top + cityObj.outerHeight() + "px"}).slideDown("fast"); | |||
| $("body").bind("mousedown", onBodyDown); | |||
| } | |||
| function hideMenu() { | |||
| $("#menuContent").fadeOut("fast"); | |||
| $("body").unbind("mousedown", onBodyDown); | |||
| } | |||
| function onBodyDown(event) { | |||
| if (!(event.target.id == "menuBtn" || event.target.id == "modelSelectedFile" || event.target.id == "menuContent" || $(event.target).parents("#menuContent").length>0)) { | |||
| hideMenu(); | |||
| } | |||
| } | |||
| function loadSelectedModelFile(trainJob){ | |||
| console.log("trainJob=" + trainJob); | |||
| $('#choice_file').dropdown('clear') | |||
| $("#model-file").empty() | |||
| if(trainJob ==null || trainJob ==""){ | |||
| console.log("trainJob is null"); | |||
| }else{ | |||
| $.get(`/${userName}/${repoPath}/modelmanage/query_train_model?jobName=${trainJob.JobName}&type=1&VersionName=${trainJob.VersionName}`, (data) => { | |||
| const n_length = data.length | |||
| let file_html='' | |||
| let firstFileName ='' | |||
| var zNodes=[]; | |||
| var nodesMap={}; | |||
| for (let i=0;i<n_length;i++){ | |||
| parentNodeMap = nodesMap; | |||
| var fileSplits = data[i].FileName.split("/"); | |||
| for(let j=0;j < fileSplits.length;j++){ | |||
| if(fileSplits[j] == ""){ | |||
| break; | |||
| } | |||
| if(parentNodeMap[fileSplits[j]] == null){ | |||
| parentNodeMap[fileSplits[j]] = {}; | |||
| } | |||
| parentNodeMap = parentNodeMap[fileSplits[j]] | |||
| } | |||
| } | |||
| convertToNode(zNodes,nodesMap); | |||
| $.fn.zTree.init($("#treeDemo"), setting, zNodes); | |||
| }) | |||
| } | |||
| } | |||
| function convertToNode(nodeList,nodesMap){ | |||
| var keyList = Object.keys(nodesMap); | |||
| keyList.sort(function(a,b){ | |||
| return a-b; | |||
| }); | |||
| var isFirst = true; | |||
| for(var i=0; i<keyList.length;i++){ | |||
| var node = {}; | |||
| node["name"] = keyList[i]; | |||
| nodeList.push(node); | |||
| if(nodesMap[keyList[i]] != null && Object.keys(nodesMap[keyList[i]]).length >0){ | |||
| node["children"]=[]; | |||
| if(isFirst){ | |||
| node["open"] = true; | |||
| isFirst= false; | |||
| } | |||
| convertToNode(node["children"],nodesMap[keyList[i]]); | |||
| } | |||
| } | |||
| } | |||
| function showcreate(obj) { | |||
| $('.ui.modal.second') | |||
| .modal({ | |||
| centered: false, | |||
| onShow: function () { | |||
| $('input[name="Version"]').addClass('model_disabled') | |||
| // $('input[name="JobId"]').text(obj.JobName) | |||
| $('#JobName').val(obj.DisplayJobName).addClass('model_disabled') | |||
| $('input[name="JobId"]').val(obj.JobID) | |||
| $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | |||
| if(obj.EngineID ==122 || obj.EngineID ==35){ | |||
| $('input[name="Engine_name"]').val("MindSpore").addClass('model_disabled'); | |||
| $('input[name="Engine"]').val(2); | |||
| } | |||
| if(obj.EngineID ==121){ | |||
| $('input[name="Engine_name"]').val("TensorFlow").addClass('model_disabled'); | |||
| $('input[name="Engine"]').val(1); | |||
| } | |||
| $('.ui.dimmer').css({ "background-color": "rgb(136, 136, 136,0.7)" }) | |||
| createModelName(); | |||
| loadSelectedModelFile(obj); | |||
| }, | |||
| onHide: function () { | |||
| var cityObj = $("#modelSelectedFile"); | |||
| cityObj.attr("value", ""); | |||
| document.getElementById("formId").reset(); | |||
| $('.ui.dimmer').css({ "background-color": "" }) | |||
| $('.ui.error.message').text() | |||
| $('.ui.error.message').css('display', 'none') | |||
| } | |||
| }) | |||
| .modal('show') | |||
| } | |||
| function createModel() { | |||
| let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | |||
| let data = $("#formId").serialize() | |||
| $("#mask").css({ "display": "block", "z-index": "9999" }) | |||
| $.ajax({ | |||
| url: url_href, | |||
| type: 'POST', | |||
| data: data, | |||
| success: function (res) { | |||
| $('input[name="Engine_name"]').val(""); | |||
| $('input[name="Engine"]').val(""); | |||
| location.href = `/${userName}/${repoPath}/modelmanage/show_model` | |||
| $('.ui.modal.second').modal('hide') | |||
| }, | |||
| error: function (xhr) { | |||
| // 隐藏 loading | |||
| // 只有请求不正常(状态码不为200)才会执行 | |||
| $('.ui.error.message').text(xhr.responseText) | |||
| $('.ui.error.message').css('display', 'block') | |||
| }, | |||
| complete: function (xhr) { | |||
| $("#mask").css({ "display": "none", "z-index": "1" }) | |||
| } | |||
| }) | |||
| } | |||
| function createModelName() { | |||
| let repoName = location.pathname.split('/')[2] | |||
| let modelName = repoName + '_model_' + Math.random().toString(36).substr(2, 4) | |||
| $('#name').val(modelName) | |||
| $('#version').val("0.0.1") | |||
| } | |||
| $('.menu .item').tab() | |||
| $(document).ready(function () { | |||