Browse Source

Merge remote-tracking branch 'origin/V20211228' into inference-job

tags/v1.22.1.2
liuzx 4 years ago
parent
commit
b31dc4d234
20 changed files with 227 additions and 73 deletions
  1. +4
    -1
      models/cloudbrain.go
  2. +1
    -0
      modules/cloudbrain/cloudbrain.go
  3. +2
    -6
      modules/modelarts/modelarts.go
  4. +4
    -0
      modules/storage/local.go
  5. +25
    -0
      modules/storage/minio.go
  6. +1
    -0
      modules/storage/storage.go
  7. +5
    -0
      package-lock.json
  8. +1
    -0
      package.json
  9. +23
    -1
      routers/api/v1/repo/modelarts.go
  10. +33
    -2
      routers/repo/cloudbrain.go
  11. +5
    -11
      routers/repo/modelarts.go
  12. +20
    -3
      templates/repo/cloudbrain/new.tmpl
  13. +2
    -1
      templates/repo/debugjob/index.tmpl
  14. +0
    -6
      templates/repo/header.tmpl
  15. +6
    -24
      templates/repo/modelarts/trainjob/index.tmpl
  16. +10
    -6
      templates/repo/modelarts/trainjob/show.tmpl
  17. +0
    -1
      templates/repo/modelmanage/index.tmpl
  18. +79
    -8
      templates/repo/modelmanage/showinfo.tmpl
  19. +5
    -2
      web_src/js/components/Model.vue
  20. +1
    -1
      web_src/less/index.less

+ 4
- 1
models/cloudbrain.go View File

@@ -19,6 +19,9 @@ type JobType string
type ModelArtsJobStatus string

const (
NPUResource = "NPU"
GPUResource = "CPU/GPU"

JobWaiting CloudbrainStatus = "WAITING"
JobStopped CloudbrainStatus = "STOPPED"
JobSucceeded CloudbrainStatus = "SUCCEEDED"
@@ -106,7 +109,7 @@ type Cloudbrain struct {
IsLatestVersion string //是否是最新版本,1是,0否
CommitID string //提交的仓库代码id
PreVersionName string //父版本名称
ComputeResource string `xorm:"-"` //计算资源,例如npu
ComputeResource string //计算资源,例如npu
EngineID int64 //引擎id

TrainUrl string //输出模型的obs路径


+ 1
- 0
modules/cloudbrain/cloudbrain.go View File

@@ -212,6 +212,7 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
Image: image,
GpuQueue: gpuQueue,
ResourceSpecId: resourceSpecId,
ComputeResource: models.GPUResource,
})

