| @@ -152,6 +152,10 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||
| } | |||
| func SaveNewNameModel(ctx *context.Context) { | |||
| if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { | |||
| ctx.Error(403, ctx.Tr("repo.model_noright")) | |||
| return | |||
| } | |||
| name := ctx.Query("Name") | |||
| if name == "" { | |||
| ctx.Error(500, fmt.Sprintf("name or version is null.")) | |||
| @@ -169,6 +173,10 @@ func SaveNewNameModel(ctx *context.Context) { | |||
| } | |||
| func SaveModel(ctx *context.Context) { | |||
| if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { | |||
| ctx.Error(403, ctx.Tr("repo.model_noright")) | |||
| return | |||
| } | |||
| log.Info("save model start.") | |||
| JobId := ctx.Query("JobId") | |||
| VersionName := ctx.Query("VersionName") | |||
| @@ -177,16 +185,8 @@ func SaveModel(ctx *context.Context) { | |||
| label := ctx.Query("Label") | |||
| description := ctx.Query("Description") | |||
| engine := ctx.QueryInt("Engine") | |||
| trainTaskCreate := ctx.QueryBool("trainTaskCreate") | |||
| modelSelectedFile := ctx.Query("modelSelectedFile") | |||
| log.Info("engine=" + fmt.Sprint(engine) + " modelSelectedFile=" + modelSelectedFile) | |||
| if !trainTaskCreate { | |||
| if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { | |||
| //ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| ctx.JSON(403, ctx.Tr("repo.model_noright")) | |||
| return | |||
| } | |||
| } | |||
| if JobId == "" || VersionName == "" { | |||
| ctx.Error(500, fmt.Sprintf("JobId or VersionName is null.")) | |||
| @@ -421,7 +421,7 @@ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||
| } | |||
| ] | |||
| }, | |||
| @@ -472,9 +472,9 @@ | |||
| document.getElementById("mask").style.display = "none" | |||
| } | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function(e) { | |||
| send_run_para() | |||
| get_name() | |||
| validate() | |||
| }) | |||
| </script> | |||
| @@ -294,6 +294,27 @@ | |||
| context.value = '' | |||
| $(".icon.icons").css("visibility", "hidden") | |||
| } | |||
| function validate(){ | |||
| $('.ui.form').form({ | |||
| on: 'blur', | |||
| fields: { | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||
| } | |||
| ] | |||
| }, | |||
| }, | |||
| onSuccess: function(){ | |||
| }, | |||
| onFailure: function(e){ | |||
| return false; | |||
| } | |||
| }) | |||
| } | |||
| validate(); | |||
| form.onsubmit = function (e) { | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| let value_image = $("input[name='image']").val() | |||
| @@ -483,9 +483,9 @@ | |||
| $("input#ai_flaver_name").val(name2) | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function (e) { | |||
| get_name() | |||
| send_run_para() | |||
| validate() | |||
| send_run_para() | |||
| }) | |||
| </script> | |||
| @@ -427,6 +427,7 @@ | |||
| {{if .CanDebug}} | |||
| <a id="model-image-{{.Cloudbrain.ID}}" | |||
| class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button' | |||
| target="_blank" | |||
| href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image">{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| {{else}} | |||
| <a | |||
| @@ -433,9 +433,9 @@ | |||
| $("input#ai_flavor_name").val(name2) | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function(e) { | |||
| get_name() | |||
| send_run_para() | |||
| validate() | |||
| }) | |||
| </script> | |||
| @@ -425,9 +425,9 @@ | |||
| $("input#trainjob_work_server_num").val(val_server_num_select) | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function(e) { | |||
| get_name() | |||
| send_run_para() | |||
| validate() | |||
| }) | |||
| </script> | |||
| @@ -11,7 +11,7 @@ | |||
| {{template "base/alert" .}} | |||
| <div class="inline required field {{if .Err_CloneAddr}}error{{end}}"> | |||
| <label for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label> | |||
| <input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required> | |||
| <input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required autocomplete="off" /> | |||
| <span class="help"> | |||
| {{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}} | |||
| <br/>{{.i18n.Tr "repo.migrate.migrate_items_options"}} | |||
| @@ -438,7 +438,7 @@ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||
| } | |||
| ] | |||
| }, | |||
| @@ -489,9 +489,9 @@ | |||
| document.getElementById("mask").style.display = "none" | |||
| } | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function(e) { | |||
| send_run_para() | |||
| get_name() | |||
| validate() | |||
| }) | |||
| </script> | |||
| @@ -110,6 +110,28 @@ | |||
| $('#messageInfo').css('display','none') | |||
| function validate(){ | |||
| $('.ui.form').form({ | |||
| on: 'blur', | |||
| fields: { | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,36}$/]', | |||
| } | |||
| ] | |||
| }, | |||
| }, | |||
| onSuccess: function(){ | |||
| }, | |||
| onFailure: function(e){ | |||
| return false; | |||
| } | |||
| }) | |||
| } | |||
| validate(); | |||
| form.onsubmit = function(e){ | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| @@ -500,9 +500,9 @@ | |||
| $("input#trainjob_work_server_num").val(val_server_num_select) | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function (e) { | |||
| get_name() | |||
| send_run_para() | |||
| validate() | |||
| }) | |||
| </script> | |||
| @@ -6,7 +6,8 @@ | |||
| text-align: right; | |||
| } | |||
| .inline .ui.dropdown .text { | |||
| color: rgba(0, 0, 0, .87) !important | |||
| color: rgba(0, 0, 0, .87) !important; | |||
| max-width: 360px; | |||
| } | |||
| .newtext{ | |||
| left: 15px !important | |||
| @@ -6,7 +6,7 @@ | |||
| ref="table" | |||
| :data="tableData" | |||
| style="min-width: 100%" | |||
| row-key="ID" | |||
| row-key="rowKey" | |||
| lazy | |||
| :load="load" | |||
| :tree-props="{children: 'Children', hasChildren: 'hasChildren'}" | |||
| @@ -171,6 +171,7 @@ export default { | |||
| tableData[i].EngineName = this.getEngineName(tableData[i]) | |||
| tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | |||
| tableData[i].cName=tableData[i].Name | |||
| tableData[i].rowKey = tableData[i].ID + Math.random() | |||
| tableData[i].Name='' | |||
| tableData[i].VersionCount = '' | |||
| tableData[i].Children = true | |||
| @@ -310,18 +311,18 @@ export default { | |||
| const store = this.$refs.table.store | |||
| if(!this.loadNodeMap.get(row.cName)){ | |||
| const parent = store.states.data | |||
| const index = parent.findIndex(child => child.ID == row.ID) | |||
| const index = parent.findIndex(child => child.rowKey == row.rowKey) | |||
| this.getModelList() | |||
| }else{ | |||
| let {tree,treeNode,resolve} = this.loadNodeMap.get(row.cName) | |||
| const keys = Object.keys(store.states.lazyTreeNodeMap); | |||
| if(keys.includes(row.ID)){ | |||
| if(keys.includes(row.rowKey)){ | |||
| this.getModelList() | |||
| }else{ | |||
| let parentRow = store.states.data.find(child => child.cName == row.cName); | |||
| let childrenIndex = store.states.lazyTreeNodeMap[parentRow.ID].findIndex(child => child.ID == row.ID) | |||
| let childrenIndex = store.states.lazyTreeNodeMap[parentRow.rowKey].findIndex(child => child.rowKey == row.rowKey) | |||
| parentRow.VersionCount = parentRow.VersionCount-1 | |||
| const parent = store.states.lazyTreeNodeMap[parentRow.ID] | |||
| const parent = store.states.lazyTreeNodeMap[parentRow.rowKey] | |||
| if(parent.length===1){ | |||
| this.getModelList() | |||
| }else{ | |||
| @@ -379,8 +380,8 @@ export default { | |||
| } | |||
| }, | |||
| getModelList(){ | |||
| try { | |||
| this.$refs.table.store.states.lazyTreeNodeMap = {} | |||
| try { | |||
| this.loadNodeMap.clear(); | |||
| this.$axios.get(location.href+'_api',{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| @@ -391,6 +392,7 @@ export default { | |||
| for(let i=0;i<this.tableData.length;i++){ | |||
| TrainTaskInfo = JSON.parse(this.tableData[i].TrainTaskInfo) | |||
| this.tableData[i].cName=this.tableData[i].Name | |||
| this.tableData[i].rowKey=this.tableData[i].ID + Math.random() | |||
| this.tableData[i].EngineName = this.getEngineName(this.tableData[i]) | |||
| this.tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | |||
| this.tableData[i].hasChildren = res.data.data[i].VersionCount===1 ? false : true | |||
| @@ -215,16 +215,16 @@ | |||
| <div style="display:flex;align-items: center;justify-content: center;"> | |||
| <span v-if="scope.row.isPrivate" style="color: rgb(250, 140, 22);">私有</span> | |||
| <span v-else style="color: rgb(19, 194, 141);">公开</span> | |||
| <el-tooltip class="item" effect="dark" content="镜像提交中..." placement="top"> | |||
| <i v-if="scope.row.status===0" class="CREATING" style="margin-left:0.3rem"></i> | |||
| <el-tooltip v-if="scope.row.status===0" class="item" effect="dark" content="镜像提交中..." placement="top"> | |||
| <i class="CREATING" style="margin-left:0.3rem"></i> | |||
| </el-tooltip> | |||
| <el-tooltip class="item" effect="dark" content="检测提交镜像是否大小超过20G!" placement="top"> | |||
| <i v-if="scope.row.status===2" class="FAILED" style="margin-left:0.3rem"></i> | |||
| <el-tooltip v-if="scope.row.status===2" class="item" effect="dark" content="检测提交镜像是否大小超过20G!" placement="top"> | |||
| <i class="FAILED" style="margin-left:0.3rem"></i> | |||
| </el-tooltip> | |||
| <el-tooltip class="item" effect="dark" content="镜像提交成功" placement="top"> | |||
| <i v-if="scope.row.status===1" class="SUCCEEDED" style="margin-left:0.3rem"></i> | |||
| <el-tooltip v-if="scope.row.status===1" class="item" effect="dark" content="镜像提交成功" placement="top"> | |||
| <i class="SUCCEEDED" style="margin-left:0.3rem"></i> | |||
| </el-tooltip> | |||
| </div> | |||
| @@ -473,6 +473,7 @@ export default { | |||
| tableDataCustom: [], | |||
| starCustom:[], | |||
| loadingCustom:false, | |||
| refreshCustomTimer: null, | |||
| currentPageStar:1, | |||
| pageSizeStar:10, | |||
| @@ -485,6 +486,7 @@ export default { | |||
| methods: { | |||
| handleClick(tab, event) { | |||
| this.search = '' | |||
| this.stopImageListCustomRefresh(); | |||
| if(tab.name=="first"){ | |||
| this.paramsPublic.q = '' | |||
| this.getImageListPublic() | |||
| @@ -560,9 +562,31 @@ export default { | |||
| }); | |||
| this.loadingCustom = false | |||
| this.getImageListCustomRefresh() | |||
| }) | |||
| }, | |||
| getImageListCustomRefresh() { | |||
| this.stopImageListCustomRefresh(); | |||
| this.refreshCustomTimer = setInterval(() => { | |||
| this.tableDataCustom.forEach(item => { | |||
| if (item.status === 0) { | |||
| this.$axios.get(`/image/${item.id}`, {}).then((res) => { | |||
| const newData = res.data; | |||
| this.tableDataCustom.forEach(it => { | |||
| if (it.id === newData.id) { | |||
| it.status = newData.status; | |||
| } | |||
| }); | |||
| }) | |||
| } | |||
| }); | |||
| }, 5000); | |||
| }, | |||
| stopImageListCustomRefresh() { | |||
| this.refreshCustomTimer && clearInterval(this.refreshCustomTimer); | |||
| }, | |||
| getImageListStar(){ | |||
| this.loadingStar = true | |||
| this.$axios.get('/explore/images/star',{ | |||
| @@ -715,8 +739,10 @@ export default { | |||
| else{ | |||
| this.getImageListPublic() | |||
| } | |||
| }, | |||
| beforeDestroy() { | |||
| this.stopImageListCustomRefresh(); | |||
| } | |||
| }; | |||
| </script> | |||
| @@ -2950,13 +2950,13 @@ $(document).ready(async () => { | |||
| } | |||
| const $cloneAddr = $("#clone_addr"); | |||
| $cloneAddr.on("change", () => { | |||
| $cloneAddr.on("input change", () => { | |||
| const $repoName = $("#alias"); | |||
| const $owner = $("#ownerDropdown div.text").attr("title"); | |||
| const $urlAdd = | |||
| location.href.split("/")[0] + "//" + location.href.split("/")[2]; | |||
| if ($cloneAddr.val().length > 0 && $repoName.val().length === 0) { | |||
| // Only modify if repo_name input is blank | |||
| if ($cloneAddr.val().length > 0 /* && $repoName.val().length === 0 */) { | |||
| // modify when clone address change | |||
| const repoValue = $cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]; | |||
| $repoName.val($cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]); | |||
| $.get( | |||