|
|
|
@@ -1,215 +1,357 @@ |
|
|
|
{{template "base/head" .}} |
|
|
|
<!-- 弹窗 --> |
|
|
|
<div id="mask"> |
|
|
|
<div id="loadingPage"> |
|
|
|
<div class="rect1"></div> |
|
|
|
<div class="rect2"></div> |
|
|
|
<div class="rect3"></div> |
|
|
|
<div class="rect4"></div> |
|
|
|
<div class="rect5"></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 提示框 --> |
|
|
|
<div class="alert"></div> |
|
|
|
|
|
|
|
<div class="repository release dataset-list view"> |
|
|
|
{{template "repo/header" .}} |
|
|
|
<div class="ui container"> |
|
|
|
<div class="ui three column stackable grid"> |
|
|
|
<div class="column"> |
|
|
|
<h2>{{.i18n.Tr "repo.cloudbrain"}}</h2> |
|
|
|
</div> |
|
|
|
<div class="column"> |
|
|
|
</div> |
|
|
|
<div class="column right aligned"> |
|
|
|
{{if .Permission.CanWrite $.UnitTypeCloudBrain}} |
|
|
|
<a class="ui green button" href="{{.RepoLink}}/cloudbrain/create">{{.i18n.Tr "repo.cloudbrain.new"}}</a> |
|
|
|
{{end}} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="ui divider"></div> |
|
|
|
<div class="ui grid"> |
|
|
|
<div class="row"> |
|
|
|
<div class="ui sixteen wide column"> |
|
|
|
<div class="ui sixteen wide column"> |
|
|
|
<div class="ui two column stackable grid"> |
|
|
|
<div class="column"> |
|
|
|
</div> |
|
|
|
<div class="column right aligned"> |
|
|
|
<div class="ui right dropdown type jump item"> |
|
|
|
<span class="text"> |
|
|
|
{{template "repo/header" .}} |
|
|
|
<div class="ui container"> |
|
|
|
<div class="ui three column stackable grid"> |
|
|
|
<div class="column"> |
|
|
|
<h2>{{.i18n.Tr "repo.cloudbrain"}}</h2> |
|
|
|
</div> |
|
|
|
<div class="column"> |
|
|
|
</div> |
|
|
|
<div class="column right aligned"> |
|
|
|
{{if .Permission.CanWrite $.UnitTypeCloudBrain}} |
|
|
|
<a class="ui green button" href="{{.RepoLink}}/cloudbrain/create">{{.i18n.Tr "repo.cloudbrain.new"}}</a> {{end}} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="ui divider"></div> |
|
|
|
<div class="ui grid"> |
|
|
|
<div class="row"> |
|
|
|
<div class="ui sixteen wide column"> |
|
|
|
<div class="ui sixteen wide column"> |
|
|
|
<div class="ui two column stackable grid"> |
|
|
|
<div class="column"> |
|
|
|
</div> |
|
|
|
<div class="column right aligned"> |
|
|
|
<div class="ui right dropdown type jump item"> |
|
|
|
<span class="text"> |
|
|
|
{{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="dataset list"> |
|
|
|
{{range .Tasks}} |
|
|
|
<div class="ui grid item"> |
|
|
|
<div class="row"> |
|
|
|
<div class="five wide column"> |
|
|
|
<a class="title" href="{{$.Link}}/{{.JobID}}"> |
|
|
|
<span class="fitted">{{svg "octicon-tasklist" 16}}</span> |
|
|
|
<span class="fitted">{{.JobName}}</span> |
|
|
|
</a> |
|
|
|
</div> |
|
|
|
<div class="three wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> |
|
|
|
{{.Status}} |
|
|
|
</div> |
|
|
|
<div class="three wide column"> |
|
|
|
<span class="ui text center">{{svg "octicon-flame" 16}} {{TimeSinceUnix .CreatedUnix $.Lang}}</span> |
|
|
|
</div> |
|
|
|
<div class="one wide column"> |
|
|
|
<span class="ui text center clipboard"> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="dataset list"> |
|
|
|
{{range .Tasks}} |
|
|
|
<div class="ui grid item"> |
|
|
|
<div class="row"> |
|
|
|
<div class="five wide column"> |
|
|
|
<a class="title" href="{{$.Link}}/{{.JobID}}"> |
|
|
|
<span class="fitted">{{svg "octicon-tasklist" 16}}</span> |
|
|
|
<span class="fitted">{{.JobName}}</span> |
|
|
|
</a> |
|
|
|
</div> |
|
|
|
<div class="three wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> |
|
|
|
{{.Status}} |
|
|
|
</div> |
|
|
|
<div class="three wide column"> |
|
|
|
<span class="ui text center">{{svg "octicon-flame" 16}} {{TimeSinceUnix .CreatedUnix $.Lang}}</span> |
|
|
|
</div> |
|
|
|
<div class="one wide column"> |
|
|
|
<span class="ui text center clipboard"> |
|
|
|
<a class="title" href="{{$.Link}}/{{.JobID}}"> |
|
|
|
<span class="fitted">查看</span> |
|
|
|
</a> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
<div class="one wide column"> |
|
|
|
<span class="ui text center clipboard"> |
|
|
|
</a> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
<div class="one wide column"> |
|
|
|
<span class="ui text center clipboard"> |
|
|
|
<a class="title" href="{{if not .CanDebug}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/debug{{end}}" style="{{if not .CanDebug}}color:#CCCCCC{{end}}"> |
|
|
|
<span class="fitted">调试</span> |
|
|
|
</a> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
<div class="one wide column"> |
|
|
|
<span class="ui text center clipboard"> |
|
|
|
</a> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
<div class="one wide column"> |
|
|
|
<span class="ui text center clipboard"> |
|
|
|
<form id="stopForm-{{.JobID}}" action="{{if ne .Status "RUNNING"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/stop{{end}}" method="post"> |
|
|
|
{{$.CsrfTokenHtml}} |
|
|
|
<a class="fitted" onclick="document.getElementById('stopForm-{{.JobID}}').submit();" style="{{if ne .Status "RUNNING"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">停止</a> |
|
|
|
</form> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 打开弹窗按钮 --> |
|
|
|
<a class="imageBtn" style="{{if not .CanDebug}}color:#CCCCCC;cursor:pointer;pointer-events:none;{{end}}; font-size:16px; font-weight:bold" value="{{.CanDebug}}">提交镜像</a> |
|
|
|
<!-- 弹窗 --> |
|
|
|
<div id="imageModal" class="modal"> |
|
|
|
<!-- 弹窗内容 --> |
|
|
|
<div class="modal-content"> |
|
|
|
<span class="close">×</span> |
|
|
|
<form id="commitImageForm" action="{{$.Link}}/{{.JobID}}/commit_image" method="post"> |
|
|
|
{{$.CsrfTokenHtml}} |
|
|
|
<p>提交任务镜像</p> |
|
|
|
<div class="ui divider"></div> |
|
|
|
<div class="inline required field dis"> |
|
|
|
<label>镜像标签:</label> |
|
|
|
<input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255" style="width:75%"> |
|
|
|
</div> |
|
|
|
<div class="inline required field" style="position:relative;height:180px;"> |
|
|
|
<div style="height:20px;width:75px;"> |
|
|
|
<label>镜像描述:</label> |
|
|
|
</div> |
|
|
|
<div style="position:absolute;left:75px;top:0;width:75%"> |
|
|
|
<textarea name="description" rows="10" style="width:100%"></textarea> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="ui divider"></div> |
|
|
|
<div class="inline field"> |
|
|
|
<label></label> |
|
|
|
<button class="ui green button"> |
|
|
|
{{$.i18n.Tr "repo.cloudbrain.commit_image"}} |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</form> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{{end}} |
|
|
|
{{template "base/paginate" .}} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 接收结果 --> |
|
|
|
<iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe> |
|
|
|
|
|
|
|
<!-- 打开弹窗按钮 --> |
|
|
|
<a class="imageBtn" style="{{if not .CanDebug}}color:#CCCCCC;cursor:pointer;pointer-events:none;{{end}}; font-size:16px; font-weight:bold" value="{{.CanDebug}}">提交镜像</a> |
|
|
|
<!-- 弹窗 --> |
|
|
|
<div id="imageModal" class="modal"> |
|
|
|
<!-- 弹窗内容 --> |
|
|
|
<div class="modal-content"> |
|
|
|
<span class="close">×</span> |
|
|
|
<!-- target="_parent" --> |
|
|
|
<form id="commitImageForm" action="{{$.Link}}/{{.JobID}}/commit_image" method="post" target="iframeContent"> |
|
|
|
{{$.CsrfTokenHtml}} |
|
|
|
<p>提交任务镜像</p> |
|
|
|
<div class="ui divider"></div> |
|
|
|
<div class="inline required field dis"> |
|
|
|
<label>镜像标签:</label> |
|
|
|
<input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255" style="width:75%"> |
|
|
|
</div> |
|
|
|
<div class="inline required field" style="position:relative;height:180px;"> |
|
|
|
<div style="height:20px;width:75px;"> |
|
|
|
<label>镜像描述:</label> |
|
|
|
</div> |
|
|
|
<div style="position:absolute;left:75px;top:0;width:75%"> |
|
|
|
<textarea name="description" rows="10" style="width:100%"></textarea> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="ui divider"></div> |
|
|
|
<div class="inline field"> |
|
|
|
<label></label> |
|
|
|
<button class="ui green button" onclick="showmask()"> |
|
|
|
{{$.i18n.Tr "repo.cloudbrain.commit_image"}} |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</form> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{{end}} {{template "base/paginate" .}} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{{template "base/footer" .}} |
|
|
|
|
|
|
|
<script> |
|
|
|
$( document ).ready(function() { |
|
|
|
$( ".job-status" ).each(( index, job ) => { |
|
|
|
const jobID = job.dataset.jobid; |
|
|
|
const repoPath = job.dataset.repopath; |
|
|
|
if (job.textContent.trim() == 'STOPPED') { |
|
|
|
return |
|
|
|
} |
|
|
|
$(document).ready(function() { |
|
|
|
$(".job-status").each((index, job) => { |
|
|
|
const jobID = job.dataset.jobid; |
|
|
|
const repoPath = job.dataset.repopath; |
|
|
|
if (job.textContent.trim() == 'STOPPED') { |
|
|
|
return |
|
|
|
} |
|
|
|
$.get(`/api/v1/repos/${repoPath}/cloudbrain/${jobID}`, (data) => { |
|
|
|
const jobID = data.JobID |
|
|
|
const status = data.JobStatus |
|
|
|
$('#' + jobID).text(status) |
|
|
|
// console.log(data) |
|
|
|
}).fail(function(err) { |
|
|
|
console.log(err); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
$.get( `/api/v1/repos/${repoPath}/cloudbrain/${jobID}`, ( data ) => { |
|
|
|
const jobID = data.JobID |
|
|
|
const status = data.JobStatus |
|
|
|
$('#'+ jobID).text(status) |
|
|
|
// console.log(data) |
|
|
|
}).fail(function(err) { |
|
|
|
console.log( err ); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
// 获取弹窗 |
|
|
|
var modal = document.getElementById('imageModal'); |
|
|
|
|
|
|
|
// 获取弹窗 |
|
|
|
var modal = document.getElementById('imageModal'); |
|
|
|
|
|
|
|
// 打开弹窗的按钮对象 |
|
|
|
var btns = document.getElementsByClassName("imageBtn"); |
|
|
|
|
|
|
|
// 获取 <span> 元素,用于关闭弹窗 |
|
|
|
var spans = document.getElementsByClassName('close'); |
|
|
|
|
|
|
|
// 点击按钮打开弹窗 |
|
|
|
for(i=0;i<btns.length;i++){ |
|
|
|
btns[i].onclick = function() { |
|
|
|
modal.style.display = "block"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 点击 <span> (x), 关闭弹窗 |
|
|
|
for(i=0;i<spans.length;i++){ |
|
|
|
spans[i].onclick = function() { |
|
|
|
|
|
|
|
modal.style.display = "none"; |
|
|
|
} |
|
|
|
} |
|
|
|
// 打开弹窗的按钮对象 |
|
|
|
var btns = document.getElementsByClassName("imageBtn"); |
|
|
|
|
|
|
|
// 在用户点击其他地方时,关闭弹窗 |
|
|
|
window.onclick = function(event) { |
|
|
|
if (event.target == modal) { |
|
|
|
modal.style.display = "none"; |
|
|
|
} |
|
|
|
} |
|
|
|
// 获取 <span> 元素,用于关闭弹窗 |
|
|
|
var spans = document.getElementsByClassName('close'); |
|
|
|
|
|
|
|
</script> |
|
|
|
// 点击按钮打开弹窗 |
|
|
|
for (i = 0; i < btns.length; i++) { |
|
|
|
btns[i].onclick = function() { |
|
|
|
modal.style.display = "block"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 点击 <span> (x), 关闭弹窗 |
|
|
|
for (i = 0; i < spans.length; i++) { |
|
|
|
spans[i].onclick = function() { |
|
|
|
modal.style.display = "none"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
<style> |
|
|
|
/* 弹窗 (background) */ |
|
|
|
.modal { |
|
|
|
display: none; /* 默认隐藏 */ |
|
|
|
position: fixed; /* 固定定位 */ |
|
|
|
z-index: 1; /* 设置在顶层 */ |
|
|
|
left: 0; |
|
|
|
top: 0; |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
overflow: auto; |
|
|
|
background-color: rgb(0,0,0); |
|
|
|
background-color: rgba(0,0,0,0.4); |
|
|
|
} |
|
|
|
|
|
|
|
/* 弹窗内容 */ |
|
|
|
.modal-content { |
|
|
|
background-color: #fefefe; |
|
|
|
margin: 15% auto; |
|
|
|
padding: 20px; |
|
|
|
border: 1px solid #888; |
|
|
|
width: 25%; |
|
|
|
} |
|
|
|
|
|
|
|
/* 关闭按钮 */ |
|
|
|
.close { |
|
|
|
color: #aaa; |
|
|
|
float: right; |
|
|
|
font-size: 28px; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
|
|
|
|
.close:hover, |
|
|
|
.close:focus { |
|
|
|
color: black; |
|
|
|
text-decoration: none; |
|
|
|
cursor: pointer; |
|
|
|
} |
|
|
|
// 显示弹窗,弹出相应的信息 |
|
|
|
function showmask() { |
|
|
|
$('#imageModal').css('display', 'none') |
|
|
|
$('#mask').css('display', 'block') |
|
|
|
|
|
|
|
.dis{ |
|
|
|
margin-bottom:20px; |
|
|
|
} |
|
|
|
$("iframe[name=iframeContent]").on("load", function() { |
|
|
|
var responseText = $("iframe")[0].contentDocument.body.getElementsByTagName("pre")[0].innerHTML; |
|
|
|
var json1 = JSON.parse(responseText) |
|
|
|
$('#mask').css('display', 'none') |
|
|
|
parent.location.href |
|
|
|
|
|
|
|
if (json1.result_code === "0") { |
|
|
|
$('.alert').html('操作成功!').removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut(); |
|
|
|
} else { |
|
|
|
$('.alert').html(json1.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(5000).fadeOut(); |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style> |
|
|
|
/* 弹窗 */ |
|
|
|
|
|
|
|
#mask { |
|
|
|
position: fixed; |
|
|
|
top: 0px; |
|
|
|
left: 0px; |
|
|
|
right: 0px; |
|
|
|
bottom: 0px; |
|
|
|
filter: alpha(opacity=60); |
|
|
|
background-color: #777; |
|
|
|
z-index: 1000; |
|
|
|
display: none; |
|
|
|
opacity: 0.8; |
|
|
|
-moz-opacity: 0.5; |
|
|
|
padding-top: 100px; |
|
|
|
color: #000000 |
|
|
|
} |
|
|
|
|
|
|
|
#loadingPage { |
|
|
|
margin: 200px auto; |
|
|
|
width: 50px; |
|
|
|
height: 40px; |
|
|
|
text-align: center; |
|
|
|
font-size: 10px; |
|
|
|
display: block; |
|
|
|
} |
|
|
|
|
|
|
|
#loadingPage>div { |
|
|
|
background-color: green; |
|
|
|
height: 100%; |
|
|
|
width: 6px; |
|
|
|
display: inline-block; |
|
|
|
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out; |
|
|
|
animation: sk-stretchdelay 1.2s infinite ease-in-out; |
|
|
|
} |
|
|
|
|
|
|
|
#loadingPage .rect2 { |
|
|
|
-webkit-animation-delay: -1.1s; |
|
|
|
animation-delay: -1.1s; |
|
|
|
} |
|
|
|
|
|
|
|
#loadingPage .rect3 { |
|
|
|
-webkit-animation-delay: -1.0s; |
|
|
|
animation-delay: -1.0s; |
|
|
|
} |
|
|
|
|
|
|
|
#loadingPage .rect4 { |
|
|
|
-webkit-animation-delay: -0.9s; |
|
|
|
animation-delay: -0.9s; |
|
|
|
} |
|
|
|
|
|
|
|
#loadingPage .rect5 { |
|
|
|
-webkit-animation-delay: -0.8s; |
|
|
|
animation-delay: -0.8s; |
|
|
|
} |
|
|
|
|
|
|
|
@-webkit-keyframes sk-stretchdelay { |
|
|
|
0%, |
|
|
|
40%, |
|
|
|
100% { |
|
|
|
-webkit-transform: scaleY(0.4) |
|
|
|
} |
|
|
|
20% { |
|
|
|
-webkit-transform: scaleY(1.0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@keyframes sk-stretchdelay { |
|
|
|
0%, |
|
|
|
40%, |
|
|
|
100% { |
|
|
|
transform: scaleY(0.4); |
|
|
|
-webkit-transform: scaleY(0.4); |
|
|
|
} |
|
|
|
20% { |
|
|
|
transform: scaleY(1.0); |
|
|
|
-webkit-transform: scaleY(1.0); |
|
|
|
} |
|
|
|
} |
|
|
|
/* 消息框 */ |
|
|
|
|
|
|
|
.alert { |
|
|
|
display: none; |
|
|
|
position: fixed; |
|
|
|
width: 100%; |
|
|
|
z-index: 1001; |
|
|
|
padding: 15px; |
|
|
|
border: 1px solid transparent; |
|
|
|
border-radius: 4px; |
|
|
|
text-align: center; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
|
|
|
|
.alert-success { |
|
|
|
color: #3c763d; |
|
|
|
background-color: #dff0d8; |
|
|
|
border-color: #d6e9c6; |
|
|
|
} |
|
|
|
|
|
|
|
.alert-info { |
|
|
|
color: #31708f; |
|
|
|
background-color: #d9edf7; |
|
|
|
border-color: #bce8f1; |
|
|
|
} |
|
|
|
|
|
|
|
.alert-warning { |
|
|
|
color: #8a6d3b; |
|
|
|
background-color: #fcf8e3; |
|
|
|
border-color: #faebcc; |
|
|
|
} |
|
|
|
|
|
|
|
.alert-danger { |
|
|
|
color: #a94442; |
|
|
|
background-color: #f2dede; |
|
|
|
border-color: #ebccd1; |
|
|
|
} |
|
|
|
|
|
|
|
.modal { |
|
|
|
display: none; |
|
|
|
/* 默认隐藏 */ |
|
|
|
position: fixed; |
|
|
|
/* 固定定位 */ |
|
|
|
z-index: 1; |
|
|
|
/* 设置在顶层 */ |
|
|
|
left: 0; |
|
|
|
top: 0; |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
overflow: auto; |
|
|
|
background-color: rgb(0, 0, 0); |
|
|
|
background-color: rgba(0, 0, 0, 0.4); |
|
|
|
} |
|
|
|
/* 弹窗内容 */ |
|
|
|
|
|
|
|
.modal-content { |
|
|
|
background-color: #fefefe; |
|
|
|
margin: 15% auto; |
|
|
|
padding: 20px; |
|
|
|
border: 1px solid #888; |
|
|
|
width: 25%; |
|
|
|
} |
|
|
|
/* 关闭按钮 */ |
|
|
|
|
|
|
|
.close { |
|
|
|
color: #aaa; |
|
|
|
float: right; |
|
|
|
font-size: 28px; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
|
|
|
|
.close:hover, |
|
|
|
.close:focus { |
|
|
|
color: black; |
|
|
|
text-decoration: none; |
|
|
|
cursor: pointer; |
|
|
|
} |
|
|
|
|
|
|
|
.dis { |
|
|
|
margin-bottom: 20px; |
|
|
|
} |
|
|
|
</style> |