if err != nil {


+ 2
- 6
modules/modelarts/modelarts.go View File

@@ -51,10 +51,6 @@ const (
PerPage = 10
IsLatestVersion = "1"
NotLatestVersion = "0"
// ComputeResource = "NPU"
NPUResource = "NPU"
GPUResource = "CPU/GPU"
AllResource = "all"
DebugType = -1
VersionCount = 1

@@ -306,7 +302,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
DatasetName: attach.Name,
CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion,
//ComputeResource: NPUResource,
ComputeResource: models.NPUResource,
EngineID: req.EngineID,
TrainUrl: req.TrainUrl,
BranchName: req.BranchName,
@@ -389,7 +385,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job
CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion,
PreVersionName: req.PreVersionName,
ComputeResource: NPUResource,
ComputeResource: models.GPUResource,
EngineID: req.EngineID,
TrainUrl: req.TrainUrl,
BranchName: req.BranchName,


+ 4
- 0
modules/storage/local.go View File

@@ -80,3 +80,7 @@ func (l *LocalStorage) HasObject(path string) (bool, error) {
func (l *LocalStorage) UploadObject(fileName, filePath string) error {
return nil
}

func (l *LocalStorage) DeleteDir(dir string) error {
return nil
}

+ 25
- 0
modules/storage/minio.go View File

@@ -11,7 +11,9 @@ import (
"strings"
"time"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"

"github.com/minio/minio-go"
)

@@ -77,6 +79,29 @@ func (m *MinioStorage) Delete(path string) error {
return m.client.RemoveObject(m.bucket, m.buildMinioPath(path))
}

// Delete delete a file
func (m *MinioStorage) DeleteDir(dir string) error {
objectsCh := make(chan string)

// Send object names that are needed to be removed to objectsCh
go func() {
defer close(objectsCh)
// List all objects from a bucket-name with a matching prefix.
for object := range m.client.ListObjects(m.bucket, dir, true, nil) {
if object.Err != nil {
log.Error("ListObjects failed:%v", object.Err)
}
objectsCh <- object.Key
}
}()

for rErr := range m.client.RemoveObjects(m.bucket, objectsCh) {
log.Error("Error detected during deletion: ", rErr)
}

return nil
}

//Get Presigned URL for get object
func (m *MinioStorage) PresignedGetURL(path string, fileName string) (string, error) {
// Set request parameters for content-disposition.


+ 1
- 0
modules/storage/storage.go View File

@@ -23,6 +23,7 @@ type ObjectStorage interface {
Save(path string, r io.Reader) (int64, error)
Open(path string) (io.ReadCloser, error)
Delete(path string) error
DeleteDir(dir string) error
PresignedGetURL(path string, fileName string) (string, error)
PresignedPutURL(path string) (string, error)
HasObject(path string) (bool, error)


+ 5
- 0
package-lock.json View File

@@ -11655,6 +11655,11 @@
"autolinker": "~0.28.0"
}
},
"remixicon": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/remixicon/-/remixicon-2.5.0.tgz",
"integrity": "sha512-q54ra2QutYDZpuSnFjmeagmEiN9IMo56/zz5dDNitzKD23oFRw77cWo4TsrAdmdkPiEn8mxlrTqxnkujDbEGww=="
},
"remove-bom-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",


+ 1
- 0
package.json View File

@@ -42,6 +42,7 @@
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "4.0.2",
"qs": "6.9.4",
"remixicon": "2.5.0",
"spark-md5": "3.0.1",
"svg-sprite-loader": "5.0.0",
"svgo": "1.3.2",


+ 23
- 1
routers/api/v1/repo/modelarts.go View File

@@ -7,6 +7,7 @@ package repo

import (
"net/http"
"os"
"strconv"
"strings"

@@ -14,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
)

@@ -237,7 +239,7 @@ func DelTrainJobVersion(ctx *context.APIContext) {
JobID: jobID,
})
if err != nil {
ctx.ServerError("get VersionListCount faild", err)
ctx.ServerError("get VersionListCount failed", err)
return
}
if VersionListCount > 0 {
@@ -255,6 +257,8 @@ func DelTrainJobVersion(ctx *context.APIContext) {
return
}
}
} else { //已删除该任务下的所有版本
deleteJobStorage(task.JobName)
}

ctx.JSON(http.StatusOK, map[string]interface{}{
@@ -321,3 +325,21 @@ func ModelList(ctx *context.APIContext) {
"PageIsCloudBrain": true,
})
}

func deleteJobStorage(jobName string) error {
//delete local
localJobPath := setting.JobPath + jobName
err := os.RemoveAll(localJobPath)
if err != nil {
log.Error("RemoveAll(%s) failed:%v", localJobPath, err)
}

//delete oss
dirPath := setting.CodePathPrefix + jobName + "/"
err = storage.ObsRemoveObject(setting.Bucket, dirPath)
if err != nil {
log.Error("ObsRemoveObject(%s) failed:%v", localJobPath, err)
}

return nil
}

+ 33
- 2
routers/repo/cloudbrain.go View File

@@ -245,7 +245,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form)
return
}
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}

func CloudBrainRestart(ctx *context.Context) {
@@ -566,7 +566,9 @@ func CloudBrainDel(ctx *context.Context) {
ctx.ServerError("DeleteJob failed", err)
return
}
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")

deleteJobStorage(task.JobName, models.TypeCloudBrainOne)
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}

func CloudBrainShowModels(ctx *context.Context) {
@@ -840,6 +842,35 @@ func mkModelPath(modelPath string) error {
return nil
}

func deleteJobStorage(jobName string, cloudbrainType int) error {
//delete local
localJobPath := setting.JobPath + jobName
err := os.RemoveAll(localJobPath)
if err != nil {
log.Error("RemoveAll(%s) failed:%v", localJobPath, err)
}

//delete oss
if cloudbrainType == models.TypeCloudBrainOne {
dirPath := setting.CBCodePathPrefix + jobName + "/"
err = storage.Attachments.DeleteDir(dirPath)
if err != nil {
log.Error("DeleteDir(%s) failed:%v", localJobPath, err)
}
} else if cloudbrainType == models.TypeCloudBrainTwo {
//dirPath := setting.CodePathPrefix + jobName + "/"
//err = storage.ObsRemoveObject(setting.Bucket, dirPath)
//if err != nil {
// log.Error("ObsRemoveObject(%s) failed:%v", localJobPath, err)
//}
log.Info("no need to delete")
} else {
log.Error("cloudbrainType(%d) error", cloudbrainType)
}

return nil
}

func SyncCloudbrainStatus() {
cloudBrains, err := models.GetCloudBrainUnStoppedJob()
if err != nil {


+ 5
- 11
routers/repo/modelarts.go View File

@@ -56,11 +56,11 @@ func DebugJobIndex(ctx *context.Context) {
}
debugType := modelarts.DebugType
jobType := string(models.JobTypeDebug)
if debugListType == modelarts.GPUResource {
if debugListType == models.GPUResource {
debugType = models.TypeCloudBrainOne
jobType = ""
}
if debugListType == modelarts.NPUResource {
if debugListType == models.NPUResource {
debugType = models.TypeCloudBrainTwo
}

@@ -81,16 +81,10 @@ func DebugJobIndex(ctx *context.Context) {
for i, task := range ciTasks {
ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)

if task.Cloudbrain.Type == models.TypeCloudBrainOne {
ciTasks[i].Cloudbrain.ComputeResource = modelarts.GPUResource
} else if task.Cloudbrain.Type == models.TypeCloudBrainTwo {
ciTasks[i].Cloudbrain.ComputeResource = modelarts.NPUResource
}
ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource
}

pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
//pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "debugListType", "ListType")
ctx.Data["Page"] = pager
ctx.Data["PageIsCloudBrain"] = true
@@ -350,7 +344,7 @@ func NotebookDel(ctx *context.Context) {
return
}

ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}

func TrainJobIndex(ctx *context.Context) {
@@ -380,7 +374,7 @@ func TrainJobIndex(ctx *context.Context) {
for i, task := range tasks {
tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
tasks[i].ComputeResource = modelarts.NPUResource
tasks[i].ComputeResource = models.NPUResource
}

pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)


+ 20
- 3
templates/repo/cloudbrain/new.tmpl View File

@@ -93,6 +93,14 @@
display: none;
}

.icons{
/* position: absolute !important;
right: 150px;
top: 14px;
z-index: 2; */
}


</style>

<div id="mask">
@@ -182,9 +190,10 @@
</select>
</div>

<div class="inline required field">
<div class="inline required field" style="position: relative;">
<label>镜像</label>
<input type="text" list="cloudbrain_image" placeholder="选择镜像" name="image" required autofocus maxlength="254">
<i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i>
<datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image">
{{range .images}}
<option name="image" value="{{.Place}}">{{.PlaceView}}</option>
@@ -261,9 +270,17 @@
<script>
let form = document.getElementById('form_id');

$('#messageInfo').css('display','none')
let inputs = document.querySelectorAll('input[list]');
inputs[0].addEventListener('change', function() {
$(".icon.icons").css("visibility","visible")
});

$('#messageInfo').css('display','none')
function clearValue(){
context=inputs[0]
context.value=''
$(".icon.icons").css("visibility","hidden")
}
form.onsubmit = function(e){
let value_task = $("input[name='job_name']").val()
let value_image = $("input[name='image']").val()


+ 2
- 1
templates/repo/debugjob/index.tmpl View File

@@ -568,9 +568,10 @@
$('#' + JobID+'-icon').removeClass().addClass(res.status)
$('#' + JobID+ '-text').text(res.status)
if(res.status==="STOPPED"){
$('#model-debug-'+JobID).removeClass('blue').addClass('disabled').text("再次调试").css("margin","0")
$('#model-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0")
$('#model-image-'+JobID).removeClass('blue').addClass('disabled')
$('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled')
$('#model-delete-'+JobID).removeClass('disabled').addClass('blue')
}
else{
$('#model-debug-'+JobID).removeClass('blue').addClass('disabled')


+ 0
- 6
templates/repo/header.tmpl View File

@@ -149,12 +149,6 @@
{{.i18n.Tr "repo.model_manager"}}
</a>
{{end}}
{{if .Permission.CanRead $.UnitTypeModelManage}}
<a class="{{if .isModelManage}}active{{end}} item" href="{{.RepoLink}}/modelmanage/show_model">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M3.741 1.408l18.462 10.154a.5.5 0 0 1 0 .876L3.741 22.592A.5.5 0 0 1 3 22.154V1.846a.5.5 0 0 1 .741-.438zM5 13v6.617L18.85 12 5 4.383V11h5v2H5z"/></svg>
{{.i18n.Tr "repo.model_manager"}}
</a>
{{end}}
{{if .Permission.CanRead $.UnitTypeCloudBrain}}
<a class="{{if .PageIsCloudBrain}}active{{end}} item" href="{{.RepoLink}}/debugjob?debugListType=all">
<span>


+ 6
- 24
templates/repo/modelarts/trainjob/index.tmpl View File

@@ -121,7 +121,7 @@
</div>
<!-- 任务运行时间 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;" id="duration-{{.JobID}}"></span>
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span>
</div>
<!-- 计算资源 -->
<div class="two wide column text center padding0">
@@ -253,35 +253,18 @@
}
}

function loadJobDuration() {
$(".job-status").each((index, job) => {
const jobID = job.dataset.jobid;
const repoPath = job.dataset.repopath;
const versionname = job.dataset.version
$.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => {
console.log(data)
const duration = data.JobDuration
const jobID = data.JobID
$('#duration-'+jobID).text(duration)
})
})
}
$(document).ready(loadJobDuration);
// 加载任务状态
var timeid = window.setInterval(loadJobStatus, 15000);
$(document).ready(loadJobStatus);
function loadJobStatus() {
$(".job-status").each((index, job) => {
const jobID = job.dataset.jobid;
const repoPath = job.dataset.repopath;
const jobID = job.dataset.jobid
const repoPath = job.dataset.repopath
const versionname = job.dataset.version
if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED'
|| job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED'
|| job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') {
return
const status_text = $(`#${jobID}-text`).text()
if(['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'].includes(status_text)){
return
}

$.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => {
const jobID = data.JobID
const status = data.JobStatus
@@ -329,7 +312,6 @@
}
}
function stopVersion(version_name,jobID){
const url = '/api/v1/repos/{{$.RepoRelPath}}/modelarts/train-job/'+jobID+'/stop_version'
$.post(url,{version_name:version_name},(data)=>{
if(data.StatusOK===0){


+ 10
- 6
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -450,7 +450,6 @@ td, th {
{{template "base/footer" .}}

<script>
console.log({{.version_list_task}})
$('.menu .item').tab()

$(document).ready(function(){
@@ -495,14 +494,19 @@ td, th {
}
function loadJobStatus() {
$(".ui.accordion.border-according").each((index, job) => {
const jobID = job.dataset.jobid;
const repoPath = job.dataset.repopath;
const versionname = job.dataset.version
if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED'
|| job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED'
|| job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') {
return
// ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED']
// if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED'
// || job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED'
// || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') {
// return
// }
let status = $(`#${versionname}-status-span`).text()
if(['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'].includes(status)){
return
}
let stopArray=["KILLED","FAILED","START_FAILED","KILLING","COMPLETED"]
$.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => {


+ 0
- 1
templates/repo/modelmanage/index.tmpl View File

@@ -141,7 +141,6 @@
<script>
let repolink = {{.RepoLink}}
let repoId = {{$repository}}
let url_href = window.location.pathname.split('show_model')[0] + 'create_model'
const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config;
$('input[name="_csrf"]').val(csrf)



+ 79
- 8
templates/repo/modelmanage/showinfo.tmpl View File

@@ -110,7 +110,36 @@
</tr>
<tr>
<td class="ti-text-form-label text-width80">模型描述</td>
<td class="ti-text-form-content" ><div id="edit-td" style="display:flex"><span id="Description" title="" class="iword-elipsis"></span><i id="edit-pencil" data-id="" data-desc="" class="pencil alternate icon" style="cursor:pointer;vertical-align: top;" id="editor" onclick="editorFn(this)"></div></td>
<td class="ti-text-form-content" >
<div id="edit-td" style="display:flex">
<span id="Description" title="" class="iword-elipsis"></span>
<i id="edit-pencil" data-id="" data-desc="" class="pencil alternate icon" style="cursor:pointer;vertical-align: top;" id="editor" onclick="editorFn(this)"></i>
</div>
</td>
</tr>
<tr>
<td class="ti-text-form-label text-width80">代码版本</td>
<td class="ti-text-form-content word-elipsis"><span id="CodeBranch" title=""></span></td>
</tr>
<tr>
<td class="ti-text-form-label text-width80">启动文件</td>
<td class="ti-text-form-content word-elipsis"><span id="BootFile" title=""></span></td>
</tr>
<tr>
<td class="ti-text-form-label text-width80">训练数据集</td>
<td class="ti-text-form-content word-elipsis"><span id="DatasetName" title=""></span></td>
</tr>
<tr>
<td class="ti-text-form-label text-width80">运行参数</td>
<td class="ti-text-form-content word-elipsis"><span id="Parameters" title=""></span></td>
</tr>
<tr>
<td class="ti-text-form-label text-width80">规格</td>
<td class="ti-text-form-content word-elipsis"><span id="FlavorName" title=""></span></td>
</tr>
<tr>
<td class="ti-text-form-label text-width80">计算节点</td>
<td class="ti-text-form-content word-elipsis"><span id="WorkServerNumber" title=""></span></td>
</tr>
</tbody>
</table>
@@ -155,6 +184,7 @@ function changeInfo(version){
let returnArray = []
returnArray = transObj(versionData)
let [initObj,initModelAcc,id] = returnArray
editorCancel('','')
renderInfo(initObj,initModelAcc,id)
})
}
@@ -175,8 +205,15 @@ function loadInfo(){
})
}
function transObj(data){
let {ID,Name,Version,Label,Size,Description,CreatedUnix,Accuracy} = data[0]
let {ID,Name,Version,Label,Size,Description,CreatedUnix,Accuracy,CodeBranch,CodeCommitID,TrainTaskInfo} = data[0]
let modelAcc = JSON.parse(Accuracy)
TrainTaskInfo = JSON.parse(TrainTaskInfo)
// Parameters = JSON.parse(Parameters)
console.log("TrainTaskInfo",TrainTaskInfo)
let {Parameters} = TrainTaskInfo
Parameters = JSON.parse(Parameters)
Parameters = Parameters.parameter.length === 0 ? '--':Parameters.parameter
console.log(Parameters)
let size = tranSize(Size)
let time = transTime(CreatedUnix)
let initObj = {
@@ -186,6 +223,14 @@ function transObj(data){
Size:size,
CreateTime:time,
Description:Description || '--',
CodeBranch:CodeBranch || '--',
CodeCommitID:CodeCommitID || '--',
BootFile:TrainTaskInfo.BootFile || '--',
DatasetName:TrainTaskInfo.DatasetName || '--',
Parameters:TrainTaskInfo.Parameters || '--',
FlavorName:TrainTaskInfo.FlavorName || '--',
WorkServerNumber:TrainTaskInfo.WorkServerNumber || '--',
Parameters:Parameters
}
let initModelAcc = {
Accuracy: modelAcc.Accuracy || '--',
@@ -221,15 +266,16 @@ function tranSize(value){
function editorFn(context){
let id= context.dataset.id
let text = context.dataset.desc
console.log(id,text)
$('#edit-td').replaceWith("<div id='edit-div' style='width:80%;display: inline-block;'><textarea id='textarea-value' value='' rows='3' maxlength='255' style='width:80%;' id='edit-text'>"+text+"</textarea><i class='check icon' style='color: #50d4ab;' onclick='editorSure(\"" + text + "\",\"" + id + "\")'></i><i class='times icon' style='color: #f66f6a;' onclick='editorCancel(\"" + text + "\",\"" + id + "\")'></i></div>");
let textValue = text.replace(/enter;/g,'\r\n')
$('#edit-td').replaceWith(`<div id='edit-div' style='width:80%;display: inline-block;'><textarea id='textarea-value' value='' rows='3' maxlength='255' style='width:80%;white-space: nowrap;' id='edit-text'>${textValue}</textarea><i class='check icon' style='color: #50d4ab;' onclick='editorSure("${text}","${id}")'></i><i class='times icon' style='color: #f66f6a;' onclick='editorCancel("${text}","${id}")'></i></div>`);
}
function editorCancel(text,id){
$('#edit-div').replaceWith(`<div id="edit-td" style="display:flex;"><span id="Description" title="${text}" class="iword-elipsis">${text}</span><i id="edit-pencil" data-id="${id}" data-desc="${text}" class="pencil alternate icon" style="cursor:pointer;vertical-align: top;" id="editor" onclick="editorFn(this)"></div>`)
let objkey = text.replace(/enter;/g,'\r\n')
$('#edit-div').replaceWith(`<div id="edit-td" style="display:flex;"><span id="Description" title="${objkey}" class="iword-elipsis">${objkey}</span><i id="edit-pencil" data-id="${id}" data-desc="${text}" class="pencil alternate icon" style="cursor:pointer;vertical-align: top;" id="editor" onclick="editorFn(this)"></div>`)
}
function editorSure(text,id){
let description=$('#textarea-value').val()
let sourcetext = $('#textarea-value').val().replace(/\n/g,'enter;')
let data = {
ID:id,
Description:description
@@ -239,16 +285,18 @@ function editorSure(text,id){
type:'PUT',
data:data
}).done((res)=>{
$('#edit-div').replaceWith(`<div id="edit-td" style="display:flex;"><span id="Description" title="${description}" class="iword-elipsis">${description}</span><i id="edit-pencil" data-id="${id}" data-desc="${description}" class="pencil alternate icon" style="cursor:pointer;vertical-align: top;" id="editor" onclick="editorFn(this)"></div>`)
$('#edit-div').replaceWith(`<div id="edit-td" style="display:flex;"><span id="Description" title="${description}" class="iword-elipsis">${description}</span><i id="edit-pencil" data-id="${id}" data-desc="${sourcetext}" class="pencil alternate icon" style="cursor:pointer;vertical-align: top;" id="editor" onclick="editorFn(this)"></div>`)
})
}
function renderInfo(obj,accObj,id){
for(let key in obj){
if(key==="Description"){
let descriptionText=obj[key].replace(/\r\n|\n/g,'enter;')
$(`#${key}`).text(obj[key])
$(`#${key}`).attr("title",obj[key])

$('#edit-pencil').attr("data-id",id)
$('#edit-pencil').attr("data-desc",obj[key])
$('#edit-pencil').attr("data-desc",descriptionText)
}
else if(key==="Label"){
$('#Label').empty()
@@ -263,6 +311,29 @@ function renderInfo(obj,accObj,id){
}
$('#Label').append(html)
}
}
else if(key==="CodeCommitID"){
let codeCommit = obj[key].slice(0,10)
let html = `<a style="margin-left:1rem" class="ui label" title="${codeCommit}">${codeCommit}</a>`
$('#CodeBranch').append(html)

}
else if(key==="Parameters"){
console.log("obj[key",obj[key])
if(obj[key]==='--'){
$(`#${key}`).text(obj[key])
}else{
const parameterArray = obj[key].map(element => {
let labelValue = `${element.label}=${element.value}`
return labelValue
});
const parameter = parameterArray.join('; ')
console.log(parameter)
$(`#${key}`).text(parameter)
$(`#${key}`).attr("title",parameter)
}

}
else{
$(`#${key}`).text(obj[key])


+ 5
- 2
web_src/js/components/Model.vue View File

@@ -263,6 +263,7 @@ export default {
let cName = $("input[name='Name']").val()
let version = $("input[name='Version']").val()
let data = $("#formId").serialize()
let url_href = version === '0.0.1' ? context.url_create_newModel : context.url_create_newVersion
$("#mask").css({"display":"block","z-index":"9999"})
$.ajax({
url:url_href,
@@ -292,7 +293,7 @@ export default {
if(!this.loadNodeMap.get(row.cName)){
const parent = store.states.data
const index = parent.findIndex(child => child.ID == row.ID)
parent.splice(index, 1)
this.getModelList()
}else{
let {tree,treeNode,resolve} = this.loadNodeMap.get(row.cName)
const keys = Object.keys(store.states.lazyTreeNodeMap);
@@ -406,6 +407,8 @@ export default {
this.getModelList()
this.url = location.href.split('show_model')[0]
this.submitId.addEventListener("click", this.submit)
this.url_create_newVersion = this.url + 'create_model'
this.url_create_newModel = this.url + 'create_new_model'
},

beforeDestroy() { // 实例销毁之前对点击事件进行解绑
@@ -517,4 +520,4 @@ export default {
opacity: .45 !important;
}

</style>
</style>

+ 1
- 1
web_src/less/index.less View File

@@ -1,6 +1,6 @@
@import "~highlight.js/styles/github.css";
@import "./vendor/gitGraph.css";
// @import "~/remixicon/fonts/remixicon.css";
@import "_svg";
@import "_tribute";
@import "_base";


Loading…
Cancel
Save