| @ -1,139 +0,0 @@ | ||||
| function Recursion(node){ | ||||
|     var count=0; | ||||
|     for (var key in node) { | ||||
|       count++; | ||||
|       var value = node[key]; | ||||
|       delete node[key]; | ||||
|       //如果node为叶子节点
 | ||||
|       if (key.toString() == '$') { | ||||
|         for (var attr in value) | ||||
|           node[attr] = value[attr]; | ||||
|       } else { | ||||
|         if (value instanceof Array) { | ||||
|           if (value.length > 0) { | ||||
|             node["children"] = value; | ||||
|             for (var obj in value) | ||||
|               Recursion(value[obj]); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if(count==1) | ||||
|       node["children"]=[]; | ||||
| } | ||||
| 
 | ||||
| function randomString(len) { | ||||
|     len = len || 32; | ||||
|     var $chars = 'abcdefhijkmnprstwxyz'; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
 | ||||
|     var maxPos = $chars.length; | ||||
|     var pwd = ''; | ||||
|     for (i = 0; i < len; i++) { | ||||
|         pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); | ||||
|     } | ||||
|     return pwd; | ||||
| } | ||||
| 
 | ||||
| function compArray(array1,array2){ | ||||
|    if((array1&&typeof array1 ==="object"&&array1.constructor===Array)&&(array2&&typeof array2 ==="object"&&array2.constructor===Array)){ | ||||
|        if(array1.length==array2.length){ | ||||
|           for(var i=0;i<array1.length;i++){ | ||||
|              var ggg=compObj(array1[i],array2[i]); | ||||
|              if(!ggg) | ||||
|                 return false; | ||||
|           } | ||||
| 
 | ||||
|        }else{ | ||||
|           return false; | ||||
|       } | ||||
|    }else{ | ||||
|        throw new Error("argunment is  error ;"); | ||||
|    } | ||||
|    return true; | ||||
| }; | ||||
| 
 | ||||
| function compObj(obj1,obj2){//比较两个对象是否相等,不包含原形上的属性计较
 | ||||
|    if((obj1&&typeof obj1==="object")&&((obj2&&typeof obj2==="object"))){ | ||||
|        var count1=propertyLength(obj1); | ||||
|        var count2=propertyLength(obj2); | ||||
|        if(count1==count2){ | ||||
|            for(var ob in obj1){ | ||||
|                if(obj1.hasOwnProperty(ob)&&obj2.hasOwnProperty(ob)){ | ||||
|                    if(obj1[ob].constructor==Array&&obj2[ob].constructor==Array){//如果属性是数组
 | ||||
|                        if(!compArray(obj1[ob],obj2[ob])){ | ||||
|                            return false; | ||||
|                        }; | ||||
|                    }else if(typeof obj1[ob]==="string"&&typeof obj2[ob]==="string"){//纯属性
 | ||||
|                        if(obj1[ob]!==obj2[ob]){ | ||||
|                            return false; | ||||
|                        } | ||||
|                    }else if(typeof obj1[ob]==="object"&&typeof obj2[ob]==="object"){//属性是对象
 | ||||
|                        if(!compObj(obj1[ob],obj2[ob])){ | ||||
|                            return false; | ||||
|                        }; | ||||
|                    }else{ | ||||
|                        return false; | ||||
|                    } | ||||
|                }else{ | ||||
|                    return false; | ||||
|                } | ||||
|            } | ||||
|        }else{ | ||||
|            return false; | ||||
|        } | ||||
|    } | ||||
|     return true; | ||||
| }; | ||||
| 
 | ||||
| function propertyLength(obj){//获得对象上的属性个数,不包含对象原形上的属性
 | ||||
|    var count=0; | ||||
|    if(obj&&typeof obj==="object") { | ||||
|        for(var ooo in obj) { | ||||
|            if(obj.hasOwnProperty(ooo)) { | ||||
|                count++; | ||||
|            } | ||||
|        } | ||||
|        return count; | ||||
|    }else { | ||||
|        throw new Error("argunment can not be null;"); | ||||
|    } | ||||
| }; | ||||
| 
 | ||||
| function selectorMatches(selector,labels){ | ||||
| 	if(typeof(selector) === 'object'){ | ||||
| 		var answer = true; | ||||
| 		var count = 0; | ||||
| 		for(var key in selector){ | ||||
| 			count++; | ||||
| 			if(answer && labels[key] !== selector[key]) | ||||
| 				answer = false; | ||||
| 		} | ||||
| 
 | ||||
| 		return answer && count > 0; | ||||
| 	}else{ | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| Date.prototype.Format = function(fmt) | ||||
| { //author: meizz
 | ||||
|   var o = { | ||||
|     "M+" : this.getMonth()+1,                 //月份
 | ||||
|     "d+" : this.getDate(),                    //日
 | ||||
|     "h+" : this.getHours(),                   //小时
 | ||||
|     "m+" : this.getMinutes(),                 //分
 | ||||
|     "s+" : this.getSeconds(),                 //秒
 | ||||
|     "q+" : Math.floor((this.getMonth()+3)/3), //季度
 | ||||
|     "S"  : this.getMilliseconds()             //毫秒
 | ||||
|   }; | ||||
|   if(/(y+)/.test(fmt)) | ||||
|     fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); | ||||
|   for(var k in o) | ||||
|     if(new RegExp("("+ k +")").test(fmt)) | ||||
|   fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); | ||||
|   return fmt; | ||||
| } | ||||
| 
 | ||||
| exports.randomString = randomString; | ||||
| exports.Recursion = Recursion; | ||||
| exports.compObj = compObj; | ||||
| exports.selectorMatches = selectorMatches; | ||||
| @ -1,213 +0,0 @@ | ||||
| var fs = require('fs'), path = require('path'), util = require('util'), Stream = require('stream').Stream; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| module.exports = resumable = function(temporaryFolder){ | ||||
|   var $ = this; | ||||
|   $.temporaryFolder = temporaryFolder; | ||||
|   $.maxFileSize = null; | ||||
|   $.fileParameterName = 'file'; | ||||
| 
 | ||||
|   try { | ||||
|     fs.mkdirSync($.temporaryFolder); | ||||
|   }catch(e){} | ||||
| 
 | ||||
| 
 | ||||
|   var cleanIdentifier = function(identifier){ | ||||
|     return identifier.replace(/^0-9A-Za-z_-/img, ''); | ||||
|   } | ||||
| 
 | ||||
|   var getChunkFilename = function(chunkNumber, identifier){ | ||||
|     // Clean up the identifier
 | ||||
|     identifier = cleanIdentifier(identifier); | ||||
|     // What would the file name be?
 | ||||
|     return path.join($.temporaryFolder, './resumable-'+identifier+'.'+chunkNumber); | ||||
|   } | ||||
| 
 | ||||
|   var validateRequest = function(chunkNumber, chunkSize, totalSize, identifier, filename, fileSize){ | ||||
|     // Clean up the identifier
 | ||||
|     identifier = cleanIdentifier(identifier); | ||||
| 
 | ||||
|     // Check if the request is sane
 | ||||
|     if (chunkNumber==0 || chunkSize==0 || totalSize==0 || identifier.length==0 || filename.length==0) { | ||||
|       return 'non_resumable_request'; | ||||
|     } | ||||
|     var numberOfChunks = Math.max(Math.floor(totalSize/(chunkSize*1.0)), 1); | ||||
|     if (chunkNumber>numberOfChunks) { | ||||
|       return 'invalid_resumable_request1'; | ||||
|     } | ||||
| 
 | ||||
|     // Is the file too big?
 | ||||
|     if($.maxFileSize && totalSize>$.maxFileSize) { | ||||
|       return 'invalid_resumable_request2'; | ||||
|     } | ||||
| 
 | ||||
|     if(typeof(fileSize)!='undefined') { | ||||
|       if(chunkNumber<numberOfChunks && fileSize!=chunkSize) { | ||||
|         // The chunk in the POST request isn't the correct size
 | ||||
|         return 'invalid_resumable_request3'; | ||||
|       } | ||||
|       if(numberOfChunks>1 && chunkNumber==numberOfChunks && fileSize!=((totalSize%chunkSize)+chunkSize)) { | ||||
|         // The chunks in the POST is the last one, and the fil is not the correct size
 | ||||
|         return 'invalid_resumable_request4'; | ||||
|       } | ||||
|       if(numberOfChunks==1 && fileSize!=totalSize) { | ||||
|         // The file is only a single chunk, and the data size does not fit
 | ||||
|         return 'invalid_resumable_request5'; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return 'valid'; | ||||
|   } | ||||
| 
 | ||||
|   //'found', filename, original_filename, identifier
 | ||||
|   //'not_found', null, null, null
 | ||||
|   $.get = function(req, callback){ | ||||
|     var chunkNumber = req.param('resumableChunkNumber', 0); | ||||
|     var chunkSize = req.param('resumableChunkSize', 0); | ||||
|     var totalSize = req.param('resumableTotalSize', 0); | ||||
|     var identifier = req.param('resumableIdentifier', ""); | ||||
|     var filename = req.param('resumableFilename', ""); | ||||
| 
 | ||||
|     if(validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename)=='valid') { | ||||
|       var chunkFilename = getChunkFilename(chunkNumber, identifier); | ||||
|       fs.exists(chunkFilename, function(exists){ | ||||
|           if(exists){ | ||||
|             callback('found', chunkFilename, filename, identifier); | ||||
|           } else { | ||||
|             callback('not_found', chunkFilename, filename, identifier); | ||||
|           } | ||||
|         }); | ||||
|     } else { | ||||
|       callback('not_found2', chunkFilename, filename, identifier); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   //'partly_done', filename, original_filename, identifier
 | ||||
|   //'done', filename, original_filename, identifier
 | ||||
|   //'invalid_resumable_request', null, null, null
 | ||||
|   //'non_resumable_request', null, null, null
 | ||||
|   $.post = function(req, callback){ | ||||
| 
 | ||||
|     var fields = req.body; | ||||
|     var files = req.files; | ||||
| 
 | ||||
|     var chunkNumber = fields['resumableChunkNumber']; | ||||
|     var chunkSize = fields['resumableChunkSize']; | ||||
|     var totalSize = fields['resumableTotalSize']; | ||||
|     var identifier = cleanIdentifier(fields['resumableIdentifier']); | ||||
|     var filename = fields['resumableFilename']; | ||||
| 
 | ||||
| 		var original_filename = fields['resumableIdentifier']; | ||||
| 
 | ||||
|     if(!files[$.fileParameterName] || !files[$.fileParameterName].size) { | ||||
|       callback('invalid_resumable_request', null, null, null); | ||||
|       return; | ||||
|     } | ||||
|     var validation = validateRequest(chunkNumber, chunkSize, totalSize, identifier, files[$.fileParameterName].size); | ||||
|     if(validation=='valid') { | ||||
|       var chunkFilename = getChunkFilename(chunkNumber, identifier); | ||||
| 
 | ||||
|       // Save the chunk (TODO: OVERWRITE)
 | ||||
|       fs.rename(files[$.fileParameterName].path, chunkFilename, function(){ | ||||
| 
 | ||||
|         // Do we have all the chunks?
 | ||||
|         var currentTestChunk = 1; | ||||
|         var numberOfChunks = Math.max(Math.floor(totalSize/(chunkSize*1.0)), 1); | ||||
|         var testChunkExists = function(){ | ||||
|               fs.exists(getChunkFilename(currentTestChunk, identifier), function(exists){ | ||||
|                 if(exists){ | ||||
|                   currentTestChunk++; | ||||
|                   if(currentTestChunk>numberOfChunks) { | ||||
|                     callback('done', filename, original_filename, identifier); | ||||
|                   } else { | ||||
|                     // Recursion
 | ||||
|                     testChunkExists(); | ||||
|                   } | ||||
|                 } else { | ||||
|                   callback('partly_done', filename, original_filename, identifier); | ||||
|                 } | ||||
|               }); | ||||
|             } | ||||
|         testChunkExists(); | ||||
|       }); | ||||
|     } else { | ||||
|           callback(validation, filename, original_filename, identifier); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   // Pipe chunks directly in to an existsing WritableStream
 | ||||
|   //   r.write(identifier, response);
 | ||||
|   //   r.write(identifier, response, {end:false});
 | ||||
|   //
 | ||||
|   //   var stream = fs.createWriteStream(filename);
 | ||||
|   //   r.write(identifier, stream);
 | ||||
|   //   stream.on('data', function(data){...});
 | ||||
|   //   stream.on('end', function(){...});
 | ||||
|   $.write = function(identifier, writableStream, options) { | ||||
|       options = options || {}; | ||||
|       options.end = (typeof options['end'] == 'undefined' ? true : options['end']); | ||||
| 
 | ||||
|       // Iterate over each chunk
 | ||||
|       var pipeChunk = function(number) { | ||||
| 
 | ||||
|           var chunkFilename = getChunkFilename(number, identifier); | ||||
|            | ||||
|           fs.exists(chunkFilename, function(exists) { | ||||
| 
 | ||||
|               if (exists) { | ||||
|                   // If the chunk with the current number exists,
 | ||||
|                   // then create a ReadStream from the file
 | ||||
|                   // and pipe it to the specified writableStream.
 | ||||
|                   var sourceStream = fs.createReadStream(chunkFilename); | ||||
|                   sourceStream.pipe(writableStream, { | ||||
|                       end: false | ||||
|                   }); | ||||
|                   sourceStream.on('end', function() { | ||||
|                       // When the chunk is fully streamed,
 | ||||
|                       // jump to the next one
 | ||||
|                       pipeChunk(number + 1); | ||||
|                   }); | ||||
|               } else { | ||||
|                   // When all the chunks have been piped, end the stream
 | ||||
|                   if (options.end) writableStream.end(); | ||||
|                   if (options.onDone) options.onDone(); | ||||
|               } | ||||
|           }); | ||||
|       } | ||||
|       pipeChunk(1); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   $.clean = function(identifier, options) { | ||||
|       options = options || {}; | ||||
| 
 | ||||
|       // Iterate over each chunk
 | ||||
|       var pipeChunkRm = function(number) { | ||||
| 
 | ||||
|           var chunkFilename = getChunkFilename(number, identifier); | ||||
| 
 | ||||
|           //console.log('removing pipeChunkRm ', number, 'chunkFilename', chunkFilename);
 | ||||
|           fs.exists(chunkFilename, function(exists) { | ||||
|               if (exists) { | ||||
| 
 | ||||
|                   console.log('exist removing ', chunkFilename); | ||||
|                   fs.unlink(chunkFilename, function(err) { | ||||
|                       if (err && options.onError) options.onError(err); | ||||
|                   }); | ||||
| 
 | ||||
|                   pipeChunkRm(number + 1); | ||||
| 
 | ||||
|               } else { | ||||
| 
 | ||||
|                   if (options.onDone) options.onDone(); | ||||
| 
 | ||||
|               } | ||||
|           }); | ||||
|       } | ||||
|       pipeChunkRm(1); | ||||
|   } | ||||
| 
 | ||||
|   return $; | ||||
| } | ||||
| @ -1,216 +0,0 @@ | ||||
| /*   样式重置 */ | ||||
| body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;} | ||||
| body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#fff;} | ||||
| div,img,tr,td,table{ border:0;} | ||||
| table,tr,td{border:0;cellspacing:0; cellpadding:0;} | ||||
| ol,ul,li{ list-style-type:none} | ||||
| a:link,a:visited{color:#7f7f7f;text-decoration:none;} | ||||
| a:hover,a:active{color:#000;} | ||||
| .fl{ float:left;} | ||||
| .fr{ float:right;} | ||||
| .cl{ clear:both; overflow:hidden;} | ||||
| 
 | ||||
| /*   数据页面 */ | ||||
| .data_container{ | ||||
|   width:100%; | ||||
|   margin:0 auto; | ||||
| } | ||||
| .data_heaer{ | ||||
|   height:66px; | ||||
|   width:100%; | ||||
|   background-color:#3499db; | ||||
|   text-align:center; | ||||
| } | ||||
| .data_heaer h2{ | ||||
|   font-size:30px; | ||||
|   font-weight:300; | ||||
|   color:#fff; | ||||
|   line-height:66px; | ||||
| } | ||||
| .data_content{ | ||||
|   width:1280px; | ||||
|   height:838px; | ||||
|   margin:0 auto; | ||||
|   background-color:#fff; | ||||
|   border:1px solid #e0dede; | ||||
|   border-top:none; | ||||
| } | ||||
| .data_leftside{ | ||||
|   width:612px; | ||||
|   border-right:1px solid #e0dede; | ||||
| } | ||||
| .data_h3{ | ||||
|   width:100%; | ||||
|   text-align:center; | ||||
|   height:50px; | ||||
|   font-size:18px; | ||||
|   color:#444; | ||||
|   line-height:50px; | ||||
| } | ||||
| .data_leftside_files{ | ||||
|   border-right:1px solid #e0dede; | ||||
|    border-bottom:1px solid #e0dede; | ||||
|   height:710px; | ||||
|   overflow :auto; | ||||
| } | ||||
| .data_leftside_files input{ | ||||
|   margin-top:15px; | ||||
|   width:15px; | ||||
|   height:15px; | ||||
| } | ||||
| .data_leftside_files li{ | ||||
|   height:40px; | ||||
|   line-height:40px; | ||||
|   border-bottom:1px solid #e0dede; | ||||
|   padding:0 10px; | ||||
| } | ||||
| .data_leftside_files li.data_title{ | ||||
|   width:210px; height:36px; | ||||
|   line-height:36px; | ||||
|   text-align:center; | ||||
|   background-color:#e9f3fb; | ||||
|   border:none; | ||||
|    overflow:hidden; | ||||
|   text-overflow:ellipsis; | ||||
|   -o-text-overflow:ellipsis; | ||||
|   white-space:nowrap; | ||||
| } | ||||
| .date_label{ | ||||
|   display:block; | ||||
|   width:168px; | ||||
|   overflow:hidden; | ||||
|   text-overflow:ellipsis; | ||||
|   -o-text-overflow:ellipsis; | ||||
|   white-space:nowrap; | ||||
| } | ||||
| .data_leftside_shu{ | ||||
|   border-right:none; | ||||
| } | ||||
| .data_leftside_shu li{ | ||||
|   border-bottom:none; | ||||
| } | ||||
| .data_conbar{ width:149px; | ||||
|   height:834px; | ||||
|   border-right:1px solid #e0dede; | ||||
|   border-left:1px solid #e0dede; | ||||
| } | ||||
| .date_btns{ | ||||
| 	 width:260px; | ||||
|   margin:20px auto; | ||||
| } | ||||
| .date_btns_w{ | ||||
| 	 width:390px; | ||||
| } | ||||
| .date_btns button{ | ||||
|   margin:10px 20px; | ||||
| } | ||||
| .data_btn{ | ||||
|   border:none; | ||||
|   width:108px; | ||||
|   height:35px; | ||||
|   line-height:35px; | ||||
|   text-align:center; | ||||
|   background-color:#3499db; | ||||
|   color:#fff; | ||||
|   font-size:14px; | ||||
|   -webkit-border-radius:5px; | ||||
|   -moz-border-radius:5px; | ||||
|   -o-border-radius:5px; | ||||
|   border-radius:5px; | ||||
| } | ||||
| .data_btn:hover{ | ||||
|   background-color:#2989da; | ||||
| } | ||||
| .data_rightside{ | ||||
|   width:667px; | ||||
| } | ||||
| .data_rightside_w{ | ||||
|   width:407px; | ||||
| } | ||||
| .data_leftside_files li.data_title_w{ | ||||
|   width:183px; | ||||
| } | ||||
| .date_label_w{ | ||||
|   width:150px; | ||||
| } | ||||
| .data_leftside_shu li{ | ||||
|   border-bottom:none; | ||||
| } | ||||
| 
 | ||||
| a.data_file_btn{ display:block; position:relative; width:108px; height:35px; margin:15px auto; line-height:35px; font-size:14px;  color: #fff; text-align:center; | ||||
|   background-color: #79b4e7; | ||||
|   background-image: -webkit-linear-gradient(#79b4e7, #1377cf); | ||||
|   background-image: linear-gradient(#79b4e7, #1377cf); | ||||
|   border-color: #076bc2; | ||||
|   -webkit-border-radius:5px; | ||||
|   -moz-border-radius:5px; | ||||
|   -o-border-radius:5px; | ||||
|   border-radius:5px; | ||||
|   vertical-align: middle; | ||||
|   cursor: pointer; | ||||
|   margin:0 10px; | ||||
| } | ||||
| a:hover.data_file_btn{ | ||||
|   background-color: #076bc2; | ||||
|   background-image: -webkit-linear-gradient(#79b4e7, #076bc2); | ||||
|   background-image: linear-gradient(#79b4e7, #076bc2); | ||||
|   border-color: #076bc2;} | ||||
| .data_file_btn input{ position:absolute; left:0px;opacity:0; filter:alpha(opacity=0); width:108px; height:35px;} | ||||
| 
 | ||||
| 
 | ||||
| .data_conbox{ | ||||
| 	width:407px; | ||||
| 	 height:709px; | ||||
| 	 border-top:1px solid #e0dede; | ||||
| 	 border-bottom:1px solid #e0dede; | ||||
| 	 overflow: auto; | ||||
| 	 } | ||||
| .data_con_title{ | ||||
| 	width:49.8%; | ||||
| 	height:36px; | ||||
|   line-height:36px; | ||||
|   text-align:center; | ||||
|   background-color:#e9f3fb; | ||||
|    overflow:hidden; | ||||
|   text-overflow:ellipsis; | ||||
|   -o-text-overflow:ellipsis; | ||||
|   white-space:nowrap; | ||||
|   } | ||||
|   .data_con_line{ | ||||
| 	  border-right:1px solid #e0dede; | ||||
| 	   | ||||
| 	  } | ||||
| .data_con_li{ | ||||
| 	width:49.8%; | ||||
| 	height:36px; | ||||
|   line-height:36px; | ||||
|   overflow:hidden; | ||||
|   text-overflow:ellipsis; | ||||
|   -o-text-overflow:ellipsis; | ||||
|   white-space:nowrap; | ||||
|    border-bottom:1px solid #e0dede; | ||||
| 	} | ||||
| .mt15{ margin-top:15px;} | ||||
| 
 | ||||
| 
 | ||||
| /*   树形结构 */ | ||||
| .data_rightside_tree{ | ||||
|   width:259px; | ||||
|   height:709px; | ||||
|   border-right:1px solid #e0dede; | ||||
|   border-top:1px solid #e0dede; | ||||
|   border-bottom:1px solid #e0dede; | ||||
|   overflow: auto; | ||||
| } | ||||
| .tree { min-height:20px;padding:15px;padding-left:30px;border-bottom:1px dashed #ccc;} | ||||
| .tree li {list-style-type:none;margin:0; padding:10px 5px 0 20px; position:relative} | ||||
| .tree li::before, .tree li::after { content:'';left:-30px;position:absolute; right:auto} | ||||
| .tree li::before { border-left:1px solid #999; bottom:50px;height:100%; top:0; width:0px} | ||||
| .tree li::after {border-top:1px solid #999;height:20px; top:25px; width:35px} | ||||
| .tree li p {display:inline-block;padding:3px 10px;border:1px solid #fff; margin-left:-15px; width:150px; } | ||||
| .tree li.parent_li>p {cursor:pointer} | ||||
| .tree>ul>li::before, .tree>ul>li::after {border:0} | ||||
| .tree li:last-child::before { height:30px} | ||||
| .tree li.parent_li>p:hover, .tree li.parent_li>p:hover+ul li p {  } | ||||
| .icon-plus-sign{ margin-left:-15px;  background:url(../img/icons1.gif)  -5px 10px no-repeat;   } | ||||
| .icon-minus-sign{ margin-left:-15px;  background:url(../img/icons2.gif)  -6px 9px no-repeat;} | ||||
| @ -1 +0,0 @@ | ||||
| 1 | ||||
| @ -0,0 +1,10 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="developerHelpers.d.ts" />
 | ||||
| declare module Developer { | ||||
|     var _module: ng.IModule; | ||||
|     var controller: (name: string, inlineAnnotatedConstructor: any[]) => ng.IModule; | ||||
|     var route: (templateName: string, reloadOnSearch?: boolean) => { | ||||
|         templateUrl: string; | ||||
|         reloadOnSearch: boolean; | ||||
|     }; | ||||
| } | ||||
| @ -0,0 +1,10 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="developerHelpers.d.ts" />
 | ||||
| declare module Developer { | ||||
|     var _module: ng.IModule; | ||||
|     var controller: (name: string, inlineAnnotatedConstructor: any[]) => ng.IModule; | ||||
|     var route: (templateName: string, reloadOnSearch?: boolean) => { | ||||
|         templateUrl: string; | ||||
|         reloadOnSearch: boolean; | ||||
|     }; | ||||
| } | ||||
| @ -0,0 +1,10 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="developerHelpers.d.ts" />
 | ||||
| declare module Developer { | ||||
|     var _module: ng.IModule; | ||||
|     var controller: (name: string, inlineAnnotatedConstructor: any[]) => ng.IModule; | ||||
|     var route: (templateName: string, reloadOnSearch?: boolean) => { | ||||
|         templateUrl: string; | ||||
|         reloadOnSearch: boolean; | ||||
|     }; | ||||
| } | ||||
| @ -1,5 +1,5 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     var BuildConfigsController: ng.IModule; | ||||
| } | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     var BuildConfigsController: ng.IModule; | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesHelpers.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     var PodController: ng.IModule; | ||||
| } | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesHelpers.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     var PodController: ng.IModule; | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesHelpers.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     var KubernetesJsonDirective: ng.IModule; | ||||
| } | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesHelpers.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     var KubernetesJsonDirective: ng.IModule; | ||||
| } | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     class oracleModelService { | ||||
|         oraclecontrollers: any[]; | ||||
|         oracleControllers: Array<any>; | ||||
|         findIndexOfOracleControllers(oracleControllers: Array<any>, name: string): number; | ||||
|     } | ||||
| } | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| /// <reference path="kubernetesPlugin.d.ts" />
 | ||||
| declare module Kubernetes { | ||||
|     class oracleModelService { | ||||
|         oraclecontrollers: any[]; | ||||
|         oracleControllers: Array<any>; | ||||
|         findIndexOfOracleControllers(oracleControllers: Array<any>, name: string): number; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,30 +1,30 @@ | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| declare module Service { | ||||
|     var pluginName: string; | ||||
|     var log: Logging.Logger; | ||||
|     /** | ||||
|      * Used to specify whether the "service" URL should be polled for services using kubernetes or kubernetes-like service discover. | ||||
|      * For more details see: https://github.com/hawtio/hawtio/blob/master/docs/Services.md
 | ||||
|      */ | ||||
|     var pollServices: boolean; | ||||
|     /** | ||||
|      * Returns true if there is a service available for the given ID or false | ||||
|      */ | ||||
|     function hasService(ServiceRegistry: any, serviceName: string): boolean; | ||||
|     /** | ||||
|      * Returns the service for the given service name (ID) or null if it cannot be found | ||||
|      * | ||||
|      * @param ServiceRegistry | ||||
|      * @param serviceName | ||||
|      * @return {null} | ||||
|      */ | ||||
|     function findService(ServiceRegistry: any, serviceName: string): any; | ||||
|     /** | ||||
|      * Returns the service link for the given service name | ||||
|      * | ||||
|      * @param ServiceRegistry | ||||
|      * @param serviceName | ||||
|      * @return {null} | ||||
|      */ | ||||
|     function serviceLink(ServiceRegistry: any, serviceName: string): string; | ||||
| } | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| declare module Service { | ||||
|     var pluginName: string; | ||||
|     var log: Logging.Logger; | ||||
|     /** | ||||
|      * Used to specify whether the "service" URL should be polled for services using kubernetes or kubernetes-like service discover. | ||||
|      * For more details see: https://github.com/hawtio/hawtio/blob/master/docs/Services.md
 | ||||
|      */ | ||||
|     var pollServices: boolean; | ||||
|     /** | ||||
|      * Returns true if there is a service available for the given ID or false | ||||
|      */ | ||||
|     function hasService(ServiceRegistry: any, serviceName: string): boolean; | ||||
|     /** | ||||
|      * Returns the service for the given service name (ID) or null if it cannot be found | ||||
|      * | ||||
|      * @param ServiceRegistry | ||||
|      * @param serviceName | ||||
|      * @return {null} | ||||
|      */ | ||||
|     function findService(ServiceRegistry: any, serviceName: string): any; | ||||
|     /** | ||||
|      * Returns the service link for the given service name | ||||
|      * | ||||
|      * @param ServiceRegistry | ||||
|      * @param serviceName | ||||
|      * @return {null} | ||||
|      */ | ||||
|     function serviceLink(ServiceRegistry: any, serviceName: string): string; | ||||
| } | ||||
|  | ||||
| @ -1,19 +1,19 @@ | ||||
| /// <reference path="serviceHelpers.d.ts" />
 | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| declare module Service { | ||||
|     interface SelectorMap { | ||||
|         [name: string]: string; | ||||
|     } | ||||
|     interface Service { | ||||
|         kind: string; | ||||
|         id: string; | ||||
|         portalIP: string; | ||||
|         selector?: SelectorMap; | ||||
|         port: number; | ||||
|         containerPort: number; | ||||
|     } | ||||
|     interface ServiceResponse { | ||||
|         items: Array<Service>; | ||||
|     } | ||||
|     var _module: ng.IModule; | ||||
| } | ||||
| /// <reference path="serviceHelpers.d.ts" />
 | ||||
| /// <reference path="../../includes.d.ts" />
 | ||||
| declare module Service { | ||||
|     interface SelectorMap { | ||||
|         [name: string]: string; | ||||
|     } | ||||
|     interface Service { | ||||
|         kind: string; | ||||
|         id: string; | ||||
|         portalIP: string; | ||||
|         selector?: SelectorMap; | ||||
|         port: number; | ||||
|         containerPort: number; | ||||
|     } | ||||
|     interface ServiceResponse { | ||||
|         items: Array<Service>; | ||||
|     } | ||||
|     var _module: ng.IModule; | ||||
| } | ||||
|  | ||||
| @ -1,108 +1,108 @@ | ||||
| /* console specific stuff here */ | ||||
| body { | ||||
|   padding-top: 110px; | ||||
| } | ||||
| .pane { | ||||
|   top: 110px; | ||||
| } | ||||
| .navbar-brand > img { | ||||
|   height: 20px; | ||||
|   margin-top: -5px; | ||||
|   margin-bottom: -5px; | ||||
| } | ||||
| 
 | ||||
| .navbar-persistent { | ||||
|   background: #f6f6f6; | ||||
|   border-bottom: 1px solid #cecdcd; | ||||
|   padding: 0; | ||||
|   width: 100%; | ||||
| } | ||||
| .navbar-persistent > li.active:before, | ||||
| .navbar-persistent > li.active:hover:before { | ||||
|   background: #0099d3; | ||||
|   bottom: -1px; | ||||
|   content: ''; | ||||
|   display: block; | ||||
|   height: 2px; | ||||
|   left: 20px; | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
| } | ||||
| .navbar-persistent > li.active > a, | ||||
| .navbar-persistent > li.active > a:hover, | ||||
| .navbar-persistent > li.active:hover > a { | ||||
|   background: transparent !important; | ||||
|   color: #0099d3 !important; | ||||
| } | ||||
| .navbar-persistent > li.active .active > a { | ||||
|   color: #f1f1f1; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu:hover > .dropdown-menu { | ||||
|   display: none; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu.open > .dropdown-menu { | ||||
|   display: block; | ||||
|   left: 20px; | ||||
|   margin-top: 1px; | ||||
|   top: 100%; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu.open > .dropdown-toggle { | ||||
|   color: #222222; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu.open > .dropdown-toggle:after { | ||||
|   border-top-color: #222222; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu > .dropdown-toggle { | ||||
|   padding-right: 35px !important; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu > .dropdown-toggle:after { | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
|   top: 10px; | ||||
| } | ||||
| .navbar-persistent > li:hover:before, | ||||
| .navbar-persistent > li.open:before { | ||||
|   background: #aaaaaa; | ||||
|   bottom: -1px; | ||||
|   content: ''; | ||||
|   display: block; | ||||
|   height: 2px; | ||||
|   left: 20px; | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
| } | ||||
| .navbar-persistent > li:hover > a, | ||||
| .navbar-persistent > li.open > a { | ||||
|   color: #222222; | ||||
| } | ||||
| .navbar-persistent > li:hover > a:after, | ||||
| .navbar-persistent > li.open > a:after { | ||||
|   border-top-color: #222222; | ||||
| } | ||||
| .navbar-persistent > li > a { | ||||
|   background-color: transparent; | ||||
|   display: block; | ||||
|   line-height: 1; | ||||
|   padding: 9px 20px !important; | ||||
| } | ||||
| .navbar-persistent > li > a.dropdown-toggle { | ||||
|   padding-right: 35px; | ||||
| } | ||||
| .navbar-persistent > li > a.dropdown-toggle:after { | ||||
|   font-size: 15px; | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
|   top: 9px; | ||||
| } | ||||
| .navbar-persistent > li > a:hover { | ||||
|   color: #222222 !important; | ||||
| } | ||||
| .navbar-persistent > li a { | ||||
|   color: #4d5258 !important; | ||||
| } | ||||
| .navbar-pf .navbar-primary > li > a { | ||||
|   border-bottom: 1px solid transparent; | ||||
|   border-top: 1px solid transparent; | ||||
|   position: relative; | ||||
|   margin: -1px 0 0; | ||||
| } | ||||
| /* console specific stuff here */ | ||||
| body { | ||||
|   padding-top: 110px; | ||||
| } | ||||
| .pane { | ||||
|   top: 110px; | ||||
| } | ||||
| .navbar-brand > img { | ||||
|   height: 20px; | ||||
|   margin-top: -5px; | ||||
|   margin-bottom: -5px; | ||||
| } | ||||
| 
 | ||||
| .navbar-persistent { | ||||
|   background: #f6f6f6; | ||||
|   border-bottom: 1px solid #cecdcd; | ||||
|   padding: 0; | ||||
|   width: 100%; | ||||
| } | ||||
| .navbar-persistent > li.active:before, | ||||
| .navbar-persistent > li.active:hover:before { | ||||
|   background: #0099d3; | ||||
|   bottom: -1px; | ||||
|   content: ''; | ||||
|   display: block; | ||||
|   height: 2px; | ||||
|   left: 20px; | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
| } | ||||
| .navbar-persistent > li.active > a, | ||||
| .navbar-persistent > li.active > a:hover, | ||||
| .navbar-persistent > li.active:hover > a { | ||||
|   background: transparent !important; | ||||
|   color: #0099d3 !important; | ||||
| } | ||||
| .navbar-persistent > li.active .active > a { | ||||
|   color: #f1f1f1; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu:hover > .dropdown-menu { | ||||
|   display: none; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu.open > .dropdown-menu { | ||||
|   display: block; | ||||
|   left: 20px; | ||||
|   margin-top: 1px; | ||||
|   top: 100%; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu.open > .dropdown-toggle { | ||||
|   color: #222222; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu.open > .dropdown-toggle:after { | ||||
|   border-top-color: #222222; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu > .dropdown-toggle { | ||||
|   padding-right: 35px !important; | ||||
| } | ||||
| .navbar-persistent > li.dropdown-submenu > .dropdown-toggle:after { | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
|   top: 10px; | ||||
| } | ||||
| .navbar-persistent > li:hover:before, | ||||
| .navbar-persistent > li.open:before { | ||||
|   background: #aaaaaa; | ||||
|   bottom: -1px; | ||||
|   content: ''; | ||||
|   display: block; | ||||
|   height: 2px; | ||||
|   left: 20px; | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
| } | ||||
| .navbar-persistent > li:hover > a, | ||||
| .navbar-persistent > li.open > a { | ||||
|   color: #222222; | ||||
| } | ||||
| .navbar-persistent > li:hover > a:after, | ||||
| .navbar-persistent > li.open > a:after { | ||||
|   border-top-color: #222222; | ||||
| } | ||||
| .navbar-persistent > li > a { | ||||
|   background-color: transparent; | ||||
|   display: block; | ||||
|   line-height: 1; | ||||
|   padding: 9px 20px !important; | ||||
| } | ||||
| .navbar-persistent > li > a.dropdown-toggle { | ||||
|   padding-right: 35px; | ||||
| } | ||||
| .navbar-persistent > li > a.dropdown-toggle:after { | ||||
|   font-size: 15px; | ||||
|   position: absolute; | ||||
|   right: 20px; | ||||
|   top: 9px; | ||||
| } | ||||
| .navbar-persistent > li > a:hover { | ||||
|   color: #222222 !important; | ||||
| } | ||||
| .navbar-persistent > li a { | ||||
|   color: #4d5258 !important; | ||||
| } | ||||
| .navbar-pf .navbar-primary > li > a { | ||||
|   border-bottom: 1px solid transparent; | ||||
|   border-top: 1px solid transparent; | ||||
|   position: relative; | ||||
|   margin: -1px 0 0; | ||||
| } | ||||
|  | ||||
| Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.8 KiB | 
| Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 37 KiB | 
| @ -1,358 +1,358 @@ | ||||
| var gulp = require('gulp'), | ||||
|     wiredep = require('wiredep').stream, | ||||
|     eventStream = require('event-stream'), | ||||
|     gulpLoadPlugins = require('gulp-load-plugins'), | ||||
|     fs = require('fs'), | ||||
|     path = require('path'), | ||||
|     url = require('url'), | ||||
|     uri = require('urijs'), | ||||
|     urljoin = require('url-join'), | ||||
|     s = require('underscore.string'), | ||||
|     stringifyObject = require('stringify-object'), | ||||
|     hawtio = require('hawtio-node-backend'), | ||||
|     argv = require('yargs').argv, | ||||
|     del = require('del'); | ||||
| 
 | ||||
| var plugins = gulpLoadPlugins({}); | ||||
| var pkg = require('./package.json'); | ||||
| 
 | ||||
| var config = { | ||||
|     main: '.', | ||||
|     ts: ['plugins/**/*.ts'], | ||||
|     less: ['plugins/**/*.less'], | ||||
|     templates: ['plugins/**/*.html'], | ||||
|     templateModule: pkg.name + '-templates', | ||||
|     dist: argv.out || './dist/', | ||||
|     js: pkg.name + '.js', | ||||
|     css: pkg.name + '.css', | ||||
|     tsProject: plugins.typescript.createProject({ | ||||
|         target: 'ES5', | ||||
|         module: 'commonjs', | ||||
|         declarationFiles: true, | ||||
|         noExternalResolve: false | ||||
|     }) | ||||
| }; | ||||
| 
 | ||||
| gulp.task('bower', function() { | ||||
|     return gulp.src('index.html') | ||||
|         .pipe(wiredep({})) | ||||
|         .pipe(gulp.dest('.')); | ||||
| }); | ||||
| 
 | ||||
| /** Adjust the reference path of any typescript-built plugin this project depends on */ | ||||
| gulp.task('path-adjust', function() { | ||||
|     return gulp.src('libs/**/includes.d.ts') | ||||
|         .pipe(plugins.replace(/"\.\.\/libs/gm, '"../../../libs')) | ||||
|         .pipe(gulp.dest('libs')); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('clean-defs', function() { | ||||
|     return del('defs.d.ts'); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('tsc', ['clean-defs'], function() { | ||||
|     var cwd = process.cwd(); | ||||
|     var tsResult = gulp.src(config.ts) | ||||
|         .pipe(plugins.sourcemaps.init()) | ||||
|         .pipe(plugins.typescript(config.tsProject)) | ||||
|         .on('error', plugins.notify.onError({ | ||||
|             onLast: true, | ||||
|             message: '<%= error.message %>', | ||||
|             title: 'Typescript compilation error' | ||||
|         })); | ||||
| 
 | ||||
|     return eventStream.merge( | ||||
|             tsResult.js | ||||
|             .pipe(plugins.concat('compiled.js')) | ||||
|             .pipe(plugins.sourcemaps.write()) | ||||
|             .pipe(gulp.dest('.')), | ||||
|             tsResult.dts | ||||
|             .pipe(gulp.dest('d.ts'))) | ||||
|         .pipe(plugins.filter('**/*.d.ts')) | ||||
|         .pipe(plugins.concatFilenames('defs.d.ts', { | ||||
|             root: cwd, | ||||
|             prepend: '/// <reference path="', | ||||
|             append: '"/>' | ||||
|         })) | ||||
|         .pipe(gulp.dest('.')); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('less', function() { | ||||
|     return gulp.src(config.less) | ||||
|         .pipe(plugins.less({ | ||||
|             paths: [path.join(__dirname, 'less', 'includes')] | ||||
|         })) | ||||
|         .on('error', plugins.notify.onError({ | ||||
|             onLast: true, | ||||
|             message: '<%= error.message %>', | ||||
|             title: 'less file compilation error' | ||||
|         })) | ||||
|         .pipe(plugins.concat(config.css)) | ||||
|         .pipe(gulp.dest(config.dist)); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('template', ['tsc'], function() { | ||||
|     return gulp.src(config.templates) | ||||
|         .pipe(plugins.angularTemplatecache({ | ||||
|             filename: 'templates.js', | ||||
|             root: 'plugins/', | ||||
|             standalone: true, | ||||
|             module: config.templateModule, | ||||
|             templateFooter: '}]); hawtioPluginLoader.addModule("' + config.templateModule + '");' | ||||
|         })) | ||||
|         .pipe(gulp.dest('.')); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('concat', ['template'], function() { | ||||
|     return gulp.src(['compiled.js', 'templates.js']) | ||||
|         .pipe(plugins.concat(config.js)) | ||||
|         .pipe(plugins.ngAnnotate()) | ||||
|         .pipe(gulp.dest(config.dist)); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('clean', ['concat'], function() { | ||||
|     return del(['templates.js', 'compiled.js', './site/']); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('watch-less', function() { | ||||
|     plugins.watch(config.less, function() { | ||||
|         gulp.start('less'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('watch', ['build', 'watch-less'], function() { | ||||
|     plugins.watch(['libs/**/*.js', 'libs/**/*.css', 'index.html', config.dist + '/*'], function() { | ||||
|         gulp.start('reload'); | ||||
|     }); | ||||
|     plugins.watch(['libs/**/*.d.ts', config.ts, config.templates], function() { | ||||
|         gulp.start(['tsc', 'template', 'concat', 'clean']); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('connect', ['watch'], function() { | ||||
|     // lets disable unauthorised TLS issues with kube REST API
 | ||||
|     process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; | ||||
| 
 | ||||
|     var kubeBase = process.env.KUBERNETES_MASTER || 'https://localhost:8443'; | ||||
|     console.log("==== using KUBERNETES URL: " + kubeBase); | ||||
|     var kube = uri(urljoin(kubeBase, 'api')); | ||||
|     var kubeapis = uri(urljoin(kubeBase, 'apis')); | ||||
|     var oapi = uri(urljoin(kubeBase, 'oapi')); | ||||
|     console.log("Connecting to Kubernetes on: " + kube); | ||||
| 
 | ||||
|     var staticAssets = [{ | ||||
|         path: '/', | ||||
|         dir: '.' | ||||
|     }]; | ||||
| 
 | ||||
|     var dirs = fs.readdirSync('./libs'); | ||||
|     dirs.forEach(function(dir) { | ||||
|         var dir = './libs/' + dir; | ||||
|         console.log("dir: ", dir); | ||||
|         if (fs.statSync(dir).isDirectory()) { | ||||
|             console.log("Adding directory to search path: ", dir); | ||||
|             staticAssets.push({ | ||||
|                 path: '/', | ||||
|                 dir: dir | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     var localProxies = []; | ||||
|     if (process.env.LOCAL_APP_LIBRARY === "true") { | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: "8588", | ||||
|             hostname: "localhost", | ||||
|             path: '/api/v1/proxy/namespaces/default/services/app-library', | ||||
|             targetPath: "/" | ||||
|         }); | ||||
|         console.log("because of $LOCAL_APP_LIBRARY being true we are using a local proxy for /api/v1/proxy/namespaces/default/services/app-library"); | ||||
|     } | ||||
|     if (process.env.LOCAL_FABRIC8_FORGE === "true") { | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: "8080", | ||||
|             hostname: "localhost", | ||||
|             path: '/api/v1/proxy/namespaces/default/services/fabric8-forge', | ||||
|             targetPath: "/" | ||||
|         }); | ||||
|         console.log("because of LOCAL_FABRIC8_FORGE being true we are using a local proxy for /api/v1/proxy/namespaces/default/services/fabric8-forge"); | ||||
|     } | ||||
|     if (process.env.LOCAL_GOGS_HOST) { | ||||
|         var gogsPort = process.env.LOCAL_GOGS_PORT || "3000"; | ||||
|         //var gogsHostName = process.env.LOCAL_GOGS_HOST + ":" + gogsPort;
 | ||||
|         var gogsHostName = process.env.LOCAL_GOGS_HOST; | ||||
|         console.log("Using gogs host: " + gogsHostName); | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: gogsPort, | ||||
|             hostname: gogsHostName, | ||||
|             path: '/kubernetes/api/v1/proxy/services/gogs-http-service', | ||||
|             targetPath: "/" | ||||
|         }); | ||||
|         console.log("because of LOCAL_GOGS_HOST being set we are using a local proxy for /kubernetes/api/v1/proxy/services/gogs-http-service to point to http://" + process.env.LOCAL_GOGS_HOST + ":" + gogsPort); | ||||
|     } | ||||
|     if (process.env.LOCAL_JENKINSHIFT) { | ||||
|         var jenkinshiftPort = process.env.LOCAL_JENKINSHIFT_PORT || "9090"; | ||||
|         var jenkinshiftHost = process.env.LOCAL_JENKINSHIFT; | ||||
|         console.log("Using jenkinshift host: " + jenkinshiftHost); | ||||
|         var proxyPath = '/api/v1/proxy/namespaces/default/services/templates/oapi/v1'; | ||||
|         console.log("Using jenkinshift host: " + jenkinshiftHost); | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: jenkinshiftPort, | ||||
|             hostname: jenkinshiftHost, | ||||
|             path: proxyPath, | ||||
|             targetPath: "/oapi/v1" | ||||
|         }); | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: jenkinshiftPort, | ||||
|             hostname: jenkinshiftHost, | ||||
|             path: "/oapi/v1", | ||||
|             targetPath: "/oapi/v1" | ||||
|         }); | ||||
|         console.log("because of LOCAL_JENKINSHIFT being set we are using a local proxy for " + proxyPath + " to point to http://" + jenkinshiftHost + ":" + jenkinshiftPort); | ||||
|     } | ||||
| 
 | ||||
|     var defaultProxies = [{ | ||||
|         proto: kube.protocol(), | ||||
|         port: kube.port(), | ||||
|         hostname: kube.hostname(), | ||||
|         path: '/kubernetes/api', | ||||
|         targetPath: kube.path() | ||||
|     }, { | ||||
|         proto: kubeapis.protocol(), | ||||
|         port: kubeapis.port(), | ||||
|         hostname: kubeapis.hostname(), | ||||
|         path: '/apis', | ||||
|         targetPath: kubeapis.path() | ||||
|     }, { | ||||
|         proto: oapi.protocol(), | ||||
|         port: oapi.port(), | ||||
|         hostname: oapi.hostname(), | ||||
|         path: '/kubernetes/oapi', | ||||
|         targetPath: oapi.path() | ||||
|     }, { | ||||
|         proto: kube.protocol(), | ||||
|         hostname: kube.hostname(), | ||||
|         port: kube.port(), | ||||
|         path: '/jolokia', | ||||
|         targetPath: '/hawtio/jolokia' | ||||
|     }, { | ||||
|         proto: kube.protocol(), | ||||
|         hostname: kube.hostname(), | ||||
|         port: kube.port(), | ||||
|         path: '/git', | ||||
|         targetPath: '/hawtio/git' | ||||
|     }, { | ||||
|         proto: "http", | ||||
|         port: "8080", | ||||
|         hostname: "192.168.0.102", | ||||
|         path: '/java/console/api', | ||||
|         targetPath: "/" | ||||
|     }]; | ||||
| 
 | ||||
|     var staticProxies = localProxies.concat(defaultProxies); | ||||
| 
 | ||||
|     hawtio.setConfig({ | ||||
|         port: process.env.DEV_PORT || 9000, | ||||
|         staticProxies: staticProxies, | ||||
|         staticAssets: staticAssets, | ||||
|         fallback: 'index.html', | ||||
|         liveReload: { | ||||
|             enabled: true | ||||
|         } | ||||
|     }); | ||||
|     var debugLoggingOfProxy = process.env.DEBUG_PROXY === "true"; | ||||
|     var useAuthentication = process.env.DISABLE_OAUTH !== "true"; | ||||
| 
 | ||||
|     var googleClientId = process.env.GOOGLE_OAUTH_CLIENT_ID; | ||||
|     var googleClientSecret = process.env.GOOGLE_OAUTH_CLIENT_SECRET; | ||||
| 
 | ||||
|     hawtio.use('/osconsole/config.js', function(req, res, next) { | ||||
|         var config = { | ||||
|             api: { | ||||
|                 openshift: { | ||||
|                     proto: oapi.protocol(), | ||||
|                     hostPort: oapi.host(), | ||||
|                     prefix: oapi.path() | ||||
|                 }, | ||||
|                 k8s: { | ||||
|                     proto: kube.protocol(), | ||||
|                     hostPort: kube.host(), | ||||
|                     prefix: kube.path() | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         if (googleClientId && googleClientSecret) { | ||||
|             config.master_uri = kubeBase; | ||||
|             config.google = { | ||||
|                 clientId: googleClientId, | ||||
|                 clientSecret: googleClientSecret, | ||||
|                 authenticationURI: "https://accounts.google.com/o/oauth2/auth", | ||||
|                 authorizationURI: "https://accounts.google.com/o/oauth2/auth", | ||||
|                 scope: "profile", | ||||
|                 redirectURI: "http://localhost:9000" | ||||
|             }; | ||||
| 
 | ||||
|         } else if (useAuthentication) { | ||||
|             config.master_uri = kubeBase; | ||||
|             config.openshift = { | ||||
|                 oauth_authorize_uri: urljoin(kubeBase, '/oauth/authorize'), | ||||
|                 oauth_client_id: 'fabric8' | ||||
|             }; | ||||
|         } | ||||
|         var answer = "window.OPENSHIFT_CONFIG = window.HAWTIO_OAUTH_CONFIG = " + stringifyObject(config); | ||||
|         res.set('Content-Type', 'application/javascript'); | ||||
|         res.send(answer); | ||||
|     }); | ||||
| 
 | ||||
|     hawtio.use('/', function(req, res, next) { | ||||
|         var path = req.originalUrl; | ||||
|         // avoid returning these files, they should get pulled from js
 | ||||
|         if (s.startsWith(path, '/plugins/') && s.endsWith(path, 'html')) { | ||||
|             console.log("returning 404 for: ", path); | ||||
|             res.statusCode = 404; | ||||
|             res.end(); | ||||
|         } else { | ||||
|             if (debugLoggingOfProxy) { | ||||
|                 console.log("allowing: ", path); | ||||
|             } | ||||
|             next(); | ||||
|         } | ||||
|     }); | ||||
|     hawtio.listen(function(server) { | ||||
|         var host = server.address().address; | ||||
|         var port = server.address().port; | ||||
|         console.log("started from gulp file at ", host, ":", port); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('reload', function() { | ||||
|     gulp.src('.') | ||||
|         .pipe(hawtio.reload()); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('build', ['bower', 'path-adjust', 'tsc', 'less', 'template', 'concat', 'clean']); | ||||
| 
 | ||||
| gulp.task('site', ['clean', 'build'], function() { | ||||
|     gulp.src(['index.html', 'osconsole/config.js.tmpl', 'css/**', 'images/**', 'img/**', 'libs/**', 'dist/**'], { base: '.' }).pipe(gulp.dest('site')); | ||||
| 
 | ||||
|     var dirs = fs.readdirSync('./libs'); | ||||
|     dirs.forEach(function(dir) { | ||||
|         var path = './libs/' + dir + "/img"; | ||||
|         try { | ||||
|             if (fs.statSync(path).isDirectory()) { | ||||
|                 console.log("found image dir: " + path); | ||||
|                 var pattern = 'libs/' + dir + "/img/**"; | ||||
|                 gulp.src([pattern]).pipe(gulp.dest('site/img')); | ||||
|             } | ||||
|         } catch (e) { | ||||
|             // ignore, file does not exist
 | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('default', ['connect']); | ||||
| var gulp = require('gulp'), | ||||
|     wiredep = require('wiredep').stream, | ||||
|     eventStream = require('event-stream'), | ||||
|     gulpLoadPlugins = require('gulp-load-plugins'), | ||||
|     fs = require('fs'), | ||||
|     path = require('path'), | ||||
|     url = require('url'), | ||||
|     uri = require('urijs'), | ||||
|     urljoin = require('url-join'), | ||||
|     s = require('underscore.string'), | ||||
|     stringifyObject = require('stringify-object'), | ||||
|     hawtio = require('hawtio-node-backend'), | ||||
|     argv = require('yargs').argv, | ||||
|     del = require('del'); | ||||
| 
 | ||||
| var plugins = gulpLoadPlugins({}); | ||||
| var pkg = require('./package.json'); | ||||
| 
 | ||||
| var config = { | ||||
|     main: '.', | ||||
|     ts: ['plugins/**/*.ts'], | ||||
|     less: ['plugins/**/*.less'], | ||||
|     templates: ['plugins/**/*.html'], | ||||
|     templateModule: pkg.name + '-templates', | ||||
|     dist: argv.out || './dist/', | ||||
|     js: pkg.name + '.js', | ||||
|     css: pkg.name + '.css', | ||||
|     tsProject: plugins.typescript.createProject({ | ||||
|         target: 'ES5', | ||||
|         module: 'commonjs', | ||||
|         declarationFiles: true, | ||||
|         noExternalResolve: false | ||||
|     }) | ||||
| }; | ||||
| 
 | ||||
| gulp.task('bower', function() { | ||||
|     return gulp.src('index.html') | ||||
|         .pipe(wiredep({})) | ||||
|         .pipe(gulp.dest('.')); | ||||
| }); | ||||
| 
 | ||||
| /** Adjust the reference path of any typescript-built plugin this project depends on */ | ||||
| gulp.task('path-adjust', function() { | ||||
|     return gulp.src('libs/**/includes.d.ts') | ||||
|         .pipe(plugins.replace(/"\.\.\/libs/gm, '"../../../libs')) | ||||
|         .pipe(gulp.dest('libs')); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('clean-defs', function() { | ||||
|     return del('defs.d.ts'); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('tsc', ['clean-defs'], function() { | ||||
|     var cwd = process.cwd(); | ||||
|     var tsResult = gulp.src(config.ts) | ||||
|         .pipe(plugins.sourcemaps.init()) | ||||
|         .pipe(plugins.typescript(config.tsProject)) | ||||
|         .on('error', plugins.notify.onError({ | ||||
|             onLast: true, | ||||
|             message: '<%= error.message %>', | ||||
|             title: 'Typescript compilation error' | ||||
|         })); | ||||
| 
 | ||||
|     return eventStream.merge( | ||||
|             tsResult.js | ||||
|             .pipe(plugins.concat('compiled.js')) | ||||
|             .pipe(plugins.sourcemaps.write()) | ||||
|             .pipe(gulp.dest('.')), | ||||
|             tsResult.dts | ||||
|             .pipe(gulp.dest('d.ts'))) | ||||
|         .pipe(plugins.filter('**/*.d.ts')) | ||||
|         .pipe(plugins.concatFilenames('defs.d.ts', { | ||||
|             root: cwd, | ||||
|             prepend: '/// <reference path="', | ||||
|             append: '"/>' | ||||
|         })) | ||||
|         .pipe(gulp.dest('.')); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('less', function() { | ||||
|     return gulp.src(config.less) | ||||
|         .pipe(plugins.less({ | ||||
|             paths: [path.join(__dirname, 'less', 'includes')] | ||||
|         })) | ||||
|         .on('error', plugins.notify.onError({ | ||||
|             onLast: true, | ||||
|             message: '<%= error.message %>', | ||||
|             title: 'less file compilation error' | ||||
|         })) | ||||
|         .pipe(plugins.concat(config.css)) | ||||
|         .pipe(gulp.dest(config.dist)); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('template', ['tsc'], function() { | ||||
|     return gulp.src(config.templates) | ||||
|         .pipe(plugins.angularTemplatecache({ | ||||
|             filename: 'templates.js', | ||||
|             root: 'plugins/', | ||||
|             standalone: true, | ||||
|             module: config.templateModule, | ||||
|             templateFooter: '}]); hawtioPluginLoader.addModule("' + config.templateModule + '");' | ||||
|         })) | ||||
|         .pipe(gulp.dest('.')); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('concat', ['template'], function() { | ||||
|     return gulp.src(['compiled.js', 'templates.js']) | ||||
|         .pipe(plugins.concat(config.js)) | ||||
|         .pipe(plugins.ngAnnotate()) | ||||
|         .pipe(gulp.dest(config.dist)); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('clean', ['concat'], function() { | ||||
|     return del(['templates.js', 'compiled.js', './site/']); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('watch-less', function() { | ||||
|     plugins.watch(config.less, function() { | ||||
|         gulp.start('less'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('watch', ['build', 'watch-less'], function() { | ||||
|     plugins.watch(['libs/**/*.js', 'libs/**/*.css', 'index.html', config.dist + '/*'], function() { | ||||
|         gulp.start('reload'); | ||||
|     }); | ||||
|     plugins.watch(['libs/**/*.d.ts', config.ts, config.templates], function() { | ||||
|         gulp.start(['tsc', 'template', 'concat', 'clean']); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('connect', ['watch'], function() { | ||||
|     // lets disable unauthorised TLS issues with kube REST API
 | ||||
|     process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; | ||||
| 
 | ||||
|     var kubeBase = process.env.KUBERNETES_MASTER || 'https://localhost:8443'; | ||||
|     console.log("==== using KUBERNETES URL: " + kubeBase); | ||||
|     var kube = uri(urljoin(kubeBase, 'api')); | ||||
|     var kubeapis = uri(urljoin(kubeBase, 'apis')); | ||||
|     var oapi = uri(urljoin(kubeBase, 'oapi')); | ||||
|     console.log("Connecting to Kubernetes on: " + kube); | ||||
| 
 | ||||
|     var staticAssets = [{ | ||||
|         path: '/', | ||||
|         dir: '.' | ||||
|     }]; | ||||
| 
 | ||||
|     var dirs = fs.readdirSync('./libs'); | ||||
|     dirs.forEach(function(dir) { | ||||
|         var dir = './libs/' + dir; | ||||
|         console.log("dir: ", dir); | ||||
|         if (fs.statSync(dir).isDirectory()) { | ||||
|             console.log("Adding directory to search path: ", dir); | ||||
|             staticAssets.push({ | ||||
|                 path: '/', | ||||
|                 dir: dir | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     var localProxies = []; | ||||
|     if (process.env.LOCAL_APP_LIBRARY === "true") { | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: "8588", | ||||
|             hostname: "localhost", | ||||
|             path: '/api/v1/proxy/namespaces/default/services/app-library', | ||||
|             targetPath: "/" | ||||
|         }); | ||||
|         console.log("because of $LOCAL_APP_LIBRARY being true we are using a local proxy for /api/v1/proxy/namespaces/default/services/app-library"); | ||||
|     } | ||||
|     if (process.env.LOCAL_FABRIC8_FORGE === "true") { | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: "8080", | ||||
|             hostname: "localhost", | ||||
|             path: '/api/v1/proxy/namespaces/default/services/fabric8-forge', | ||||
|             targetPath: "/" | ||||
|         }); | ||||
|         console.log("because of LOCAL_FABRIC8_FORGE being true we are using a local proxy for /api/v1/proxy/namespaces/default/services/fabric8-forge"); | ||||
|     } | ||||
|     if (process.env.LOCAL_GOGS_HOST) { | ||||
|         var gogsPort = process.env.LOCAL_GOGS_PORT || "3000"; | ||||
|         //var gogsHostName = process.env.LOCAL_GOGS_HOST + ":" + gogsPort;
 | ||||
|         var gogsHostName = process.env.LOCAL_GOGS_HOST; | ||||
|         console.log("Using gogs host: " + gogsHostName); | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: gogsPort, | ||||
|             hostname: gogsHostName, | ||||
|             path: '/kubernetes/api/v1/proxy/services/gogs-http-service', | ||||
|             targetPath: "/" | ||||
|         }); | ||||
|         console.log("because of LOCAL_GOGS_HOST being set we are using a local proxy for /kubernetes/api/v1/proxy/services/gogs-http-service to point to http://" + process.env.LOCAL_GOGS_HOST + ":" + gogsPort); | ||||
|     } | ||||
|     if (process.env.LOCAL_JENKINSHIFT) { | ||||
|         var jenkinshiftPort = process.env.LOCAL_JENKINSHIFT_PORT || "9090"; | ||||
|         var jenkinshiftHost = process.env.LOCAL_JENKINSHIFT; | ||||
|         console.log("Using jenkinshift host: " + jenkinshiftHost); | ||||
|         var proxyPath = '/api/v1/proxy/namespaces/default/services/templates/oapi/v1'; | ||||
|         console.log("Using jenkinshift host: " + jenkinshiftHost); | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: jenkinshiftPort, | ||||
|             hostname: jenkinshiftHost, | ||||
|             path: proxyPath, | ||||
|             targetPath: "/oapi/v1" | ||||
|         }); | ||||
|         localProxies.push({ | ||||
|             proto: "http", | ||||
|             port: jenkinshiftPort, | ||||
|             hostname: jenkinshiftHost, | ||||
|             path: "/oapi/v1", | ||||
|             targetPath: "/oapi/v1" | ||||
|         }); | ||||
|         console.log("because of LOCAL_JENKINSHIFT being set we are using a local proxy for " + proxyPath + " to point to http://" + jenkinshiftHost + ":" + jenkinshiftPort); | ||||
|     } | ||||
| 
 | ||||
|     var defaultProxies = [{ | ||||
|         proto: kube.protocol(), | ||||
|         port: kube.port(), | ||||
|         hostname: kube.hostname(), | ||||
|         path: '/kubernetes/api', | ||||
|         targetPath: kube.path() | ||||
|     }, { | ||||
|         proto: kubeapis.protocol(), | ||||
|         port: kubeapis.port(), | ||||
|         hostname: kubeapis.hostname(), | ||||
|         path: '/apis', | ||||
|         targetPath: kubeapis.path() | ||||
|     }, { | ||||
|         proto: oapi.protocol(), | ||||
|         port: oapi.port(), | ||||
|         hostname: oapi.hostname(), | ||||
|         path: '/kubernetes/oapi', | ||||
|         targetPath: oapi.path() | ||||
|     }, { | ||||
|         proto: kube.protocol(), | ||||
|         hostname: kube.hostname(), | ||||
|         port: kube.port(), | ||||
|         path: '/jolokia', | ||||
|         targetPath: '/hawtio/jolokia' | ||||
|     }, { | ||||
|         proto: kube.protocol(), | ||||
|         hostname: kube.hostname(), | ||||
|         port: kube.port(), | ||||
|         path: '/git', | ||||
|         targetPath: '/hawtio/git' | ||||
|     }, { | ||||
|         proto: "http", | ||||
|         port: "8080", | ||||
|         hostname: "192.168.0.102", | ||||
|         path: '/java/console/api', | ||||
|         targetPath: "/" | ||||
|     }]; | ||||
| 
 | ||||
|     var staticProxies = localProxies.concat(defaultProxies); | ||||
| 
 | ||||
|     hawtio.setConfig({ | ||||
|         port: process.env.DEV_PORT || 9000, | ||||
|         staticProxies: staticProxies, | ||||
|         staticAssets: staticAssets, | ||||
|         fallback: 'index.html', | ||||
|         liveReload: { | ||||
|             enabled: true | ||||
|         } | ||||
|     }); | ||||
|     var debugLoggingOfProxy = process.env.DEBUG_PROXY === "true"; | ||||
|     var useAuthentication = process.env.DISABLE_OAUTH !== "true"; | ||||
| 
 | ||||
|     var googleClientId = process.env.GOOGLE_OAUTH_CLIENT_ID; | ||||
|     var googleClientSecret = process.env.GOOGLE_OAUTH_CLIENT_SECRET; | ||||
| 
 | ||||
|     hawtio.use('/osconsole/config.js', function(req, res, next) { | ||||
|         var config = { | ||||
|             api: { | ||||
|                 openshift: { | ||||
|                     proto: oapi.protocol(), | ||||
|                     hostPort: oapi.host(), | ||||
|                     prefix: oapi.path() | ||||
|                 }, | ||||
|                 k8s: { | ||||
|                     proto: kube.protocol(), | ||||
|                     hostPort: kube.host(), | ||||
|                     prefix: kube.path() | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         if (googleClientId && googleClientSecret) { | ||||
|             config.master_uri = kubeBase; | ||||
|             config.google = { | ||||
|                 clientId: googleClientId, | ||||
|                 clientSecret: googleClientSecret, | ||||
|                 authenticationURI: "https://accounts.google.com/o/oauth2/auth", | ||||
|                 authorizationURI: "https://accounts.google.com/o/oauth2/auth", | ||||
|                 scope: "profile", | ||||
|                 redirectURI: "http://localhost:9000" | ||||
|             }; | ||||
| 
 | ||||
|         } else if (useAuthentication) { | ||||
|             config.master_uri = kubeBase; | ||||
|             config.openshift = { | ||||
|                 oauth_authorize_uri: urljoin(kubeBase, '/oauth/authorize'), | ||||
|                 oauth_client_id: 'fabric8' | ||||
|             }; | ||||
|         } | ||||
|         var answer = "window.OPENSHIFT_CONFIG = window.HAWTIO_OAUTH_CONFIG = " + stringifyObject(config); | ||||
|         res.set('Content-Type', 'application/javascript'); | ||||
|         res.send(answer); | ||||
|     }); | ||||
| 
 | ||||
|     hawtio.use('/', function(req, res, next) { | ||||
|         var path = req.originalUrl; | ||||
|         // avoid returning these files, they should get pulled from js
 | ||||
|         if (s.startsWith(path, '/plugins/') && s.endsWith(path, 'html')) { | ||||
|             console.log("returning 404 for: ", path); | ||||
|             res.statusCode = 404; | ||||
|             res.end(); | ||||
|         } else { | ||||
|             if (debugLoggingOfProxy) { | ||||
|                 console.log("allowing: ", path); | ||||
|             } | ||||
|             next(); | ||||
|         } | ||||
|     }); | ||||
|     hawtio.listen(function(server) { | ||||
|         var host = server.address().address; | ||||
|         var port = server.address().port; | ||||
|         console.log("started from gulp file at ", host, ":", port); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('reload', function() { | ||||
|     gulp.src('.') | ||||
|         .pipe(hawtio.reload()); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('build', ['bower', 'path-adjust', 'tsc', 'less', 'template', 'concat', 'clean']); | ||||
| 
 | ||||
| gulp.task('site', ['clean', 'build'], function() { | ||||
|     gulp.src(['index.html', 'osconsole/config.js.tmpl', 'css/**', 'images/**', 'img/**', 'libs/**', 'dist/**'], { base: '.' }).pipe(gulp.dest('site')); | ||||
| 
 | ||||
|     var dirs = fs.readdirSync('./libs'); | ||||
|     dirs.forEach(function(dir) { | ||||
|         var path = './libs/' + dir + "/img"; | ||||
|         try { | ||||
|             if (fs.statSync(path).isDirectory()) { | ||||
|                 console.log("found image dir: " + path); | ||||
|                 var pattern = 'libs/' + dir + "/img/**"; | ||||
|                 gulp.src([pattern]).pipe(gulp.dest('site/img')); | ||||
|             } | ||||
|         } catch (e) { | ||||
|             // ignore, file does not exist
 | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('default', ['connect']); | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <module type="WEB_MODULE" version="4"> | ||||
|   <component name="NewModuleRootManager" inherit-compiler-output="true"> | ||||
|     <exclude-output /> | ||||
|     <content url="file://$MODULE_DIR$" /> | ||||
|     <orderEntry type="inheritedJdk" /> | ||||
|     <orderEntry type="sourceFolder" forTests="false" /> | ||||
|   </component> | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <module type="WEB_MODULE" version="4"> | ||||
|   <component name="NewModuleRootManager" inherit-compiler-output="true"> | ||||
|     <exclude-output /> | ||||
|     <content url="file://$MODULE_DIR$" /> | ||||
|     <orderEntry type="inheritedJdk" /> | ||||
|     <orderEntry type="sourceFolder" forTests="false" /> | ||||
|   </component> | ||||
| </module> | ||||
| Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.8 KiB | 
| Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 37 KiB | 
| @ -1,24 +0,0 @@ | ||||
| function Recursion(node){ | ||||
|     var count=0; | ||||
|     for (var key in node) { | ||||
|       count++; | ||||
|       var value = node[key]; | ||||
|       delete node[key]; | ||||
|       //如果node为叶子节点
 | ||||
|       if (key.toString() == '$') { | ||||
|         for (var attr in value) | ||||
|           node[attr] = value[attr]; | ||||
|       } else { | ||||
|         if (value instanceof Array) { | ||||
|           if (value.length > 0) { | ||||
|             node["children"] = value; | ||||
|             for (var obj in value) | ||||
|               Recursion(value[obj]); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if(count==1) | ||||
|       node["children"]=[]; | ||||
| } | ||||
| exports.Recursion=Recursion; | ||||
| After Width: | Height: | Size: 24 KiB | 
| After Width: | Height: | Size: 98 KiB | 
| @ -0,0 +1,85 @@ | ||||
| /* 样式重置 */ | ||||
| body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;} | ||||
| body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#fff;} | ||||
| div,img,tr,td,table{ border:0;} | ||||
| table,tr,td{border:0;cellspacing:0; cellpadding:0;} | ||||
| ol,ul,li{ list-style-type:none} | ||||
| a:link,a:visited{color:#7a7a7a;text-decoration:none;} | ||||
| a:hover,a:active{color:#333;} | ||||
| 
 | ||||
| 
 | ||||
| /* 清除 */ | ||||
| .clear{ zoom:1;} | ||||
| .clear:after {content:".";height:0;visibility:hidden;display:block;clear:both;} | ||||
| .fl{ float:left;} | ||||
| .fr{ float:right;} | ||||
| .cl{ clear:both; overflow:hidden;} | ||||
| /* public*/ | ||||
| .ml5{ margin-top: 5px;}.ml10{ margin-top: 10px;} | ||||
| .ml5{ margin-left:5px;}.ml10{ margin-left:10px;} | ||||
| .mr5{ margin-right:5px;}.mr10{ margin-right:10px;} | ||||
| a.sj_btn_grey{ display:inline-block; padding:0px 15px; height:30px; line-height:30px; -webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px;  background-image:-webkit-linear-gradient(top, #fdfdfd,#e8e8e8);background-image:linear-gradient(top,#fdfdfd,#e8e8e8); border:1px solid #cecece; color:#505050;} | ||||
| a:hover.sj_btn_grey{ background-image:-webkit-linear-gradient(top, #eeeeee,#d3d3d3);background-image:linear-gradient(top,#eeeeee,#d3d3d3);} | ||||
| .sj_btn_grey{ display:inline-block; padding:0px 15px; height:30px; line-height:30px; -webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px;  background-image:-webkit-linear-gradient(top, #fdfdfd,#e8e8e8);background-image:linear-gradient(top,#fdfdfd,#e8e8e8); border:1px solid #cecece; color:#505050;} | ||||
| .sj_btn_grey:hover{ background-image:-webkit-linear-gradient(top, #eeeeee,#d3d3d3);background-image:linear-gradient(top,#eeeeee,#d3d3d3);} | ||||
| /* sj_header */ | ||||
| .sj_header{ height:70px; width:100%; background:#1d1d1d;} | ||||
| .sj_header a.sj_logo{ display:block; height:41px; width:146px; padding:14px 20px 0 12px;} | ||||
| .sj_topnav{ height:70px; width:100%; padding-left: 180px; } | ||||
| .sj_topnav li  a{  height:70px; line-height:70px; font-size:14px; color:#fff; padding:0 20px;} | ||||
| .sj_topnav  li a:hover,.sj_topnav  li a.sj_topnav_active{  background-image:-webkit-linear-gradient(top, #424242,#323232);background-image:linear-gradient(top,#424242,#323232); } | ||||
| /* sj_content */ | ||||
| .sj_content{ width:100%; position:relative;  color:#505050;} | ||||
| .sj_leftnav{ width:170px; min-height:800px; max-height:985px; background:#1d1d1d; position:absolute; left:0; top:0px;} | ||||
| .sj_leftnav_i{  background:#717171; padding:0 5px;;-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px; margin-left:80px;	} | ||||
| .sj_menu {margin-top:12px;background:#1d1d1d; 	} | ||||
| .sj_menu_nav { background-image:-webkit-linear-gradient(top, #404040,#353535);background-image:linear-gradient(top,#404040,#353535);  color: #fff;  height:40px; line-height:38px; padding-left:15px; border: none;     border-top: 2px solid #4d4d4d; border-bottom: 2px solid #1d1d1d;} | ||||
| .sj_menu_nav:hover{ background-image:-webkit-linear-gradient(top, #535353,#353535);background-image:linear-gradient(top,#535353,#353535);} | ||||
| .sj_menu_nav  i{ font-style: normal;} | ||||
| .sj_menu_nav a{ color: #fff;} | ||||
| .sj_menu .sj_menu_nav ul{background: #1d1d1d; color: #fff;padding-left: 20px; border:none;} | ||||
| .sj_menu_ul{  } | ||||
| .sj_menu_ul li a{ display: block;  background: #1d1d1d; color: #fff;padding-left: 30px; height: 40px; line-height: 40px; } | ||||
| .sj_menu_ul li a:hover{background: #fff; color:#1d1d1d;} | ||||
| 
 | ||||
| 
 | ||||
| #menu li a:hover {  background-image:-webkit-linear-gradient(top, #535353,#353535);background-image:linear-gradient(top,#535353,#353535);} | ||||
| #menu li ul li a { background: #1d1d1d; color: #fff;padding-left: 20px; border:none;} | ||||
| #menu li ul li a:hover,.sj_leftnav ul#menu li ul li .leftnavact { background: #fff; color:#1d1d1d;} | ||||
| .sj_menu_01{  background:url(../new/images/sj_icons.png) 0 0px no-repeat; padding-left:20px;} | ||||
| .sj_menu_02{  background:url(../new/images/sj_icons.png) 0 -29px no-repeat; padding-left:20px;} | ||||
| .sj_menu_03{  background:url(../new/images/sj_icons.png) 0 -112px no-repeat; padding-left:20px;} | ||||
| .sj_menu_04{  background:url(../new/images/sj_icons.png) 0 -133px no-repeat; padding-left:20px;} | ||||
| .sj_contentbox{ width:100%;  background:#fff; min-height:800px;  } | ||||
| .sj_icons_home{ background:url(../new/images/sj_icons.png) 0 -60px no-repeat; width:15px; height:15px; margin-top:10px; margin-right:3px;} | ||||
| .sj_content_position{ background:#eee; height:35px; line-height:35px; color:#7a7a7a; margin:2px 0 0 170px; padding-left:20px;} | ||||
| .sj_content_position ul li{ float:left;} | ||||
| .sj_filter  li{ float:left;} | ||||
| .sj_filter  li a{ display: inline-block; border:1px solid #cecece;background-image:-webkit-linear-gradient(top, #fcfcfc,#e9e9e9);background-image:linear-gradient(top, #fcfcfc,#e9e9e9); padding:5px 15px; color:#505050; margin-right:5px;} | ||||
| .sj_filter  li a:hover,.sj_filter  li a.active{ background:#cdcdcd; border:1px solid #9e9e9e;} | ||||
| .sj_content_top{ margin:20px 20px 0 190px;} | ||||
| .sj_searchbox{position:relative;} | ||||
| .sj_search_input{-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px; border:1px solid #d3d3d3; background:#fff; padding-left:5px; color:#888; height:28px; width:210px;box-shadow: inset 0px 0px 5px #dcdcdc; 	} | ||||
| .sj_searchbox a.sj_search_btn{ position:absolute; top:5px; right:5px; background:url(../new/images/sj_icons.png) 0 -82px no-repeat; display:block; width:20px; height:20px; } | ||||
| /* table */ | ||||
| .sj_content_table{  } | ||||
| .sj_content_table > tbody > tr > td{ height:36px; line-height:36px;} | ||||
| .sj_content_table tr td.tl{ text-align:left;} | ||||
| .sj_content_table .table-header{background-image:-webkit-linear-gradient(top, #f7f7f7,#dfdfdf);background-image:linear-gradient(top, #f7f7f7,#dfdfdf);  border-bottom:1px solid #a6a6a6;} | ||||
| .sj_content_table > thead > tr > th{ height:36px; line-height:36px;} | ||||
| .sj_content_table .sj_tr_grey{ background:#f3f3f3;} | ||||
| .sj_table_td01{ width:2%;} | ||||
| .sj_table_td02{ width:9%;} | ||||
| .sj_table_td03{ width:22%;} | ||||
| .sj_table_td04{ width:14%;} | ||||
| .sj_table_td05{ width:13%;} | ||||
| .sj_table_td06{ width:10%;} | ||||
| .sj_table_td07{ width:30%;} | ||||
| .sj_table_td08{ width:60%;} | ||||
| .sj_table_td09{ width:70%;} | ||||
| .sj_over_hid{ display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} | ||||
| .sj_content_table table tr td input{ margin-top:15px;} | ||||
| .sj_content_table .sj_table_top td{ border-bottom:1px solid #a6a6a6; font-weight:bold; border-right:1px solid #ccc;} | ||||
| .sj_table_bottom{ height:30px; line-height:30px; } | ||||
| .sj_table_bottom li{ float:left;} | ||||
| .sj_table_select{ background:#fff; border:1px solid #b1b1b1; height:25px; margin:0 5px;} | ||||
| @ -1,7 +1,7 @@ | ||||
| window.OPENSHIFT_CONFIG = { | ||||
|   auth: { | ||||
|     oauth_authorize_uri: "{{ .Env.OAUTH_AUTHORIZE_URI }}", | ||||
|     oauth_client_id: "{{ .Env.OAUTH_CLIENT_ID }}", | ||||
|     logout_uri: "", | ||||
|   } | ||||
| }; | ||||
| window.OPENSHIFT_CONFIG = { | ||||
|   auth: { | ||||
|     oauth_authorize_uri: "{{ .Env.OAUTH_AUTHORIZE_URI }}", | ||||
|     oauth_client_id: "{{ .Env.OAUTH_CLIENT_ID }}", | ||||
|     logout_uri: "", | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @ -1,42 +1,42 @@ | ||||
| { | ||||
|   "name": "hawtio-kubernetes", | ||||
|   "version": "2.0.0", | ||||
|   "devDependencies": { | ||||
|     "bower": "^1.3.12", | ||||
|     "del": "^2.2.0", | ||||
|     "event-stream": "^3.1.7", | ||||
|     "gulp": "^3.8.10", | ||||
|     "gulp-angular-templatecache": "^1.5.0", | ||||
|     "gulp-concat": "^2.4.2", | ||||
|     "gulp-concat-filenames": "^1.0.0", | ||||
|     "gulp-filter": "^3.0.1", | ||||
|     "gulp-less": "^3.0.5", | ||||
|     "gulp-load-plugins": "^0.8.0", | ||||
|     "gulp-ng-annotate": "^1.1.0", | ||||
|     "gulp-notify": "^2.1.0", | ||||
|     "gulp-replace": "^0.5.4", | ||||
|     "gulp-sourcemaps": "^1.5.1", | ||||
|     "gulp-typescript": "^2.4.2", | ||||
|     "gulp-watch": "^3.0.0", | ||||
|     "hawtio-node-backend": "^2.0.5", | ||||
|     "stringify-object": "^2.0.0", | ||||
|     "through2": "^0.6.3", | ||||
|     "underscore.string": "^2.4.0", | ||||
|     "urijs": "^1.17.0", | ||||
|     "url-join": "^0.0.1", | ||||
|     "which": "^1.0.8", | ||||
|     "wiredep": "^2.2.2", | ||||
|     "yargs": "^3.32.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "async": "^2.0.0-rc.6", | ||||
|     "connect-multiparty": "^2.0.0", | ||||
|     "hawtio-node-backend": "^2.1.0", | ||||
|     "k8s": "^0.2.7", | ||||
|     "node-crontab": "0.0.8", | ||||
|     "oracledb": "^1.9.3", | ||||
|     "xml2js": "^0.4.16", | ||||
|     "xmldom": "^0.1.22", | ||||
|     "xpath.js": "^1.0.6" | ||||
|   } | ||||
| } | ||||
| { | ||||
|   "name": "hawtio-kubernetes", | ||||
|   "version": "2.0.0", | ||||
|   "devDependencies": { | ||||
|     "bower": "^1.3.12", | ||||
|     "del": "^2.2.0", | ||||
|     "event-stream": "^3.1.7", | ||||
|     "gulp": "^3.8.10", | ||||
|     "gulp-angular-templatecache": "^1.5.0", | ||||
|     "gulp-concat": "^2.4.2", | ||||
|     "gulp-concat-filenames": "^1.0.0", | ||||
|     "gulp-filter": "^3.0.1", | ||||
|     "gulp-less": "^3.0.5", | ||||
|     "gulp-load-plugins": "^0.8.0", | ||||
|     "gulp-ng-annotate": "^1.1.0", | ||||
|     "gulp-notify": "^2.1.0", | ||||
|     "gulp-replace": "^0.5.4", | ||||
|     "gulp-sourcemaps": "^1.5.1", | ||||
|     "gulp-typescript": "^2.4.2", | ||||
|     "gulp-watch": "^3.0.0", | ||||
|     "hawtio-node-backend": "^2.0.5", | ||||
|     "stringify-object": "^2.0.0", | ||||
|     "through2": "^0.6.3", | ||||
|     "underscore.string": "^2.4.0", | ||||
|     "urijs": "^1.17.0", | ||||
|     "url-join": "^0.0.1", | ||||
|     "which": "^1.0.8", | ||||
|     "wiredep": "^2.2.2", | ||||
|     "yargs": "^3.32.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "async": "^2.0.0-rc.6", | ||||
|     "connect-multiparty": "^2.0.0", | ||||
|     "hawtio-node-backend": "^2.1.0", | ||||
|     "k8s": "^0.2.7", | ||||
|     "node-crontab": "0.0.8", | ||||
|     "oracledb": "^1.9.3", | ||||
|     "xml2js": "^0.4.16", | ||||
|     "xmldom": "^0.1.22", | ||||
|     "xpath.js": "^1.0.6" | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,51 +1,51 @@ | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.tools.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter tools..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="entity.tools.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no tools currently available.</p> | ||||
|         </div> | ||||
|         <div ng-show="entity.tools.length"> | ||||
|           <div ng-hide="entity.tools.length" class="align-center"> | ||||
|             <p class="alert alert-info">There are no tools currently available.</p> | ||||
|           </div> | ||||
|           <div ng-repeat="env in entity.tools | filter:filterTemplates | orderBy:'label' track by $index"> | ||||
|             <div class="row" | ||||
|                  title="{{env.description}}"> | ||||
|               <div class="col-md-9"> | ||||
|                 <a href="{{env.url}}"> | ||||
|                   <h3> | ||||
|                     <i class="{{env.iconClass}}"></i> | ||||
|                     {{env.label}} | ||||
|                   </h3> | ||||
|                 </a> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.tools.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter tools..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="entity.tools.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no tools currently available.</p> | ||||
|         </div> | ||||
|         <div ng-show="entity.tools.length"> | ||||
|           <div ng-hide="entity.tools.length" class="align-center"> | ||||
|             <p class="alert alert-info">There are no tools currently available.</p> | ||||
|           </div> | ||||
|           <div ng-repeat="env in entity.tools | filter:filterTemplates | orderBy:'label' track by $index"> | ||||
|             <div class="row" | ||||
|                  title="{{env.description}}"> | ||||
|               <div class="col-md-9"> | ||||
|                 <a href="{{env.url}}"> | ||||
|                   <h3> | ||||
|                     <i class="{{env.iconClass}}"></i> | ||||
|                     {{env.label}} | ||||
|                   </h3> | ||||
|                 </a> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,87 +1,87 @@ | ||||
| <div class="inline-block environment-row" ng-controller="Developer.EnvironmentPanelController"> | ||||
|   <div class="panel-group"> | ||||
|     <div class="panel panel-default"> | ||||
|       <div class="panel-heading"> | ||||
|         <h2 class="panel-title inline-block"> | ||||
|           <a href="{{env.url}}" title="namespace: {{env.namespace}}"> | ||||
|             <!-- <i class="{{env.iconClass}}"></i>  --> | ||||
|             {{env.label}} | ||||
|           </a> | ||||
|         </h2> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="panel-body"> | ||||
|         <div class="environment-deploy-block" | ||||
|           ng-repeat="(project, versions) in envVersions[env.namespace] | orderBy:'project' track by $index"> | ||||
|           <div ng-repeat="(version, versionInfo) in versions.versions | orderBy:'version' track by $index"> | ||||
|             <div ng-repeat="(rcname, rc) in versionInfo.replicationControllers"> | ||||
|               <div class="environment-deploy-version-and-pods"> | ||||
|                 <a href="{{rc.$viewLink}}" ng-show="rc.$viewLink" | ||||
|                   title="View the Replication Controller from project {{project}} of version {{version}}"> | ||||
|                   <i class="fa fa-cubes"></i> | ||||
|                   {{rc.$name}} | ||||
|                   : {{version}} | ||||
|                 </a> | ||||
|                 <span ng-hide="rc.$viewLink" | ||||
|                   title="View the Replication Controller from project {{project}} of version {{version}}"> | ||||
|                   <i class="fa fa-cubes"></i> | ||||
|                   {{rc.$name}} | ||||
|                   : {{version}} | ||||
|                 </span> | ||||
|                 <span class="pull-right" ng-show="rc.$serviceLink.href"> | ||||
|                     | ||||
|                     | ||||
|                     | ||||
|                   <a target="test-service" href="{{rc.$serviceLink.href}}" title="Open this service in a new tab"> | ||||
|                     <i class="fa fa-external-link"></i> | ||||
|                   </a> | ||||
|                 </span> | ||||
|                   | ||||
|                   | ||||
|                   | ||||
|                 <span class="pull-right"> | ||||
|                   <a ng-show="rc.$podCounters.podsLink" href="{{rc.$podCounters.podsLink}}" title="View pods"> | ||||
|                     <span ng-show="rc.$podCounters.ready" | ||||
|                       class="badge badge-success">{{rc.$podCounters.ready}}</span> | ||||
|                     <span ng-show="rc.$podCounters.valid" | ||||
|                       class="badge badge-info">{{rc.$podCounters.valid}}</span> | ||||
|                     <span ng-show="rc.$podCounters.waiting" class="badge">{{rc.$podCounters.waiting}}</span> | ||||
|                     <span ng-show="rc.$podCounters.error" | ||||
|                       class="badge badge-warning">{{rc.$podCounters.error}}</span> | ||||
|                   </a> | ||||
|                 </span> | ||||
|               </div> | ||||
|               <div class="environment-deploy-build-info"> | ||||
|                 <a href="{{rc.$buildUrl}}" target="builds" ng-show="rc.$buildUrl && rc.$buildId" class="=" | ||||
|                   title="View the build which created this Replication Controller"> | ||||
|                   <i class="fa fa-tasks"></i> | ||||
|                   Build #{{rc.$buildId}} | ||||
|                 </a> | ||||
|                   | ||||
|                   | ||||
|                   | ||||
|                 <a href="{{rc.$gitUrl}}" target="git" ng-show="rc.$gitUrl" class="pull-right" | ||||
|                   title="{{rc.$gitCommit}} | ||||
|                   {{rc.$gitCommitAuthor}} | ||||
|                   {{rc.$gitCommitDate}} | ||||
|                   {{rc.$gitCommitMessage}}"> | ||||
|                   <i class="fa fa-code-fork"></i> | ||||
|                   Commit {{rc.$gitCommit | limitTo:7}} | ||||
|                 </a> | ||||
|                 <span ng-hide="rc.$gitUrl || !rc.$gitCommit" class="pull-right" | ||||
|                   title="{{rc.$gitCommit}} | ||||
|                   {{rc.$gitCommitAuthor}} | ||||
|                   {{rc.$gitCommitDate}} | ||||
|                   {{rc.$gitCommitMessage}}"> | ||||
|                   <i class="fa fa-code-fork"></i> | ||||
|                   Commit {{rc.$gitCommit | limitTo:7}} | ||||
|                 </span> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
| 
 | ||||
|         </div> | ||||
| 
 | ||||
|       </div> | ||||
|     </div> | ||||
| <div class="inline-block environment-row" ng-controller="Developer.EnvironmentPanelController"> | ||||
|   <div class="panel-group"> | ||||
|     <div class="panel panel-default"> | ||||
|       <div class="panel-heading"> | ||||
|         <h2 class="panel-title inline-block"> | ||||
|           <a href="{{env.url}}" title="namespace: {{env.namespace}}"> | ||||
|             <!-- <i class="{{env.iconClass}}"></i>  --> | ||||
|             {{env.label}} | ||||
|           </a> | ||||
|         </h2> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="panel-body"> | ||||
|         <div class="environment-deploy-block" | ||||
|           ng-repeat="(project, versions) in envVersions[env.namespace] | orderBy:'project' track by $index"> | ||||
|           <div ng-repeat="(version, versionInfo) in versions.versions | orderBy:'version' track by $index"> | ||||
|             <div ng-repeat="(rcname, rc) in versionInfo.replicationControllers"> | ||||
|               <div class="environment-deploy-version-and-pods"> | ||||
|                 <a href="{{rc.$viewLink}}" ng-show="rc.$viewLink" | ||||
|                   title="View the Replication Controller from project {{project}} of version {{version}}"> | ||||
|                   <i class="fa fa-cubes"></i> | ||||
|                   {{rc.$name}} | ||||
|                   : {{version}} | ||||
|                 </a> | ||||
|                 <span ng-hide="rc.$viewLink" | ||||
|                   title="View the Replication Controller from project {{project}} of version {{version}}"> | ||||
|                   <i class="fa fa-cubes"></i> | ||||
|                   {{rc.$name}} | ||||
|                   : {{version}} | ||||
|                 </span> | ||||
|                 <span class="pull-right" ng-show="rc.$serviceLink.href"> | ||||
|                     | ||||
|                     | ||||
|                     | ||||
|                   <a target="test-service" href="{{rc.$serviceLink.href}}" title="Open this service in a new tab"> | ||||
|                     <i class="fa fa-external-link"></i> | ||||
|                   </a> | ||||
|                 </span> | ||||
|                   | ||||
|                   | ||||
|                   | ||||
|                 <span class="pull-right"> | ||||
|                   <a ng-show="rc.$podCounters.podsLink" href="{{rc.$podCounters.podsLink}}" title="View pods"> | ||||
|                     <span ng-show="rc.$podCounters.ready" | ||||
|                       class="badge badge-success">{{rc.$podCounters.ready}}</span> | ||||
|                     <span ng-show="rc.$podCounters.valid" | ||||
|                       class="badge badge-info">{{rc.$podCounters.valid}}</span> | ||||
|                     <span ng-show="rc.$podCounters.waiting" class="badge">{{rc.$podCounters.waiting}}</span> | ||||
|                     <span ng-show="rc.$podCounters.error" | ||||
|                       class="badge badge-warning">{{rc.$podCounters.error}}</span> | ||||
|                   </a> | ||||
|                 </span> | ||||
|               </div> | ||||
|               <div class="environment-deploy-build-info"> | ||||
|                 <a href="{{rc.$buildUrl}}" target="builds" ng-show="rc.$buildUrl && rc.$buildId" class="=" | ||||
|                   title="View the build which created this Replication Controller"> | ||||
|                   <i class="fa fa-tasks"></i> | ||||
|                   Build #{{rc.$buildId}} | ||||
|                 </a> | ||||
|                   | ||||
|                   | ||||
|                   | ||||
|                 <a href="{{rc.$gitUrl}}" target="git" ng-show="rc.$gitUrl" class="pull-right" | ||||
|                   title="{{rc.$gitCommit}} | ||||
|                   {{rc.$gitCommitAuthor}} | ||||
|                   {{rc.$gitCommitDate}} | ||||
|                   {{rc.$gitCommitMessage}}"> | ||||
|                   <i class="fa fa-code-fork"></i> | ||||
|                   Commit {{rc.$gitCommit | limitTo:7}} | ||||
|                 </a> | ||||
|                 <span ng-hide="rc.$gitUrl || !rc.$gitCommit" class="pull-right" | ||||
|                   title="{{rc.$gitCommit}} | ||||
|                   {{rc.$gitCommitAuthor}} | ||||
|                   {{rc.$gitCommitDate}} | ||||
|                   {{rc.$gitCommitMessage}}"> | ||||
|                   <i class="fa fa-code-fork"></i> | ||||
|                   Commit {{rc.$gitCommit | limitTo:7}} | ||||
|                 </span> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
| 
 | ||||
|         </div> | ||||
| 
 | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
| @ -1,100 +1,100 @@ | ||||
| <div class="project-dashboard" ng-controller="Developer.ProjectController" hawtio-card-bg> | ||||
| 
 | ||||
|   <div hawtio-breadcrumbs></div> | ||||
|   <div hawtio-tabs></div> | ||||
| 
 | ||||
|   <!-- | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.environments.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter environments..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   --> | ||||
| 
 | ||||
|   <div ng-hide="model.fetched"> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="align-center"> | ||||
|           <div class="spinner spinner-lg"></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div ng-show="model.fetched" style="float: none; position: static;"> | ||||
| <!-- | ||||
|     <div class="row page-header-row"> | ||||
|       <div class="col-md-12"> | ||||
|         <h1 class="inline-block">{{id}}</h1> | ||||
|       </div> | ||||
|     </div> | ||||
| --> | ||||
| 
 | ||||
|     <!-- | ||||
|     <div class="pull-right"> | ||||
|       <a href="{{entity.$build.url}}" class="btn btn-default" target="browse"> | ||||
|         <i class="{{entity.$build.iconClass}}"></i> | ||||
|         {{entity.$build.label}} | ||||
|       </a> | ||||
|     </div> | ||||
|     --> | ||||
| 
 | ||||
|     <div class="row row-cards-pf" title="{{env.description}}"> | ||||
|       <div class="col-md-12 environment-rows"> | ||||
|         <div class="card-pf"> | ||||
|           <div class="card-pf-heading"> | ||||
|             <h2 class="card-pf-title inline-block">Environments Overview</h2> | ||||
|           </div> | ||||
|           <div class="card-pf-body"> | ||||
|             <div ng-hide="entity.environments.length"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-md-12 align-center"> | ||||
|                   <h2>No Environment Available</h2> | ||||
|                   <p>Environment is a logical place where deployments happen which maps to a kubernetes / openshift namespace.  You will see environments here after you add a build.</p> | ||||
|                   <a class="btn btn-primary" ng-href="{{settingsLink}}"><i class="fa fa-plus"></i> New Build</a> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div ng-show="entity.environments.length"> | ||||
|               <div ng-repeat="env in entity.environments | filter:filterTemplates track by $index" | ||||
|                 class="inline-block environment-block" ng-include="'plugins/developer/html/environmentPanel.html'"> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row row-cards-pf"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="card-pf pipeline"> | ||||
|           <div class="card-pf-heading no-border"> | ||||
|             <h2 class="card-pf-title inline-block">Active Pipelines</h4> | ||||
|             <a ng-href="{{$projectLink}}/jenkinsJob/{{jobId}}/pipelines">View All Pipelines >></a> | ||||
|           </div> | ||||
|           <div class="card-pf-body no-top-margin"> | ||||
|             <div class="full-card-width" ng-controller="Developer.PipelinesController" ng-include="'plugins/kubernetes/html/pendingPipelines.html'"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row row-cards-pf"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="card-pf"> | ||||
|           <div class="card-pf-heading"> | ||||
|             <h2 class="card-pf-title inline-block">Commits</h2> | ||||
|             <a ng-href="{{$projectLink}}/wiki/history//">View All Commits >></a> | ||||
|           </div> | ||||
|           <div class="card-pf-body"> | ||||
|             <div ng-include="'plugins/wiki/html/projectCommitsPanel.html'"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
| </div> | ||||
| <div class="project-dashboard" ng-controller="Developer.ProjectController" hawtio-card-bg> | ||||
| 
 | ||||
|   <div hawtio-breadcrumbs></div> | ||||
|   <div hawtio-tabs></div> | ||||
| 
 | ||||
|   <!-- | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.environments.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter environments..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   --> | ||||
| 
 | ||||
|   <div ng-hide="model.fetched"> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="align-center"> | ||||
|           <div class="spinner spinner-lg"></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div ng-show="model.fetched" style="float: none; position: static;"> | ||||
| <!-- | ||||
|     <div class="row page-header-row"> | ||||
|       <div class="col-md-12"> | ||||
|         <h1 class="inline-block">{{id}}</h1> | ||||
|       </div> | ||||
|     </div> | ||||
| --> | ||||
| 
 | ||||
|     <!-- | ||||
|     <div class="pull-right"> | ||||
|       <a href="{{entity.$build.url}}" class="btn btn-default" target="browse"> | ||||
|         <i class="{{entity.$build.iconClass}}"></i> | ||||
|         {{entity.$build.label}} | ||||
|       </a> | ||||
|     </div> | ||||
|     --> | ||||
| 
 | ||||
|     <div class="row row-cards-pf" title="{{env.description}}"> | ||||
|       <div class="col-md-12 environment-rows"> | ||||
|         <div class="card-pf"> | ||||
|           <div class="card-pf-heading"> | ||||
|             <h2 class="card-pf-title inline-block">Environments Overview</h2> | ||||
|           </div> | ||||
|           <div class="card-pf-body"> | ||||
|             <div ng-hide="entity.environments.length"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-md-12 align-center"> | ||||
|                   <h2>No Environment Available</h2> | ||||
|                   <p>Environment is a logical place where deployments happen which maps to a kubernetes / openshift namespace.  You will see environments here after you add a build.</p> | ||||
|                   <a class="btn btn-primary" ng-href="{{settingsLink}}"><i class="fa fa-plus"></i> New Build</a> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div ng-show="entity.environments.length"> | ||||
|               <div ng-repeat="env in entity.environments | filter:filterTemplates track by $index" | ||||
|                 class="inline-block environment-block" ng-include="'plugins/developer/html/environmentPanel.html'"> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row row-cards-pf"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="card-pf pipeline"> | ||||
|           <div class="card-pf-heading no-border"> | ||||
|             <h2 class="card-pf-title inline-block">Active Pipelines</h4> | ||||
|             <a ng-href="{{$projectLink}}/jenkinsJob/{{jobId}}/pipelines">View All Pipelines >></a> | ||||
|           </div> | ||||
|           <div class="card-pf-body no-top-margin"> | ||||
|             <div class="full-card-width" ng-controller="Developer.PipelinesController" ng-include="'plugins/kubernetes/html/pendingPipelines.html'"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row row-cards-pf"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="card-pf"> | ||||
|           <div class="card-pf-heading"> | ||||
|             <h2 class="card-pf-title inline-block">Commits</h2> | ||||
|             <a ng-href="{{$projectLink}}/wiki/history//">View All Commits >></a> | ||||
|           </div> | ||||
|           <div class="card-pf-body"> | ||||
|             <div ng-include="'plugins/wiki/html/projectCommitsPanel.html'"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
| </div> | ||||
|  | ||||
| @ -1,38 +1,38 @@ | ||||
| <div ng-controller="Developer.HomeController"> | ||||
|   <div class="jumbotron"> | ||||
|     <h1>Perspectives</h1> | ||||
| 
 | ||||
|     <p> | ||||
|       Please choose the perspective you would like to use: | ||||
|     </p> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
| 
 | ||||
|     <div class="col-md-6"> | ||||
|       <p class="text-center"> | ||||
|         <a class="btn btn-lg btn-primary" href="/workspaces" role="button" | ||||
|            title="Create or work on Projects"> | ||||
|           <i class="fa fa-tasks"></i> | ||||
|            Develop » | ||||
|         </a> | ||||
|       </p> | ||||
| 
 | ||||
|       <p class="text-center"> | ||||
|         Work on projects and source code | ||||
|       </p> | ||||
|     </div> | ||||
|     <div class="col-md-6"> | ||||
|       <p class="text-center"> | ||||
|         <a class="btn btn-lg btn-primary" href="/namespaces" role="button" | ||||
|            title="Look around the various Namespaces at running Pods and Services"> | ||||
|           <i class="fa fa-cubes"></i> | ||||
|            Operate » | ||||
|         </a> | ||||
|       </p> | ||||
| 
 | ||||
|       <p class="text-center"> | ||||
|         Manage and run Pods and Services | ||||
|       </p> | ||||
|     </div> | ||||
|   </div> | ||||
| <div ng-controller="Developer.HomeController"> | ||||
|   <div class="jumbotron"> | ||||
|     <h1>Perspectives</h1> | ||||
| 
 | ||||
|     <p> | ||||
|       Please choose the perspective you would like to use: | ||||
|     </p> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
| 
 | ||||
|     <div class="col-md-6"> | ||||
|       <p class="text-center"> | ||||
|         <a class="btn btn-lg btn-primary" href="/workspaces" role="button" | ||||
|            title="Create or work on Projects"> | ||||
|           <i class="fa fa-tasks"></i> | ||||
|            Develop » | ||||
|         </a> | ||||
|       </p> | ||||
| 
 | ||||
|       <p class="text-center"> | ||||
|         Work on projects and source code | ||||
|       </p> | ||||
|     </div> | ||||
|     <div class="col-md-6"> | ||||
|       <p class="text-center"> | ||||
|         <a class="btn btn-lg btn-primary" href="/namespaces" role="button" | ||||
|            title="Look around the various Namespaces at running Pods and Services"> | ||||
|           <i class="fa fa-cubes"></i> | ||||
|            Operate » | ||||
|         </a> | ||||
|       </p> | ||||
| 
 | ||||
|       <p class="text-center"> | ||||
|         Manage and run Pods and Services | ||||
|       </p> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| @ -1,10 +1,10 @@ | ||||
| <div class="modal-header"> | ||||
|   <h3 class="modal-title">{{operation}}?</h3> | ||||
| </div> | ||||
| <div class="modal-body"> | ||||
|   Are you sure you wish to {{operation}}? | ||||
| </div> | ||||
| <div class="modal-footer"> | ||||
|   <button class="btn btn-primary" ng-click="ok()">{{operation}}</button> | ||||
|   <button class="btn btn-warning" ng-click="cancel()">Cancel</button> | ||||
| </div> | ||||
| <div class="modal-header"> | ||||
|   <h3 class="modal-title">{{operation}}?</h3> | ||||
| </div> | ||||
| <div class="modal-body"> | ||||
|   Are you sure you wish to {{operation}}? | ||||
| </div> | ||||
| <div class="modal-footer"> | ||||
|   <button class="btn btn-primary" ng-click="ok()">{{operation}}</button> | ||||
|   <button class="btn btn-warning" ng-click="cancel()">Cancel</button> | ||||
| </div> | ||||
|  | ||||
| @ -1,79 +1,79 @@ | ||||
| <div class="row" ng-controller="Developer.JenkinsJobController"> | ||||
|   <script type="text/ng-template" id="jenkinsBuildIdTemplate.html"> | ||||
|     <div class="ngCellText" title="{{row.entity.fullDisplayName}} {{row.entity.result}}"> | ||||
|       <a href="{{row.entity.$logsLink}}" title="View the build logs"> | ||||
|         <i class="{{row.entity.$iconClass}}"></i>  {{row.entity.displayName}} | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildButtonsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a class="btn btn-default" href="{{row.entity.$pipelineLink}}" ng-show="row.entity.$pipelineLink" target="View the pipeline for this build"> | ||||
|         <i class="fa fa-tasks"></i> Pipeline | ||||
|       </a> | ||||
|          | ||||
|       <a class="btn btn-default" href="{{row.entity.$logsLink}}" ng-show="row.entity.$logsLink" title="View the build logs"> | ||||
|         <i class="fa fa-tasks"></i> Logs | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildTimestampTemplate.html"> | ||||
|     <div class="ngCellText" title="Build started at: {{row.entity.$timestamp}}"> | ||||
|       {{row.entity.$timestamp.relative()}} | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildDurationTemplate.html"> | ||||
|     <div class="ngCellText" title="Build took {{row.entity.$duration}} milliseconds"> | ||||
|       {{row.entity.$duration.duration()}} | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="job.builds.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter builds..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched" | ||||
|               title="Delete this build history" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" ng-click="triggerBuild()" | ||||
|          title="Trigger this build"> | ||||
|         <i class="fa fa-play-circle-o"></i>  Trigger</a> | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="job.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no builds in this job.</p> | ||||
|         </div> | ||||
|         <div ng-show="job.builds.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.JenkinsJobController"> | ||||
|   <script type="text/ng-template" id="jenkinsBuildIdTemplate.html"> | ||||
|     <div class="ngCellText" title="{{row.entity.fullDisplayName}} {{row.entity.result}}"> | ||||
|       <a href="{{row.entity.$logsLink}}" title="View the build logs"> | ||||
|         <i class="{{row.entity.$iconClass}}"></i>  {{row.entity.displayName}} | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildButtonsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a class="btn btn-default" href="{{row.entity.$pipelineLink}}" ng-show="row.entity.$pipelineLink" target="View the pipeline for this build"> | ||||
|         <i class="fa fa-tasks"></i> Pipeline | ||||
|       </a> | ||||
|          | ||||
|       <a class="btn btn-default" href="{{row.entity.$logsLink}}" ng-show="row.entity.$logsLink" title="View the build logs"> | ||||
|         <i class="fa fa-tasks"></i> Logs | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildTimestampTemplate.html"> | ||||
|     <div class="ngCellText" title="Build started at: {{row.entity.$timestamp}}"> | ||||
|       {{row.entity.$timestamp.relative()}} | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildDurationTemplate.html"> | ||||
|     <div class="ngCellText" title="Build took {{row.entity.$duration}} milliseconds"> | ||||
|       {{row.entity.$duration.duration()}} | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="job.builds.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter builds..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched" | ||||
|               title="Delete this build history" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" ng-click="triggerBuild()" | ||||
|          title="Trigger this build"> | ||||
|         <i class="fa fa-play-circle-o"></i>  Trigger</a> | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="job.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no builds in this job.</p> | ||||
|         </div> | ||||
|         <div ng-show="job.builds.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,97 +1,97 @@ | ||||
| <div class="row" ng-controller="Developer.JenkinsJobsController"> | ||||
|   <script type="text/ng-template" id="jenkinsJobNameTemplate.html"> | ||||
|     <div class="ngCellText" title="{{row.entity.fullDisplayName}} {{row.entity.result}}"> | ||||
|       <a href="{{row.entity.$buildsLink}}"> | ||||
|         <i class="{{row.entity.$iconClass}}"></i>  {{row.entity.displayName}} | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsJobButtonsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a class="btn btn-default" href="{{row.entity.$pipelinesLink}}" ng-show="row.entity.$pipelinesLink" title="View the pipelines for this build"> | ||||
|         <i class="fa fa-tasks"></i> Pipelines | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildTimestampTemplate.html"> | ||||
|     <div class="ngCellText" title="Build started at: {{row.entity.$timestamp}}"> | ||||
|       {{row.entity.$timestamp.relative()}} | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildDurationTemplate.html"> | ||||
|     <div class="ngCellText" title="Build took {{row.entity.$duration}} milliseconds"> | ||||
|       {{row.entity.$duration.duration()}} | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsLastSuccessTemplate.html"> | ||||
|     <div class="ngCellText"  ng-init="success=row.entity.lastSuccessfulBuild"> | ||||
|       <span title="Build took {{success.$duration.duration()}} milliseconds"> | ||||
|       <span ng-show="success"> | ||||
|         {{success.$timestamp.relative()}} | ||||
|       </span> | ||||
|       <span ng-show="success.$buildLink"> | ||||
|         - | ||||
|         <a href="{{success.$buildLink}}" target="build" title="View the builds"> | ||||
|           {{success.displayName}} | ||||
|         </a> | ||||
|       </span> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsLastFailureTemplate.html"> | ||||
|     <div class="ngCellText" ng-init="fail=row.entity.lastFailedBuild"> | ||||
|       <span title="Build took {{fail.$duration.duration()}} milliseconds"> | ||||
|       <span ng-show="fail"> | ||||
|         {{fail.$timestamp.relative()}} | ||||
|       </span> | ||||
|       <span ng-show="fail.$buildLink"> | ||||
|         - | ||||
|         <a href="{{fail.$buildLink}}" target="build" title="View the builds"> | ||||
|           {{fail.displayName}} | ||||
|         </a> | ||||
|       </span> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="jenkins.jobs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter jobs..."></hawtio-filter> | ||||
|       </span> | ||||
|       <a class="btn btn-primary pull-right" ng-click="triggerBuild()" | ||||
|          title="Trigger this build"> | ||||
|         <i class="fa fa-play-circle-o"></i>  Trigger</a> | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="jenkins.jobs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no jobs in this jenkins.</p> | ||||
|         </div> | ||||
|         <div ng-show="jenkins.jobs.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.JenkinsJobsController"> | ||||
|   <script type="text/ng-template" id="jenkinsJobNameTemplate.html"> | ||||
|     <div class="ngCellText" title="{{row.entity.fullDisplayName}} {{row.entity.result}}"> | ||||
|       <a href="{{row.entity.$buildsLink}}"> | ||||
|         <i class="{{row.entity.$iconClass}}"></i>  {{row.entity.displayName}} | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsJobButtonsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a class="btn btn-default" href="{{row.entity.$pipelinesLink}}" ng-show="row.entity.$pipelinesLink" title="View the pipelines for this build"> | ||||
|         <i class="fa fa-tasks"></i> Pipelines | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildTimestampTemplate.html"> | ||||
|     <div class="ngCellText" title="Build started at: {{row.entity.$timestamp}}"> | ||||
|       {{row.entity.$timestamp.relative()}} | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsBuildDurationTemplate.html"> | ||||
|     <div class="ngCellText" title="Build took {{row.entity.$duration}} milliseconds"> | ||||
|       {{row.entity.$duration.duration()}} | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsLastSuccessTemplate.html"> | ||||
|     <div class="ngCellText"  ng-init="success=row.entity.lastSuccessfulBuild"> | ||||
|       <span title="Build took {{success.$duration.duration()}} milliseconds"> | ||||
|       <span ng-show="success"> | ||||
|         {{success.$timestamp.relative()}} | ||||
|       </span> | ||||
|       <span ng-show="success.$buildLink"> | ||||
|         - | ||||
|         <a href="{{success.$buildLink}}" target="build" title="View the builds"> | ||||
|           {{success.displayName}} | ||||
|         </a> | ||||
|       </span> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="jenkinsLastFailureTemplate.html"> | ||||
|     <div class="ngCellText" ng-init="fail=row.entity.lastFailedBuild"> | ||||
|       <span title="Build took {{fail.$duration.duration()}} milliseconds"> | ||||
|       <span ng-show="fail"> | ||||
|         {{fail.$timestamp.relative()}} | ||||
|       </span> | ||||
|       <span ng-show="fail.$buildLink"> | ||||
|         - | ||||
|         <a href="{{fail.$buildLink}}" target="build" title="View the builds"> | ||||
|           {{fail.displayName}} | ||||
|         </a> | ||||
|       </span> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="jenkins.jobs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter jobs..."></hawtio-filter> | ||||
|       </span> | ||||
|       <a class="btn btn-primary pull-right" ng-click="triggerBuild()" | ||||
|          title="Trigger this build"> | ||||
|         <i class="fa fa-play-circle-o"></i>  Trigger</a> | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="jenkins.jobs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no jobs in this jenkins.</p> | ||||
|         </div> | ||||
|         <div ng-show="jenkins.jobs.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,39 +1,39 @@ | ||||
| <div class="row" ng-controller="Developer.JenkinsLogController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-model="log.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter logs..."></hawtio-filter> | ||||
|       </span> | ||||
|       <a class="btn btn-default pull-right" target="jenkins" href="{{$viewJenkinsLogLink}}" ng-show="$viewJenkinsLogLink" | ||||
|          title="View this log inside Jenkins"> | ||||
|         <i class="fa fa-external-link"></i>  Log in Jenkins</a> | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" target="jenkins" href="{{$viewJenkinsBuildLink}}" ng-show="$viewJenkinsBuildLink" | ||||
|          title="View this build inside Jenkins"> | ||||
|         <i class="fa fa-external-link"></i>  Build in Jenkins</a> | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div class="log-window" viewport-height scroll-glue> | ||||
|         <div class="log-window-inner" > | ||||
|           <p ng-repeat="log in log.logs | filter:log.filterText track by $index" ng-bind-html="log | asTrustedHtml"></p> | ||||
|         </div> | ||||
|       </div> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.JenkinsLogController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-model="log.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter logs..."></hawtio-filter> | ||||
|       </span> | ||||
|       <a class="btn btn-default pull-right" target="jenkins" href="{{$viewJenkinsLogLink}}" ng-show="$viewJenkinsLogLink" | ||||
|          title="View this log inside Jenkins"> | ||||
|         <i class="fa fa-external-link"></i>  Log in Jenkins</a> | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" target="jenkins" href="{{$viewJenkinsBuildLink}}" ng-show="$viewJenkinsBuildLink" | ||||
|          title="View this build inside Jenkins"> | ||||
|         <i class="fa fa-external-link"></i>  Build in Jenkins</a> | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div class="log-window" viewport-height scroll-glue> | ||||
|         <div class="log-window-inner" > | ||||
|           <p ng-repeat="log in log.logs | filter:log.filterText track by $index" ng-bind-html="log | asTrustedHtml"></p> | ||||
|         </div> | ||||
|       </div> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,27 +1,27 @@ | ||||
| <div class="row" ng-controller="Developer.JenkinsMetricsController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="metrics.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no completed builds in this job.</p> | ||||
|         </div> | ||||
|         <div ng-show="metrics.builds.length"> | ||||
|           <nvd3 options="options" data="data" api="api"></nvd3> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.JenkinsMetricsController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="metrics.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no completed builds in this job.</p> | ||||
|         </div> | ||||
|         <div ng-show="metrics.builds.length"> | ||||
|           <nvd3 options="options" data="data" api="api"></nvd3> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <div class="log-panel" ng-controller="Developer.JenkinsLogController" scroll-glue> | ||||
|   <div class="log-panel-inner" style="height: 25px;"> | ||||
|     <p ng-repeat="log in log.logs track by $index" ng-bind-html="log | asTrustedHtml"></p> | ||||
|   </div> | ||||
| </div> | ||||
| 
 | ||||
| 
 | ||||
| <div class="log-panel" ng-controller="Developer.JenkinsLogController" scroll-glue> | ||||
|   <div class="log-panel-inner" style="height: 25px;"> | ||||
|     <p ng-repeat="log in log.logs track by $index" ng-bind-html="log | asTrustedHtml"></p> | ||||
|   </div> | ||||
| </div> | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,40 +1,40 @@ | ||||
| <div class="row" ng-controller="Developer.PipelineController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="model.stages.length" | ||||
|                        ng-model="model.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter pipeline..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.stages.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no pipeline stages in this build.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.stages.length"> | ||||
| 
 | ||||
|           <h2>Pipeline for {{jobId}}</h2> | ||||
| 
 | ||||
|           <div pipeline-view></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.PipelineController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="model.stages.length" | ||||
|                        ng-model="model.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter pipeline..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.stages.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no pipeline stages in this build.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.stages.length"> | ||||
| 
 | ||||
|           <h2>Pipeline for {{jobId}}</h2> | ||||
| 
 | ||||
|           <div pipeline-view></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,77 +1,77 @@ | ||||
| <div class="panel-group"> | ||||
|   <div class="panel panel-default"> | ||||
|     <div class="panel-heading"> | ||||
|       <h2 class="panel-title"> | ||||
|         <a data-toggle="collapse" data-parent=".panel-group" href="#build-{{build.id}}"> | ||||
|           Build {{build.displayName}} | ||||
|         </a> | ||||
|         <span class="pull-right" title="This build started at {{build.$timestamp}}"> | ||||
|           started {{build.$timestamp.relative()}} | ||||
|         </span> | ||||
|       </h2> | ||||
|     </div> | ||||
| 
 | ||||
|     <div id="build-{{build.id}}" class="panel-collapse collapse in"> | ||||
|       <div class="panel-body"> | ||||
| 
 | ||||
|         <div class="row"> | ||||
|           <div class="col-md-12"> | ||||
|             <!-- | ||||
|           <div class="pipeline-build inline-block" | ||||
|             title="{{build.description || 'Pipeline build number ' + build.displayName}}"> | ||||
|             <div class="buildName"> | ||||
|               <a href="{{build.$viewLink}}" title="View the build details"> | ||||
|                 {{build.displayName}} | ||||
|               </a> | ||||
|               <span class="buildParameters pull-right" ng-show="$parameterText"> | ||||
|                 <i class="fa fa-ellipsis-v" title="build parameters: {{build.$parameterText}}"></i> | ||||
|               </span> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="buildDuration text-center"> | ||||
|               <a href="{{build.$logLink}}" title="This build started at {{build.$timestamp}}"> | ||||
|                 started {{build.$timestamp.relative()}} | ||||
|               </a> | ||||
|             </div> | ||||
|           </div> | ||||
|             --> | ||||
| 
 | ||||
|             <div ng-repeat="stage in build.stages | filter:model.filterText track by $index" class="inline-block"> | ||||
|               <div class="pipeline-arrow inline-block" ng-show="$index"> | ||||
|                 <i class="fa fa-angle-double-right"></i> | ||||
|               </div> | ||||
|               <div class="pipeline-deploy {{stage.$backgroundClass}} inline-block"> | ||||
|                 <div class="text-center stageName" title="{{stage.status}}"><i class="{{stage.$iconClass}}"></i> | ||||
|                   <a href="{{stage.$viewLink}}" title="This stage started at {{stage.$startTime}}" target="jenkins"> | ||||
|                     {{stage.stageName}} | ||||
|                   </a> | ||||
|                 </div> | ||||
|                 <div class="text-center stageStartTime" title="Stage started at {{stage.$startTime}}"> | ||||
|                   <a href="{{stage.$logLink}}" title="View the logs of this stage"> | ||||
|                     {{stage.duration.duration()}} | ||||
|                   </a> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
| 
 | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row" ng-show="hideLogs && !build.building"> | ||||
|           <div class="col-md-12"> | ||||
|             <a href="{{build.$logLink}}" class="pull-right">View Full Log</a> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row" ng-hide="hideLogs && !build.building"> | ||||
|           <div class="col-md-12"> | ||||
|             <h4 class="inline-block">Logs</h4> | ||||
|             <a href="{{build.$logLink}}" class="pull-right">View Full Log</a> | ||||
|             <div style="height: 250px;" ng-include="'plugins/developer/html/logPanel.html'"></div> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
| 
 | ||||
|   </div> | ||||
| </div> | ||||
| <div class="panel-group"> | ||||
|   <div class="panel panel-default"> | ||||
|     <div class="panel-heading"> | ||||
|       <h2 class="panel-title"> | ||||
|         <a data-toggle="collapse" data-parent=".panel-group" href="#build-{{build.id}}"> | ||||
|           Build {{build.displayName}} | ||||
|         </a> | ||||
|         <span class="pull-right" title="This build started at {{build.$timestamp}}"> | ||||
|           started {{build.$timestamp.relative()}} | ||||
|         </span> | ||||
|       </h2> | ||||
|     </div> | ||||
| 
 | ||||
|     <div id="build-{{build.id}}" class="panel-collapse collapse in"> | ||||
|       <div class="panel-body"> | ||||
| 
 | ||||
|         <div class="row"> | ||||
|           <div class="col-md-12"> | ||||
|             <!-- | ||||
|           <div class="pipeline-build inline-block" | ||||
|             title="{{build.description || 'Pipeline build number ' + build.displayName}}"> | ||||
|             <div class="buildName"> | ||||
|               <a href="{{build.$viewLink}}" title="View the build details"> | ||||
|                 {{build.displayName}} | ||||
|               </a> | ||||
|               <span class="buildParameters pull-right" ng-show="$parameterText"> | ||||
|                 <i class="fa fa-ellipsis-v" title="build parameters: {{build.$parameterText}}"></i> | ||||
|               </span> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="buildDuration text-center"> | ||||
|               <a href="{{build.$logLink}}" title="This build started at {{build.$timestamp}}"> | ||||
|                 started {{build.$timestamp.relative()}} | ||||
|               </a> | ||||
|             </div> | ||||
|           </div> | ||||
|             --> | ||||
| 
 | ||||
|             <div ng-repeat="stage in build.stages | filter:model.filterText track by $index" class="inline-block"> | ||||
|               <div class="pipeline-arrow inline-block" ng-show="$index"> | ||||
|                 <i class="fa fa-angle-double-right"></i> | ||||
|               </div> | ||||
|               <div class="pipeline-deploy {{stage.$backgroundClass}} inline-block"> | ||||
|                 <div class="text-center stageName" title="{{stage.status}}"><i class="{{stage.$iconClass}}"></i> | ||||
|                   <a href="{{stage.$viewLink}}" title="This stage started at {{stage.$startTime}}" target="jenkins"> | ||||
|                     {{stage.stageName}} | ||||
|                   </a> | ||||
|                 </div> | ||||
|                 <div class="text-center stageStartTime" title="Stage started at {{stage.$startTime}}"> | ||||
|                   <a href="{{stage.$logLink}}" title="View the logs of this stage"> | ||||
|                     {{stage.duration.duration()}} | ||||
|                   </a> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
| 
 | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row" ng-show="hideLogs && !build.building"> | ||||
|           <div class="col-md-12"> | ||||
|             <a href="{{build.$logLink}}" class="pull-right">View Full Log</a> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row" ng-hide="hideLogs && !build.building"> | ||||
|           <div class="col-md-12"> | ||||
|             <h4 class="inline-block">Logs</h4> | ||||
|             <a href="{{build.$logLink}}" class="pull-right">View Full Log</a> | ||||
|             <div style="height: 250px;" ng-include="'plugins/developer/html/logPanel.html'"></div> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
| 
 | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,44 +1,44 @@ | ||||
| <div class="row" ng-controller="Developer.PipelinesController"> | ||||
|   <div hawtio-breadcrumbs></div> | ||||
|   <div hawtio-tabs></div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-4"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="model.job.builds.length" | ||||
|                        ng-model="model.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter pipelines..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="col-md-4"> | ||||
|       <form class="form-inline"> | ||||
|         <div class="checkbox" title="Only show build pipelines which are pending"> | ||||
|           <label> | ||||
|             <input type="checkbox" ng-model="model.pendingOnly">  Only pending builds | ||||
|           </label> | ||||
|         </div> | ||||
|       </form> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row" ng-init="hideLogs = true"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.job.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no pipelines for this job.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.job.builds.length"> | ||||
|           <div ng-repeat="build in model.job.builds | filter:model.filterText track by $index"> | ||||
|             <div pipeline-view></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.PipelinesController"> | ||||
|   <div hawtio-breadcrumbs></div> | ||||
|   <div hawtio-tabs></div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-4"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="model.job.builds.length" | ||||
|                        ng-model="model.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter pipelines..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="col-md-4"> | ||||
|       <form class="form-inline"> | ||||
|         <div class="checkbox" title="Only show build pipelines which are pending"> | ||||
|           <label> | ||||
|             <input type="checkbox" ng-model="model.pendingOnly">  Only pending builds | ||||
|           </label> | ||||
|         </div> | ||||
|       </form> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row" ng-init="hideLogs = true"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.job.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no pipelines for this job.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.job.builds.length"> | ||||
|           <div ng-repeat="build in model.job.builds | filter:model.filterText track by $index"> | ||||
|             <div pipeline-view></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,36 +1,36 @@ | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/buildConfigs"><i class="fa fa-list"></i></a> | ||||
|       <div class="pull-right" ng-repeat="view in entity.$fabric8Views | orderBy:'label'"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|         <span class="pull-right" ng-show="view.url" > </span> | ||||
|       </div> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button class="btn btn-primary pull-right" | ||||
|          title="Trigger this build" | ||||
|          ng-disabled="!entity.$triggerUrl" | ||||
|          ng-click="triggerBuild(entity)"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/buildConfigs"><i class="fa fa-list"></i></a> | ||||
|       <div class="pull-right" ng-repeat="view in entity.$fabric8Views | orderBy:'label'"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|         <span class="pull-right" ng-show="view.url" > </span> | ||||
|       </div> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button class="btn btn-primary pull-right" | ||||
|          title="Trigger this build" | ||||
|          ng-disabled="!entity.$triggerUrl" | ||||
|          ng-click="triggerBuild(entity)"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| <ul class="project-selector" ng-controller="Developer.ProjectSelector" ng-show='projectId'> | ||||
|   <li class="dropdown"> | ||||
|     <a href="#" class="dropdown-toggle" data-toggle="dropdown"> | ||||
|       <strong ng-bind="projectId"></strong> | ||||
|       <b class="caret"></b> | ||||
|     </a> | ||||
|     <ul class="dropdown-menu"> | ||||
|       <li ng-repeat='project in projects'> | ||||
|         <a ng-href="{{project.$viewLink}}">{{project.$name}}</a> | ||||
|       </li> | ||||
|     </ul> | ||||
|   </li> | ||||
| </ul> | ||||
| <ul class="project-selector" ng-controller="Developer.ProjectSelector" ng-show='projectId'> | ||||
|   <li class="dropdown"> | ||||
|     <a href="#" class="dropdown-toggle" data-toggle="dropdown"> | ||||
|       <strong ng-bind="projectId"></strong> | ||||
|       <b class="caret"></b> | ||||
|     </a> | ||||
|     <ul class="dropdown-menu"> | ||||
|       <li ng-repeat='project in projects'> | ||||
|         <a ng-href="{{project.$viewLink}}">{{project.$name}}</a> | ||||
|       </li> | ||||
|     </ul> | ||||
|   </li> | ||||
| </ul> | ||||
|  | ||||
| @ -1,126 +1,126 @@ | ||||
| <div class="row" ng-controller="Developer.ProjectsController"> | ||||
|   <script type="text/ng-template" id="buildConfigLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build configuration" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigs/{{row.entity.metadata.name}}"> | ||||
| <!-- | ||||
|         <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
| --> | ||||
|         {{row.entity.metadata.name}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8Views track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigCodeViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8CodeViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigBuildViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8BuildViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigEnvironmentViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8EnvironmentViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigTeamViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8TeamViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="model.buildconfigs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter apps..."></hawtio-filter> | ||||
|       </span> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button ng-show="fetched" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|               <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
| 
 | ||||
|       <button ng-show="model.fetched" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="!id && tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(id || tableConfig.selectedItems)" | ||||
|               title="Delete the selected apps"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
| 
 | ||||
|       <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" href="{{baseUri}}/workspaces/{{namespace}}/forge/createProject" | ||||
|          title="Create a new app in this project"> | ||||
|         <i class="fa fa-plus"></i> Create App</a> | ||||
|       </a> | ||||
| 
 | ||||
| <!-- | ||||
|       <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <button class="btn btn-default pull-right" | ||||
|          title="Trigger the given build" | ||||
|          ng-disabled="tableConfig.selectedItems.length != 1 || !tableConfig.selectedItems[0].$triggerUrl" | ||||
|          ng-click="triggerBuild(tableConfig.selectedItems[0])"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
| --> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.buildconfigs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no projects in this workspace.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.buildconfigs.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Developer.ProjectsController"> | ||||
|   <script type="text/ng-template" id="buildConfigLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build configuration" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigs/{{row.entity.metadata.name}}"> | ||||
| <!-- | ||||
|         <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
| --> | ||||
|         {{row.entity.metadata.name}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8Views track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigCodeViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8CodeViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigBuildViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8BuildViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigEnvironmentViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8EnvironmentViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigTeamViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8TeamViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="model.buildconfigs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter apps..."></hawtio-filter> | ||||
|       </span> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button ng-show="fetched" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|               <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
| 
 | ||||
|       <button ng-show="model.fetched" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="!id && tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(id || tableConfig.selectedItems)" | ||||
|               title="Delete the selected apps"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
| 
 | ||||
|       <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" href="{{baseUri}}/workspaces/{{namespace}}/forge/createProject" | ||||
|          title="Create a new app in this project"> | ||||
|         <i class="fa fa-plus"></i> Create App</a> | ||||
|       </a> | ||||
| 
 | ||||
| <!-- | ||||
|       <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <button class="btn btn-default pull-right" | ||||
|          title="Trigger the given build" | ||||
|          ng-disabled="tableConfig.selectedItems.length != 1 || !tableConfig.selectedItems[0].$triggerUrl" | ||||
|          ng-click="triggerBuild(tableConfig.selectedItems[0])"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
| --> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.buildconfigs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no projects in this workspace.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.buildconfigs.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,51 +1,51 @@ | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.tools.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter tools..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="entity.tools.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no tools currently available.</p> | ||||
|         </div> | ||||
|         <div ng-show="entity.tools.length"> | ||||
|           <div ng-hide="entity.tools.length" class="align-center"> | ||||
|             <p class="alert alert-info">There are no tools currently available.</p> | ||||
|           </div> | ||||
|           <div ng-repeat="env in entity.tools | filter:filterTemplates | orderBy:'label' track by $index"> | ||||
|             <div class="row" | ||||
|                  title="{{env.description}}"> | ||||
|               <div class="col-md-9"> | ||||
|                 <a href="{{env.url}}"> | ||||
|                   <h3> | ||||
|                     <i class="{{env.iconClass}}"></i> | ||||
|                     {{env.label}} | ||||
|                   </h3> | ||||
|                 </a> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.tools.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter tools..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="entity.tools.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no tools currently available.</p> | ||||
|         </div> | ||||
|         <div ng-show="entity.tools.length"> | ||||
|           <div ng-hide="entity.tools.length" class="align-center"> | ||||
|             <p class="alert alert-info">There are no tools currently available.</p> | ||||
|           </div> | ||||
|           <div ng-repeat="env in entity.tools | filter:filterTemplates | orderBy:'label' track by $index"> | ||||
|             <div class="row" | ||||
|                  title="{{env.description}}"> | ||||
|               <div class="col-md-9"> | ||||
|                 <a href="{{env.url}}"> | ||||
|                   <h3> | ||||
|                     <i class="{{env.iconClass}}"></i> | ||||
|                     {{env.label}} | ||||
|                   </h3> | ||||
|                 </a> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,46 +1,46 @@ | ||||
| <div ng-controller="Developer.WorkspaceController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/workspaces"><i class="fa fa-list"></i></a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$configLink" | ||||
|               title="View the workspace configuration" | ||||
|               href="{{entity.$configLink}}"> | ||||
|         Configuration | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$podLink" | ||||
|               title="View the workspace pod" | ||||
|               href="{{entity.$podLink}}"> | ||||
|         Pod | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-primary pull-right" ng-show="entity.$logsLink" | ||||
|               title="View the workspace logs" | ||||
|               href="{{entity.$logsLink}}"> | ||||
|         View Log | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Developer.WorkspaceController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/workspaces"><i class="fa fa-list"></i></a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$configLink" | ||||
|               title="View the workspace configuration" | ||||
|               href="{{entity.$configLink}}"> | ||||
|         Configuration | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$podLink" | ||||
|               title="View the workspace pod" | ||||
|               href="{{entity.$podLink}}"> | ||||
|         Pod | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-primary pull-right" ng-show="entity.$logsLink" | ||||
|               title="View the workspace logs" | ||||
|               href="{{entity.$logsLink}}"> | ||||
|         View Log | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,66 +1,66 @@ | ||||
| 
 | ||||
| .environment-row a { | ||||
|     color: black; | ||||
| } | ||||
| 
 | ||||
| .environment-row { | ||||
| 
 | ||||
|   .panel { | ||||
|     min-width: 255px; | ||||
|     min-height: 160px; | ||||
|   } | ||||
| 
 | ||||
|   .panel-group { | ||||
|     margin-left: 10px; | ||||
|     margin-right: 10px; | ||||
|   } | ||||
| 
 | ||||
|   .panel-title > a:before { | ||||
|     display: none; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| .environment-rows { | ||||
|     /* | ||||
|     background-color: rgb(238, 238, 238); | ||||
|     */ | ||||
|     padding-top: 5px; | ||||
|     vertical-align: top; | ||||
| } | ||||
| 
 | ||||
| .environment-name-block { | ||||
|     width: 200px; | ||||
| } | ||||
| 
 | ||||
| .environment-name-block, .environment-deploy-block { | ||||
|     background: white; | ||||
|     -moz-border-radius: 10px; | ||||
|     border-radius: 10px; | ||||
|     padding-top: 10px; | ||||
|     padding-bottom: 10px; | ||||
|     padding-left: 20px; | ||||
|     padding-right: 20px; | ||||
|     margin-top: 10px; | ||||
|     margin-bottom: 10px; | ||||
|     margin-left: 20px; | ||||
|     margin-right: 20px; | ||||
| } | ||||
| 
 | ||||
| .environment-name-block { | ||||
|     padding-top: 0px; | ||||
| } | ||||
| 
 | ||||
| .environment-block { | ||||
|     vertical-align: top; | ||||
| } | ||||
| 
 | ||||
| .environment-deploy-block { | ||||
|     border:1px dashed; | ||||
|     border-color: silver; | ||||
| } | ||||
| 
 | ||||
| .environment-deploy-version-and-pods { | ||||
|     padding-bottom: 5px; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .environment-row a { | ||||
|     color: black; | ||||
| } | ||||
| 
 | ||||
| .environment-row { | ||||
| 
 | ||||
|   .panel { | ||||
|     min-width: 255px; | ||||
|     min-height: 160px; | ||||
|   } | ||||
| 
 | ||||
|   .panel-group { | ||||
|     margin-left: 10px; | ||||
|     margin-right: 10px; | ||||
|   } | ||||
| 
 | ||||
|   .panel-title > a:before { | ||||
|     display: none; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| .environment-rows { | ||||
|     /* | ||||
|     background-color: rgb(238, 238, 238); | ||||
|     */ | ||||
|     padding-top: 5px; | ||||
|     vertical-align: top; | ||||
| } | ||||
| 
 | ||||
| .environment-name-block { | ||||
|     width: 200px; | ||||
| } | ||||
| 
 | ||||
| .environment-name-block, .environment-deploy-block { | ||||
|     background: white; | ||||
|     -moz-border-radius: 10px; | ||||
|     border-radius: 10px; | ||||
|     padding-top: 10px; | ||||
|     padding-bottom: 10px; | ||||
|     padding-left: 20px; | ||||
|     padding-right: 20px; | ||||
|     margin-top: 10px; | ||||
|     margin-bottom: 10px; | ||||
|     margin-left: 20px; | ||||
|     margin-right: 20px; | ||||
| } | ||||
| 
 | ||||
| .environment-name-block { | ||||
|     padding-top: 0px; | ||||
| } | ||||
| 
 | ||||
| .environment-block { | ||||
|     vertical-align: top; | ||||
| } | ||||
| 
 | ||||
| .environment-deploy-block { | ||||
|     border:1px dashed; | ||||
|     border-color: silver; | ||||
| } | ||||
| 
 | ||||
| .environment-deploy-version-and-pods { | ||||
|     padding-bottom: 5px; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,50 +1,50 @@ | ||||
| .project-dashboard { | ||||
| 
 | ||||
|   .page-header-row { | ||||
|     background: white; | ||||
|     margin-left: -20px; | ||||
|     margin-right: -20px; | ||||
|     margin-top: -20px; | ||||
|     border-bottom: 1px solid #d1d1d1; | ||||
|     margin-bottom: 13px; | ||||
|     padding-bottom: 7px; | ||||
|   } | ||||
| 
 | ||||
|   .card-pf-title { | ||||
|     margin-right: 1em; | ||||
|   } | ||||
| 
 | ||||
|   .no-border { | ||||
|     border: none; | ||||
|     margin-bottom: 0; | ||||
|   } | ||||
| 
 | ||||
|   .no-top-margin { | ||||
|     margin-top: 0; | ||||
|   } | ||||
| 
 | ||||
|   .full-card-width { | ||||
|     margin-left: -20px; | ||||
|     margin-right: -20px; | ||||
|   } | ||||
| 
 | ||||
|   .card-pf.pipeline { | ||||
|     .panel-group { | ||||
|       border-width: 0; | ||||
|       .panel { | ||||
|         box-shadow: none; | ||||
|       } | ||||
|       .panel.panel-default { | ||||
|         border-width: 0; | ||||
|         border-top-width: 1px; | ||||
| 
 | ||||
|         .log-panel { | ||||
|           border: 1px solid #d4d4d4; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| .project-dashboard { | ||||
| 
 | ||||
|   .page-header-row { | ||||
|     background: white; | ||||
|     margin-left: -20px; | ||||
|     margin-right: -20px; | ||||
|     margin-top: -20px; | ||||
|     border-bottom: 1px solid #d1d1d1; | ||||
|     margin-bottom: 13px; | ||||
|     padding-bottom: 7px; | ||||
|   } | ||||
| 
 | ||||
|   .card-pf-title { | ||||
|     margin-right: 1em; | ||||
|   } | ||||
| 
 | ||||
|   .no-border { | ||||
|     border: none; | ||||
|     margin-bottom: 0; | ||||
|   } | ||||
| 
 | ||||
|   .no-top-margin { | ||||
|     margin-top: 0; | ||||
|   } | ||||
| 
 | ||||
|   .full-card-width { | ||||
|     margin-left: -20px; | ||||
|     margin-right: -20px; | ||||
|   } | ||||
| 
 | ||||
|   .card-pf.pipeline { | ||||
|     .panel-group { | ||||
|       border-width: 0; | ||||
|       .panel { | ||||
|         box-shadow: none; | ||||
|       } | ||||
|       .panel.panel-default { | ||||
|         border-width: 0; | ||||
|         border-top-width: 1px; | ||||
| 
 | ||||
|         .log-panel { | ||||
|           border: 1px solid #d4d4d4; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| .filter-header { | ||||
| 
 | ||||
|   .btn, form { | ||||
|     margin-top: 1.05em; | ||||
|     margin-bottom: 1em; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| .filter-header { | ||||
| 
 | ||||
|   .btn, form { | ||||
|     margin-top: 1.05em; | ||||
|     margin-bottom: 1em; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,25 +1,25 @@ | ||||
| 
 | ||||
| .log-window { | ||||
|   border-top: 1px solid #d4d4d4; | ||||
|   overflow: auto; | ||||
| } | ||||
| 
 | ||||
| .log-window-inner * { | ||||
|   font-family: "DroidSansMonoRegular", monospace; | ||||
|   line-height: 13px; | ||||
| } | ||||
| 
 | ||||
| .log-panel { | ||||
|   position: static; | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
|   overflow: auto; | ||||
|   border: none; | ||||
|   padding: 3px; | ||||
| } | ||||
| 
 | ||||
| .log-panel-inner * { | ||||
|   font-family: "DroidSansMonoRegular", monospace; | ||||
|   line-height: 13px; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .log-window { | ||||
|   border-top: 1px solid #d4d4d4; | ||||
|   overflow: auto; | ||||
| } | ||||
| 
 | ||||
| .log-window-inner * { | ||||
|   font-family: "DroidSansMonoRegular", monospace; | ||||
|   line-height: 13px; | ||||
| } | ||||
| 
 | ||||
| .log-panel { | ||||
|   position: static; | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
|   overflow: auto; | ||||
|   border: none; | ||||
|   padding: 3px; | ||||
| } | ||||
| 
 | ||||
| .log-panel-inner * { | ||||
|   font-family: "DroidSansMonoRegular", monospace; | ||||
|   line-height: 13px; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| .project-selector { | ||||
|   margin-top: 10px; | ||||
|   margin-bottom: 10px; | ||||
| 
 | ||||
|   list-style-type: none; | ||||
| 
 | ||||
|   a, a:hover { | ||||
|     color: #fff; | ||||
|     text-decoration: none; | ||||
|     font-size: 13px; | ||||
|     line-height: 21px; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| .project-selector { | ||||
|   margin-top: 10px; | ||||
|   margin-bottom: 10px; | ||||
| 
 | ||||
|   list-style-type: none; | ||||
| 
 | ||||
|   a, a:hover { | ||||
|     color: #fff; | ||||
|     text-decoration: none; | ||||
|     font-size: 13px; | ||||
|     line-height: 21px; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,247 +1,247 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export function enrichWorkspaces(projects) { | ||||
|     angular.forEach(projects, (project) => { | ||||
|       enrichWorkspace(project); | ||||
|     }); | ||||
|     return projects; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichWorkspace(build) { | ||||
|     if (build) { | ||||
|       var name = Kubernetes.getName(build); | ||||
|       build.$name = name; | ||||
|       build.$sortOrder = 0 - build.number; | ||||
| 
 | ||||
|       var nameArray = name.split("-"); | ||||
|       var nameArrayLength = nameArray.length; | ||||
|       build.$shortName = (nameArrayLength > 4) ? nameArray.slice(0, nameArrayLength - 4).join("-") : name.substring(0, 30); | ||||
| 
 | ||||
|       var labels = Kubernetes.getLabels(build); | ||||
|       build.$creationDate = asDate(Kubernetes.getCreationTimestamp(build)); | ||||
|       build.$labelsText = Kubernetes.labelsToString(labels); | ||||
| 
 | ||||
|       if (name) { | ||||
|         build.$projectsLink = UrlHelpers.join("workspaces", name); | ||||
|         build.$runtimeLink = UrlHelpers.join("kubernetes/namespace/", name, "/apps"); | ||||
|         build.$viewLink = build.$projectsLink; | ||||
|       } | ||||
|     } | ||||
|     return build; | ||||
|   } | ||||
| 
 | ||||
|   export function asDate(value) { | ||||
|     return value ? new Date(value) : null; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsJobs(jobsData, projectId, jobName) { | ||||
|     if (jobsData) { | ||||
|       angular.forEach(jobsData.jobs, (job) => { | ||||
|         enrichJenkinsJob(job, projectId, jobName); | ||||
|       }); | ||||
|     } | ||||
|     return jobsData; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsJob(job, projectId, jobName) { | ||||
|     if (job) { | ||||
|       jobName = jobName || job.name || projectId; | ||||
|       job.$jobId = jobName; | ||||
|       job.$project = projectId || jobName; | ||||
|       var lastBuild = job.lastBuild; | ||||
|       var lastBuildResult = lastBuild ? lastBuild.result : "NOT_STARTED"; | ||||
|       var $iconClass = createBuildStatusIconClass(lastBuildResult); | ||||
| 
 | ||||
|       job.$lastBuildNumber = enrichJenkinsBuild(job, lastBuild); | ||||
|       job.$lastSuccessfulBuildNumber = enrichJenkinsBuild(job, job.lastSuccessfulBuild); | ||||
|       job.$lastFailedlBuildNumber = enrichJenkinsBuild(job, job.lastFailedlBuild); | ||||
| 
 | ||||
|       if (lastBuild) { | ||||
|         job.$duration = lastBuild.duration; | ||||
|         job.$timestamp = asDate(lastBuild.timestamp); | ||||
|       } | ||||
|       var jobUrl = (job || {}).url; | ||||
|       if (!jobUrl || !jobUrl.startsWith("http")) { | ||||
|         var jenkinsUrl = jenkinsLink(); | ||||
|         if (jenkinsUrl) { | ||||
|           jobUrl = UrlHelpers.join(jenkinsUrl, "job", jobName) | ||||
|         } | ||||
|       } | ||||
|       if (jobUrl) { | ||||
|         job.$jobLink = jobUrl; | ||||
|         var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
|         job.$pipelinesLink = UrlHelpers.join("/workspaces", workspaceName, "projects", job.$project, "jenkinsJob", jobName, "pipelines"); | ||||
|         job.$buildsLink = UrlHelpers.join("/workspaces", workspaceName, "projects", job.$project, "jenkinsJob", jobName); | ||||
|       } | ||||
|       job.$iconClass = $iconClass; | ||||
| 
 | ||||
|       angular.forEach(job.builds, (build) => { | ||||
|         enrichJenkinsBuild(job, build); | ||||
|       }); | ||||
|     } | ||||
|     return job; | ||||
|   } | ||||
| 
 | ||||
|   export function createBuildStatusIconClass(result) { | ||||
|     var $iconClass = "fa fa-spinner fa-spin"; | ||||
|     if (result) { | ||||
|       if (result === "FAILURE" || result === "FAILED") { | ||||
|         // TODO not available yet
 | ||||
|         $iconClass = "fa fa-exclamation-circle red"; | ||||
|       } else if (result === "ABORTED" || result === "INTERUPTED") { | ||||
|         $iconClass = "fa fa-circle grey"; | ||||
|       } else if (result === "SUCCESS" || result === "COMPLETE" || result === "COMPLETED") { | ||||
|         $iconClass = "fa fa-check-circle green"; | ||||
|       } else if (result === "NOT_STARTED") { | ||||
|         $iconClass = "fa fa-circle-thin grey"; | ||||
|       } | ||||
|     } | ||||
|     return $iconClass; | ||||
|   } | ||||
| 
 | ||||
|   export function createBuildStatusBackgroundClass(result) { | ||||
|     var $iconClass = "build-pending"; | ||||
|     if (result) { | ||||
|       if (result === "FAILURE" || result === "FAILED") { | ||||
|         $iconClass = "build-fail"; | ||||
|       } else if (result === "ABORTED" || result === "INTERUPTED") { | ||||
|         $iconClass = "build-aborted"; | ||||
|       } else if (result === "SUCCESS" || result === "COMPLETE" || result === "COMPLETED") { | ||||
|         $iconClass = "build-success"; | ||||
|       } else if (result === "NOT_STARTED") { | ||||
|         $iconClass = "build-not-started"; | ||||
|       } | ||||
|     } | ||||
|     return $iconClass; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsBuild(job, build) { | ||||
|     var number = null; | ||||
|     if (build) { | ||||
|       build.$duration = build.duration; | ||||
|       build.$timestamp = asDate(build.timestamp); | ||||
|       var projectId = job.$project; | ||||
|       var jobName = job.$jobId || projectId; | ||||
|       var buildId = build.id; | ||||
|       number = build.number; | ||||
|       var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
| 
 | ||||
|       var $iconClass = createBuildStatusIconClass(build.result); | ||||
|       var jobUrl = (job || {}).url; | ||||
|       if (!jobUrl || !jobUrl.startsWith("http")) { | ||||
|         var jenkinsUrl = jenkinsLink(); | ||||
|         if (jenkinsUrl) { | ||||
|           jobUrl = UrlHelpers.join(jenkinsUrl, "job", jobName) | ||||
|         } | ||||
|       } | ||||
|       if (jobUrl) { | ||||
|         build.$jobLink = jobUrl; | ||||
|         if (buildId) { | ||||
|           //build.$logsLink = UrlHelpers.join(build.$buildLink, "console");
 | ||||
|           build.$logsLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "log", buildId); | ||||
|           build.$pipelineLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "pipeline", buildId); | ||||
|           build.$buildsLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName); | ||||
|           //build.$buildLink = UrlHelpers.join(jobUrl, build.id);
 | ||||
|           build.$buildLink = build.$logsLink; | ||||
|         } | ||||
|       } | ||||
|       build.$iconClass = $iconClass; | ||||
|     } | ||||
|     return number; | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   export function jenkinsLink() { | ||||
|     var ServiceRegistry = Kubernetes.inject<any>("ServiceRegistry"); | ||||
|     if (ServiceRegistry) { | ||||
|       return ServiceRegistry.serviceLink(jenkinsServiceName); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   export function forgeReadyLink() { | ||||
|     var ServiceRegistry = Kubernetes.inject<any>("ServiceRegistry"); | ||||
|     if (ServiceRegistry) { | ||||
|       return ServiceRegistry.serviceReadyLink(Kubernetes.fabric8ForgeServiceName); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsPipelineJob(job, projectId, jobId) { | ||||
|     if (job) { | ||||
|       job.$project = projectId; | ||||
|       job.$jobId = jobId; | ||||
|       angular.forEach(job.builds, (build) => { | ||||
|         enrichJenkinsStages(build, projectId, jobId); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsStages(build, projectId, jobName) { | ||||
|     if (build) { | ||||
|       build.$project = projectId; | ||||
|       build.$jobId = jobName; | ||||
|       build.$timestamp = asDate(build.timeInMillis); | ||||
|       build.$iconClass = createBuildStatusIconClass(build.result || "NOT_STARTED"); | ||||
| 
 | ||||
|       var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
|       var parameters = build.parameters; | ||||
|       var $parameterCount = 0; | ||||
|       var $parameterText = "No parameters"; | ||||
|       if (parameters) { | ||||
|         $parameterCount = _.keys(parameters).length || 0; | ||||
|         $parameterText = Kubernetes.labelsToString(parameters, " "); | ||||
|       } | ||||
|       build.$parameterCount = $parameterCount; | ||||
|       build.$parameterText = $parameterText; | ||||
|       var jenkinsUrl = jenkinsLink(); | ||||
|       if (jenkinsUrl) { | ||||
|         var url = build.url; | ||||
|         if (url) { | ||||
| /* | ||||
|           build.$viewLink = UrlHelpers.join(jenkinsUrl, url); | ||||
|           build.$logLink = UrlHelpers.join(build.$viewLink, "log"); | ||||
| */ | ||||
|         } | ||||
|       } | ||||
|       build.$logLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "log", build.id); | ||||
|       build.$viewLink = build.$logLink; | ||||
| 
 | ||||
|       angular.forEach(build.stages, (stage) => { | ||||
|         enrichJenkinsStage(stage, build); | ||||
|       }); | ||||
|     } | ||||
|     return build; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsStage(stage, build = null) { | ||||
|     if (stage) { | ||||
|       if (build) { | ||||
|         stage.$buildId = build.id; | ||||
|         stage.$project = build.$project; | ||||
|       } | ||||
|       var projectId = build.$project; | ||||
|       var jobName = build.$jobId || projectId; | ||||
|       var buildId = build.id; | ||||
|       var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
|       stage.$backgroundClass =  createBuildStatusBackgroundClass(stage.status); | ||||
|       stage.$iconClass = createBuildStatusIconClass(stage.status); | ||||
|       stage.$startTime = asDate(stage.startTime); | ||||
|       if (!stage.duration) { | ||||
|         stage.duration = 0; | ||||
|       } | ||||
|       var jenkinsUrl = jenkinsLink(); | ||||
|       if (jenkinsUrl) { | ||||
|         var url = stage.url; | ||||
|         if (url) { | ||||
|           stage.$viewLink = UrlHelpers.join(jenkinsUrl, url); | ||||
|           stage.$logLink = UrlHelpers.join(stage.$viewLink, "log"); | ||||
|           if (projectId && buildId) { | ||||
|             stage.$logLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "log", buildId); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export function enrichWorkspaces(projects) { | ||||
|     angular.forEach(projects, (project) => { | ||||
|       enrichWorkspace(project); | ||||
|     }); | ||||
|     return projects; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichWorkspace(build) { | ||||
|     if (build) { | ||||
|       var name = Kubernetes.getName(build); | ||||
|       build.$name = name; | ||||
|       build.$sortOrder = 0 - build.number; | ||||
| 
 | ||||
|       var nameArray = name.split("-"); | ||||
|       var nameArrayLength = nameArray.length; | ||||
|       build.$shortName = (nameArrayLength > 4) ? nameArray.slice(0, nameArrayLength - 4).join("-") : name.substring(0, 30); | ||||
| 
 | ||||
|       var labels = Kubernetes.getLabels(build); | ||||
|       build.$creationDate = asDate(Kubernetes.getCreationTimestamp(build)); | ||||
|       build.$labelsText = Kubernetes.labelsToString(labels); | ||||
| 
 | ||||
|       if (name) { | ||||
|         build.$projectsLink = UrlHelpers.join("workspaces", name); | ||||
|         build.$runtimeLink = UrlHelpers.join("kubernetes/namespace/", name, "/apps"); | ||||
|         build.$viewLink = build.$projectsLink; | ||||
|       } | ||||
|     } | ||||
|     return build; | ||||
|   } | ||||
| 
 | ||||
|   export function asDate(value) { | ||||
|     return value ? new Date(value) : null; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsJobs(jobsData, projectId, jobName) { | ||||
|     if (jobsData) { | ||||
|       angular.forEach(jobsData.jobs, (job) => { | ||||
|         enrichJenkinsJob(job, projectId, jobName); | ||||
|       }); | ||||
|     } | ||||
|     return jobsData; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsJob(job, projectId, jobName) { | ||||
|     if (job) { | ||||
|       jobName = jobName || job.name || projectId; | ||||
|       job.$jobId = jobName; | ||||
|       job.$project = projectId || jobName; | ||||
|       var lastBuild = job.lastBuild; | ||||
|       var lastBuildResult = lastBuild ? lastBuild.result : "NOT_STARTED"; | ||||
|       var $iconClass = createBuildStatusIconClass(lastBuildResult); | ||||
| 
 | ||||
|       job.$lastBuildNumber = enrichJenkinsBuild(job, lastBuild); | ||||
|       job.$lastSuccessfulBuildNumber = enrichJenkinsBuild(job, job.lastSuccessfulBuild); | ||||
|       job.$lastFailedlBuildNumber = enrichJenkinsBuild(job, job.lastFailedlBuild); | ||||
| 
 | ||||
|       if (lastBuild) { | ||||
|         job.$duration = lastBuild.duration; | ||||
|         job.$timestamp = asDate(lastBuild.timestamp); | ||||
|       } | ||||
|       var jobUrl = (job || {}).url; | ||||
|       if (!jobUrl || !jobUrl.startsWith("http")) { | ||||
|         var jenkinsUrl = jenkinsLink(); | ||||
|         if (jenkinsUrl) { | ||||
|           jobUrl = UrlHelpers.join(jenkinsUrl, "job", jobName) | ||||
|         } | ||||
|       } | ||||
|       if (jobUrl) { | ||||
|         job.$jobLink = jobUrl; | ||||
|         var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
|         job.$pipelinesLink = UrlHelpers.join("/workspaces", workspaceName, "projects", job.$project, "jenkinsJob", jobName, "pipelines"); | ||||
|         job.$buildsLink = UrlHelpers.join("/workspaces", workspaceName, "projects", job.$project, "jenkinsJob", jobName); | ||||
|       } | ||||
|       job.$iconClass = $iconClass; | ||||
| 
 | ||||
|       angular.forEach(job.builds, (build) => { | ||||
|         enrichJenkinsBuild(job, build); | ||||
|       }); | ||||
|     } | ||||
|     return job; | ||||
|   } | ||||
| 
 | ||||
|   export function createBuildStatusIconClass(result) { | ||||
|     var $iconClass = "fa fa-spinner fa-spin"; | ||||
|     if (result) { | ||||
|       if (result === "FAILURE" || result === "FAILED") { | ||||
|         // TODO not available yet
 | ||||
|         $iconClass = "fa fa-exclamation-circle red"; | ||||
|       } else if (result === "ABORTED" || result === "INTERUPTED") { | ||||
|         $iconClass = "fa fa-circle grey"; | ||||
|       } else if (result === "SUCCESS" || result === "COMPLETE" || result === "COMPLETED") { | ||||
|         $iconClass = "fa fa-check-circle green"; | ||||
|       } else if (result === "NOT_STARTED") { | ||||
|         $iconClass = "fa fa-circle-thin grey"; | ||||
|       } | ||||
|     } | ||||
|     return $iconClass; | ||||
|   } | ||||
| 
 | ||||
|   export function createBuildStatusBackgroundClass(result) { | ||||
|     var $iconClass = "build-pending"; | ||||
|     if (result) { | ||||
|       if (result === "FAILURE" || result === "FAILED") { | ||||
|         $iconClass = "build-fail"; | ||||
|       } else if (result === "ABORTED" || result === "INTERUPTED") { | ||||
|         $iconClass = "build-aborted"; | ||||
|       } else if (result === "SUCCESS" || result === "COMPLETE" || result === "COMPLETED") { | ||||
|         $iconClass = "build-success"; | ||||
|       } else if (result === "NOT_STARTED") { | ||||
|         $iconClass = "build-not-started"; | ||||
|       } | ||||
|     } | ||||
|     return $iconClass; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsBuild(job, build) { | ||||
|     var number = null; | ||||
|     if (build) { | ||||
|       build.$duration = build.duration; | ||||
|       build.$timestamp = asDate(build.timestamp); | ||||
|       var projectId = job.$project; | ||||
|       var jobName = job.$jobId || projectId; | ||||
|       var buildId = build.id; | ||||
|       number = build.number; | ||||
|       var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
| 
 | ||||
|       var $iconClass = createBuildStatusIconClass(build.result); | ||||
|       var jobUrl = (job || {}).url; | ||||
|       if (!jobUrl || !jobUrl.startsWith("http")) { | ||||
|         var jenkinsUrl = jenkinsLink(); | ||||
|         if (jenkinsUrl) { | ||||
|           jobUrl = UrlHelpers.join(jenkinsUrl, "job", jobName) | ||||
|         } | ||||
|       } | ||||
|       if (jobUrl) { | ||||
|         build.$jobLink = jobUrl; | ||||
|         if (buildId) { | ||||
|           //build.$logsLink = UrlHelpers.join(build.$buildLink, "console");
 | ||||
|           build.$logsLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "log", buildId); | ||||
|           build.$pipelineLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "pipeline", buildId); | ||||
|           build.$buildsLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName); | ||||
|           //build.$buildLink = UrlHelpers.join(jobUrl, build.id);
 | ||||
|           build.$buildLink = build.$logsLink; | ||||
|         } | ||||
|       } | ||||
|       build.$iconClass = $iconClass; | ||||
|     } | ||||
|     return number; | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   export function jenkinsLink() { | ||||
|     var ServiceRegistry = Kubernetes.inject<any>("ServiceRegistry"); | ||||
|     if (ServiceRegistry) { | ||||
|       return ServiceRegistry.serviceLink(jenkinsServiceName); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   export function forgeReadyLink() { | ||||
|     var ServiceRegistry = Kubernetes.inject<any>("ServiceRegistry"); | ||||
|     if (ServiceRegistry) { | ||||
|       return ServiceRegistry.serviceReadyLink(Kubernetes.fabric8ForgeServiceName); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsPipelineJob(job, projectId, jobId) { | ||||
|     if (job) { | ||||
|       job.$project = projectId; | ||||
|       job.$jobId = jobId; | ||||
|       angular.forEach(job.builds, (build) => { | ||||
|         enrichJenkinsStages(build, projectId, jobId); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsStages(build, projectId, jobName) { | ||||
|     if (build) { | ||||
|       build.$project = projectId; | ||||
|       build.$jobId = jobName; | ||||
|       build.$timestamp = asDate(build.timeInMillis); | ||||
|       build.$iconClass = createBuildStatusIconClass(build.result || "NOT_STARTED"); | ||||
| 
 | ||||
|       var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
|       var parameters = build.parameters; | ||||
|       var $parameterCount = 0; | ||||
|       var $parameterText = "No parameters"; | ||||
|       if (parameters) { | ||||
|         $parameterCount = _.keys(parameters).length || 0; | ||||
|         $parameterText = Kubernetes.labelsToString(parameters, " "); | ||||
|       } | ||||
|       build.$parameterCount = $parameterCount; | ||||
|       build.$parameterText = $parameterText; | ||||
|       var jenkinsUrl = jenkinsLink(); | ||||
|       if (jenkinsUrl) { | ||||
|         var url = build.url; | ||||
|         if (url) { | ||||
| /* | ||||
|           build.$viewLink = UrlHelpers.join(jenkinsUrl, url); | ||||
|           build.$logLink = UrlHelpers.join(build.$viewLink, "log"); | ||||
| */ | ||||
|         } | ||||
|       } | ||||
|       build.$logLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "log", build.id); | ||||
|       build.$viewLink = build.$logLink; | ||||
| 
 | ||||
|       angular.forEach(build.stages, (stage) => { | ||||
|         enrichJenkinsStage(stage, build); | ||||
|       }); | ||||
|     } | ||||
|     return build; | ||||
|   } | ||||
| 
 | ||||
|   export function enrichJenkinsStage(stage, build = null) { | ||||
|     if (stage) { | ||||
|       if (build) { | ||||
|         stage.$buildId = build.id; | ||||
|         stage.$project = build.$project; | ||||
|       } | ||||
|       var projectId = build.$project; | ||||
|       var jobName = build.$jobId || projectId; | ||||
|       var buildId = build.id; | ||||
|       var workspaceName = Kubernetes.currentKubernetesNamespace(); | ||||
|       stage.$backgroundClass =  createBuildStatusBackgroundClass(stage.status); | ||||
|       stage.$iconClass = createBuildStatusIconClass(stage.status); | ||||
|       stage.$startTime = asDate(stage.startTime); | ||||
|       if (!stage.duration) { | ||||
|         stage.duration = 0; | ||||
|       } | ||||
|       var jenkinsUrl = jenkinsLink(); | ||||
|       if (jenkinsUrl) { | ||||
|         var url = stage.url; | ||||
|         if (url) { | ||||
|           stage.$viewLink = UrlHelpers.join(jenkinsUrl, url); | ||||
|           stage.$logLink = UrlHelpers.join(stage.$viewLink, "log"); | ||||
|           if (projectId && buildId) { | ||||
|             stage.$logLink = UrlHelpers.join("/workspaces", workspaceName, "projects", projectId, "jenkinsJob", jobName, "log", buildId); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,294 +1,294 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var context = '/workspaces'; | ||||
|   export var hash = '#' + context; | ||||
|   export var pluginName = 'Developer'; | ||||
|   export var pluginPath = 'plugins/developer/'; | ||||
|   export var templatePath = pluginPath + 'html/'; | ||||
|   export var log:Logging.Logger = Logger.get(pluginName); | ||||
| 
 | ||||
|   export var jenkinsServiceName = "jenkins"; | ||||
|   export var jenkinsServiceNameAndPort = jenkinsServiceName + ":http"; | ||||
| 
 | ||||
|   export var jenkinsHttpConfig = { | ||||
|     headers: { | ||||
|       Accept: "application/json, text/x-json, text/plain" | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   /** | ||||
|    * Returns true if the value hasn't changed from the last cached JSON version of this object | ||||
|    */ | ||||
|   export function hasObjectChanged(value, state) { | ||||
|     var json = angular.toJson(value || ""); | ||||
|     var oldJson = state.json; | ||||
|     state.json = json; | ||||
|     return !oldJson || json !== oldJson; | ||||
|   } | ||||
| 
 | ||||
|   export function projectForScope($scope) { | ||||
|     if ($scope) { | ||||
|       return $scope.buildConfig || $scope.entity || ($scope.model || {}).project; | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
|   /** | ||||
|    * Lets load the project versions for the given namespace | ||||
|    */ | ||||
|   export function loadProjectVersions($scope, $element, project, env, ns, answer, caches) { | ||||
|     var projectAnnotation = "project"; | ||||
|     var versionAnnotation = "version"; | ||||
| 
 | ||||
|     var projectNamespace = project.$namespace; | ||||
|     var projectName = project.$name; | ||||
| 
 | ||||
|     var cache = caches[ns]; | ||||
|     if (!cache) { | ||||
|       cache = {}; | ||||
|       caches[ns] = cache; | ||||
|     } | ||||
| 
 | ||||
|     var status = { | ||||
|       rcs: [], | ||||
|       pods: [], | ||||
|       routes: [], | ||||
|       services: [] | ||||
|     }; | ||||
| 
 | ||||
|     var imageStreamTags = []; | ||||
| 
 | ||||
|     function updateModel() { | ||||
|       var projectInfos = {}; | ||||
|       var model = $scope.model || {}; | ||||
| 
 | ||||
|       angular.forEach(status.rcs, (item) => { | ||||
|         var metadata = item.metadata || {}; | ||||
|         var name = metadata.name; | ||||
|         var labels = metadata.labels || {}; | ||||
|         var annotations = metadata.annotations || {}; | ||||
|         var spec = item.spec || {}; | ||||
|         var selector = spec.selector; | ||||
| 
 | ||||
|         var project = labels[projectAnnotation]; | ||||
|         var version = labels[versionAnnotation]; | ||||
| 
 | ||||
|         // lets try the S2I defaults...
 | ||||
|         if (!project) { | ||||
|           project = labels["app"]; | ||||
|         } | ||||
|         if (!version) { | ||||
|           version = annotations["openshift.io/deployment-config.latest-version"] | ||||
|         } | ||||
|         if (project && version && project === projectName) { | ||||
|           var projects = projectInfos[project]; | ||||
|           if (!projects) { | ||||
|             projects = { | ||||
|               project: project, | ||||
|               versions: {} | ||||
|             }; | ||||
|             projectInfos[project] = projects; | ||||
|           } | ||||
|           var versionInfo = projects.versions[version]; | ||||
|           if (!versionInfo) { | ||||
|             versionInfo = { | ||||
|               replicationControllers: {} | ||||
|             }; | ||||
|             projects.versions[version] = versionInfo; | ||||
|           } | ||||
|           if (name) { | ||||
|             versionInfo.replicationControllers[name] = item; | ||||
|             item.$name = name; | ||||
|             if (projectNamespace && projectName) { | ||||
|               item.$viewLink = UrlHelpers.join("/workspaces/", projectNamespace, "projects", projectName, "namespace", ns, "replicationControllers", name); | ||||
|             } else { | ||||
|               log.warn("Missing project data! " + projectNamespace + " name " + projectName); | ||||
|             } | ||||
| 
 | ||||
|             item.$services = []; | ||||
|             var rcLink = null; | ||||
|             status.services.forEach((service) => { | ||||
|               var repSelector = Kubernetes.getSelector(item); | ||||
|               var serviceSelector = Kubernetes.getSelector(service); | ||||
|               if (serviceSelector && repSelector && | ||||
|                 Kubernetes.selectorMatches(serviceSelector, repSelector) && | ||||
|                 Kubernetes.getNamespace(service) === Kubernetes.getNamespace(item)) { | ||||
|                 status.routes.forEach((route) => { | ||||
|                   var serviceName = Kubernetes.getName(service); | ||||
|                   if (serviceName === Kubernetes.getName(route)) { | ||||
|                     service["$route"] = route; | ||||
|                     service["$host"] = Core.pathGet(route, ["spec", "host"]); | ||||
|                     item.$services.push(service); | ||||
|                     if (!rcLink) { | ||||
|                       var url = Kubernetes.serviceLinkUrl(service, true); | ||||
|                       if (url) { | ||||
|                         // TODO find icon etc?
 | ||||
|                         rcLink = { | ||||
|                           name: serviceName, | ||||
|                           href: url | ||||
|                         }; | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 }); | ||||
|               } | ||||
|             }); | ||||
|             item["$serviceLink"] = rcLink; | ||||
|           } | ||||
|           item.$buildId = annotations["fabric8.io/build-id"] || item.$buildId; | ||||
|           item.$buildUrl = annotations["fabric8.io/build-url"] || item.$buildUrl; | ||||
|           item.$gitCommit = annotations["fabric8.io/git-commit"] || item.$gitCommit; | ||||
|           item.$gitUrl = annotations["fabric8.io/git-url"] || item.$gitUrl; | ||||
|           item.$gitBranch = annotations["fabric8.io/git-branch"] || item.$gitBranch; | ||||
|           if (!item.$gitCommit) { | ||||
|             var image = getImage(item); | ||||
|             if (image) { | ||||
|               if (!$scope.$isWatchImages) { | ||||
|                 $scope.$isWatchImages = true; | ||||
|                 Kubernetes.watch($scope, $element, "images", null, (data) => { | ||||
|                   imageStreamTags = data; | ||||
|                   checkForMissingMetadata(); | ||||
|                 }); | ||||
|               } else { | ||||
|                 checkForMissingMetadata(); | ||||
|               } | ||||
|             } | ||||
| 
 | ||||
|             function getImage(item) { | ||||
|               var image = ""; | ||||
|               // lets see if we can find the commit id from a S2I image name
 | ||||
|               // TODO needs this issue fixed to find it via an OpenShift annotation:
 | ||||
|               // https://github.com/openshift/origin/issues/6241
 | ||||
|               var containers = Core.pathGet(item, ["spec", "template", "spec", "containers"]); | ||||
|               if (containers && containers.length) { | ||||
|                 var container = containers[0]; | ||||
|                 if (container) { | ||||
|                   image = container.image; | ||||
|                 } | ||||
|               } | ||||
|               return image; | ||||
|             } | ||||
| 
 | ||||
|             function checkForMissingMetadata() { | ||||
|               angular.forEach(projects.versions, (vi) => { | ||||
|                 angular.forEach(vi.replicationControllers, (item, name) => { | ||||
|                   if (!item.$gitCommit) { | ||||
|                     var image = getImage(item); | ||||
|                     if (image) { | ||||
|                       angular.forEach(imageStreamTags, (imageStreamTag) => { | ||||
|                         var imageName = imageStreamTag.dockerImageReference; | ||||
|                         if (imageName && imageName === image) { | ||||
|                           var foundISTag = imageStreamTag; | ||||
|                           var manifestJSON = imageStreamTag.dockerImageManifest; | ||||
|                           if (manifestJSON) { | ||||
|                             var manifest = angular.fromJson(manifestJSON) || {}; | ||||
|                             var history = manifest.history; | ||||
|                             if (history && history.length) { | ||||
|                               var v1 = history[0].v1Compatibility; | ||||
|                               if (v1) { | ||||
|                                 var data = angular.fromJson(v1); | ||||
|                                 var env = Core.pathGet(data, ["config", "Env"]); | ||||
|                                 angular.forEach(env, (envExp) => { | ||||
|                                   if (envExp) { | ||||
|                                     var values = envExp.split("="); | ||||
|                                     if (values.length === 2 && values[0] == "OPENSHIFT_BUILD_NAME") { | ||||
|                                       var buildName = values[1]; | ||||
|                                       if (buildName) { | ||||
|                                         item.$buildId = buildName; | ||||
|                                         item.$buildUrl = Developer.projectWorkspaceLink(ns, projectName, "buildLogs/" + buildName); | ||||
|                                       } | ||||
|                                     } | ||||
|                                   } | ||||
|                                 }); | ||||
|                                 var labels = Core.pathGet(data, ["config", "Labels"]); | ||||
|                                 if (labels) { | ||||
|                                   item.$gitCommit = labels["io.openshift.build.commit.id"] || item.$gitCommit; | ||||
|                                   item.$gitCommitAuthor = labels["io.openshift.build.commit.author"] || item.$gitCommitAuthor; | ||||
|                                   item.$gitCommitDate = labels["io.openshift.build.commit.date"] || item.$gitCommitDate; | ||||
|                                   item.$gitCommitMessage = labels["io.openshift.build.commit.message"] || item.$gitCommitMessage; | ||||
|                                   item.$gitBranch = labels["io.openshift.build.commit.ref"] || item.$gitBranch; | ||||
| 
 | ||||
|                                   if (!item.$gitUrl && item.$gitCommit) { | ||||
|                                     item.$gitUrl = Developer.projectWorkspaceLink(ns, projectName, "wiki/commitDetail///" + item.$gitCommit); | ||||
|                                   } | ||||
|                                 } | ||||
|                               } | ||||
|                             } | ||||
|                           } | ||||
|                         } | ||||
|                       }); | ||||
|                     } | ||||
|                   } | ||||
|                 }); | ||||
|               }); | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
|           if (selector) { | ||||
|             var selectorText = Kubernetes.labelsToString(selector, ","); | ||||
|             var podLinkUrl = UrlHelpers.join(projectLink(projectName), "namespace", ns, "pods"); | ||||
|             item.pods = []; | ||||
|             item.$podCounters = Kubernetes.createPodCounters(selector, status.pods, item.pods, selectorText, podLinkUrl); | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       // lets check for a project name if we have lots of RCs with no pods, lets remove them!
 | ||||
|       angular.forEach(projectInfos, (project, projectName) => { | ||||
|         var rcsNoPods = []; | ||||
|         var rcsWithPods = []; | ||||
|         angular.forEach(project.versions, (versionInfo) => { | ||||
|           var rcs = versionInfo.replicationControllers; | ||||
|           angular.forEach(rcs, (item, name) => { | ||||
|             var count = Kubernetes.podCounterTotal(item.$podCounters); | ||||
|             if (count) { | ||||
|               rcsWithPods.push(name); | ||||
|             } else { | ||||
|               rcsNoPods.push(() => { | ||||
|                 delete rcs[name]; | ||||
|               }); | ||||
|             } | ||||
|           }); | ||||
|         }); | ||||
|         if (rcsWithPods.length) { | ||||
|           // lets remove all the empty RCs
 | ||||
|           angular.forEach(rcsNoPods, (fn) => { | ||||
|             fn(); | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       if (hasObjectChanged(projectInfos, cache)) { | ||||
|         log.debug("project versions has changed!"); | ||||
|         answer[ns] = projectInfos; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     Kubernetes.watch($scope, $element, "replicationcontrollers", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.rcs = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|     Kubernetes.watch($scope, $element, "services", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.services = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|     Kubernetes.watch($scope, $element, "routes", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.routes = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|     Kubernetes.watch($scope, $element, "pods", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.pods = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var context = '/workspaces'; | ||||
|   export var hash = '#' + context; | ||||
|   export var pluginName = 'Developer'; | ||||
|   export var pluginPath = 'plugins/developer/'; | ||||
|   export var templatePath = pluginPath + 'html/'; | ||||
|   export var log:Logging.Logger = Logger.get(pluginName); | ||||
| 
 | ||||
|   export var jenkinsServiceName = "jenkins"; | ||||
|   export var jenkinsServiceNameAndPort = jenkinsServiceName + ":http"; | ||||
| 
 | ||||
|   export var jenkinsHttpConfig = { | ||||
|     headers: { | ||||
|       Accept: "application/json, text/x-json, text/plain" | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   /** | ||||
|    * Returns true if the value hasn't changed from the last cached JSON version of this object | ||||
|    */ | ||||
|   export function hasObjectChanged(value, state) { | ||||
|     var json = angular.toJson(value || ""); | ||||
|     var oldJson = state.json; | ||||
|     state.json = json; | ||||
|     return !oldJson || json !== oldJson; | ||||
|   } | ||||
| 
 | ||||
|   export function projectForScope($scope) { | ||||
|     if ($scope) { | ||||
|       return $scope.buildConfig || $scope.entity || ($scope.model || {}).project; | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
|   /** | ||||
|    * Lets load the project versions for the given namespace | ||||
|    */ | ||||
|   export function loadProjectVersions($scope, $element, project, env, ns, answer, caches) { | ||||
|     var projectAnnotation = "project"; | ||||
|     var versionAnnotation = "version"; | ||||
| 
 | ||||
|     var projectNamespace = project.$namespace; | ||||
|     var projectName = project.$name; | ||||
| 
 | ||||
|     var cache = caches[ns]; | ||||
|     if (!cache) { | ||||
|       cache = {}; | ||||
|       caches[ns] = cache; | ||||
|     } | ||||
| 
 | ||||
|     var status = { | ||||
|       rcs: [], | ||||
|       pods: [], | ||||
|       routes: [], | ||||
|       services: [] | ||||
|     }; | ||||
| 
 | ||||
|     var imageStreamTags = []; | ||||
| 
 | ||||
|     function updateModel() { | ||||
|       var projectInfos = {}; | ||||
|       var model = $scope.model || {}; | ||||
| 
 | ||||
|       angular.forEach(status.rcs, (item) => { | ||||
|         var metadata = item.metadata || {}; | ||||
|         var name = metadata.name; | ||||
|         var labels = metadata.labels || {}; | ||||
|         var annotations = metadata.annotations || {}; | ||||
|         var spec = item.spec || {}; | ||||
|         var selector = spec.selector; | ||||
| 
 | ||||
|         var project = labels[projectAnnotation]; | ||||
|         var version = labels[versionAnnotation]; | ||||
| 
 | ||||
|         // lets try the S2I defaults...
 | ||||
|         if (!project) { | ||||
|           project = labels["app"]; | ||||
|         } | ||||
|         if (!version) { | ||||
|           version = annotations["openshift.io/deployment-config.latest-version"] | ||||
|         } | ||||
|         if (project && version && project === projectName) { | ||||
|           var projects = projectInfos[project]; | ||||
|           if (!projects) { | ||||
|             projects = { | ||||
|               project: project, | ||||
|               versions: {} | ||||
|             }; | ||||
|             projectInfos[project] = projects; | ||||
|           } | ||||
|           var versionInfo = projects.versions[version]; | ||||
|           if (!versionInfo) { | ||||
|             versionInfo = { | ||||
|               replicationControllers: {} | ||||
|             }; | ||||
|             projects.versions[version] = versionInfo; | ||||
|           } | ||||
|           if (name) { | ||||
|             versionInfo.replicationControllers[name] = item; | ||||
|             item.$name = name; | ||||
|             if (projectNamespace && projectName) { | ||||
|               item.$viewLink = UrlHelpers.join("/workspaces/", projectNamespace, "projects", projectName, "namespace", ns, "replicationControllers", name); | ||||
|             } else { | ||||
|               log.warn("Missing project data! " + projectNamespace + " name " + projectName); | ||||
|             } | ||||
| 
 | ||||
|             item.$services = []; | ||||
|             var rcLink = null; | ||||
|             status.services.forEach((service) => { | ||||
|               var repSelector = Kubernetes.getSelector(item); | ||||
|               var serviceSelector = Kubernetes.getSelector(service); | ||||
|               if (serviceSelector && repSelector && | ||||
|                 Kubernetes.selectorMatches(serviceSelector, repSelector) && | ||||
|                 Kubernetes.getNamespace(service) === Kubernetes.getNamespace(item)) { | ||||
|                 status.routes.forEach((route) => { | ||||
|                   var serviceName = Kubernetes.getName(service); | ||||
|                   if (serviceName === Kubernetes.getName(route)) { | ||||
|                     service["$route"] = route; | ||||
|                     service["$host"] = Core.pathGet(route, ["spec", "host"]); | ||||
|                     item.$services.push(service); | ||||
|                     if (!rcLink) { | ||||
|                       var url = Kubernetes.serviceLinkUrl(service, true); | ||||
|                       if (url) { | ||||
|                         // TODO find icon etc?
 | ||||
|                         rcLink = { | ||||
|                           name: serviceName, | ||||
|                           href: url | ||||
|                         }; | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 }); | ||||
|               } | ||||
|             }); | ||||
|             item["$serviceLink"] = rcLink; | ||||
|           } | ||||
|           item.$buildId = annotations["fabric8.io/build-id"] || item.$buildId; | ||||
|           item.$buildUrl = annotations["fabric8.io/build-url"] || item.$buildUrl; | ||||
|           item.$gitCommit = annotations["fabric8.io/git-commit"] || item.$gitCommit; | ||||
|           item.$gitUrl = annotations["fabric8.io/git-url"] || item.$gitUrl; | ||||
|           item.$gitBranch = annotations["fabric8.io/git-branch"] || item.$gitBranch; | ||||
|           if (!item.$gitCommit) { | ||||
|             var image = getImage(item); | ||||
|             if (image) { | ||||
|               if (!$scope.$isWatchImages) { | ||||
|                 $scope.$isWatchImages = true; | ||||
|                 Kubernetes.watch($scope, $element, "images", null, (data) => { | ||||
|                   imageStreamTags = data; | ||||
|                   checkForMissingMetadata(); | ||||
|                 }); | ||||
|               } else { | ||||
|                 checkForMissingMetadata(); | ||||
|               } | ||||
|             } | ||||
| 
 | ||||
|             function getImage(item) { | ||||
|               var image = ""; | ||||
|               // lets see if we can find the commit id from a S2I image name
 | ||||
|               // TODO needs this issue fixed to find it via an OpenShift annotation:
 | ||||
|               // https://github.com/openshift/origin/issues/6241
 | ||||
|               var containers = Core.pathGet(item, ["spec", "template", "spec", "containers"]); | ||||
|               if (containers && containers.length) { | ||||
|                 var container = containers[0]; | ||||
|                 if (container) { | ||||
|                   image = container.image; | ||||
|                 } | ||||
|               } | ||||
|               return image; | ||||
|             } | ||||
| 
 | ||||
|             function checkForMissingMetadata() { | ||||
|               angular.forEach(projects.versions, (vi) => { | ||||
|                 angular.forEach(vi.replicationControllers, (item, name) => { | ||||
|                   if (!item.$gitCommit) { | ||||
|                     var image = getImage(item); | ||||
|                     if (image) { | ||||
|                       angular.forEach(imageStreamTags, (imageStreamTag) => { | ||||
|                         var imageName = imageStreamTag.dockerImageReference; | ||||
|                         if (imageName && imageName === image) { | ||||
|                           var foundISTag = imageStreamTag; | ||||
|                           var manifestJSON = imageStreamTag.dockerImageManifest; | ||||
|                           if (manifestJSON) { | ||||
|                             var manifest = angular.fromJson(manifestJSON) || {}; | ||||
|                             var history = manifest.history; | ||||
|                             if (history && history.length) { | ||||
|                               var v1 = history[0].v1Compatibility; | ||||
|                               if (v1) { | ||||
|                                 var data = angular.fromJson(v1); | ||||
|                                 var env = Core.pathGet(data, ["config", "Env"]); | ||||
|                                 angular.forEach(env, (envExp) => { | ||||
|                                   if (envExp) { | ||||
|                                     var values = envExp.split("="); | ||||
|                                     if (values.length === 2 && values[0] == "OPENSHIFT_BUILD_NAME") { | ||||
|                                       var buildName = values[1]; | ||||
|                                       if (buildName) { | ||||
|                                         item.$buildId = buildName; | ||||
|                                         item.$buildUrl = Developer.projectWorkspaceLink(ns, projectName, "buildLogs/" + buildName); | ||||
|                                       } | ||||
|                                     } | ||||
|                                   } | ||||
|                                 }); | ||||
|                                 var labels = Core.pathGet(data, ["config", "Labels"]); | ||||
|                                 if (labels) { | ||||
|                                   item.$gitCommit = labels["io.openshift.build.commit.id"] || item.$gitCommit; | ||||
|                                   item.$gitCommitAuthor = labels["io.openshift.build.commit.author"] || item.$gitCommitAuthor; | ||||
|                                   item.$gitCommitDate = labels["io.openshift.build.commit.date"] || item.$gitCommitDate; | ||||
|                                   item.$gitCommitMessage = labels["io.openshift.build.commit.message"] || item.$gitCommitMessage; | ||||
|                                   item.$gitBranch = labels["io.openshift.build.commit.ref"] || item.$gitBranch; | ||||
| 
 | ||||
|                                   if (!item.$gitUrl && item.$gitCommit) { | ||||
|                                     item.$gitUrl = Developer.projectWorkspaceLink(ns, projectName, "wiki/commitDetail///" + item.$gitCommit); | ||||
|                                   } | ||||
|                                 } | ||||
|                               } | ||||
|                             } | ||||
|                           } | ||||
|                         } | ||||
|                       }); | ||||
|                     } | ||||
|                   } | ||||
|                 }); | ||||
|               }); | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
|           if (selector) { | ||||
|             var selectorText = Kubernetes.labelsToString(selector, ","); | ||||
|             var podLinkUrl = UrlHelpers.join(projectLink(projectName), "namespace", ns, "pods"); | ||||
|             item.pods = []; | ||||
|             item.$podCounters = Kubernetes.createPodCounters(selector, status.pods, item.pods, selectorText, podLinkUrl); | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       // lets check for a project name if we have lots of RCs with no pods, lets remove them!
 | ||||
|       angular.forEach(projectInfos, (project, projectName) => { | ||||
|         var rcsNoPods = []; | ||||
|         var rcsWithPods = []; | ||||
|         angular.forEach(project.versions, (versionInfo) => { | ||||
|           var rcs = versionInfo.replicationControllers; | ||||
|           angular.forEach(rcs, (item, name) => { | ||||
|             var count = Kubernetes.podCounterTotal(item.$podCounters); | ||||
|             if (count) { | ||||
|               rcsWithPods.push(name); | ||||
|             } else { | ||||
|               rcsNoPods.push(() => { | ||||
|                 delete rcs[name]; | ||||
|               }); | ||||
|             } | ||||
|           }); | ||||
|         }); | ||||
|         if (rcsWithPods.length) { | ||||
|           // lets remove all the empty RCs
 | ||||
|           angular.forEach(rcsNoPods, (fn) => { | ||||
|             fn(); | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       if (hasObjectChanged(projectInfos, cache)) { | ||||
|         log.debug("project versions has changed!"); | ||||
|         answer[ns] = projectInfos; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     Kubernetes.watch($scope, $element, "replicationcontrollers", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.rcs = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|     Kubernetes.watch($scope, $element, "services", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.services = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|     Kubernetes.watch($scope, $element, "routes", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.routes = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|     Kubernetes.watch($scope, $element, "pods", ns, (data) => { | ||||
|       if (data) { | ||||
|         status.pods = data; | ||||
|         updateModel(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -1,22 +1,22 @@ | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
|   _module.controller('Developer.EnvironmentPanelController', ($scope, $element, $location, $routeParams, KubernetesModel:Kubernetes.KubernetesModelService, $http, $timeout, KubernetesState, KubernetesApiURL) => { | ||||
| 
 | ||||
|     $scope.envVersions = {}; | ||||
|     $scope.model = KubernetesModel; | ||||
|     $scope.env = $scope.$eval('env'); | ||||
|     $scope.buildConfig = $scope.$eval('entity'); | ||||
| 
 | ||||
|     $scope.open = true; | ||||
| 
 | ||||
|     $scope.toggle = () => $scope.open = !$scope.open; | ||||
| 
 | ||||
|     var caches = {}; | ||||
| 
 | ||||
|     Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
| 
 | ||||
|     loadProjectVersions($scope, $element, $scope.buildConfig, $scope.env, $scope.env.namespace, $scope.envVersions, caches); | ||||
| 
 | ||||
|   }); | ||||
| } | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
|   _module.controller('Developer.EnvironmentPanelController', ($scope, $element, $location, $routeParams, KubernetesModel:Kubernetes.KubernetesModelService, $http, $timeout, KubernetesState, KubernetesApiURL) => { | ||||
| 
 | ||||
|     $scope.envVersions = {}; | ||||
|     $scope.model = KubernetesModel; | ||||
|     $scope.env = $scope.$eval('env'); | ||||
|     $scope.buildConfig = $scope.$eval('entity'); | ||||
| 
 | ||||
|     $scope.open = true; | ||||
| 
 | ||||
|     $scope.toggle = () => $scope.open = !$scope.open; | ||||
| 
 | ||||
|     var caches = {}; | ||||
| 
 | ||||
|     Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
| 
 | ||||
|     loadProjectVersions($scope, $element, $scope.buildConfig, $scope.env, $scope.env.namespace, $scope.envVersions, caches); | ||||
| 
 | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -1,17 +1,17 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var HomeController = controller("HomeController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|         $scope.namespace = Kubernetes.currentKubernetesNamespace(); | ||||
| 
 | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var HomeController = controller("HomeController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|         $scope.namespace = Kubernetes.currentKubernetesNamespace(); | ||||
| 
 | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,94 +1,94 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var JenkinsJobController = controller("JenkinsJobController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.jobId = $routeParams["job"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|         $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.tableConfig = { | ||||
|           data: 'job.builds', | ||||
|           showSelectionCheckbox: true, | ||||
|           enableRowClickSelection: false, | ||||
|           multiSelect: true, | ||||
|           selectedItems: [], | ||||
|           filterOptions: { | ||||
|             filterText: $location.search()["q"] || '' | ||||
|           }, | ||||
|           columnDefs: [ | ||||
|             { | ||||
|               field: '$sortOrder', | ||||
|               displayName: 'Name', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildIdTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$buildLink', | ||||
|               displayName: 'Views', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildButtonsTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$duration', | ||||
|               displayName: 'Duration', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildDurationTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$timestamp', | ||||
|               displayName: 'Time Started', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildTimestampTemplate.html") | ||||
|             } | ||||
|           ] | ||||
|         }; | ||||
|         updateData(); | ||||
| 
 | ||||
| 
 | ||||
|         function updateData() { | ||||
|           if ($scope.jobId) { | ||||
|             var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", $scope.jobId, "api/json?depth=1")); | ||||
|             if (url && (!$scope.job || Kubernetes.keepPollingModel)) { | ||||
|               $http.get(url). | ||||
|                 success(function (data, status, headers, config) { | ||||
|                   if (data) { | ||||
|                     enrichJenkinsJob(data, $scope.id, $scope.jobId); | ||||
|                     if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                       log.info("entity has changed!"); | ||||
|                       $scope.job = data; | ||||
|                     } | ||||
|                   } | ||||
|                   $scope.model.fetched = true; | ||||
|                   Core.$apply($scope); | ||||
|                 }). | ||||
|                 error(function (data, status, headers, config) { | ||||
|                   log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|                 }); | ||||
|             } | ||||
|           } else { | ||||
|             $scope.model.fetched = true; | ||||
|             Core.$apply($scope); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var JenkinsJobController = controller("JenkinsJobController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.jobId = $routeParams["job"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|         $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.tableConfig = { | ||||
|           data: 'job.builds', | ||||
|           showSelectionCheckbox: true, | ||||
|           enableRowClickSelection: false, | ||||
|           multiSelect: true, | ||||
|           selectedItems: [], | ||||
|           filterOptions: { | ||||
|             filterText: $location.search()["q"] || '' | ||||
|           }, | ||||
|           columnDefs: [ | ||||
|             { | ||||
|               field: '$sortOrder', | ||||
|               displayName: 'Name', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildIdTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$buildLink', | ||||
|               displayName: 'Views', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildButtonsTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$duration', | ||||
|               displayName: 'Duration', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildDurationTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$timestamp', | ||||
|               displayName: 'Time Started', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildTimestampTemplate.html") | ||||
|             } | ||||
|           ] | ||||
|         }; | ||||
|         updateData(); | ||||
| 
 | ||||
| 
 | ||||
|         function updateData() { | ||||
|           if ($scope.jobId) { | ||||
|             var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", $scope.jobId, "api/json?depth=1")); | ||||
|             if (url && (!$scope.job || Kubernetes.keepPollingModel)) { | ||||
|               $http.get(url). | ||||
|                 success(function (data, status, headers, config) { | ||||
|                   if (data) { | ||||
|                     enrichJenkinsJob(data, $scope.id, $scope.jobId); | ||||
|                     if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                       log.info("entity has changed!"); | ||||
|                       $scope.job = data; | ||||
|                     } | ||||
|                   } | ||||
|                   $scope.model.fetched = true; | ||||
|                   Core.$apply($scope); | ||||
|                 }). | ||||
|                 error(function (data, status, headers, config) { | ||||
|                   log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|                 }); | ||||
|             } | ||||
|           } else { | ||||
|             $scope.model.fetched = true; | ||||
|             Core.$apply($scope); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,101 +1,101 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var JenkinsJobsController = controller("JenkinsJobsController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.jenkins = null; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = createProjectBreadcrumbs(); | ||||
|         $scope.subTabConfig = Developer.createWorkspaceSubNavBars(); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.tableConfig = { | ||||
|           data: 'jenkins.jobs', | ||||
|           showSelectionCheckbox: true, | ||||
|           enableRowClickSelection: false, | ||||
|           multiSelect: true, | ||||
|           selectedItems: [], | ||||
|           filterOptions: { | ||||
|             filterText: $location.search()["q"] || '' | ||||
|           }, | ||||
|           columnDefs: [ | ||||
|             { | ||||
|               field: 'name', | ||||
|               displayName: 'Name', | ||||
|               cellTemplate: $templateCache.get("jenkinsJobNameTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$buildLink', | ||||
|               displayName: 'Views', | ||||
|               cellTemplate: $templateCache.get("jenkinsJobButtonsTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$lastSuccessfulBuildNumber', | ||||
|               displayName: 'Last Success', | ||||
|               cellTemplate: $templateCache.get("jenkinsLastSuccessTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$lastFailedlBuildNumber', | ||||
|               displayName: 'Last Failure', | ||||
|               cellTemplate: $templateCache.get("jenkinsLastFailureTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$duration', | ||||
|               displayName: 'Last Duration', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildDurationTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$timestamp', | ||||
|               displayName: 'Time Started', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildTimestampTemplate.html") | ||||
|             } | ||||
|           ] | ||||
|         }; | ||||
|         updateData(); | ||||
| 
 | ||||
| 
 | ||||
|         function updateData() { | ||||
|           // TODO only need depth 2 to be able to fetch the lastBuild
 | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, "api/json?depth=2"); | ||||
|           log.info(""); | ||||
|           if (url && (!$scope.jenkins || Kubernetes.keepPollingModel)) { | ||||
|             $http.get(url, jenkinsHttpConfig). | ||||
|               success(function (data, status, headers, config) { | ||||
|                 if (data) { | ||||
|                   enrichJenkinsJobs(data, $scope.id, $scope.id); | ||||
|                   if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                     log.info("entity has changed!"); | ||||
|                     $scope.jenkins = data; | ||||
|                   } | ||||
|                 } | ||||
|                 $scope.model.fetched = true; | ||||
|                 Core.$apply($scope); | ||||
|               }). | ||||
|               error(function (data, status, headers, config) { | ||||
|                 log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|               }); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var JenkinsJobsController = controller("JenkinsJobsController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.jenkins = null; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = createProjectBreadcrumbs(); | ||||
|         $scope.subTabConfig = Developer.createWorkspaceSubNavBars(); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.tableConfig = { | ||||
|           data: 'jenkins.jobs', | ||||
|           showSelectionCheckbox: true, | ||||
|           enableRowClickSelection: false, | ||||
|           multiSelect: true, | ||||
|           selectedItems: [], | ||||
|           filterOptions: { | ||||
|             filterText: $location.search()["q"] || '' | ||||
|           }, | ||||
|           columnDefs: [ | ||||
|             { | ||||
|               field: 'name', | ||||
|               displayName: 'Name', | ||||
|               cellTemplate: $templateCache.get("jenkinsJobNameTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$buildLink', | ||||
|               displayName: 'Views', | ||||
|               cellTemplate: $templateCache.get("jenkinsJobButtonsTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$lastSuccessfulBuildNumber', | ||||
|               displayName: 'Last Success', | ||||
|               cellTemplate: $templateCache.get("jenkinsLastSuccessTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$lastFailedlBuildNumber', | ||||
|               displayName: 'Last Failure', | ||||
|               cellTemplate: $templateCache.get("jenkinsLastFailureTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$duration', | ||||
|               displayName: 'Last Duration', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildDurationTemplate.html") | ||||
|             }, | ||||
|             { | ||||
|               field: '$timestamp', | ||||
|               displayName: 'Time Started', | ||||
|               cellTemplate: $templateCache.get("jenkinsBuildTimestampTemplate.html") | ||||
|             } | ||||
|           ] | ||||
|         }; | ||||
|         updateData(); | ||||
| 
 | ||||
| 
 | ||||
|         function updateData() { | ||||
|           // TODO only need depth 2 to be able to fetch the lastBuild
 | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, "api/json?depth=2"); | ||||
|           log.info(""); | ||||
|           if (url && (!$scope.jenkins || Kubernetes.keepPollingModel)) { | ||||
|             $http.get(url, jenkinsHttpConfig). | ||||
|               success(function (data, status, headers, config) { | ||||
|                 if (data) { | ||||
|                   enrichJenkinsJobs(data, $scope.id, $scope.id); | ||||
|                   if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                     log.info("entity has changed!"); | ||||
|                     $scope.jenkins = data; | ||||
|                   } | ||||
|                 } | ||||
|                 $scope.model.fetched = true; | ||||
|                 Core.$apply($scope); | ||||
|               }). | ||||
|               error(function (data, status, headers, config) { | ||||
|                 log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|               }); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,350 +1,350 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesInterfaces.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesModel.ts"/>
 | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export function clickApprove(element, url) { | ||||
|     var $scope: any = angular.element(element).scope(); | ||||
|     if ($scope) { | ||||
|       $scope.approve(url, element.text); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   export var JenkinsLogController = _module.controller("Developer.JenkinsLogController", ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|         $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, $modal, KubernetesApiURL, ServiceRegistry, $element) => { | ||||
| 
 | ||||
|     $scope.kubernetes = KubernetesState; | ||||
|     $scope.model = KubernetesModel; | ||||
| 
 | ||||
|     $scope.selectedBuild = $scope.$eval('build') || $scope.$eval('selectedBuild'); | ||||
| 
 | ||||
|     $scope.id = $scope.$eval('build.id') || $routeParams["id"]; | ||||
|     $scope.schema = KubernetesSchema; | ||||
|     $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|     $element.on('$destroy', () => { | ||||
|       $scope.$destroy(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.log = { | ||||
|       html: "", | ||||
|       start: 0, | ||||
|       firstIdx: null | ||||
|     }; | ||||
| 
 | ||||
|     $scope.$on('kubernetesModelUpdated', function () { | ||||
|       updateJenkinsLink(); | ||||
|       Core.$apply($scope); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.$on('jenkinsSelectedBuild', (event, build) => { | ||||
|       log.info("==== jenkins build selected! " + build.id + " " + build.$jobId); | ||||
|       $scope.selectedBuild = build; | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     $scope.$watch('selectedBuild', (selectedBuild) => { | ||||
|       log.info("Selected build updated: ", selectedBuild); | ||||
|       $scope.fetch(); | ||||
|     }); | ||||
| 
 | ||||
|     Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|     $scope.breadcrumbConfig = createJenkinsBreadcrumbs($scope.id, getJobId(), getBuildId()); | ||||
|     $scope.subTabConfig = createJenkinsSubNavBars($scope.id, getJobId(), getBuildId(), { | ||||
|       label: "Log", | ||||
|       title: "Views the logs of this build" | ||||
|     }); | ||||
| 
 | ||||
|     function getJobId() { | ||||
|       // lets allow the parent scope to be used too for when this is used as a panel
 | ||||
|       return $routeParams["job"] || ($scope.selectedBuild || {}).$jobId; | ||||
|     } | ||||
|     $scope.getJobId = getJobId; | ||||
| 
 | ||||
|     function getBuildId() { | ||||
|       // lets allow the parent scope to be used too for when this is used as a panel
 | ||||
|       return $routeParams["build"] || ($scope.selectedBuild || {}).id; | ||||
|     } | ||||
|     $scope.getBuildId = getBuildId; | ||||
| 
 | ||||
|     function updateJenkinsLink() { | ||||
|       var jenkinsUrl = jenkinsLink(); | ||||
|       if (jenkinsUrl) { | ||||
|         $scope.$viewJenkinsBuildLink = UrlHelpers.join(jenkinsUrl, "job", getJobId(), getBuildId()); | ||||
|         $scope.$viewJenkinsLogLink = UrlHelpers.join($scope.$viewJenkinsBuildLink, "console"); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     var querySize = 50000; | ||||
| 
 | ||||
|     $scope.approve = (url, operation) => { | ||||
|       var modal = $modal.open({ | ||||
|       templateUrl: UrlHelpers.join(templatePath, 'jenkinsApproveModal.html'), | ||||
|       controller: ['$scope', '$modalInstance', ($scope, $modalInstance) => { | ||||
|         $scope.operation = operation; | ||||
|         $scope.header = operation + "?"; | ||||
|         $scope.ok = () => { | ||||
|           modal.close(); | ||||
|           postToJenkins(url, operation); | ||||
|         }; | ||||
|         $scope.cancel = () => { | ||||
|           modal.dismiss(); | ||||
|         }; | ||||
|       }] | ||||
|       }); | ||||
|     }; | ||||
| 
 | ||||
|     function postToJenkins(uri, operation) { | ||||
|       var url =  Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, uri); | ||||
|       if (url) { | ||||
|         var body = null; | ||||
|         var config = { | ||||
|         headers: { | ||||
|         } | ||||
|         }; | ||||
|         log.info("posting to jenkinsUrl: " + url); | ||||
|         $http.post(url, body, config). | ||||
|           success(function (data, status, headers, config) { | ||||
|             log.info("Managed to " + operation + " at " + url); | ||||
|           }). | ||||
|         error(function (data, status, headers, config) { | ||||
|           log.warn("Failed " + operation + " job at " + url + " " + data + " " + status); | ||||
|         }); | ||||
|       } else { | ||||
|         log.warn("Cannot post to jenkins URI: " + uri + " as no jenkins found!"); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     $scope.$keepPolling = () => Kubernetes.keepPollingModel; | ||||
| 
 | ||||
|     $scope.fetch = PollHelpers.setupPolling($scope, (next:() => void) => { | ||||
|       if ($scope.$eval('hideLogs && !build.building')) { | ||||
|         log.debug("Log hidden, not fetching logs"); | ||||
|         return; | ||||
|       } else { | ||||
|         log.debug("Fetching logs for build: ", $scope.$eval('build')); | ||||
|       } | ||||
|       var buildId = getBuildId(); | ||||
|       var jobId = getJobId(); | ||||
|       //log.info("=== jenkins log querying job " + jobId + " build " + buildId + " selected build " +  $scope.selectedBuild);
 | ||||
|       if (jobId && buildId) { | ||||
|         if ($scope.buildId !== buildId || $scope.jobId !== jobId) { | ||||
|           // lets clear the query
 | ||||
|           $scope.log = { | ||||
|             html: "", | ||||
|             start: 0, | ||||
|             firstIdx: null | ||||
|           }; | ||||
|         } | ||||
|         $scope.buildId = buildId; | ||||
|         $scope.jobId = jobId; | ||||
| 
 | ||||
|         var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", jobId, buildId, "fabric8/logHtml?tail=1&start=" + $scope.log.start + "&size=" + querySize)); | ||||
|         if ($scope.log.firstIdx !== null) { | ||||
|           url += "&first=" + $scope.log.firstIdx; | ||||
|         } | ||||
|         if (url && (!$scope.log.fetched || Kubernetes.keepPollingModel)) { | ||||
|           $http.get(url). | ||||
|             success(function (data, status, headers, config) { | ||||
|               if (data) { | ||||
|                 var replaceClusterIPsInHtml = replaceClusterIpFunction(); | ||||
| 
 | ||||
|                 if (!$scope.log.logs) { | ||||
|                   $scope.log.logs = []; | ||||
|                 } | ||||
|                 var lines = data.lines; | ||||
|                 var returnedLength = data.returnedLength; | ||||
|                 var logLength = data.logLength; | ||||
|                 var returnedStart = data.start; | ||||
|                 var earlierLog = false; | ||||
|                 if (angular.isDefined(returnedStart)) { | ||||
|                   earlierLog = returnedStart < $scope.log.start; | ||||
|                 } | ||||
|                 var lineSplit = data.lineSplit; | ||||
|                 // log.info("start was: " + $scope.log.start + " first: " + $scope.log.firstIdx + " => returnedLength: " + returnedLength + " logLength: " + logLength +  " returnedStart: " + returnedStart + " earlierLog: " + earlierLog + " lineSplit: " + lineSplit);
 | ||||
|                 if (lines) { | ||||
|                   var currentLogs = $scope.log.logs; | ||||
| 
 | ||||
|                   // lets re-join split lines
 | ||||
|                   if (lineSplit && currentLogs.length) { | ||||
|                     var lastIndex; | ||||
|                     var restOfLine; | ||||
|                     if (earlierLog) { | ||||
|                       lastIndex = 0; | ||||
|                       restOfLine = lines.pop(); | ||||
|                       if (restOfLine) { | ||||
|                         currentLogs[lastIndex] = replaceClusterIPsInHtml(restOfLine + currentLogs[lastIndex]); | ||||
|                       } | ||||
|                     } else { | ||||
|                       lastIndex = currentLogs.length - 1; | ||||
|                       restOfLine = lines.shift(); | ||||
|                       if (restOfLine) { | ||||
|                         currentLogs[lastIndex] = replaceClusterIPsInHtml(currentLogs[lastIndex] + restOfLine); | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                   for (var i = 0; i < lines.length; i++) { | ||||
|                     lines[i] = replaceClusterIPsInHtml(lines[i]); | ||||
|                   } | ||||
|                   if (earlierLog) { | ||||
|                     $scope.log.logs = lines.concat(currentLogs); | ||||
|                   } else { | ||||
|                     $scope.log.logs = currentLogs.concat(lines); | ||||
|                   } | ||||
|                 } | ||||
|                 var moveForward = true; | ||||
|                 if (angular.isDefined(returnedStart)) { | ||||
|                   if (returnedStart > $scope.log.start && $scope.log.start === 0) { | ||||
|                     // we've jumped to the end of the file to read the tail of it
 | ||||
|                     $scope.log.start = returnedStart; | ||||
|                     $scope.log.firstIdx = returnedStart; | ||||
|                   } else if ($scope.log.firstIdx === null) { | ||||
|                     // lets remember where the first request started
 | ||||
|                     $scope.log.firstIdx = returnedStart; | ||||
|                   } else if (returnedStart < $scope.log.firstIdx) { | ||||
|                     // we've got an earlier bit of the log
 | ||||
|                     // after starting at the tail
 | ||||
|                     // so lets move firstIdx backwards and leave start as it is (at the end of the file)
 | ||||
|                     $scope.log.firstIdx = returnedStart; | ||||
|                     moveForward = false; | ||||
|                   } | ||||
|                 } | ||||
|                 if (moveForward && returnedLength && !earlierLog) { | ||||
|                   $scope.log.start += returnedLength; | ||||
|                   if (logLength && $scope.log.start > logLength) { | ||||
|                     $scope.log.start = logLength; | ||||
|                   } | ||||
|                 } | ||||
|                 updateJenkinsLink(); | ||||
|               } | ||||
|               $scope.log.fetched = true; | ||||
|               // Core.$apply($scope);
 | ||||
|               next(); | ||||
|             }). | ||||
|           error(function (data, status, headers, config) { | ||||
|             log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|             next(); | ||||
|           }); | ||||
|         } | ||||
|       } else { | ||||
|         $scope.log.fetched = true; | ||||
|         Core.$apply($scope); | ||||
|         next(); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     if (angular.isFunction($scope.fetch)) { | ||||
|       $scope.fetch(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     function replaceClusterIpFunction() { | ||||
|       function createReplaceFunction(from, to) { | ||||
|         return (text) => replaceText(text, from, to); | ||||
|       } | ||||
| 
 | ||||
|       var replacements = []; | ||||
|       angular.forEach($scope.model.services, (service) => { | ||||
|         var $portalIP = service.$portalIP; | ||||
|         var $serviceUrl = service.$serviceUrl; | ||||
|         var $portsText = service.$portsText; | ||||
|         if ($portalIP && $serviceUrl) { | ||||
|           var idx = $serviceUrl.indexOf("://"); | ||||
|           if (idx > 0) { | ||||
|             var replaceWith = $serviceUrl.substring(idx, $serviceUrl.length); | ||||
|             if (!replaceWith.endsWith("/")) { | ||||
|               replaceWith += "/"; | ||||
|             } | ||||
|             if (replaceWith.length > 4) { | ||||
|               replacements.push(createReplaceFunction( | ||||
|                     "://" + $portalIP + "/", | ||||
|                     replaceWith | ||||
|                     )); | ||||
|               if ($portsText) { | ||||
|                 var suffix = ":" + $portsText; | ||||
|                 var serviceWithPort = replaceWith.substring(0, replaceWith.length - 1); | ||||
|                 if (!serviceWithPort.endsWith(suffix)) { | ||||
|                   serviceWithPort += suffix; | ||||
|                 } | ||||
|                 serviceWithPort += "/"; | ||||
|                 replacements.push(createReplaceFunction( | ||||
|                       "://" + $portalIP + ":" + $portsText + "/", | ||||
|                       serviceWithPort | ||||
|                       )); | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       function addReplaceFn(from, to) { | ||||
|         replacements.push((text) => { | ||||
|           return replaceText(text, from, to); | ||||
|         }); | ||||
| 
 | ||||
|       } | ||||
|       addReplaceFn("[INFO]", "<span class='log-success'>[INFO]</span>"); | ||||
|       addReplaceFn("[WARN]", "<span class='log-warn'>[WARN]</span>"); | ||||
|       addReplaceFn("[WARNING]", "<span class='log-warn'>[WARNING]</span>"); | ||||
|       addReplaceFn("[ERROR]", "<span class='log-error'>[ERROR]</span>"); | ||||
|       addReplaceFn("FAILURE", "<span class='log-error'>FAILURE</span>"); | ||||
|       addReplaceFn("SUCCESS", "<span class='log-success'>SUCCESS</span>"); | ||||
| 
 | ||||
|       // lets try convert the Proceed / Abort links
 | ||||
|       replacements.push((text) => { | ||||
|         var prefix = "<a href='#' onclick=\"new Ajax.Request('"; | ||||
|         var idx = 0; | ||||
|         while (idx >= 0) { | ||||
|           idx = text.indexOf(prefix, idx); | ||||
|           if (idx >= 0) { | ||||
|             var start = idx + prefix.length; | ||||
|             var endQuote = text.indexOf("'", start + 1); | ||||
|             if (endQuote <= 0) { | ||||
|               break; | ||||
|             } | ||||
|             var endDoubleQuote = text.indexOf('"', endQuote + 1); | ||||
|             if (endDoubleQuote <= 0) { | ||||
|               break; | ||||
|             } | ||||
|             var url = text.substring(start, endQuote); | ||||
|             // TODO using $compile is a tad complex, for now lets cheat with a little onclick ;)
 | ||||
|             //text = text.substring(0, idx) + "<a class='btn btn-default btn-lg' ng-click=\"approve('" + url + "')\"" + text.substring(endDoubleQuote + 1);
 | ||||
|             text = text.substring(0, idx) + "<a class='btn btn-default btn-lg' onclick=\"Developer.clickApprove(this, '" + url + "')\"" + text.substring(endDoubleQuote + 1); | ||||
|           } | ||||
|         } | ||||
|         return text; | ||||
|       }); | ||||
|       return function(text) { | ||||
|         var answer = text; | ||||
|         angular.forEach(replacements, (fn) => { | ||||
|           answer = fn(answer); | ||||
|         }); | ||||
|         return answer; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     function replaceText(text, from, to) { | ||||
|       if (from && to && text) { | ||||
|         //log.info("Replacing '" + from + "' => '" + to + "'");
 | ||||
|         var idx = 0; | ||||
|         while (true) { | ||||
|           idx = text.indexOf(from, idx); | ||||
|           if (idx >= 0) { | ||||
|             text = text.substring(0, idx) + to + text.substring(idx + from.length); | ||||
|             idx += to.length; | ||||
|           } else { | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       return text; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesInterfaces.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesModel.ts"/>
 | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export function clickApprove(element, url) { | ||||
|     var $scope: any = angular.element(element).scope(); | ||||
|     if ($scope) { | ||||
|       $scope.approve(url, element.text); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   export var JenkinsLogController = _module.controller("Developer.JenkinsLogController", ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|         $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, $modal, KubernetesApiURL, ServiceRegistry, $element) => { | ||||
| 
 | ||||
|     $scope.kubernetes = KubernetesState; | ||||
|     $scope.model = KubernetesModel; | ||||
| 
 | ||||
|     $scope.selectedBuild = $scope.$eval('build') || $scope.$eval('selectedBuild'); | ||||
| 
 | ||||
|     $scope.id = $scope.$eval('build.id') || $routeParams["id"]; | ||||
|     $scope.schema = KubernetesSchema; | ||||
|     $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|     $element.on('$destroy', () => { | ||||
|       $scope.$destroy(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.log = { | ||||
|       html: "", | ||||
|       start: 0, | ||||
|       firstIdx: null | ||||
|     }; | ||||
| 
 | ||||
|     $scope.$on('kubernetesModelUpdated', function () { | ||||
|       updateJenkinsLink(); | ||||
|       Core.$apply($scope); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.$on('jenkinsSelectedBuild', (event, build) => { | ||||
|       log.info("==== jenkins build selected! " + build.id + " " + build.$jobId); | ||||
|       $scope.selectedBuild = build; | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     $scope.$watch('selectedBuild', (selectedBuild) => { | ||||
|       log.info("Selected build updated: ", selectedBuild); | ||||
|       $scope.fetch(); | ||||
|     }); | ||||
| 
 | ||||
|     Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|     $scope.breadcrumbConfig = createJenkinsBreadcrumbs($scope.id, getJobId(), getBuildId()); | ||||
|     $scope.subTabConfig = createJenkinsSubNavBars($scope.id, getJobId(), getBuildId(), { | ||||
|       label: "Log", | ||||
|       title: "Views the logs of this build" | ||||
|     }); | ||||
| 
 | ||||
|     function getJobId() { | ||||
|       // lets allow the parent scope to be used too for when this is used as a panel
 | ||||
|       return $routeParams["job"] || ($scope.selectedBuild || {}).$jobId; | ||||
|     } | ||||
|     $scope.getJobId = getJobId; | ||||
| 
 | ||||
|     function getBuildId() { | ||||
|       // lets allow the parent scope to be used too for when this is used as a panel
 | ||||
|       return $routeParams["build"] || ($scope.selectedBuild || {}).id; | ||||
|     } | ||||
|     $scope.getBuildId = getBuildId; | ||||
| 
 | ||||
|     function updateJenkinsLink() { | ||||
|       var jenkinsUrl = jenkinsLink(); | ||||
|       if (jenkinsUrl) { | ||||
|         $scope.$viewJenkinsBuildLink = UrlHelpers.join(jenkinsUrl, "job", getJobId(), getBuildId()); | ||||
|         $scope.$viewJenkinsLogLink = UrlHelpers.join($scope.$viewJenkinsBuildLink, "console"); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     var querySize = 50000; | ||||
| 
 | ||||
|     $scope.approve = (url, operation) => { | ||||
|       var modal = $modal.open({ | ||||
|       templateUrl: UrlHelpers.join(templatePath, 'jenkinsApproveModal.html'), | ||||
|       controller: ['$scope', '$modalInstance', ($scope, $modalInstance) => { | ||||
|         $scope.operation = operation; | ||||
|         $scope.header = operation + "?"; | ||||
|         $scope.ok = () => { | ||||
|           modal.close(); | ||||
|           postToJenkins(url, operation); | ||||
|         }; | ||||
|         $scope.cancel = () => { | ||||
|           modal.dismiss(); | ||||
|         }; | ||||
|       }] | ||||
|       }); | ||||
|     }; | ||||
| 
 | ||||
|     function postToJenkins(uri, operation) { | ||||
|       var url =  Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, uri); | ||||
|       if (url) { | ||||
|         var body = null; | ||||
|         var config = { | ||||
|         headers: { | ||||
|         } | ||||
|         }; | ||||
|         log.info("posting to jenkinsUrl: " + url); | ||||
|         $http.post(url, body, config). | ||||
|           success(function (data, status, headers, config) { | ||||
|             log.info("Managed to " + operation + " at " + url); | ||||
|           }). | ||||
|         error(function (data, status, headers, config) { | ||||
|           log.warn("Failed " + operation + " job at " + url + " " + data + " " + status); | ||||
|         }); | ||||
|       } else { | ||||
|         log.warn("Cannot post to jenkins URI: " + uri + " as no jenkins found!"); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     $scope.$keepPolling = () => Kubernetes.keepPollingModel; | ||||
| 
 | ||||
|     $scope.fetch = PollHelpers.setupPolling($scope, (next:() => void) => { | ||||
|       if ($scope.$eval('hideLogs && !build.building')) { | ||||
|         log.debug("Log hidden, not fetching logs"); | ||||
|         return; | ||||
|       } else { | ||||
|         log.debug("Fetching logs for build: ", $scope.$eval('build')); | ||||
|       } | ||||
|       var buildId = getBuildId(); | ||||
|       var jobId = getJobId(); | ||||
|       //log.info("=== jenkins log querying job " + jobId + " build " + buildId + " selected build " +  $scope.selectedBuild);
 | ||||
|       if (jobId && buildId) { | ||||
|         if ($scope.buildId !== buildId || $scope.jobId !== jobId) { | ||||
|           // lets clear the query
 | ||||
|           $scope.log = { | ||||
|             html: "", | ||||
|             start: 0, | ||||
|             firstIdx: null | ||||
|           }; | ||||
|         } | ||||
|         $scope.buildId = buildId; | ||||
|         $scope.jobId = jobId; | ||||
| 
 | ||||
|         var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", jobId, buildId, "fabric8/logHtml?tail=1&start=" + $scope.log.start + "&size=" + querySize)); | ||||
|         if ($scope.log.firstIdx !== null) { | ||||
|           url += "&first=" + $scope.log.firstIdx; | ||||
|         } | ||||
|         if (url && (!$scope.log.fetched || Kubernetes.keepPollingModel)) { | ||||
|           $http.get(url). | ||||
|             success(function (data, status, headers, config) { | ||||
|               if (data) { | ||||
|                 var replaceClusterIPsInHtml = replaceClusterIpFunction(); | ||||
| 
 | ||||
|                 if (!$scope.log.logs) { | ||||
|                   $scope.log.logs = []; | ||||
|                 } | ||||
|                 var lines = data.lines; | ||||
|                 var returnedLength = data.returnedLength; | ||||
|                 var logLength = data.logLength; | ||||
|                 var returnedStart = data.start; | ||||
|                 var earlierLog = false; | ||||
|                 if (angular.isDefined(returnedStart)) { | ||||
|                   earlierLog = returnedStart < $scope.log.start; | ||||
|                 } | ||||
|                 var lineSplit = data.lineSplit; | ||||
|                 // log.info("start was: " + $scope.log.start + " first: " + $scope.log.firstIdx + " => returnedLength: " + returnedLength + " logLength: " + logLength +  " returnedStart: " + returnedStart + " earlierLog: " + earlierLog + " lineSplit: " + lineSplit);
 | ||||
|                 if (lines) { | ||||
|                   var currentLogs = $scope.log.logs; | ||||
| 
 | ||||
|                   // lets re-join split lines
 | ||||
|                   if (lineSplit && currentLogs.length) { | ||||
|                     var lastIndex; | ||||
|                     var restOfLine; | ||||
|                     if (earlierLog) { | ||||
|                       lastIndex = 0; | ||||
|                       restOfLine = lines.pop(); | ||||
|                       if (restOfLine) { | ||||
|                         currentLogs[lastIndex] = replaceClusterIPsInHtml(restOfLine + currentLogs[lastIndex]); | ||||
|                       } | ||||
|                     } else { | ||||
|                       lastIndex = currentLogs.length - 1; | ||||
|                       restOfLine = lines.shift(); | ||||
|                       if (restOfLine) { | ||||
|                         currentLogs[lastIndex] = replaceClusterIPsInHtml(currentLogs[lastIndex] + restOfLine); | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                   for (var i = 0; i < lines.length; i++) { | ||||
|                     lines[i] = replaceClusterIPsInHtml(lines[i]); | ||||
|                   } | ||||
|                   if (earlierLog) { | ||||
|                     $scope.log.logs = lines.concat(currentLogs); | ||||
|                   } else { | ||||
|                     $scope.log.logs = currentLogs.concat(lines); | ||||
|                   } | ||||
|                 } | ||||
|                 var moveForward = true; | ||||
|                 if (angular.isDefined(returnedStart)) { | ||||
|                   if (returnedStart > $scope.log.start && $scope.log.start === 0) { | ||||
|                     // we've jumped to the end of the file to read the tail of it
 | ||||
|                     $scope.log.start = returnedStart; | ||||
|                     $scope.log.firstIdx = returnedStart; | ||||
|                   } else if ($scope.log.firstIdx === null) { | ||||
|                     // lets remember where the first request started
 | ||||
|                     $scope.log.firstIdx = returnedStart; | ||||
|                   } else if (returnedStart < $scope.log.firstIdx) { | ||||
|                     // we've got an earlier bit of the log
 | ||||
|                     // after starting at the tail
 | ||||
|                     // so lets move firstIdx backwards and leave start as it is (at the end of the file)
 | ||||
|                     $scope.log.firstIdx = returnedStart; | ||||
|                     moveForward = false; | ||||
|                   } | ||||
|                 } | ||||
|                 if (moveForward && returnedLength && !earlierLog) { | ||||
|                   $scope.log.start += returnedLength; | ||||
|                   if (logLength && $scope.log.start > logLength) { | ||||
|                     $scope.log.start = logLength; | ||||
|                   } | ||||
|                 } | ||||
|                 updateJenkinsLink(); | ||||
|               } | ||||
|               $scope.log.fetched = true; | ||||
|               // Core.$apply($scope);
 | ||||
|               next(); | ||||
|             }). | ||||
|           error(function (data, status, headers, config) { | ||||
|             log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|             next(); | ||||
|           }); | ||||
|         } | ||||
|       } else { | ||||
|         $scope.log.fetched = true; | ||||
|         Core.$apply($scope); | ||||
|         next(); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     if (angular.isFunction($scope.fetch)) { | ||||
|       $scope.fetch(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     function replaceClusterIpFunction() { | ||||
|       function createReplaceFunction(from, to) { | ||||
|         return (text) => replaceText(text, from, to); | ||||
|       } | ||||
| 
 | ||||
|       var replacements = []; | ||||
|       angular.forEach($scope.model.services, (service) => { | ||||
|         var $portalIP = service.$portalIP; | ||||
|         var $serviceUrl = service.$serviceUrl; | ||||
|         var $portsText = service.$portsText; | ||||
|         if ($portalIP && $serviceUrl) { | ||||
|           var idx = $serviceUrl.indexOf("://"); | ||||
|           if (idx > 0) { | ||||
|             var replaceWith = $serviceUrl.substring(idx, $serviceUrl.length); | ||||
|             if (!replaceWith.endsWith("/")) { | ||||
|               replaceWith += "/"; | ||||
|             } | ||||
|             if (replaceWith.length > 4) { | ||||
|               replacements.push(createReplaceFunction( | ||||
|                     "://" + $portalIP + "/", | ||||
|                     replaceWith | ||||
|                     )); | ||||
|               if ($portsText) { | ||||
|                 var suffix = ":" + $portsText; | ||||
|                 var serviceWithPort = replaceWith.substring(0, replaceWith.length - 1); | ||||
|                 if (!serviceWithPort.endsWith(suffix)) { | ||||
|                   serviceWithPort += suffix; | ||||
|                 } | ||||
|                 serviceWithPort += "/"; | ||||
|                 replacements.push(createReplaceFunction( | ||||
|                       "://" + $portalIP + ":" + $portsText + "/", | ||||
|                       serviceWithPort | ||||
|                       )); | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       function addReplaceFn(from, to) { | ||||
|         replacements.push((text) => { | ||||
|           return replaceText(text, from, to); | ||||
|         }); | ||||
| 
 | ||||
|       } | ||||
|       addReplaceFn("[INFO]", "<span class='log-success'>[INFO]</span>"); | ||||
|       addReplaceFn("[WARN]", "<span class='log-warn'>[WARN]</span>"); | ||||
|       addReplaceFn("[WARNING]", "<span class='log-warn'>[WARNING]</span>"); | ||||
|       addReplaceFn("[ERROR]", "<span class='log-error'>[ERROR]</span>"); | ||||
|       addReplaceFn("FAILURE", "<span class='log-error'>FAILURE</span>"); | ||||
|       addReplaceFn("SUCCESS", "<span class='log-success'>SUCCESS</span>"); | ||||
| 
 | ||||
|       // lets try convert the Proceed / Abort links
 | ||||
|       replacements.push((text) => { | ||||
|         var prefix = "<a href='#' onclick=\"new Ajax.Request('"; | ||||
|         var idx = 0; | ||||
|         while (idx >= 0) { | ||||
|           idx = text.indexOf(prefix, idx); | ||||
|           if (idx >= 0) { | ||||
|             var start = idx + prefix.length; | ||||
|             var endQuote = text.indexOf("'", start + 1); | ||||
|             if (endQuote <= 0) { | ||||
|               break; | ||||
|             } | ||||
|             var endDoubleQuote = text.indexOf('"', endQuote + 1); | ||||
|             if (endDoubleQuote <= 0) { | ||||
|               break; | ||||
|             } | ||||
|             var url = text.substring(start, endQuote); | ||||
|             // TODO using $compile is a tad complex, for now lets cheat with a little onclick ;)
 | ||||
|             //text = text.substring(0, idx) + "<a class='btn btn-default btn-lg' ng-click=\"approve('" + url + "')\"" + text.substring(endDoubleQuote + 1);
 | ||||
|             text = text.substring(0, idx) + "<a class='btn btn-default btn-lg' onclick=\"Developer.clickApprove(this, '" + url + "')\"" + text.substring(endDoubleQuote + 1); | ||||
|           } | ||||
|         } | ||||
|         return text; | ||||
|       }); | ||||
|       return function(text) { | ||||
|         var answer = text; | ||||
|         angular.forEach(replacements, (fn) => { | ||||
|           answer = fn(answer); | ||||
|         }); | ||||
|         return answer; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     function replaceText(text, from, to) { | ||||
|       if (from && to && text) { | ||||
|         //log.info("Replacing '" + from + "' => '" + to + "'");
 | ||||
|         var idx = 0; | ||||
|         while (true) { | ||||
|           idx = text.indexOf(from, idx); | ||||
|           if (idx >= 0) { | ||||
|             text = text.substring(0, idx) + to + text.substring(idx + from.length); | ||||
|             idx += to.length; | ||||
|           } else { | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       return text; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,181 +1,181 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var JenkinsMetricsController = controller("JenkinsMetricsController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.jobId = $routeParams["job"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.jenkins = null; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|         $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.options = { | ||||
|           chart: { | ||||
|             type: 'discreteBarChart', | ||||
|             autorefresh: false, | ||||
|             height: 450, | ||||
|             margin: { | ||||
|               top: 20, | ||||
|               right: 20, | ||||
|               bottom: 60, | ||||
|               left: 45 | ||||
|             }, | ||||
|             clipEdge: true, | ||||
|             staggerLabels: false, | ||||
|             transitionDuration: 500, | ||||
|             stacked: false, | ||||
|             interactive: true, | ||||
|             tooltip: { | ||||
|               enabled: true, | ||||
|               contentGenerator: (args) => { | ||||
|                 var data = args.data || {}; | ||||
|                 return data.tooltip; | ||||
|               }, | ||||
|             }, | ||||
|             color: (d, i) => { | ||||
|               return d.color; | ||||
|             }, | ||||
|             xAxis: { | ||||
|               axisLabel: 'Builds', | ||||
|               showMaxMin: false, | ||||
|               tickFormat: function (d) { | ||||
|                 return "#" + d; | ||||
|               } | ||||
|             }, | ||||
|             yAxis: { | ||||
|               axisLabel: 'Build Duration (seconds)', | ||||
|               tickFormat: function (d) { | ||||
|                 return d3.format(',.1f')(d); | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }; | ||||
| 
 | ||||
|         $scope.data = []; | ||||
| 
 | ||||
|         updateData(); | ||||
| 
 | ||||
|         function barColourForBuildResult(result) { | ||||
|           if (result) { | ||||
|             if (result === "FAILURE" || result === "FAILED") { | ||||
|               return "red"; | ||||
|             } else if (result === "ABORTED" || result === "INTERUPTED") { | ||||
|               return "tan"; | ||||
|             } else if (result === "SUCCESS") { | ||||
|               return "green"; | ||||
|             } else if (result === "NOT_STARTED") { | ||||
|               return "lightgrey" | ||||
|             } | ||||
|           } | ||||
|           return "darkgrey"; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         function updateChartData() { | ||||
|           var useSingleSet = true; | ||||
|           var buildsSucceeded = []; | ||||
|           var buildsFailed = []; | ||||
|           var successBuildKey = "Succeeded builds"; | ||||
|           var failedBuildKey = "Failed builds"; | ||||
| 
 | ||||
|           if (useSingleSet) { | ||||
|             successBuildKey = "Builds"; | ||||
|           } | ||||
| 
 | ||||
|           var count = 0; | ||||
|           var builds = _.sortBy($scope.metrics.builds || [], "number"); | ||||
|           angular.forEach(builds, (build:any) => { | ||||
|             var x = build.number; | ||||
|             var y = build.duration / 1000; | ||||
|             var date = Developer.asDate(build.timeInMillis); | ||||
|             var result = build.result || "NOT_STARTED"; | ||||
|             var color = barColourForBuildResult(result); | ||||
|             var iconClass = createBuildStatusIconClass(result); | ||||
|             var tooltip = '<h3><i class="' + iconClass + '"></i> ' + build.displayName + '</h3>' + | ||||
|               '<p>duration: <b>' + y + '</b> seconds</p>'; | ||||
|             if (date) { | ||||
|               tooltip += '<p>started: <b>' + date + '</b></p>'; | ||||
|             } | ||||
|             if (result) { | ||||
|               tooltip += '<p>result: <b>' + result + '</b></p>'; | ||||
|             } | ||||
| 
 | ||||
|             if (x) { | ||||
|               var data = buildsSucceeded; | ||||
|               var key = successBuildKey; | ||||
|               if (!successBuildKey && (!result || !result.startsWith("SUCC"))) { | ||||
|                 data = buildsFailed; | ||||
|                 key = failedBuildKey; | ||||
|               } | ||||
|               data.push({ | ||||
|                 tooltip: tooltip, | ||||
|                 color: color, | ||||
|                 x: x, y: y}); | ||||
|             } | ||||
|           }); | ||||
|           $scope.data = []; | ||||
|           if (buildsSucceeded.length) { | ||||
|             $scope.data.push({ | ||||
|               key: successBuildKey, | ||||
|               values: buildsSucceeded | ||||
|             }); | ||||
|           } | ||||
|           if (buildsFailed.length) { | ||||
|             $scope.data.push({ | ||||
|               key: failedBuildKey, | ||||
|               values: buildsFailed | ||||
|             }); | ||||
|           } | ||||
|           $scope.api.updateWithData($scope.data); | ||||
| 
 | ||||
|           $timeout(() => { | ||||
|             $scope.api.update(); | ||||
|           }, 50); | ||||
|         } | ||||
| 
 | ||||
|         function updateData() { | ||||
|           var metricsPath = $scope.jobId ? UrlHelpers.join("job", $scope.jobId, "fabric8/metrics") : "fabric8/metrics"; | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, metricsPath); | ||||
|           log.info(""); | ||||
|           if (url && (!$scope.jenkins || Kubernetes.keepPollingModel)) { | ||||
|             $http.get(url, jenkinsHttpConfig). | ||||
|               success(function (data, status, headers, config) { | ||||
|                 if (data) { | ||||
|                   if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                     log.info("entity has changed!"); | ||||
|                     $scope.metrics = data; | ||||
|                     updateChartData(); | ||||
|                   } | ||||
|                 } | ||||
|                 $scope.model.fetched = true; | ||||
|                 Core.$apply($scope); | ||||
|               }). | ||||
|               error(function (data, status, headers, config) { | ||||
|                 log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|               }); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var JenkinsMetricsController = controller("JenkinsMetricsController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.jobId = $routeParams["job"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.jenkins = null; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|         $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.options = { | ||||
|           chart: { | ||||
|             type: 'discreteBarChart', | ||||
|             autorefresh: false, | ||||
|             height: 450, | ||||
|             margin: { | ||||
|               top: 20, | ||||
|               right: 20, | ||||
|               bottom: 60, | ||||
|               left: 45 | ||||
|             }, | ||||
|             clipEdge: true, | ||||
|             staggerLabels: false, | ||||
|             transitionDuration: 500, | ||||
|             stacked: false, | ||||
|             interactive: true, | ||||
|             tooltip: { | ||||
|               enabled: true, | ||||
|               contentGenerator: (args) => { | ||||
|                 var data = args.data || {}; | ||||
|                 return data.tooltip; | ||||
|               }, | ||||
|             }, | ||||
|             color: (d, i) => { | ||||
|               return d.color; | ||||
|             }, | ||||
|             xAxis: { | ||||
|               axisLabel: 'Builds', | ||||
|               showMaxMin: false, | ||||
|               tickFormat: function (d) { | ||||
|                 return "#" + d; | ||||
|               } | ||||
|             }, | ||||
|             yAxis: { | ||||
|               axisLabel: 'Build Duration (seconds)', | ||||
|               tickFormat: function (d) { | ||||
|                 return d3.format(',.1f')(d); | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }; | ||||
| 
 | ||||
|         $scope.data = []; | ||||
| 
 | ||||
|         updateData(); | ||||
| 
 | ||||
|         function barColourForBuildResult(result) { | ||||
|           if (result) { | ||||
|             if (result === "FAILURE" || result === "FAILED") { | ||||
|               return "red"; | ||||
|             } else if (result === "ABORTED" || result === "INTERUPTED") { | ||||
|               return "tan"; | ||||
|             } else if (result === "SUCCESS") { | ||||
|               return "green"; | ||||
|             } else if (result === "NOT_STARTED") { | ||||
|               return "lightgrey" | ||||
|             } | ||||
|           } | ||||
|           return "darkgrey"; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         function updateChartData() { | ||||
|           var useSingleSet = true; | ||||
|           var buildsSucceeded = []; | ||||
|           var buildsFailed = []; | ||||
|           var successBuildKey = "Succeeded builds"; | ||||
|           var failedBuildKey = "Failed builds"; | ||||
| 
 | ||||
|           if (useSingleSet) { | ||||
|             successBuildKey = "Builds"; | ||||
|           } | ||||
| 
 | ||||
|           var count = 0; | ||||
|           var builds = _.sortBy($scope.metrics.builds || [], "number"); | ||||
|           angular.forEach(builds, (build:any) => { | ||||
|             var x = build.number; | ||||
|             var y = build.duration / 1000; | ||||
|             var date = Developer.asDate(build.timeInMillis); | ||||
|             var result = build.result || "NOT_STARTED"; | ||||
|             var color = barColourForBuildResult(result); | ||||
|             var iconClass = createBuildStatusIconClass(result); | ||||
|             var tooltip = '<h3><i class="' + iconClass + '"></i> ' + build.displayName + '</h3>' + | ||||
|               '<p>duration: <b>' + y + '</b> seconds</p>'; | ||||
|             if (date) { | ||||
|               tooltip += '<p>started: <b>' + date + '</b></p>'; | ||||
|             } | ||||
|             if (result) { | ||||
|               tooltip += '<p>result: <b>' + result + '</b></p>'; | ||||
|             } | ||||
| 
 | ||||
|             if (x) { | ||||
|               var data = buildsSucceeded; | ||||
|               var key = successBuildKey; | ||||
|               if (!successBuildKey && (!result || !result.startsWith("SUCC"))) { | ||||
|                 data = buildsFailed; | ||||
|                 key = failedBuildKey; | ||||
|               } | ||||
|               data.push({ | ||||
|                 tooltip: tooltip, | ||||
|                 color: color, | ||||
|                 x: x, y: y}); | ||||
|             } | ||||
|           }); | ||||
|           $scope.data = []; | ||||
|           if (buildsSucceeded.length) { | ||||
|             $scope.data.push({ | ||||
|               key: successBuildKey, | ||||
|               values: buildsSucceeded | ||||
|             }); | ||||
|           } | ||||
|           if (buildsFailed.length) { | ||||
|             $scope.data.push({ | ||||
|               key: failedBuildKey, | ||||
|               values: buildsFailed | ||||
|             }); | ||||
|           } | ||||
|           $scope.api.updateWithData($scope.data); | ||||
| 
 | ||||
|           $timeout(() => { | ||||
|             $scope.api.update(); | ||||
|           }, 50); | ||||
|         } | ||||
| 
 | ||||
|         function updateData() { | ||||
|           var metricsPath = $scope.jobId ? UrlHelpers.join("job", $scope.jobId, "fabric8/metrics") : "fabric8/metrics"; | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, metricsPath); | ||||
|           log.info(""); | ||||
|           if (url && (!$scope.jenkins || Kubernetes.keepPollingModel)) { | ||||
|             $http.get(url, jenkinsHttpConfig). | ||||
|               success(function (data, status, headers, config) { | ||||
|                 if (data) { | ||||
|                   if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                     log.info("entity has changed!"); | ||||
|                     $scope.metrics = data; | ||||
|                     updateChartData(); | ||||
|                   } | ||||
|                 } | ||||
|                 $scope.model.fetched = true; | ||||
|                 Core.$apply($scope); | ||||
|               }). | ||||
|               error(function (data, status, headers, config) { | ||||
|                 log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|               }); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,25 +1,25 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var NavBarController = controller("NavBarController", | ||||
|     ["$scope", "$location", "$routeParams", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, $location:ng.ILocationService, $routeParams, $timeout) => { | ||||
| 
 | ||||
|         $scope.isValid = (item) => { | ||||
|           if (item) { | ||||
|             var value = item.isValid; | ||||
|             if (angular.isFunction(value)) { | ||||
|               return value(item) | ||||
|             } else { | ||||
|               return angular.isUndefined(value) || value; | ||||
|             } | ||||
|           } | ||||
|           return false; | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var NavBarController = controller("NavBarController", | ||||
|     ["$scope", "$location", "$routeParams", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, $location:ng.ILocationService, $routeParams, $timeout) => { | ||||
| 
 | ||||
|         $scope.isValid = (item) => { | ||||
|           if (item) { | ||||
|             var value = item.isValid; | ||||
|             if (angular.isFunction(value)) { | ||||
|               return value(item) | ||||
|             } else { | ||||
|               return angular.isUndefined(value) || value; | ||||
|             } | ||||
|           } | ||||
|           return false; | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,67 +1,67 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var PipelineController = controller("PipelineController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.kubeModel = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.jobId = $routeParams["job"]; | ||||
|         $scope.buildId = $routeParams["build"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         $scope.model = { | ||||
|           stages: null | ||||
|         }; | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|         $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         updateData(); | ||||
| 
 | ||||
|         function updateData() { | ||||
|           if ($scope.jobId) { | ||||
|             var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", $scope.jobId, $scope.buildId, "fabric8/stages/")); | ||||
|             if (url && (!$scope.model.stages || Kubernetes.keepPollingModel)) { | ||||
|               $http.get(url). | ||||
|                 success(function (data, status, headers, config) { | ||||
|                   if (data) { | ||||
|                     enrichJenkinsStages(data, $scope.id, $scope.jobId); | ||||
|                     if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                       log.info("entity has changed!"); | ||||
|                       $scope.build = data; | ||||
|                       $scope.model.stages = data.stages; | ||||
|                     } | ||||
|                   } | ||||
|                   $scope.model.fetched = true; | ||||
|                   Core.$apply($scope); | ||||
|                 }). | ||||
|                 error(function (data, status, headers, config) { | ||||
|                   log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|                   $scope.model.fetched = true; | ||||
|                 }); | ||||
|             } | ||||
|           } else { | ||||
|             $scope.model.fetched = true; | ||||
|             Core.$apply($scope); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var PipelineController = controller("PipelineController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.kubeModel = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
|         $scope.jobId = $routeParams["job"]; | ||||
|         $scope.buildId = $routeParams["build"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|         $scope.model = { | ||||
|           stages: null | ||||
|         }; | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|         $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|         $scope.$on('kubernetesModelUpdated', function () { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         $scope.$on('$routeUpdate', ($event) => { | ||||
|           updateData(); | ||||
|         }); | ||||
| 
 | ||||
|         updateData(); | ||||
| 
 | ||||
|         function updateData() { | ||||
|           if ($scope.jobId) { | ||||
|             var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", $scope.jobId, $scope.buildId, "fabric8/stages/")); | ||||
|             if (url && (!$scope.model.stages || Kubernetes.keepPollingModel)) { | ||||
|               $http.get(url). | ||||
|                 success(function (data, status, headers, config) { | ||||
|                   if (data) { | ||||
|                     enrichJenkinsStages(data, $scope.id, $scope.jobId); | ||||
|                     if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                       log.info("entity has changed!"); | ||||
|                       $scope.build = data; | ||||
|                       $scope.model.stages = data.stages; | ||||
|                     } | ||||
|                   } | ||||
|                   $scope.model.fetched = true; | ||||
|                   Core.$apply($scope); | ||||
|                 }). | ||||
|                 error(function (data, status, headers, config) { | ||||
|                   log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|                   $scope.model.fetched = true; | ||||
|                 }); | ||||
|             } | ||||
|           } else { | ||||
|             $scope.model.fetched = true; | ||||
|             Core.$apply($scope); | ||||
|           } | ||||
|         } | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
|   _module.directive("pipelineView", () => { | ||||
|     return { | ||||
|       templateUrl: templatePath + 'pipelineView.html' | ||||
|     }; | ||||
|   }); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
|   _module.directive("pipelineView", () => { | ||||
|     return { | ||||
|       templateUrl: templatePath + 'pipelineView.html' | ||||
|     }; | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -1,165 +1,165 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var PipelinesController = _module.controller("Developer.PipelinesController", ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|         $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry, $element) => { | ||||
| 
 | ||||
|     $scope.kubernetes = KubernetesState; | ||||
|     $scope.kubeModel = KubernetesModel; | ||||
|     $scope.id = $routeParams["id"]; | ||||
|     $scope.jobId = $scope.jobId || $routeParams["job"]; | ||||
|     $scope.schema = KubernetesSchema; | ||||
|     $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|     $element.on('$destroy', () => { | ||||
|       $scope.$destroy(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.model = { | ||||
|       job: null, | ||||
|       pendingOnly: $scope.pendingPipelinesOnly | ||||
|     }; | ||||
|     Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|     $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|     $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|     $scope.$on('kubernetesModelUpdated', function () { | ||||
|       updateData(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.$on('$routeUpdate', ($event) => { | ||||
|       updateData(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.$watch('model.pendingOnly', ($event) => { | ||||
|       updateData(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.selectBuild = (build) => { | ||||
|       var id = build.id; | ||||
|       if (id) { | ||||
|         if (id !== $scope.selectedBuildId) { | ||||
|           $scope.selectedBuildId = id; | ||||
|           $scope.$broadcast("jenkinsSelectedBuild", build); | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     var updateData = _.debounce(() => { | ||||
|       var entity = $scope.entity; | ||||
|       if ($scope.jobId) { | ||||
|         if ((!entity || entity.$jenkinsJob)) { | ||||
|           var queryPath = "fabric8/stages/"; | ||||
|           if ($scope.model.pendingOnly) { | ||||
|             queryPath = "fabric8/pendingStages/"; | ||||
|           } | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", $scope.jobId, queryPath)); | ||||
|           if (url && (!$scope.model.job || Kubernetes.keepPollingModel)) { | ||||
|             $http.get(url). | ||||
|             success(function (data, status, headers, config) { | ||||
|               if (data) { | ||||
|                 enrichJenkinsPipelineJob(data, $scope.id, $scope.jobId); | ||||
|                 if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                   log.info("entity has changed!"); | ||||
|                   $scope.model.job = data; | ||||
| 
 | ||||
|                   var builds = data.builds; | ||||
|                   if (builds && builds.length) { | ||||
|                     $scope.selectBuild(builds[0]); | ||||
|                   } | ||||
|                 } | ||||
|               } | ||||
|               $scope.model.fetched = true; | ||||
|               Core.$apply($scope); | ||||
|             }). | ||||
|             error(function (data, status, headers, config) { | ||||
|               log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|               $scope.model.fetched = true; | ||||
|             }); | ||||
|           } | ||||
|         } else { | ||||
|           if ($scope.model) { | ||||
|             Kubernetes.enrichBuilds($scope.kubeModel.builds); | ||||
| 
 | ||||
|             var builds = []; | ||||
|             angular.forEach($scope.kubeModel.builds, (build) => { | ||||
|               var labels = Kubernetes.getLabels(build); | ||||
|               var app = labels["app"]; | ||||
|               if (app === $scope.projectId) { | ||||
|                 builds.push(build); | ||||
|               } | ||||
|             }); | ||||
|             builds = _.sortBy(builds, "$creationDate").reverse(); | ||||
|             var allBuilds = builds; | ||||
|             if (allBuilds.length > 1) { | ||||
|               builds = _.filter(allBuilds, (b) => !b.$creationDate); | ||||
|               if (!builds.length) { | ||||
|                 builds = [allBuilds[0]]; | ||||
|               } | ||||
|             } | ||||
|             var pipelines = []; | ||||
|             angular.forEach(builds, (build) => { | ||||
|               var buildStatus = build.status || {}; | ||||
|               var result = buildStatus.phase || ""; | ||||
|               var resultUpperCase = result.toUpperCase(); | ||||
| 
 | ||||
|               var description = ""; | ||||
|               var $viewLink = build.$viewLink; | ||||
|               var $logLink = build.$logsLink; | ||||
|               var $timestamp = build.$creationDate; | ||||
|               var duration = buildStatus.duration; | ||||
|               if (duration) { | ||||
|                 // 17s = 17,000,000,000 on openshift
 | ||||
|                 duration = duration / 1000000; | ||||
|               } | ||||
|               var displayName = Kubernetes.getName(build); | ||||
|               var $iconClass = createBuildStatusIconClass(resultUpperCase); | ||||
|               var $backgroundClass = createBuildStatusBackgroundClass(resultUpperCase); | ||||
|               var stage = { | ||||
|                 stageName: "OpenShift Build", | ||||
|                 $viewLink: $viewLink, | ||||
|                 $logLink: $logLink, | ||||
|                 $startTime: $timestamp, | ||||
|                 duration: duration, | ||||
|                 status: result, | ||||
|                 $iconClass: $iconClass, | ||||
|                 $backgroundClass: $backgroundClass | ||||
|               }; | ||||
|               var pipeline = { | ||||
|                 description: description, | ||||
|                 displayName: displayName, | ||||
|                 $viewLink: $viewLink, | ||||
|                 $logLink: $logLink, | ||||
|                 $timestamp: $timestamp, | ||||
|                 duration: duration, | ||||
|                 stages: [stage] | ||||
|               }; | ||||
|               pipelines.push(pipeline); | ||||
|             }); | ||||
| 
 | ||||
|             // lets filter the OpenShift builds and make a pipeline from that
 | ||||
|             $scope.model.job = { | ||||
|               $jobId: $scope.jobId, | ||||
|               $project: $scope.projectId, | ||||
|               builds: pipelines | ||||
|             }; | ||||
|           } | ||||
|           $scope.model.fetched = true; | ||||
|           Core.$apply($scope); | ||||
|         } | ||||
|       } else { | ||||
|         $scope.model.fetched = true; | ||||
|         Core.$apply($scope); | ||||
|       } | ||||
|     }, 50); | ||||
| 
 | ||||
|     updateData(); | ||||
| 
 | ||||
|   }); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var PipelinesController = _module.controller("Developer.PipelinesController", ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|         $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry, $element) => { | ||||
| 
 | ||||
|     $scope.kubernetes = KubernetesState; | ||||
|     $scope.kubeModel = KubernetesModel; | ||||
|     $scope.id = $routeParams["id"]; | ||||
|     $scope.jobId = $scope.jobId || $routeParams["job"]; | ||||
|     $scope.schema = KubernetesSchema; | ||||
|     $scope.entityChangedCache = {}; | ||||
| 
 | ||||
|     $element.on('$destroy', () => { | ||||
|       $scope.$destroy(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.model = { | ||||
|       job: null, | ||||
|       pendingOnly: $scope.pendingPipelinesOnly | ||||
|     }; | ||||
|     Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|     $scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id); | ||||
|     $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId); | ||||
| 
 | ||||
|     $scope.$on('kubernetesModelUpdated', function () { | ||||
|       updateData(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.$on('$routeUpdate', ($event) => { | ||||
|       updateData(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.$watch('model.pendingOnly', ($event) => { | ||||
|       updateData(); | ||||
|     }); | ||||
| 
 | ||||
|     $scope.selectBuild = (build) => { | ||||
|       var id = build.id; | ||||
|       if (id) { | ||||
|         if (id !== $scope.selectedBuildId) { | ||||
|           $scope.selectedBuildId = id; | ||||
|           $scope.$broadcast("jenkinsSelectedBuild", build); | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     var updateData = _.debounce(() => { | ||||
|       var entity = $scope.entity; | ||||
|       if ($scope.jobId) { | ||||
|         if ((!entity || entity.$jenkinsJob)) { | ||||
|           var queryPath = "fabric8/stages/"; | ||||
|           if ($scope.model.pendingOnly) { | ||||
|             queryPath = "fabric8/pendingStages/"; | ||||
|           } | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", $scope.jobId, queryPath)); | ||||
|           if (url && (!$scope.model.job || Kubernetes.keepPollingModel)) { | ||||
|             $http.get(url). | ||||
|             success(function (data, status, headers, config) { | ||||
|               if (data) { | ||||
|                 enrichJenkinsPipelineJob(data, $scope.id, $scope.jobId); | ||||
|                 if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                   log.info("entity has changed!"); | ||||
|                   $scope.model.job = data; | ||||
| 
 | ||||
|                   var builds = data.builds; | ||||
|                   if (builds && builds.length) { | ||||
|                     $scope.selectBuild(builds[0]); | ||||
|                   } | ||||
|                 } | ||||
|               } | ||||
|               $scope.model.fetched = true; | ||||
|               Core.$apply($scope); | ||||
|             }). | ||||
|             error(function (data, status, headers, config) { | ||||
|               log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|               $scope.model.fetched = true; | ||||
|             }); | ||||
|           } | ||||
|         } else { | ||||
|           if ($scope.model) { | ||||
|             Kubernetes.enrichBuilds($scope.kubeModel.builds); | ||||
| 
 | ||||
|             var builds = []; | ||||
|             angular.forEach($scope.kubeModel.builds, (build) => { | ||||
|               var labels = Kubernetes.getLabels(build); | ||||
|               var app = labels["app"]; | ||||
|               if (app === $scope.projectId) { | ||||
|                 builds.push(build); | ||||
|               } | ||||
|             }); | ||||
|             builds = _.sortBy(builds, "$creationDate").reverse(); | ||||
|             var allBuilds = builds; | ||||
|             if (allBuilds.length > 1) { | ||||
|               builds = _.filter(allBuilds, (b) => !b.$creationDate); | ||||
|               if (!builds.length) { | ||||
|                 builds = [allBuilds[0]]; | ||||
|               } | ||||
|             } | ||||
|             var pipelines = []; | ||||
|             angular.forEach(builds, (build) => { | ||||
|               var buildStatus = build.status || {}; | ||||
|               var result = buildStatus.phase || ""; | ||||
|               var resultUpperCase = result.toUpperCase(); | ||||
| 
 | ||||
|               var description = ""; | ||||
|               var $viewLink = build.$viewLink; | ||||
|               var $logLink = build.$logsLink; | ||||
|               var $timestamp = build.$creationDate; | ||||
|               var duration = buildStatus.duration; | ||||
|               if (duration) { | ||||
|                 // 17s = 17,000,000,000 on openshift
 | ||||
|                 duration = duration / 1000000; | ||||
|               } | ||||
|               var displayName = Kubernetes.getName(build); | ||||
|               var $iconClass = createBuildStatusIconClass(resultUpperCase); | ||||
|               var $backgroundClass = createBuildStatusBackgroundClass(resultUpperCase); | ||||
|               var stage = { | ||||
|                 stageName: "OpenShift Build", | ||||
|                 $viewLink: $viewLink, | ||||
|                 $logLink: $logLink, | ||||
|                 $startTime: $timestamp, | ||||
|                 duration: duration, | ||||
|                 status: result, | ||||
|                 $iconClass: $iconClass, | ||||
|                 $backgroundClass: $backgroundClass | ||||
|               }; | ||||
|               var pipeline = { | ||||
|                 description: description, | ||||
|                 displayName: displayName, | ||||
|                 $viewLink: $viewLink, | ||||
|                 $logLink: $logLink, | ||||
|                 $timestamp: $timestamp, | ||||
|                 duration: duration, | ||||
|                 stages: [stage] | ||||
|               }; | ||||
|               pipelines.push(pipeline); | ||||
|             }); | ||||
| 
 | ||||
|             // lets filter the OpenShift builds and make a pipeline from that
 | ||||
|             $scope.model.job = { | ||||
|               $jobId: $scope.jobId, | ||||
|               $project: $scope.projectId, | ||||
|               builds: pipelines | ||||
|             }; | ||||
|           } | ||||
|           $scope.model.fetched = true; | ||||
|           Core.$apply($scope); | ||||
|         } | ||||
|       } else { | ||||
|         $scope.model.fetched = true; | ||||
|         Core.$apply($scope); | ||||
|       } | ||||
|     }, 50); | ||||
| 
 | ||||
|     updateData(); | ||||
| 
 | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -1,95 +1,95 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var ProjectController = controller("ProjectController", | ||||
|     ["$scope", "$element", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, $element, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
| 
 | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.config = KubernetesSchema.definitions.os_build_BuildConfig; | ||||
|         $scope.entityChangedCache = {}; | ||||
|         $scope.envVersionsCache = {}; | ||||
|         $scope.envNSCaches = {}; | ||||
|         $scope.envVersions = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = []; //Developer.createProjectBreadcrumbs($scope.id);
 | ||||
|         updateTabs(); | ||||
|         // this is used for the pendingPipelines view
 | ||||
|         $scope.jobId = $scope.id; | ||||
|         $scope.pendingPipelinesOnly = true; | ||||
| 
 | ||||
|         $scope.$on('jenkinsSelectedBuild', (event, build) => { | ||||
|           $scope.selectedBuild = build; | ||||
|         }); | ||||
| 
 | ||||
|         // TODO this should be unnecessary but seems sometiems this watch doesn't always trigger unless you hit reload on this page
 | ||||
|         if ($scope.model.buildconfigs) { | ||||
|           onBuildConfigs($scope.model.buildconfigs); | ||||
|         } | ||||
|         Kubernetes.watch($scope, $element, "buildconfigs", $scope.namespace, onBuildConfigs); | ||||
| 
 | ||||
|         function onBuildConfigs(buildConfigs) { | ||||
|           angular.forEach(buildConfigs, (data) => { | ||||
|             var name = Kubernetes.getName(data); | ||||
|             if (name === $scope.id) { | ||||
|               var sortedBuilds = null; | ||||
|               Kubernetes.enrichBuildConfig(data, sortedBuilds); | ||||
|               if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                 log.info("entity has changed!"); | ||||
|                 $scope.entity = data; | ||||
|                 $scope.entity.$build = (data.$fabric8CodeViews || {})['fabric8.link.browseGogs.view']; | ||||
|                 $scope.model.setProject($scope.entity); | ||||
|               } | ||||
|               updateEnvironmentWatch(); | ||||
|               updateTabs(); | ||||
|             } | ||||
|           }); | ||||
|           $scope.model.fetched = true; | ||||
|           Core.$apply($scope); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /** | ||||
|          * We have updated the entity so lets make sure we are watching all the environments to find | ||||
|          * the project versions for each namespace | ||||
|          */ | ||||
|         function updateEnvironmentWatch() { | ||||
|           var project = $scope.entity; | ||||
|           if (project) { | ||||
|             var jenkinsJob = project.$jenkinsJob; | ||||
|             if (jenkinsJob) { | ||||
|               var buildsTab = _.find($scope.subTabConfig, {id: "builds"}); | ||||
|               if (buildsTab) { | ||||
|                 buildsTab["href"] = UrlHelpers.join("/workspaces", Kubernetes.currentKubernetesNamespace(), "projects", $scope.id, "jenkinsJob", jenkinsJob); | ||||
|               } | ||||
|             } | ||||
| 
 | ||||
|             angular.forEach(project.environments, (env) => { | ||||
|               var ns = env.namespace; | ||||
|               var caches = $scope.envNSCaches[ns]; | ||||
|               if (!caches) { | ||||
|                 caches = {}; | ||||
|                 $scope.envNSCaches[ns] = caches; | ||||
|                 loadProjectVersions($scope, $element, project, env, ns, $scope.envVersions, caches); | ||||
|               } | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         function updateTabs() { | ||||
|           $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, null, $scope); | ||||
|         } | ||||
| 
 | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var ProjectController = controller("ProjectController", | ||||
|     ["$scope", "$element", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, $element, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["id"]; | ||||
| 
 | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.config = KubernetesSchema.definitions.os_build_BuildConfig; | ||||
|         $scope.entityChangedCache = {}; | ||||
|         $scope.envVersionsCache = {}; | ||||
|         $scope.envNSCaches = {}; | ||||
|         $scope.envVersions = {}; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = []; //Developer.createProjectBreadcrumbs($scope.id);
 | ||||
|         updateTabs(); | ||||
|         // this is used for the pendingPipelines view
 | ||||
|         $scope.jobId = $scope.id; | ||||
|         $scope.pendingPipelinesOnly = true; | ||||
| 
 | ||||
|         $scope.$on('jenkinsSelectedBuild', (event, build) => { | ||||
|           $scope.selectedBuild = build; | ||||
|         }); | ||||
| 
 | ||||
|         // TODO this should be unnecessary but seems sometiems this watch doesn't always trigger unless you hit reload on this page
 | ||||
|         if ($scope.model.buildconfigs) { | ||||
|           onBuildConfigs($scope.model.buildconfigs); | ||||
|         } | ||||
|         Kubernetes.watch($scope, $element, "buildconfigs", $scope.namespace, onBuildConfigs); | ||||
| 
 | ||||
|         function onBuildConfigs(buildConfigs) { | ||||
|           angular.forEach(buildConfigs, (data) => { | ||||
|             var name = Kubernetes.getName(data); | ||||
|             if (name === $scope.id) { | ||||
|               var sortedBuilds = null; | ||||
|               Kubernetes.enrichBuildConfig(data, sortedBuilds); | ||||
|               if (hasObjectChanged(data, $scope.entityChangedCache)) { | ||||
|                 log.info("entity has changed!"); | ||||
|                 $scope.entity = data; | ||||
|                 $scope.entity.$build = (data.$fabric8CodeViews || {})['fabric8.link.browseGogs.view']; | ||||
|                 $scope.model.setProject($scope.entity); | ||||
|               } | ||||
|               updateEnvironmentWatch(); | ||||
|               updateTabs(); | ||||
|             } | ||||
|           }); | ||||
|           $scope.model.fetched = true; | ||||
|           Core.$apply($scope); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /** | ||||
|          * We have updated the entity so lets make sure we are watching all the environments to find | ||||
|          * the project versions for each namespace | ||||
|          */ | ||||
|         function updateEnvironmentWatch() { | ||||
|           var project = $scope.entity; | ||||
|           if (project) { | ||||
|             var jenkinsJob = project.$jenkinsJob; | ||||
|             if (jenkinsJob) { | ||||
|               var buildsTab = _.find($scope.subTabConfig, {id: "builds"}); | ||||
|               if (buildsTab) { | ||||
|                 buildsTab["href"] = UrlHelpers.join("/workspaces", Kubernetes.currentKubernetesNamespace(), "projects", $scope.id, "jenkinsJob", jenkinsJob); | ||||
|               } | ||||
|             } | ||||
| 
 | ||||
|             angular.forEach(project.environments, (env) => { | ||||
|               var ns = env.namespace; | ||||
|               var caches = $scope.envNSCaches[ns]; | ||||
|               if (!caches) { | ||||
|                 caches = {}; | ||||
|                 $scope.envNSCaches[ns] = caches; | ||||
|                 loadProjectVersions($scope, $element, project, env, ns, $scope.envVersions, caches); | ||||
|               } | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         function updateTabs() { | ||||
|           $scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, null, $scope); | ||||
|         } | ||||
| 
 | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,19 +1,19 @@ | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   _module.controller('Developer.ProjectSelector', ['$scope', '$routeParams', 'KubernetesModel', ($scope, $routeParams, KubernetesModel) => { | ||||
|     var projectId = $routeParams['projectId'] || $routeParams['project'] || $routeParams['id']; | ||||
|     if (projectId) { | ||||
|       $scope.projectId = projectId; | ||||
|       $scope.model = KubernetesModel | ||||
|       $scope.$watch('model.buildconfigs', (buildconfigs) => { | ||||
|         $scope.projects = buildconfigs; | ||||
|       }); | ||||
|     } else { | ||||
|       log.info("no project ID in routeParams: ", $routeParams); | ||||
|     } | ||||
|   }]); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /// <reference path="developerPlugin.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   _module.controller('Developer.ProjectSelector', ['$scope', '$routeParams', 'KubernetesModel', ($scope, $routeParams, KubernetesModel) => { | ||||
|     var projectId = $routeParams['projectId'] || $routeParams['project'] || $routeParams['id']; | ||||
|     if (projectId) { | ||||
|       $scope.projectId = projectId; | ||||
|       $scope.model = KubernetesModel | ||||
|       $scope.$watch('model.buildconfigs', (buildconfigs) => { | ||||
|         $scope.projects = buildconfigs; | ||||
|       }); | ||||
|     } else { | ||||
|       log.info("no project ID in routeParams: ", $routeParams); | ||||
|     } | ||||
|   }]); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,171 +1,171 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var ProjectsController = controller("ProjectsController", ["$scope", "KubernetesModel", "KubernetesState", "$dialog", "$window", "$templateCache", "$routeParams", "$location", "localStorage", "$http", "$timeout", "KubernetesApiURL", | ||||
|     ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, $dialog, $window, $templateCache, $routeParams, $location:ng.ILocationService, localStorage, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|       $scope.kubernetes = KubernetesState; | ||||
|       $scope.model = KubernetesModel; | ||||
| 
 | ||||
|       $scope.tableConfig = { | ||||
|         data: 'model.buildconfigs', | ||||
|         showSelectionCheckbox: true, | ||||
|         enableRowClickSelection: false, | ||||
|         multiSelect: true, | ||||
|         selectedItems: [], | ||||
|         filterOptions: { | ||||
|           filterText: $location.search()["q"] || '' | ||||
|         }, | ||||
|         columnDefs: [ | ||||
|           { | ||||
|             field: '$name', | ||||
|             displayName: 'Name', | ||||
|             cellTemplate: $templateCache.get("idTemplate.html") | ||||
|           }, | ||||
| /* | ||||
|           { | ||||
|             field: 'spec.source.type', | ||||
|             displayName: 'Source' | ||||
|           }, | ||||
| */ | ||||
|           { | ||||
|             field: 'spec.source.git.uri', | ||||
|             displayName: 'Repository' | ||||
|           }, | ||||
| /* | ||||
|           { | ||||
|             field: 'spec.strategy.type', | ||||
|             displayName: 'Strategy' | ||||
|           }, | ||||
|           { | ||||
|             field: 'spec.strategy.stiStrategy.image', | ||||
|             displayName: 'Source Image' | ||||
|           }, | ||||
|           { | ||||
|             field: 'spec.output.imageTag', | ||||
|             displayName: 'Output Image' | ||||
|           }, | ||||
| */ | ||||
|           { | ||||
|             field: 'metadata.description', | ||||
|             displayName: 'Description' | ||||
|           }, | ||||
|           { | ||||
|             field: '$creationDate', | ||||
|             displayName: 'Created', | ||||
|             cellTemplate: $templateCache.get("creationTimeTemplate.html") | ||||
|           }, | ||||
|           { | ||||
|             field: '$labelsText', | ||||
|             displayName: 'Labels', | ||||
|             cellTemplate: $templateCache.get("labelTemplate.html") | ||||
|           } | ||||
|         ] | ||||
|       }; | ||||
| 
 | ||||
|       Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
| 
 | ||||
|       $scope.breadcrumbConfig = createProjectBreadcrumbs(); | ||||
|       $scope.subTabConfig = Developer.createWorkspaceSubNavBars(); | ||||
| 
 | ||||
|       // TODO
 | ||||
|       //$scope.isLoggedIntoGogs = Forge.isLoggedIntoGogs;
 | ||||
| 
 | ||||
|       $scope.deletePrompt = (selected) => { | ||||
|         UI.multiItemConfirmActionDialog(<UI.MultiItemConfirmActionOptions>{ | ||||
|           collection: selected, | ||||
|           index: '$name', | ||||
|           onClose: (result:boolean) => { | ||||
|             if (result) { | ||||
|               function deleteSelected(selected, next) { | ||||
|                 if (next) { | ||||
|                   deleteEntity(next, () => { | ||||
|                     deleteSelected(selected, selected.shift()); | ||||
|                   }); | ||||
|                 } else { | ||||
|                   // TODO
 | ||||
|                   // updateData();
 | ||||
|                 } | ||||
|               } | ||||
| 
 | ||||
|               deleteSelected(selected, selected.shift()); | ||||
|             } | ||||
|           }, | ||||
|           title: 'Delete Apps', | ||||
|           action: 'The following Apps will be deleted:', | ||||
|           okText: 'Delete', | ||||
|           okClass: 'btn-danger', | ||||
|           custom: "This operation is permanent once completed!", | ||||
|           customClass: "alert alert-warning" | ||||
|         }).open(); | ||||
|       }; | ||||
| 
 | ||||
|       function deleteEntity(selection, nextCallback) { | ||||
|         var name = (selection || {}).$name; | ||||
|         var jenkinsJob = selection.$jenkinsJob; | ||||
|         var publicJenkinsUrl = jenkinsLink(); | ||||
|         //var jenkinsUrl = Core.pathGet(selection, ["$fabric8Views", "fabric8.link.jenkins.job", "url"]);
 | ||||
|         if (name) { | ||||
|           console.log("About to delete build config: " + name); | ||||
|           var url = Kubernetes.buildConfigRestUrl(name); | ||||
|           $http.delete(url). | ||||
|             success(function (data, status, headers, config) { | ||||
|               nextCallback(); | ||||
|             }). | ||||
|             error(function (data, status, headers, config) { | ||||
|               log.warn("Failed to delete build config on " + url + " " + data + " " + status); | ||||
|               nextCallback(); | ||||
|             }); | ||||
|         } else { | ||||
|           console.log("warning: no name for selection: " + angular.toJson(selection)); | ||||
|         } | ||||
| 
 | ||||
|         if (jenkinsJob && publicJenkinsUrl) { | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", jenkinsJob, "doDelete")); | ||||
|           var body = ""; | ||||
|           var config = { | ||||
|             headers: { | ||||
|               'Content-Type': "text/plain" | ||||
|             } | ||||
|           }; | ||||
|           log.info("posting to jenkinsUrl: " + url); | ||||
|           $http.post(url, body, config). | ||||
|             success(function (data, status, headers, config) { | ||||
|               log.info("Managed to delete " + url); | ||||
|             }). | ||||
|             error(function (data, status, headers, config) { | ||||
|               log.warn("Failed to delete jenkins job at " + url + " " + data + " " + status); | ||||
|             }); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
| /* | ||||
|       $scope.$keepPolling = () => Kubernetes.keepPollingModel; | ||||
|       $scope.fetch = PollHelpers.setupPolling($scope, (next:() => void) => { | ||||
|         var url = Kubernetes.buildConfigsRestURL(); | ||||
|         $http.get(url). | ||||
|           success(function (data, status, headers, config) { | ||||
|             if (data) { | ||||
|               //console.log("got data " + angular.toJson(data, true));
 | ||||
|               var sortedBuilds = null; | ||||
|               $scope.buildConfigs = Kubernetes.enrichBuildConfigs(data.items, sortedBuilds); | ||||
|               $scope.model.fetched = true; | ||||
|               Core.$apply($scope); | ||||
|               next(); | ||||
|             } | ||||
|           }). | ||||
|           error(function (data, status, headers, config) { | ||||
|             log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|             next(); | ||||
|           }); | ||||
|       }); | ||||
| 
 | ||||
|       $scope.fetch(); | ||||
| */ | ||||
|     }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var ProjectsController = controller("ProjectsController", ["$scope", "KubernetesModel", "KubernetesState", "$dialog", "$window", "$templateCache", "$routeParams", "$location", "localStorage", "$http", "$timeout", "KubernetesApiURL", | ||||
|     ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, $dialog, $window, $templateCache, $routeParams, $location:ng.ILocationService, localStorage, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|       $scope.kubernetes = KubernetesState; | ||||
|       $scope.model = KubernetesModel; | ||||
| 
 | ||||
|       $scope.tableConfig = { | ||||
|         data: 'model.buildconfigs', | ||||
|         showSelectionCheckbox: true, | ||||
|         enableRowClickSelection: false, | ||||
|         multiSelect: true, | ||||
|         selectedItems: [], | ||||
|         filterOptions: { | ||||
|           filterText: $location.search()["q"] || '' | ||||
|         }, | ||||
|         columnDefs: [ | ||||
|           { | ||||
|             field: '$name', | ||||
|             displayName: 'Name', | ||||
|             cellTemplate: $templateCache.get("idTemplate.html") | ||||
|           }, | ||||
| /* | ||||
|           { | ||||
|             field: 'spec.source.type', | ||||
|             displayName: 'Source' | ||||
|           }, | ||||
| */ | ||||
|           { | ||||
|             field: 'spec.source.git.uri', | ||||
|             displayName: 'Repository' | ||||
|           }, | ||||
| /* | ||||
|           { | ||||
|             field: 'spec.strategy.type', | ||||
|             displayName: 'Strategy' | ||||
|           }, | ||||
|           { | ||||
|             field: 'spec.strategy.stiStrategy.image', | ||||
|             displayName: 'Source Image' | ||||
|           }, | ||||
|           { | ||||
|             field: 'spec.output.imageTag', | ||||
|             displayName: 'Output Image' | ||||
|           }, | ||||
| */ | ||||
|           { | ||||
|             field: 'metadata.description', | ||||
|             displayName: 'Description' | ||||
|           }, | ||||
|           { | ||||
|             field: '$creationDate', | ||||
|             displayName: 'Created', | ||||
|             cellTemplate: $templateCache.get("creationTimeTemplate.html") | ||||
|           }, | ||||
|           { | ||||
|             field: '$labelsText', | ||||
|             displayName: 'Labels', | ||||
|             cellTemplate: $templateCache.get("labelTemplate.html") | ||||
|           } | ||||
|         ] | ||||
|       }; | ||||
| 
 | ||||
|       Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
| 
 | ||||
|       $scope.breadcrumbConfig = createProjectBreadcrumbs(); | ||||
|       $scope.subTabConfig = Developer.createWorkspaceSubNavBars(); | ||||
| 
 | ||||
|       // TODO
 | ||||
|       //$scope.isLoggedIntoGogs = Forge.isLoggedIntoGogs;
 | ||||
| 
 | ||||
|       $scope.deletePrompt = (selected) => { | ||||
|         UI.multiItemConfirmActionDialog(<UI.MultiItemConfirmActionOptions>{ | ||||
|           collection: selected, | ||||
|           index: '$name', | ||||
|           onClose: (result:boolean) => { | ||||
|             if (result) { | ||||
|               function deleteSelected(selected, next) { | ||||
|                 if (next) { | ||||
|                   deleteEntity(next, () => { | ||||
|                     deleteSelected(selected, selected.shift()); | ||||
|                   }); | ||||
|                 } else { | ||||
|                   // TODO
 | ||||
|                   // updateData();
 | ||||
|                 } | ||||
|               } | ||||
| 
 | ||||
|               deleteSelected(selected, selected.shift()); | ||||
|             } | ||||
|           }, | ||||
|           title: 'Delete Apps', | ||||
|           action: 'The following Apps will be deleted:', | ||||
|           okText: 'Delete', | ||||
|           okClass: 'btn-danger', | ||||
|           custom: "This operation is permanent once completed!", | ||||
|           customClass: "alert alert-warning" | ||||
|         }).open(); | ||||
|       }; | ||||
| 
 | ||||
|       function deleteEntity(selection, nextCallback) { | ||||
|         var name = (selection || {}).$name; | ||||
|         var jenkinsJob = selection.$jenkinsJob; | ||||
|         var publicJenkinsUrl = jenkinsLink(); | ||||
|         //var jenkinsUrl = Core.pathGet(selection, ["$fabric8Views", "fabric8.link.jenkins.job", "url"]);
 | ||||
|         if (name) { | ||||
|           console.log("About to delete build config: " + name); | ||||
|           var url = Kubernetes.buildConfigRestUrl(name); | ||||
|           $http.delete(url). | ||||
|             success(function (data, status, headers, config) { | ||||
|               nextCallback(); | ||||
|             }). | ||||
|             error(function (data, status, headers, config) { | ||||
|               log.warn("Failed to delete build config on " + url + " " + data + " " + status); | ||||
|               nextCallback(); | ||||
|             }); | ||||
|         } else { | ||||
|           console.log("warning: no name for selection: " + angular.toJson(selection)); | ||||
|         } | ||||
| 
 | ||||
|         if (jenkinsJob && publicJenkinsUrl) { | ||||
|           var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, UrlHelpers.join("job", jenkinsJob, "doDelete")); | ||||
|           var body = ""; | ||||
|           var config = { | ||||
|             headers: { | ||||
|               'Content-Type': "text/plain" | ||||
|             } | ||||
|           }; | ||||
|           log.info("posting to jenkinsUrl: " + url); | ||||
|           $http.post(url, body, config). | ||||
|             success(function (data, status, headers, config) { | ||||
|               log.info("Managed to delete " + url); | ||||
|             }). | ||||
|             error(function (data, status, headers, config) { | ||||
|               log.warn("Failed to delete jenkins job at " + url + " " + data + " " + status); | ||||
|             }); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
| /* | ||||
|       $scope.$keepPolling = () => Kubernetes.keepPollingModel; | ||||
|       $scope.fetch = PollHelpers.setupPolling($scope, (next:() => void) => { | ||||
|         var url = Kubernetes.buildConfigsRestURL(); | ||||
|         $http.get(url). | ||||
|           success(function (data, status, headers, config) { | ||||
|             if (data) { | ||||
|               //console.log("got data " + angular.toJson(data, true));
 | ||||
|               var sortedBuilds = null; | ||||
|               $scope.buildConfigs = Kubernetes.enrichBuildConfigs(data.items, sortedBuilds); | ||||
|               $scope.model.fetched = true; | ||||
|               Core.$apply($scope); | ||||
|               next(); | ||||
|             } | ||||
|           }). | ||||
|           error(function (data, status, headers, config) { | ||||
|             log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|             next(); | ||||
|           }); | ||||
|       }); | ||||
| 
 | ||||
|       $scope.fetch(); | ||||
| */ | ||||
|     }]); | ||||
| } | ||||
|  | ||||
| @ -1,53 +1,53 @@ | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var WorkspaceController = controller("WorkspaceController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["namespace"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.config = KubernetesSchema.definitions.kubernetes_Namespace; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = createWorkspaceBreadcrumbs(); | ||||
|         $scope.subTabConfig = Developer.createWorkspaceSubNavBars(); | ||||
| 
 | ||||
|         $scope.$keepPolling = () => Kubernetes.keepPollingModel; | ||||
|         $scope.fetch = PollHelpers.setupPolling($scope, (next:() => void) => { | ||||
|           $scope.item = null; | ||||
|           if ($scope.id) { | ||||
|             var url = UrlHelpers.join(Kubernetes.resourcesUriForKind("Projects"), $scope.id); | ||||
|             log.info("Loading url: " + url); | ||||
|             $http.get(url). | ||||
|               success(function (data, status, headers, config) { | ||||
|                 if (data) { | ||||
|                   $scope.entity = enrichWorkspace(data); | ||||
|                 } | ||||
|                 $scope.model.fetched = true; | ||||
|                 Core.$apply($scope); | ||||
|                 next(); | ||||
|               }). | ||||
|               error(function (data, status, headers, config) { | ||||
|                 log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|                 next(); | ||||
|               }); | ||||
|           } else { | ||||
|             $scope.model.fetched = true; | ||||
|             Core.$apply($scope); | ||||
|             next(); | ||||
| 
 | ||||
|           } | ||||
|         }); | ||||
| 
 | ||||
|         $scope.fetch(); | ||||
|       }]); | ||||
| } | ||||
| /// <reference path="../../includes.ts"/>
 | ||||
| /// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
 | ||||
| /// <reference path="developerEnrichers.ts"/>
 | ||||
| /// <reference path="developerHelpers.ts"/>
 | ||||
| /// <reference path="developerNavigation.ts"/>
 | ||||
| 
 | ||||
| module Developer { | ||||
| 
 | ||||
|   export var WorkspaceController = controller("WorkspaceController", | ||||
|     ["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", | ||||
|       ($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema, | ||||
|        $templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL) => { | ||||
| 
 | ||||
|         $scope.kubernetes = KubernetesState; | ||||
|         $scope.model = KubernetesModel; | ||||
|         $scope.id = $routeParams["namespace"]; | ||||
|         $scope.schema = KubernetesSchema; | ||||
|         $scope.config = KubernetesSchema.definitions.kubernetes_Namespace; | ||||
| 
 | ||||
|         Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL); | ||||
|         $scope.breadcrumbConfig = createWorkspaceBreadcrumbs(); | ||||
|         $scope.subTabConfig = Developer.createWorkspaceSubNavBars(); | ||||
| 
 | ||||
|         $scope.$keepPolling = () => Kubernetes.keepPollingModel; | ||||
|         $scope.fetch = PollHelpers.setupPolling($scope, (next:() => void) => { | ||||
|           $scope.item = null; | ||||
|           if ($scope.id) { | ||||
|             var url = UrlHelpers.join(Kubernetes.resourcesUriForKind("Projects"), $scope.id); | ||||
|             log.info("Loading url: " + url); | ||||
|             $http.get(url). | ||||
|               success(function (data, status, headers, config) { | ||||
|                 if (data) { | ||||
|                   $scope.entity = enrichWorkspace(data); | ||||
|                 } | ||||
|                 $scope.model.fetched = true; | ||||
|                 Core.$apply($scope); | ||||
|                 next(); | ||||
|               }). | ||||
|               error(function (data, status, headers, config) { | ||||
|                 log.warn("Failed to load " + url + " " + data + " " + status); | ||||
|                 next(); | ||||
|               }); | ||||
|           } else { | ||||
|             $scope.model.fetched = true; | ||||
|             Core.$apply($scope); | ||||
|             next(); | ||||
| 
 | ||||
|           } | ||||
|         }); | ||||
| 
 | ||||
|         $scope.fetch(); | ||||
|       }]); | ||||
| } | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| /// <reference path="../libs/hawtio-forms/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-kubernetes-api/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-oauth/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-ui/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-utilities/defs.d.ts"/>
 | ||||
| 
 | ||||
| declare var humandate; | ||||
| declare var jsyaml:any; | ||||
| 
 | ||||
| /// <reference path="../libs/hawtio-forms/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-kubernetes-api/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-oauth/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-ui/defs.d.ts"/>
 | ||||
| /// <reference path="../libs/hawtio-utilities/defs.d.ts"/>
 | ||||
| 
 | ||||
| declare var humandate; | ||||
| declare var jsyaml:any; | ||||
| 
 | ||||
|  | ||||
| @ -1,3 +1,3 @@ | ||||
| <div class="ngCellText" title="deployed at: {{row.entity.$creationDate | date:'yyyy-MMM-dd HH:mm:ss Z'}}"> | ||||
|   {{row.entity.$creationDate ? (row.entity.$creationDate | relativeTime) : ''}} | ||||
| </div> | ||||
| <div class="ngCellText" title="deployed at: {{row.entity.$creationDate | date:'yyyy-MMM-dd HH:mm:ss Z'}}"> | ||||
|   {{row.entity.$creationDate ? (row.entity.$creationDate | relativeTime) : ''}} | ||||
| </div> | ||||
|  | ||||
| @ -1,149 +1,149 @@ | ||||
| <div class="service-view-rectangle" ng-repeat="view in item.$serviceViews" ng-hide="view.appName === 'kubernetes'"> | ||||
|   <div class="service-view-header row"> | ||||
|     <div class="col-md-4"> | ||||
|       <span class="service-view-icon"> | ||||
|         <a ng-href="{{view.service | kubernetesPageLink}}" title="View the service detail page"> | ||||
|           <img ng-show="item.$iconUrl" ng-src="{{item.$iconUrl}}"> | ||||
|         </a> | ||||
|       </span> | ||||
|       <span class="service-view-name" title="{{view.name}}"> | ||||
|         <a ng-href="{{view.service | kubernetesPageLink}}" title="View the service detail page"> | ||||
|           {{view.appName}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="col-md-6"> | ||||
|       <span class="service-view-address" title="The service address"> | ||||
|         <a ng-show="view.service.$connectUrl" target="_blank" href="{{view.service.$connectUrl}}" title="Connect to the service"> | ||||
|           {{view.service.$host}} | ||||
|         </a> | ||||
|         <span ng-hide="view.service.$connectUrl">{{view.service.$host}}</span> | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="col-md-2 align-right"> | ||||
|       <a class="service-view-header-delete" href="" ng-click="deleteSingleApp(item)" title="Delete this app"><i | ||||
|           class="fa fa-remove red"></i></a> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="service-view-detail-rectangle"> | ||||
|     <div class="service-view-detail-header row"> | ||||
|       <div class="col-md-3"> | ||||
|         <div class="service-view-detail-deployed" ng-show="view.createdDate" | ||||
|           title="deployed at: {{view.createdDate | date:'yyyy-MMM-dd HH:mm:ss Z'}}"> | ||||
|           deployed: | ||||
|           <span class="value">{{view.createdDate | relativeTime}}</span> | ||||
|         </div> | ||||
|         <div class="service-view-detail-deployed" ng-hide="view.createdDate"> | ||||
|           not deployed | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="col-md-6"> | ||||
|         <div class="service-view-detail-pod-template" ng-show="view.controllerId"> | ||||
|           pod template: | ||||
|           <span class="value" title="Go to the replication controller detail page"><a | ||||
|               ng-href="{{view.replicationController | kubernetesPageLink}}">{{view.controllerId}}</a></span> | ||||
|         </div> | ||||
|         <div class="service-view-detail-pod-template" ng-hide="view.controllerId"> | ||||
|           no pod template | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="col-md-3 service-view-detail-pod-counts align-right"> | ||||
|         <span> | ||||
|           pods: | ||||
|           <a href="" ng-show="view.replicationController" class="badge badge-success" | ||||
|             ng-click="resizeDialog.open(view.replicationController)" | ||||
|             title="Resize the number of pods"> | ||||
|             {{view.podCount}} | ||||
|           </a> | ||||
|           <span ng-hide="view.replicationController" class="badge badge-info"> | ||||
|             {{view.podCount}} | ||||
|           </span> | ||||
|         </span> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="service-view-detail-pod-box row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="inline-block" ng-repeat="pod in item.pods track by $index"> | ||||
|           <div ng-show="podExpanded(pod)" class="service-view-detail-pod-summary-expand"> | ||||
|             <table> | ||||
|               <tr> | ||||
|                 <td class="service-view-detail-pod-status"> | ||||
|                   <i ng-class="pod.statusClass"></i> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-connect" ng-show="pod.$jolokiaUrl" | ||||
|                   ng-controller="Kubernetes.ConnectController"> | ||||
|                   <a class="clickable" | ||||
|                     ng-click="doConnect(pod)" | ||||
|                     title="Open a new window and connect to this container"> | ||||
|                     <i class="fa fa-sign-in"></i> | ||||
|                   </a> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                   <div class="service-view-detail-pod-id" title="{{pod.id}}"> | ||||
|                     <span class="value">Pod <a title="Go to the pod detail page" ng-href="{{pod | kubernetesPageLink}}">{{pod.idAbbrev}}</a></span> | ||||
|                   </div> | ||||
|                   <div class="service-view-detail-pod-ip"> | ||||
|                     IP: | ||||
|                     <span class="value">{{pod.status.podIP}}</span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                   <div class="service-view-detail-pod-ports"> | ||||
|                     ports: <span class="value">{{pod.$containerPorts.join(", ")}}</span> | ||||
|                   </div> | ||||
|                   <div class="service-view-detail-pod-minion"> | ||||
|                     minion: | ||||
|                     <span class="value"> | ||||
|                       <a ng-show="pod.$host" ng-href="{{baseUri}}/kubernetes/hosts/{{pod.$host}}">{{pod.$host}}</a> | ||||
|                     </span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-expand" ng-click="collapsePod(pod)"> | ||||
|                   <i class="fa fa-chevron-left"></i> | ||||
|                 </td> | ||||
|               </tr> | ||||
|             </table> | ||||
|             <!-- | ||||
|             <div class="service-view-detail-pod-status"> | ||||
|               status: | ||||
|               <span class="value">{{pod.status}}</span> | ||||
|             </div> | ||||
|             --> | ||||
|           </div> | ||||
| 
 | ||||
|           <div ng-hide="podExpanded(pod)" class="service-view-detail-pod-summary"> | ||||
|             <table> | ||||
|               <tr> | ||||
|                 <td class="service-view-detail-pod-status"> | ||||
|                   <i ng-class="pod.statusClass"></i> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-connect" ng-show="pod.$jolokiaUrl" | ||||
|                   ng-controller="Kubernetes.ConnectController"> | ||||
|                   <a class="clickable" | ||||
|                     ng-click="doConnect(pod)" | ||||
|                     title="Open a new window and connect to this container"> | ||||
|                     <i class="fa fa-sign-in"></i> | ||||
|                   </a> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                   <div class="service-view-detail-pod-id" title="{{pod.id}}"> | ||||
|                     <span class="value">Pod <a title="Go to the pod detail page" ng-href="{{pod | kubernetesPageLink}}">{{pod.idAbbrev}}</a></span> | ||||
|                   </div> | ||||
|                   <div class="service-view-detail-pod-ip"> | ||||
|                     IP: | ||||
|                     <span class="value">{{pod.status.podIP}}</span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-expand" ng-click="expandPod(pod)"> | ||||
|                   <i class="fa fa-chevron-right"></i> | ||||
|                 </td> | ||||
|               </tr> | ||||
|             </table> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="service-view-rectangle" ng-repeat="view in item.$serviceViews" ng-hide="view.appName === 'kubernetes'"> | ||||
|   <div class="service-view-header row"> | ||||
|     <div class="col-md-4"> | ||||
|       <span class="service-view-icon"> | ||||
|         <a ng-href="{{view.service | kubernetesPageLink}}" title="View the service detail page"> | ||||
|           <img ng-show="item.$iconUrl" ng-src="{{item.$iconUrl}}"> | ||||
|         </a> | ||||
|       </span> | ||||
|       <span class="service-view-name" title="{{view.name}}"> | ||||
|         <a ng-href="{{view.service | kubernetesPageLink}}" title="View the service detail page"> | ||||
|           {{view.appName}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="col-md-6"> | ||||
|       <span class="service-view-address" title="The service address"> | ||||
|         <a ng-show="view.service.$connectUrl" target="_blank" href="{{view.service.$connectUrl}}" title="Connect to the service"> | ||||
|           {{view.service.$host}} | ||||
|         </a> | ||||
|         <span ng-hide="view.service.$connectUrl">{{view.service.$host}}</span> | ||||
|       </span> | ||||
|     </div> | ||||
|     <div class="col-md-2 align-right"> | ||||
|       <a class="service-view-header-delete" href="" ng-click="deleteSingleApp(item)" title="Delete this app"><i | ||||
|           class="fa fa-remove red"></i></a> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="service-view-detail-rectangle"> | ||||
|     <div class="service-view-detail-header row"> | ||||
|       <div class="col-md-3"> | ||||
|         <div class="service-view-detail-deployed" ng-show="view.createdDate" | ||||
|           title="deployed at: {{view.createdDate | date:'yyyy-MMM-dd HH:mm:ss Z'}}"> | ||||
|           deployed: | ||||
|           <span class="value">{{view.createdDate | relativeTime}}</span> | ||||
|         </div> | ||||
|         <div class="service-view-detail-deployed" ng-hide="view.createdDate"> | ||||
|           not deployed | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="col-md-6"> | ||||
|         <div class="service-view-detail-pod-template" ng-show="view.controllerId"> | ||||
|           pod template: | ||||
|           <span class="value" title="Go to the replication controller detail page"><a | ||||
|               ng-href="{{view.replicationController | kubernetesPageLink}}">{{view.controllerId}}</a></span> | ||||
|         </div> | ||||
|         <div class="service-view-detail-pod-template" ng-hide="view.controllerId"> | ||||
|           no pod template | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="col-md-3 service-view-detail-pod-counts align-right"> | ||||
|         <span> | ||||
|           pods: | ||||
|           <a href="" ng-show="view.replicationController" class="badge badge-success" | ||||
|             ng-click="resizeDialog.open(view.replicationController)" | ||||
|             title="Resize the number of pods"> | ||||
|             {{view.podCount}} | ||||
|           </a> | ||||
|           <span ng-hide="view.replicationController" class="badge badge-info"> | ||||
|             {{view.podCount}} | ||||
|           </span> | ||||
|         </span> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="service-view-detail-pod-box row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div class="inline-block" ng-repeat="pod in item.pods track by $index"> | ||||
|           <div ng-show="podExpanded(pod)" class="service-view-detail-pod-summary-expand"> | ||||
|             <table> | ||||
|               <tr> | ||||
|                 <td class="service-view-detail-pod-status"> | ||||
|                   <i ng-class="pod.statusClass"></i> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-connect" ng-show="pod.$jolokiaUrl" | ||||
|                   ng-controller="Kubernetes.ConnectController"> | ||||
|                   <a class="clickable" | ||||
|                     ng-click="doConnect(pod)" | ||||
|                     title="Open a new window and connect to this container"> | ||||
|                     <i class="fa fa-sign-in"></i> | ||||
|                   </a> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                   <div class="service-view-detail-pod-id" title="{{pod.id}}"> | ||||
|                     <span class="value">Pod <a title="Go to the pod detail page" ng-href="{{pod | kubernetesPageLink}}">{{pod.idAbbrev}}</a></span> | ||||
|                   </div> | ||||
|                   <div class="service-view-detail-pod-ip"> | ||||
|                     IP: | ||||
|                     <span class="value">{{pod.status.podIP}}</span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                   <div class="service-view-detail-pod-ports"> | ||||
|                     ports: <span class="value">{{pod.$containerPorts.join(", ")}}</span> | ||||
|                   </div> | ||||
|                   <div class="service-view-detail-pod-minion"> | ||||
|                     minion: | ||||
|                     <span class="value"> | ||||
|                       <a ng-show="pod.$host" ng-href="{{baseUri}}/kubernetes/hosts/{{pod.$host}}">{{pod.$host}}</a> | ||||
|                     </span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-expand" ng-click="collapsePod(pod)"> | ||||
|                   <i class="fa fa-chevron-left"></i> | ||||
|                 </td> | ||||
|               </tr> | ||||
|             </table> | ||||
|             <!-- | ||||
|             <div class="service-view-detail-pod-status"> | ||||
|               status: | ||||
|               <span class="value">{{pod.status}}</span> | ||||
|             </div> | ||||
|             --> | ||||
|           </div> | ||||
| 
 | ||||
|           <div ng-hide="podExpanded(pod)" class="service-view-detail-pod-summary"> | ||||
|             <table> | ||||
|               <tr> | ||||
|                 <td class="service-view-detail-pod-status"> | ||||
|                   <i ng-class="pod.statusClass"></i> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-connect" ng-show="pod.$jolokiaUrl" | ||||
|                   ng-controller="Kubernetes.ConnectController"> | ||||
|                   <a class="clickable" | ||||
|                     ng-click="doConnect(pod)" | ||||
|                     title="Open a new window and connect to this container"> | ||||
|                     <i class="fa fa-sign-in"></i> | ||||
|                   </a> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                   <div class="service-view-detail-pod-id" title="{{pod.id}}"> | ||||
|                     <span class="value">Pod <a title="Go to the pod detail page" ng-href="{{pod | kubernetesPageLink}}">{{pod.idAbbrev}}</a></span> | ||||
|                   </div> | ||||
|                   <div class="service-view-detail-pod-ip"> | ||||
|                     IP: | ||||
|                     <span class="value">{{pod.status.podIP}}</span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|                 <td class="service-view-detail-pod-expand" ng-click="expandPod(pod)"> | ||||
|                   <i class="fa fa-chevron-right"></i> | ||||
|                 </td> | ||||
|               </tr> | ||||
|             </table> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| <div class="ngCellText" title="{{row.entity.$info.description}}"> | ||||
|   <a ng-href="row.entity.$appUrl"> | ||||
|     <img ng-show="row.entity.$iconUrl" class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
|   </a> | ||||
|   <span class="app-name"> | ||||
|     <a ng-click="row.entity.$select()"> | ||||
|       {{row.entity.$info.name}} | ||||
|     </a> | ||||
|   </span> | ||||
| </div> | ||||
| <div class="ngCellText" title="{{row.entity.$info.description}}"> | ||||
|   <a ng-href="row.entity.$appUrl"> | ||||
|     <img ng-show="row.entity.$iconUrl" class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
|   </a> | ||||
|   <span class="app-name"> | ||||
|     <a ng-click="row.entity.$select()"> | ||||
|       {{row.entity.$info.name}} | ||||
|     </a> | ||||
|   </span> | ||||
| </div> | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| <div class="ngCellText" title="Number of running pods for this controller"> | ||||
|   <div ng-repeat="podCounters in row.entity.$podCounters track by $index"> | ||||
|     <a ng-show="podCounters.podsLink" href="{{podCounters.podsLink}}" title="{{podCounters.labelText}}"> | ||||
|       <span ng-show="podCounters.valid" class="badge badge-success">{{podCounters.valid}}</span> | ||||
|       <span ng-show="podCounters.waiting" class="badge">{{podCounters.waiting}}</span> | ||||
|       <span ng-show="podCounters.error" class="badge badge-warning">{{podCounters.error}}</span> | ||||
|     </a> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="ngCellText" title="Number of running pods for this controller"> | ||||
|   <div ng-repeat="podCounters in row.entity.$podCounters track by $index"> | ||||
|     <a ng-show="podCounters.podsLink" href="{{podCounters.podsLink}}" title="{{podCounters.labelText}}"> | ||||
|       <span ng-show="podCounters.valid" class="badge badge-success">{{podCounters.valid}}</span> | ||||
|       <span ng-show="podCounters.waiting" class="badge">{{podCounters.waiting}}</span> | ||||
|       <span ng-show="podCounters.error" class="badge badge-warning">{{podCounters.error}}</span> | ||||
|     </a> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| <div class="ngCellText"> | ||||
|   <span ng-repeat="controller in row.entity.replicationControllers"> | ||||
|     <a ng-href="{{controller | kubernetesPageLink}}" | ||||
|       title="View controller details"> | ||||
|       <span>{{controller.metadata.name || controller.id}}</span> | ||||
|     </a> | ||||
|       | ||||
|     <span class="pull-right"> | ||||
|       <a class="badge badge-info" href="" ng-click="$emit('do-resize', controller)" | ||||
|         title="Resize the number of replicas of this controller"> | ||||
|         {{controller.spec.replicas || 0}}</a> | ||||
|     </span> | ||||
|   </span> | ||||
| </div> | ||||
| <div class="ngCellText"> | ||||
|   <span ng-repeat="controller in row.entity.replicationControllers"> | ||||
|     <a ng-href="{{controller | kubernetesPageLink}}" | ||||
|       title="View controller details"> | ||||
|       <span>{{controller.metadata.name || controller.id}}</span> | ||||
|     </a> | ||||
|       | ||||
|     <span class="pull-right"> | ||||
|       <a class="badge badge-info" href="" ng-click="$emit('do-resize', controller)" | ||||
|         title="Resize the number of replicas of this controller"> | ||||
|         {{controller.spec.replicas || 0}}</a> | ||||
|     </span> | ||||
|   </span> | ||||
| </div> | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| <div class="ngCellText"> | ||||
|   <span ng-repeat="service in row.entity.services"> | ||||
|     <a ng-href="{{service | kubernetesPageLink}}" | ||||
|       title="View service details"> | ||||
|       <span>{{service.metadata.name ||service.name || service.id}}</span> | ||||
|     </a> | ||||
|   </span> | ||||
| </div> | ||||
| <div class="ngCellText"> | ||||
|   <span ng-repeat="service in row.entity.services"> | ||||
|     <a ng-href="{{service | kubernetesPageLink}}" | ||||
|       title="View service details"> | ||||
|       <span>{{service.metadata.name ||service.name || service.id}}</span> | ||||
|     </a> | ||||
|   </span> | ||||
| </div> | ||||
|  | ||||
| @ -1,175 +1,175 @@ | ||||
| <div ng-controller="Kubernetes.Apps"> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div ng-hide="appSelectorShow"> | ||||
|     <div class="row filter-header"> | ||||
|       <div class="col-md-12"> | ||||
|         <span ng-show="model.apps.length && !id"> | ||||
|           <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                          css-class="input-xxlarge" | ||||
|                          placeholder="Filter apps..."></hawtio-filter> | ||||
|         </span> | ||||
|         <span ng-hide="id" class="pull-right"> | ||||
|           <div class="btn-group"> | ||||
|             <a class="btn btn-default" ng-disabled="mode == 'list'" href="" ng-click="mode = 'list'"> | ||||
|               <i class="fa fa-list"></i></a> | ||||
|             <a class="btn btn-default" ng-disabled="mode == 'detail'" href="" ng-click="mode = 'detail'"> | ||||
|               <i class="fa fa-table"></i></a> | ||||
|           </div> | ||||
|         </span> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button ng-show="model.apps.length && mode == 'list'" | ||||
|                 class="btn btn-danger pull-right" | ||||
|                 ng-disabled="!id && tableConfig.selectedItems.length == 0" | ||||
|                 ng-click="deletePrompt(id || tableConfig.selectedItems)"> | ||||
|           <i class="fa fa-remove"></i> Delete | ||||
|         </button> | ||||
|         <span class="pull-right"> </span> | ||||
| <!-- | ||||
|         <button ng-show="model.showRunButton" | ||||
|                 class="btn btn-success pull-right" | ||||
|                 ng-click="appSelectorShow = true" | ||||
|                 title="Run an application"> | ||||
|           <i class="fa fa-play-circle"></i> Run ... | ||||
|         </button> | ||||
| --> | ||||
|         <span class="pull-right"> </span> | ||||
|         <span ng-include="'runButton.html'"></span> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button ng-show="id" | ||||
|                 class="btn btn-primary pull-right" | ||||
|                 ng-click="id = undefined"><i class="fa fa-list"></i></button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div ng-hide="model.fetched"> | ||||
|           <div class="align-center"> | ||||
|             <i class="fa fa-spinner fa-spin"></i> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="model.fetched && !id"> | ||||
|           <div ng-hide="model.apps.length" class="align-center"> | ||||
|             <p class="alert alert-info">There are no apps currently available.</p> | ||||
|           </div> | ||||
|           <div ng-show="model.apps.length"> | ||||
|             <div ng-show="mode == 'list'"> | ||||
|               <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|             </div> | ||||
|             <div ng-show="mode == 'detail'"> | ||||
|               <div class="app-detail" ng-repeat="item in model.apps | filter:tableConfig.filterOptions.filterText | orderBy:'$name' track by $index"> | ||||
|                 <ng-include src="'plugins/kubernetes/html/appDetailTemplate.html'"/> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="model.fetched && id"> | ||||
|           <div class="app-detail"> | ||||
|             <ng-include src="'plugins/kubernetes/html/appDetailTemplate.html'"/> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|   </div> | ||||
|   <div ng-show="appSelectorShow"> | ||||
|     <div class="col-md-7"> | ||||
|       <div class="row"> | ||||
|         <hawtio-filter ng-model="appSelector.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter apps..."></hawtio-filter> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <ul> | ||||
|           <li class="no-list profile-selector-folder" ng-repeat="folder in model.appFolders" | ||||
|               ng-show="appSelector.showFolder(folder)"> | ||||
|             <div class="expandable" ng-class="appSelector.isOpen(folder)"> | ||||
|               <div title="{{folder.path}}" class="title"> | ||||
|                 <i class="expandable-indicator folder"></i> <span class="folder-title" ng-show="folder.path">{{folder.path.capitalize(true)}}</span><span | ||||
|                       class="folder-title" ng-hide="folder.path">Uncategorized</span> | ||||
|               </div> | ||||
|               <div class="expandable-body"> | ||||
|                 <ul> | ||||
|                   <li class="no-list profile" ng-repeat="profile in folder.apps" ng-show="appSelector.showApp(profile)"> | ||||
|                     <div class="profile-selector-item"> | ||||
|                       <div class="inline-block profile-selector-checkbox"> | ||||
|                         <input type="checkbox" ng-model="profile.selected" | ||||
|                                ng-change="appSelector.updateSelected()"> | ||||
|                       </div> | ||||
|                       <div class="inline-block profile-selector-name" ng-class="appSelector.getSelectedClass(profile)"> | ||||
|                         <span class="contained c-max"> | ||||
|                           <a href="" ng-click="appSelector.select(profile, !profile.selected)" | ||||
|                              title="Details for {{profile.id}}"> | ||||
|                             <img ng-show="profile.$iconUrl" class="icon-small-app" ng-src="{{profile.$iconUrl}}"> | ||||
|                             <span class="app-name">{{profile.name}}</span> | ||||
|                           </a> | ||||
|                         </span> | ||||
|                       </div> | ||||
|                     </div> | ||||
| 
 | ||||
|                   </li> | ||||
|                 </ul> | ||||
|               </div> | ||||
|             </div> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="col-md-5"> | ||||
|       <div class="row"> | ||||
|         <button class="btn btn-primary pull-right" | ||||
|                 ng-click="appSelectorShow = undefined"><i class="fa fa-circle-arrow-left"></i> Back | ||||
|         </button> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button class="btn pull-right" | ||||
|                 ng-disabled="!appSelector.selectedApps.length" | ||||
|                 title="Clears the selected Apps" | ||||
|                 ng-click="appSelector.clearSelected()"><i class="fa fa-check-empty"></i> Clear | ||||
|         </button> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button class="btn btn-success pull-right" | ||||
|                 ng-disabled="!appSelector.selectedApps.length" | ||||
|                 ng-click="appSelector.runSelectedApps()" | ||||
|                 title="Run the selected apps"> | ||||
|           <i class="fa fa-play-circle"></i> | ||||
|           <ng-pluralize count="appSelector.selectedApps.length" | ||||
|                         when="{'0': 'No App Selected', | ||||
|                                        '1': 'Run App', | ||||
|                                        'other': 'Run {} Apps'}"></ng-pluralize> | ||||
| 
 | ||||
|         </button> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <!-- | ||||
|                 <div ng-hide="appSelector.selectedApps.length"> | ||||
|                   <p class="alert pull-right"> | ||||
|                     Please select an App | ||||
|                   </p> | ||||
|                 </div> | ||||
|         --> | ||||
| 
 | ||||
|         <div ng-show="appSelector.selectedApps.length"> | ||||
| 
 | ||||
|           <ul class="zebra-list pull-right"> | ||||
|             <li ng-repeat="app in appSelector.selectedApps"> | ||||
|               <img ng-show="app.$iconUrl" class="icon-selected-app" ng-src="{{app.$iconUrl}}"> | ||||
|               <strong class="green selected-app-name">{{app.name}}</strong> | ||||
|                 | ||||
|               <i class="red clickable fa fa-remove" | ||||
|                  title="Remove appp" | ||||
|                  ng-click="appSelector.select(app, false)"></i> | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <ng-include src="'resizeDialog.html'"/> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.Apps"> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div ng-hide="appSelectorShow"> | ||||
|     <div class="row filter-header"> | ||||
|       <div class="col-md-12"> | ||||
|         <span ng-show="model.apps.length && !id"> | ||||
|           <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                          css-class="input-xxlarge" | ||||
|                          placeholder="Filter apps..."></hawtio-filter> | ||||
|         </span> | ||||
|         <span ng-hide="id" class="pull-right"> | ||||
|           <div class="btn-group"> | ||||
|             <a class="btn btn-default" ng-disabled="mode == 'list'" href="" ng-click="mode = 'list'"> | ||||
|               <i class="fa fa-list"></i></a> | ||||
|             <a class="btn btn-default" ng-disabled="mode == 'detail'" href="" ng-click="mode = 'detail'"> | ||||
|               <i class="fa fa-table"></i></a> | ||||
|           </div> | ||||
|         </span> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button ng-show="model.apps.length && mode == 'list'" | ||||
|                 class="btn btn-danger pull-right" | ||||
|                 ng-disabled="!id && tableConfig.selectedItems.length == 0" | ||||
|                 ng-click="deletePrompt(id || tableConfig.selectedItems)"> | ||||
|           <i class="fa fa-remove"></i> Delete | ||||
|         </button> | ||||
|         <span class="pull-right"> </span> | ||||
| <!-- | ||||
|         <button ng-show="model.showRunButton" | ||||
|                 class="btn btn-success pull-right" | ||||
|                 ng-click="appSelectorShow = true" | ||||
|                 title="Run an application"> | ||||
|           <i class="fa fa-play-circle"></i> Run ... | ||||
|         </button> | ||||
| --> | ||||
|         <span class="pull-right"> </span> | ||||
|         <span ng-include="'runButton.html'"></span> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button ng-show="id" | ||||
|                 class="btn btn-primary pull-right" | ||||
|                 ng-click="id = undefined"><i class="fa fa-list"></i></button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div ng-hide="model.fetched"> | ||||
|           <div class="align-center"> | ||||
|             <i class="fa fa-spinner fa-spin"></i> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="model.fetched && !id"> | ||||
|           <div ng-hide="model.apps.length" class="align-center"> | ||||
|             <p class="alert alert-info">There are no apps currently available.</p> | ||||
|           </div> | ||||
|           <div ng-show="model.apps.length"> | ||||
|             <div ng-show="mode == 'list'"> | ||||
|               <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|             </div> | ||||
|             <div ng-show="mode == 'detail'"> | ||||
|               <div class="app-detail" ng-repeat="item in model.apps | filter:tableConfig.filterOptions.filterText | orderBy:'$name' track by $index"> | ||||
|                 <ng-include src="'plugins/kubernetes/html/appDetailTemplate.html'"/> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="model.fetched && id"> | ||||
|           <div class="app-detail"> | ||||
|             <ng-include src="'plugins/kubernetes/html/appDetailTemplate.html'"/> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|   </div> | ||||
|   <div ng-show="appSelectorShow"> | ||||
|     <div class="col-md-7"> | ||||
|       <div class="row"> | ||||
|         <hawtio-filter ng-model="appSelector.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter apps..."></hawtio-filter> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <ul> | ||||
|           <li class="no-list profile-selector-folder" ng-repeat="folder in model.appFolders" | ||||
|               ng-show="appSelector.showFolder(folder)"> | ||||
|             <div class="expandable" ng-class="appSelector.isOpen(folder)"> | ||||
|               <div title="{{folder.path}}" class="title"> | ||||
|                 <i class="expandable-indicator folder"></i> <span class="folder-title" ng-show="folder.path">{{folder.path.capitalize(true)}}</span><span | ||||
|                       class="folder-title" ng-hide="folder.path">Uncategorized</span> | ||||
|               </div> | ||||
|               <div class="expandable-body"> | ||||
|                 <ul> | ||||
|                   <li class="no-list profile" ng-repeat="profile in folder.apps" ng-show="appSelector.showApp(profile)"> | ||||
|                     <div class="profile-selector-item"> | ||||
|                       <div class="inline-block profile-selector-checkbox"> | ||||
|                         <input type="checkbox" ng-model="profile.selected" | ||||
|                                ng-change="appSelector.updateSelected()"> | ||||
|                       </div> | ||||
|                       <div class="inline-block profile-selector-name" ng-class="appSelector.getSelectedClass(profile)"> | ||||
|                         <span class="contained c-max"> | ||||
|                           <a href="" ng-click="appSelector.select(profile, !profile.selected)" | ||||
|                              title="Details for {{profile.id}}"> | ||||
|                             <img ng-show="profile.$iconUrl" class="icon-small-app" ng-src="{{profile.$iconUrl}}"> | ||||
|                             <span class="app-name">{{profile.name}}</span> | ||||
|                           </a> | ||||
|                         </span> | ||||
|                       </div> | ||||
|                     </div> | ||||
| 
 | ||||
|                   </li> | ||||
|                 </ul> | ||||
|               </div> | ||||
|             </div> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="col-md-5"> | ||||
|       <div class="row"> | ||||
|         <button class="btn btn-primary pull-right" | ||||
|                 ng-click="appSelectorShow = undefined"><i class="fa fa-circle-arrow-left"></i> Back | ||||
|         </button> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button class="btn pull-right" | ||||
|                 ng-disabled="!appSelector.selectedApps.length" | ||||
|                 title="Clears the selected Apps" | ||||
|                 ng-click="appSelector.clearSelected()"><i class="fa fa-check-empty"></i> Clear | ||||
|         </button> | ||||
|         <span class="pull-right"> </span> | ||||
|         <button class="btn btn-success pull-right" | ||||
|                 ng-disabled="!appSelector.selectedApps.length" | ||||
|                 ng-click="appSelector.runSelectedApps()" | ||||
|                 title="Run the selected apps"> | ||||
|           <i class="fa fa-play-circle"></i> | ||||
|           <ng-pluralize count="appSelector.selectedApps.length" | ||||
|                         when="{'0': 'No App Selected', | ||||
|                                        '1': 'Run App', | ||||
|                                        'other': 'Run {} Apps'}"></ng-pluralize> | ||||
| 
 | ||||
|         </button> | ||||
|       </div> | ||||
|       <div class="row"> | ||||
|         <!-- | ||||
|                 <div ng-hide="appSelector.selectedApps.length"> | ||||
|                   <p class="alert pull-right"> | ||||
|                     Please select an App | ||||
|                   </p> | ||||
|                 </div> | ||||
|         --> | ||||
| 
 | ||||
|         <div ng-show="appSelector.selectedApps.length"> | ||||
| 
 | ||||
|           <ul class="zebra-list pull-right"> | ||||
|             <li ng-repeat="app in appSelector.selectedApps"> | ||||
|               <img ng-show="app.$iconUrl" class="icon-selected-app" ng-src="{{app.$iconUrl}}"> | ||||
|               <strong class="green selected-app-name">{{app.name}}</strong> | ||||
|                 | ||||
|               <i class="red clickable fa fa-remove" | ||||
|                  title="Remove appp" | ||||
|                  ng-click="appSelector.select(app, false)"></i> | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <ng-include src="'resizeDialog.html'"/> | ||||
| </div> | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| <div ng-show="breadcrumbConfig" ng-init="breadcrumbConfig = $parent.breadcrumbConfig" | ||||
|      ng-controller="Developer.NavBarController"> | ||||
|   <ol class="breadcrumb"> | ||||
|     <li ng-repeat="breadcrumb in breadcrumbConfig" ng-show="isValid(breadcrumb)" | ||||
|         class="{{breadcrumb.active ? 'active' : ''}}" | ||||
|         title="{{breadcrumb.title}}"> | ||||
|       <a ng-show="breadcrumb.href && !breadcrumb.active" href="{{breadcrumb.href}}">{{breadcrumb.label}}</a> | ||||
|       <span ng-hide="breadcrumb.href && !breadcrumb.active">{{breadcrumb.label}}</span> | ||||
|   </ol> | ||||
| </div> | ||||
| <div ng-show="breadcrumbConfig" ng-init="breadcrumbConfig = $parent.breadcrumbConfig" | ||||
|      ng-controller="Developer.NavBarController"> | ||||
|   <ol class="breadcrumb"> | ||||
|     <li ng-repeat="breadcrumb in breadcrumbConfig" ng-show="isValid(breadcrumb)" | ||||
|         class="{{breadcrumb.active ? 'active' : ''}}" | ||||
|         title="{{breadcrumb.title}}"> | ||||
|       <a ng-show="breadcrumb.href && !breadcrumb.active" href="{{breadcrumb.href}}">{{breadcrumb.label}}</a> | ||||
|       <span ng-hide="breadcrumb.href && !breadcrumb.active">{{breadcrumb.label}}</span> | ||||
|   </ol> | ||||
| </div> | ||||
|  | ||||
| @ -1,46 +1,46 @@ | ||||
| <div ng-controller="Kubernetes.BuildController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/builds"><i class="fa fa-list"></i></a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$configLink" | ||||
|               title="View the build configuration" | ||||
|               href="{{entity.$configLink}}"> | ||||
|         Configuration | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$podLink" | ||||
|               title="View the build pod" | ||||
|               href="{{entity.$podLink}}"> | ||||
|         Pod | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-primary pull-right" ng-show="entity.$logsLink" | ||||
|               title="View the build logs" | ||||
|               href="{{entity.$logsLink}}"> | ||||
|         View Log | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.BuildController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/builds"><i class="fa fa-list"></i></a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$configLink" | ||||
|               title="View the build configuration" | ||||
|               href="{{entity.$configLink}}"> | ||||
|         Configuration | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$podLink" | ||||
|               title="View the build pod" | ||||
|               href="{{entity.$podLink}}"> | ||||
|         Pod | ||||
|       </a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-primary pull-right" ng-show="entity.$logsLink" | ||||
|               title="View the build logs" | ||||
|               href="{{entity.$logsLink}}"> | ||||
|         View Log | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,42 +1,42 @@ | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$editLink" href="{{entity.$editLink}}"> | ||||
|         <i class="fa fa-pencil-square-o"></i> Edit | ||||
|       </a> | ||||
|       <div class="pull-right" ng-repeat="view in entity.$fabric8Views | orderBy:'label'"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|         <span class="pull-right" ng-show="view.url" > </span> | ||||
|       </div> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button class="btn btn-primary pull-right" | ||||
|          title="Trigger this build" | ||||
|          ng-disabled="!entity.$triggerUrl" | ||||
|          ng-click="triggerBuild(entity)"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.BuildConfigController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$editLink" href="{{entity.$editLink}}"> | ||||
|         <i class="fa fa-pencil-square-o"></i> Edit | ||||
|       </a> | ||||
|       <div class="pull-right" ng-repeat="view in entity.$fabric8Views | orderBy:'label'"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|         <span class="pull-right" ng-show="view.url" > </span> | ||||
|       </div> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button class="btn btn-primary pull-right" | ||||
|          title="Trigger this build" | ||||
|          ng-disabled="!entity.$triggerUrl" | ||||
|          ng-click="triggerBuild(entity)"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,62 +1,62 @@ | ||||
| <div ng-init="mode='edit'"> | ||||
|   <div ng-controller="Kubernetes.BuildConfigEditController"> | ||||
|     <div class="row"> | ||||
|       <div hawtio-breadcrumbs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div hawtio-tabs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div ng-init="subTabConfig = tabs" ng-include="'plugins/kubernetes/html/tabs.html'"></div> | ||||
|     <div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <button class="btn btn-primary pull-right" | ||||
|           title="Saves changes to this project configuration" | ||||
|           ng-disabled="!entity.metadata.name" | ||||
|           ng-click="save()"> | ||||
|           Save Changes | ||||
|         </button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div ng-hide="fetched"> | ||||
|           <div class="align-center"> | ||||
|             <i class="fa fa-spinner fa-spin"></i> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="fetched"> | ||||
| 
 | ||||
|           <form name="nameForm" ng-disabled="config.mode == 0" class="form-horizontal"> | ||||
|             <fieldset> | ||||
|               <legend ng-show="config.label || config.description" ng-hide="config.hideLegend" | ||||
|                 class="ng-binding"></legend> | ||||
|               <div class="row"> | ||||
|                 <div class="clearfix col-md-12"> | ||||
|                   <div class="form-group"> | ||||
|                     <label class="control-label">Name</label> | ||||
|                     <input type="text" class="form-control" placeholder="project name" pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*" ng-model="entity.metadata.name" required> | ||||
| 
 | ||||
|                     <p class="form-warning bg-danger" ng-show="nameForm.$error.pattern"> | ||||
|                       Project name must be a lower case DNS name with letters, numbers and dots or dashes such as `example.com` | ||||
|                     </p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </fieldset> | ||||
|           </form> | ||||
| 
 | ||||
| 
 | ||||
|           <!-- | ||||
|           <div hawtio-form-2="config" entity="entity"></div> | ||||
|           --> | ||||
|           <div hawtio-form-2="specConfig" entity="spec"></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-init="mode='edit'"> | ||||
|   <div ng-controller="Kubernetes.BuildConfigEditController"> | ||||
|     <div class="row"> | ||||
|       <div hawtio-breadcrumbs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div hawtio-tabs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div ng-init="subTabConfig = tabs" ng-include="'plugins/kubernetes/html/tabs.html'"></div> | ||||
|     <div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <button class="btn btn-primary pull-right" | ||||
|           title="Saves changes to this project configuration" | ||||
|           ng-disabled="!entity.metadata.name" | ||||
|           ng-click="save()"> | ||||
|           Save Changes | ||||
|         </button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div ng-hide="fetched"> | ||||
|           <div class="align-center"> | ||||
|             <i class="fa fa-spinner fa-spin"></i> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="fetched"> | ||||
| 
 | ||||
|           <form name="nameForm" ng-disabled="config.mode == 0" class="form-horizontal"> | ||||
|             <fieldset> | ||||
|               <legend ng-show="config.label || config.description" ng-hide="config.hideLegend" | ||||
|                 class="ng-binding"></legend> | ||||
|               <div class="row"> | ||||
|                 <div class="clearfix col-md-12"> | ||||
|                   <div class="form-group"> | ||||
|                     <label class="control-label">Name</label> | ||||
|                     <input type="text" class="form-control" placeholder="project name" pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*" ng-model="entity.metadata.name" required> | ||||
| 
 | ||||
|                     <p class="form-warning bg-danger" ng-show="nameForm.$error.pattern"> | ||||
|                       Project name must be a lower case DNS name with letters, numbers and dots or dashes such as `example.com` | ||||
|                     </p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </fieldset> | ||||
|           </form> | ||||
| 
 | ||||
| 
 | ||||
|           <!-- | ||||
|           <div hawtio-form-2="config" entity="entity"></div> | ||||
|           --> | ||||
|           <div hawtio-form-2="specConfig" entity="spec"></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,122 +1,122 @@ | ||||
| <div class="row" ng-controller="Kubernetes.BuildConfigsController"> | ||||
|   <script type="text/ng-template" id="buildConfigLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build configuration" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigs/{{row.entity.metadata.name}}"> | ||||
| <!-- | ||||
|         <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
| --> | ||||
|         {{row.entity.metadata.name}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8Views track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigCodeViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8CodeViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigBuildViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8BuildViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigEnvironmentViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8EnvironmentViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigTeamViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8TeamViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="buildConfigs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter build configurations..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          title="Add a build configuration for an existing project" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigCreate"><i class="fa fa-wrench"></i> Add Build</a> | ||||
|       <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" href="/workspaces/{{namespace}}/forge/createProject" | ||||
|          ng-show="isLoggedIntoGogs()" | ||||
|          title="Create a new app and repository"> | ||||
|         <i class="fa fa-plus"></i> Create Project</a> | ||||
|       </a> | ||||
|       <span class="pull-right" ng-show="isLoggedIntoGogs()"> </span> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" href="/workspaces/{{namespace}}/forge/repos" | ||||
|          ng-hide="isLoggedIntoGogs()" | ||||
|          title="Sign in to gogs so that you can create a new app"> | ||||
|         <i class="fa fa-sign-in"></i> Sign In</a> | ||||
|       </a> | ||||
|       <span class="pull-right" ng-hide="isLoggedIntoGogs()"> </span> | ||||
| 
 | ||||
|       <button class="btn btn-default pull-right" | ||||
|          title="Trigger the given build" | ||||
|          ng-disabled="tableConfig.selectedItems.length != 1 || !tableConfig.selectedItems[0].$triggerUrl" | ||||
|          ng-click="triggerBuild(tableConfig.selectedItems[0])"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.buildconfigs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no build configurations available.</p> | ||||
|           <a class="btn btn-primary" href="{{baseUri}}/kubernetes/buildConfigCreate"><i class="fa fa-wrench"></i> Add Build Configuration</a> | ||||
|         </div> | ||||
|         <div ng-show="model.buildconfigs.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Kubernetes.BuildConfigsController"> | ||||
|   <script type="text/ng-template" id="buildConfigLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build configuration" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigs/{{row.entity.metadata.name}}"> | ||||
| <!-- | ||||
|         <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
| --> | ||||
|         {{row.entity.metadata.name}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8Views track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigCodeViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8CodeViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigBuildViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8BuildViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigEnvironmentViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8EnvironmentViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildConfigTeamViewsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="view in row.entity.$fabric8TeamViews track by $index"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="buildConfigs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter build configurations..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          title="Add a build configuration for an existing project" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigCreate"><i class="fa fa-wrench"></i> Add Build</a> | ||||
|       <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" href="/workspaces/{{namespace}}/forge/createProject" | ||||
|          ng-show="isLoggedIntoGogs()" | ||||
|          title="Create a new app and repository"> | ||||
|         <i class="fa fa-plus"></i> Create Project</a> | ||||
|       </a> | ||||
|       <span class="pull-right" ng-show="isLoggedIntoGogs()"> </span> | ||||
| 
 | ||||
|       <a class="btn btn-primary pull-right" href="/workspaces/{{namespace}}/forge/repos" | ||||
|          ng-hide="isLoggedIntoGogs()" | ||||
|          title="Sign in to gogs so that you can create a new app"> | ||||
|         <i class="fa fa-sign-in"></i> Sign In</a> | ||||
|       </a> | ||||
|       <span class="pull-right" ng-hide="isLoggedIntoGogs()"> </span> | ||||
| 
 | ||||
|       <button class="btn btn-default pull-right" | ||||
|          title="Trigger the given build" | ||||
|          ng-disabled="tableConfig.selectedItems.length != 1 || !tableConfig.selectedItems[0].$triggerUrl" | ||||
|          ng-click="triggerBuild(tableConfig.selectedItems[0])"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.buildconfigs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no build configurations available.</p> | ||||
|           <a class="btn btn-primary" href="{{baseUri}}/kubernetes/buildConfigCreate"><i class="fa fa-wrench"></i> Add Build Configuration</a> | ||||
|         </div> | ||||
|         <div ng-show="model.buildconfigs.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,45 +1,45 @@ | ||||
| <div ng-controller="Kubernetes.BuildLogsController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$viewLink" | ||||
|          title="View the build detail" | ||||
|          href="{{entity.$viewLink}}"> | ||||
|         Build | ||||
|       </a> | ||||
|       <a class="btn btn-primary pull-right" ng-show="entity.$configLink" | ||||
|          title="View the build configuration" | ||||
|          href="{{entity.$configLink}}"> | ||||
|         Configuration | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <h3>logs for {{entity.$configId}}</h3> | ||||
| 
 | ||||
|         <p> | ||||
|           <pre> | ||||
|             <code> | ||||
|               {{logsText}} | ||||
|             </code> | ||||
|           </pre> | ||||
|         </p> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.BuildLogsController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" ng-show="entity.$viewLink" | ||||
|          title="View the build detail" | ||||
|          href="{{entity.$viewLink}}"> | ||||
|         Build | ||||
|       </a> | ||||
|       <a class="btn btn-primary pull-right" ng-show="entity.$configLink" | ||||
|          title="View the build configuration" | ||||
|          href="{{entity.$configLink}}"> | ||||
|         Configuration | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <h3>logs for {{entity.$configId}}</h3> | ||||
| 
 | ||||
|         <p> | ||||
|           <pre> | ||||
|             <code> | ||||
|               {{logsText}} | ||||
|             </code> | ||||
|           </pre> | ||||
|         </p> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,111 +1,111 @@ | ||||
| <div class="row" ng-controller="Kubernetes.BuildsController"> | ||||
|   <script type="text/ng-template" id="buildLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build: {{row.entity.$name}}" | ||||
|          href="{{row.entity.$viewLink}}"> | ||||
|         <!-- | ||||
|                 <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
|         --> | ||||
|         {{row.entity.$shortName}} | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildPodTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View the pod for this build: {{row.entity.podName}}" ng-show="row.entity.$podLink" | ||||
|          href="{{row.entity.$podLink}}"> | ||||
|         {{row.entity.$podShortName}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildLogsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View the log for this build" ng-show="row.entity.$logsLink" | ||||
|          href="{{row.entity.$logsLink}}"> | ||||
|         <i class="fa fa-file-text-o"></i>  Logs | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildRepositoryTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a ng-show="row.entity.spec.source.git.uri" target="gitRepository" | ||||
|          title="View the git based source repository" | ||||
|          href="{{row.entity.spec.source.git.uri}}"> | ||||
|         {{row.entity.spec.source.git.uri}} | ||||
|       </a> | ||||
|       <span ng-hide="row.entity.spec.source.git.uri"> | ||||
|         {{row.entity.spec.source.git.uri}} | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildStatusTemplate.html"> | ||||
|     <div class="ngCellText" ng-switch="row.entity.status.phase"> | ||||
|       <span ng-switch-when="New" class="text-primary"> | ||||
|         <i class="fa fa-spin fa-spinner"></i> New | ||||
|       </span> | ||||
|       <span ng-switch-when="Pending" class="text-primary"> | ||||
|         <i class="fa fa-spin fa-spinner"></i> Pending | ||||
|       </span> | ||||
|       <span ng-switch-when="Running" class="text-primary"> | ||||
|         <i class="fa fa-spin fa-spinner"></i> Running | ||||
|       </span> | ||||
|       <span ng-switch-when="Complete" class="text-success"> | ||||
|         <i class="fa fa-check-circle"></i> Complete | ||||
|       </span> | ||||
|       <span ng-switch-when="Failed" class="text-danger"> | ||||
|         <i class="fa fa-exclamation-circle"></i> Failed | ||||
|       </span> | ||||
|       <span ng-switch-default class="text-warning"> | ||||
|         <i class="fa fa-exclamation-triangle"></i> {{row.entity.status}} | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildTimeTemplate.html"> | ||||
|     <div class="ngCellText" title="built at: {{row.entity.$creationDate | date : 'h:mm:ss a, EEE MMM yyyy'}}"> | ||||
|       {{row.entity.$creationDate.relative()}} | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" > | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-show="model.builds.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter builds..."></hawtio-filter> | ||||
|       </span> | ||||
|       <div class="pull-right" ng-repeat="view in buildConfig.$fabric8BuildViews | orderBy:'label'"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|         <span class="pull-right" ng-show="view.url" > </span> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div ng-hide="model.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no builds currently running.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.builds.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Kubernetes.BuildsController"> | ||||
|   <script type="text/ng-template" id="buildLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build: {{row.entity.$name}}" | ||||
|          href="{{row.entity.$viewLink}}"> | ||||
|         <!-- | ||||
|                 <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
|         --> | ||||
|         {{row.entity.$shortName}} | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildPodTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View the pod for this build: {{row.entity.podName}}" ng-show="row.entity.$podLink" | ||||
|          href="{{row.entity.$podLink}}"> | ||||
|         {{row.entity.$podShortName}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildLogsTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View the log for this build" ng-show="row.entity.$logsLink" | ||||
|          href="{{row.entity.$logsLink}}"> | ||||
|         <i class="fa fa-file-text-o"></i>  Logs | ||||
|       </a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildRepositoryTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a ng-show="row.entity.spec.source.git.uri" target="gitRepository" | ||||
|          title="View the git based source repository" | ||||
|          href="{{row.entity.spec.source.git.uri}}"> | ||||
|         {{row.entity.spec.source.git.uri}} | ||||
|       </a> | ||||
|       <span ng-hide="row.entity.spec.source.git.uri"> | ||||
|         {{row.entity.spec.source.git.uri}} | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildStatusTemplate.html"> | ||||
|     <div class="ngCellText" ng-switch="row.entity.status.phase"> | ||||
|       <span ng-switch-when="New" class="text-primary"> | ||||
|         <i class="fa fa-spin fa-spinner"></i> New | ||||
|       </span> | ||||
|       <span ng-switch-when="Pending" class="text-primary"> | ||||
|         <i class="fa fa-spin fa-spinner"></i> Pending | ||||
|       </span> | ||||
|       <span ng-switch-when="Running" class="text-primary"> | ||||
|         <i class="fa fa-spin fa-spinner"></i> Running | ||||
|       </span> | ||||
|       <span ng-switch-when="Complete" class="text-success"> | ||||
|         <i class="fa fa-check-circle"></i> Complete | ||||
|       </span> | ||||
|       <span ng-switch-when="Failed" class="text-danger"> | ||||
|         <i class="fa fa-exclamation-circle"></i> Failed | ||||
|       </span> | ||||
|       <span ng-switch-default class="text-warning"> | ||||
|         <i class="fa fa-exclamation-triangle"></i> {{row.entity.status}} | ||||
|       </span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="buildTimeTemplate.html"> | ||||
|     <div class="ngCellText" title="built at: {{row.entity.$creationDate | date : 'h:mm:ss a, EEE MMM yyyy'}}"> | ||||
|       {{row.entity.$creationDate.relative()}} | ||||
|     </div> | ||||
|   </script> | ||||
| 
 | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" > | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-show="model.builds.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter builds..."></hawtio-filter> | ||||
|       </span> | ||||
|       <div class="pull-right" ng-repeat="view in buildConfig.$fabric8BuildViews | orderBy:'label'"> | ||||
|         <a title="{{view.description}}" ng-show="view.url" ng-href="{{view.url}}" class="btn btn-default"> | ||||
|           <i class="{{view.iconClass}}" ng-show="view.iconClass"></i> | ||||
|           {{view.label}} | ||||
|         </a> | ||||
|         <span class="pull-right" ng-show="view.url" > </span> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div ng-hide="model.builds.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no builds currently running.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.builds.length"> | ||||
|           <table class="table table-bordered table-striped" hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,21 +1,21 @@ | ||||
| <div ng-controller="Kubernetes.DeploymentConfigController"> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/deploymentConfigs"><i class="fa fa-list"></i></a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.DeploymentConfigController"> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/deploymentConfigs"><i class="fa fa-list"></i></a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div hawtio-object="entity" config="config"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,67 +1,67 @@ | ||||
| <div class="row" ng-controller="Kubernetes.DeploymentConfigsController"> | ||||
|   <script type="text/ng-template" id="deploymentConfigLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build configuration" | ||||
|          href="{{baseUri}}/kubernetes/deploymentConfigs/{{row.entity.metadata.name}}"> | ||||
| <!-- | ||||
|         <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
| --> | ||||
|         {{row.entity.metadata.name}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="deploymentConfigLabelTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="(key, label) in row.entity.template.controllerTemplate.template.metadata.labels track by $index" | ||||
|             class="pod-label badge" | ||||
|             ng-class="labelClass(key)" | ||||
|             ng-click="clickTag(entity, key, label)" | ||||
|             title="{{key}}">{{label}}</span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="deploymentConfigs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter deployment configurations..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched && deploymentConfigs.length" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          title="Create a new build configuration" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigCreate"><i class="fa fa-plus"></i> Create</a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button class="btn btn-primary pull-right" | ||||
|          ng-show="fetched && deploymentConfigs.length" | ||||
|          title="Trigger the given build" | ||||
|          ng-disabled="tableConfig.selectedItems.length != 1 || !tableConfig.selectedItems[0].$triggerUrl" | ||||
|          ng-click="triggerBuild(tableConfig.selectedItems[0])"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div ng-hide="deploymentConfigs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no deployment configurations available.</p> | ||||
|           <a class="btn btn-primary" href="{{baseUri}}/kubernetes/deploymentConfigCreate"><i class="fa fa-plus"></i> Create Deployment Configuration</a> | ||||
|         </div> | ||||
|         <div ng-show="deploymentConfigs.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Kubernetes.DeploymentConfigsController"> | ||||
|   <script type="text/ng-template" id="deploymentConfigLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <a title="View details for this build configuration" | ||||
|          href="{{baseUri}}/kubernetes/deploymentConfigs/{{row.entity.metadata.name}}"> | ||||
| <!-- | ||||
|         <img class="app-icon-small" ng-src="{{row.entity.$iconUrl}}"> | ||||
| --> | ||||
|         {{row.entity.metadata.name}}</a> | ||||
|     </div> | ||||
|   </script> | ||||
|   <script type="text/ng-template" id="deploymentConfigLabelTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="(key, label) in row.entity.template.controllerTemplate.template.metadata.labels track by $index" | ||||
|             class="pod-label badge" | ||||
|             ng-class="labelClass(key)" | ||||
|             ng-click="clickTag(entity, key, label)" | ||||
|             title="{{key}}">{{label}}</span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="deploymentConfigs.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter deployment configurations..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched && deploymentConfigs.length" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          title="Create a new build configuration" | ||||
|          href="{{baseUri}}/kubernetes/buildConfigCreate"><i class="fa fa-plus"></i> Create</a> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button class="btn btn-primary pull-right" | ||||
|          ng-show="fetched && deploymentConfigs.length" | ||||
|          title="Trigger the given build" | ||||
|          ng-disabled="tableConfig.selectedItems.length != 1 || !tableConfig.selectedItems[0].$triggerUrl" | ||||
|          ng-click="triggerBuild(tableConfig.selectedItems[0])"><i class="fa fa-play-circle-o"></i> Trigger</button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div ng-hide="deploymentConfigs.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no deployment configurations available.</p> | ||||
|           <a class="btn btn-primary" href="{{baseUri}}/kubernetes/deploymentConfigCreate"><i class="fa fa-plus"></i> Create Deployment Configuration</a> | ||||
|         </div> | ||||
|         <div ng-show="deploymentConfigs.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,72 +1,72 @@ | ||||
| <div ng-controller="Kubernetes.EventsController"> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.events.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="筛选日志信息..."></hawtio-filter> | ||||
|       </span> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button ng-show="id" | ||||
|               class="btn btn-primary pull-right" | ||||
|               ng-click="id = undefined"><i class="fa fa-list"></i></button> | ||||
|       <span ng-include="'runButton.html'"></span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.events.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no events currently available.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.events.length"> | ||||
|           <div ng-show="mode == 'list'"> | ||||
|             <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                    hawtio-simple-table="tableConfig"></table> | ||||
|           </div> | ||||
| 
 | ||||
|           <div ng-hide="mode == 'list'"> | ||||
|             <div class="column-box" | ||||
|                  ng-repeat="service in model.serviceApps | filter:filterTemplates | orderBy:'metadata.name' track by $index"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-md-2"> | ||||
|                   <a href="{{service.$serviceUrl}}" | ||||
|                      target="_blank" | ||||
|                      title="Click to open this app"> | ||||
|                     <img style="width: 64px; height: 64px;" ng-src="{{service.$iconUrl}}"> | ||||
|                   </a> | ||||
|                 </div> | ||||
|                 <div class="col-md-9"> | ||||
|                   <a href="{{service.$serviceUrl}}" | ||||
|                      target="_blank" | ||||
|                      title="Click to open this app"> | ||||
|                     <h3 ng-bind="service.metadata.name"></h3> | ||||
|                   </a> | ||||
|                 </div> | ||||
| <!-- | ||||
|                 <div class="col-md-1"> | ||||
|                   <a href="" ng-click="deleteService(service)"><i class="fa fa-remove red"></i></a> | ||||
|                 </div> | ||||
| --> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.EventsController"> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12" ng-show="model.events.length"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="筛选日志信息..."></hawtio-filter> | ||||
|       </span> | ||||
|       <span class="pull-right"> </span> | ||||
|       <button ng-show="id" | ||||
|               class="btn btn-primary pull-right" | ||||
|               ng-click="id = undefined"><i class="fa fa-list"></i></button> | ||||
|       <span ng-include="'runButton.html'"></span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.events.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no events currently available.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.events.length"> | ||||
|           <div ng-show="mode == 'list'"> | ||||
|             <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                    hawtio-simple-table="tableConfig"></table> | ||||
|           </div> | ||||
| 
 | ||||
|           <div ng-hide="mode == 'list'"> | ||||
|             <div class="column-box" | ||||
|                  ng-repeat="service in model.serviceApps | filter:filterTemplates | orderBy:'metadata.name' track by $index"> | ||||
|               <div class="row"> | ||||
|                 <div class="col-md-2"> | ||||
|                   <a href="{{service.$serviceUrl}}" | ||||
|                      target="_blank" | ||||
|                      title="Click to open this app"> | ||||
|                     <img style="width: 64px; height: 64px;" ng-src="{{service.$iconUrl}}"> | ||||
|                   </a> | ||||
|                 </div> | ||||
|                 <div class="col-md-9"> | ||||
|                   <a href="{{service.$serviceUrl}}" | ||||
|                      target="_blank" | ||||
|                      title="Click to open this app"> | ||||
|                     <h3 ng-bind="service.metadata.name"></h3> | ||||
|                   </a> | ||||
|                 </div> | ||||
| <!-- | ||||
|                 <div class="col-md-1"> | ||||
|                   <a href="" ng-click="deleteService(service)"><i class="fa fa-remove red"></i></a> | ||||
|                 </div> | ||||
| --> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,61 +1,61 @@ | ||||
| <div ng-controller="Kubernetes.HostController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/hosts"><i class="fa fa-list"></i></a> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          ng-click="flipRaw()" | ||||
|          title="{{rawMode ? 'Raw mode' : 'Form mode'}}">{{rawMode ? 'Form' : 'Raw'}}</a> | ||||
|        <a class="btn btn-default pull-right" ng-show="rawMode" ng-click="readOnly = !readOnly" ng-class="!readOnly ? 'btn-primary' : ''">Edit</a> | ||||
|        <span class="pull-right"> </span> | ||||
| 
 | ||||
|        <a class="btn btn-success pull-right" ng-show="dirty" ng-click="save(rawModel)">Save</a> | ||||
|        <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-primary pull-right" | ||||
|               title="View all the pods on this host" | ||||
|               href="{{baseUri}}/kubernetes/pods/?q=host={{item.id}}"> | ||||
|         Pods | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched && !rawMode"> | ||||
|         <div hawtio-object="item" config="itemConfig"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="span12"> | ||||
|     <div ng-hide="model.fetched"> | ||||
|       <div class="align-center"> | ||||
|         <i class="fa fa-spinner fa-spin"></i> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div ng-show="model.fetched && rawMode"> | ||||
|       <div class="row-fluid wiki-fixed form-horizontal"> | ||||
|         <div class="control-group editor-autoresize"> | ||||
|           <div hawtio-editor="rawModel" mode="mode" read-only="readOnly"></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
| <div ng-controller="Kubernetes.HostController"> | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|               href="{{baseUri}}/kubernetes/hosts"><i class="fa fa-list"></i></a> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          ng-click="flipRaw()" | ||||
|          title="{{rawMode ? 'Raw mode' : 'Form mode'}}">{{rawMode ? 'Form' : 'Raw'}}</a> | ||||
|        <a class="btn btn-default pull-right" ng-show="rawMode" ng-click="readOnly = !readOnly" ng-class="!readOnly ? 'btn-primary' : ''">Edit</a> | ||||
|        <span class="pull-right"> </span> | ||||
| 
 | ||||
|        <a class="btn btn-success pull-right" ng-show="dirty" ng-click="save(rawModel)">Save</a> | ||||
|        <span class="pull-right"> </span> | ||||
| 
 | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-primary pull-right" | ||||
|               title="View all the pods on this host" | ||||
|               href="{{baseUri}}/kubernetes/pods/?q=host={{item.id}}"> | ||||
|         Pods | ||||
|       </a> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched && !rawMode"> | ||||
|         <div hawtio-object="item" config="itemConfig"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="span12"> | ||||
|     <div ng-hide="model.fetched"> | ||||
|       <div class="align-center"> | ||||
|         <i class="fa fa-spinner fa-spin"></i> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div ng-show="model.fetched && rawMode"> | ||||
|       <div class="row-fluid wiki-fixed form-horizontal"> | ||||
|         <div class="control-group editor-autoresize"> | ||||
|           <div hawtio-editor="rawModel" mode="mode" read-only="readOnly"></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
|  | ||||
| @ -1,43 +1,43 @@ | ||||
| <div class="row" ng-controller="Kubernetes.HostsController"> | ||||
|   <script type="text/ng-template" id="hostLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       </div> | ||||
|   </script> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-show="model.hosts.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter hosts..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.hosts.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no hosts currently running.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.hosts.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Kubernetes.HostsController"> | ||||
|   <script type="text/ng-template" id="hostLinkTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       </div> | ||||
|   </script> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-breadcrumbs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row"> | ||||
|     <div hawtio-tabs></div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span ng-show="!id"> | ||||
|         <hawtio-filter ng-show="model.hosts.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter hosts..."></hawtio-filter> | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="model.fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="model.fetched"> | ||||
|         <div ng-hide="model.hosts.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no hosts currently running.</p> | ||||
|         </div> | ||||
|         <div ng-show="model.hosts.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,51 +1,51 @@ | ||||
| <div class="row" ng-controller="Kubernetes.ImageRepositoriesController"> | ||||
|   <script type="text/ng-template" id="imageRegistryLabelTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="(key, label) in row.entity.tags track by $index" | ||||
|             class="pod-label badge" | ||||
|             ng-class="labelClass(key)" | ||||
|             ng-click="clickTag(entity, key, label)" | ||||
|             title="{{key}}">{{label}}</span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="imageRepositories.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter image repositories..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched && imageRepositories.length" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          title="Create a new image repository" | ||||
|          href="{{baseUri}}/kubernetes/imageRepositoryCreate"><i class="fa fa-plus"></i> Create</a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div ng-hide="imageRepositories.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no image repositories available.</p> | ||||
|           <a class="btn btn-primary" href="{{baseUri}}/kubernetes/imageRepositoryCreate"><i class="fa fa-plus"></i> Create Image Repository</a> | ||||
|         </div> | ||||
|         <div ng-show="imageRepositories.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div class="row" ng-controller="Kubernetes.ImageRepositoriesController"> | ||||
|   <script type="text/ng-template" id="imageRegistryLabelTemplate.html"> | ||||
|     <div class="ngCellText"> | ||||
|       <span ng-repeat="(key, label) in row.entity.tags track by $index" | ||||
|             class="pod-label badge" | ||||
|             ng-class="labelClass(key)" | ||||
|             ng-click="clickTag(entity, key, label)" | ||||
|             title="{{key}}">{{label}}</span> | ||||
|     </div> | ||||
|   </script> | ||||
|   <div class="row filter-header"> | ||||
|     <div class="col-md-12"> | ||||
|       <span> | ||||
|         <hawtio-filter ng-show="imageRepositories.length" | ||||
|                        ng-model="tableConfig.filterOptions.filterText" | ||||
|                        css-class="input-xxlarge" | ||||
|                        placeholder="Filter image repositories..."></hawtio-filter> | ||||
|       </span> | ||||
|       <button ng-show="fetched && imageRepositories.length" | ||||
|               title="Delete the selected build configuration" | ||||
|               class="btn btn-danger pull-right" | ||||
|               ng-disabled="tableConfig.selectedItems.length == 0" | ||||
|               ng-click="deletePrompt(tableConfig.selectedItems)"> | ||||
|         <i class="fa fa-remove"></i> Delete | ||||
|       </button> | ||||
|       <span class="pull-right"> </span> | ||||
|       <a class="btn btn-default pull-right" | ||||
|          title="Create a new image repository" | ||||
|          href="{{baseUri}}/kubernetes/imageRepositoryCreate"><i class="fa fa-plus"></i> Create</a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div ng-hide="fetched"> | ||||
|         <div class="align-center"> | ||||
|           <i class="fa fa-spinner fa-spin"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div ng-show="fetched"> | ||||
|         <div ng-hide="imageRepositories.length" class="align-center"> | ||||
|           <p class="alert alert-info">There are no image repositories available.</p> | ||||
|           <a class="btn btn-primary" href="{{baseUri}}/kubernetes/imageRepositoryCreate"><i class="fa fa-plus"></i> Create Image Repository</a> | ||||
|         </div> | ||||
|         <div ng-show="imageRepositories.length"> | ||||
|           <table class="table table-bordered table-striped" ui-if="kubernetes.selectedNamespace" | ||||
|                  hawtio-simple-table="tableConfig"></table> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,58 +1,58 @@ | ||||
| <div ng-init="mode='create'"> | ||||
|   <div ng-controller="Kubernetes.BuildConfigEditController"> | ||||
|     <div class="row"> | ||||
|       <div hawtio-breadcrumbs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div hawtio-tabs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <button class="btn btn-primary pull-right" | ||||
|           title="Saves changes to this project configuration" | ||||
|           ng-disabled="!entity.metadata.name" | ||||
|           ng-click="save()"> | ||||
|           Save Changes | ||||
|         </button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div ng-hide="fetched"> | ||||
|           <div class="align-center"> | ||||
|             <i class="fa fa-spinner fa-spin"></i> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="fetched"> | ||||
| 
 | ||||
|           <p class="hero-unit"> | ||||
|             Create a project by entering or copy/pasting the Git URL for a repository, and give the project a name.  By default the name will be based on the repository name. | ||||
|           </p> | ||||
| 
 | ||||
|           <div hawtio-form-2="specConfig" entity="spec"></div> | ||||
| 
 | ||||
|           <form name="nameForm" ng-disabled="config.mode == 0" class="form-horizontal"> | ||||
|             <fieldset> | ||||
|               <div class="row"> | ||||
|                 <div class="clearfix col-md-12"> | ||||
|                   <div class="form-group"> | ||||
|                     <label class="control-label">Name</label> | ||||
|                     <input type="text" class="form-control" pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*" ng-model="entity.metadata.name" required> | ||||
| 
 | ||||
|                     <p class="form-warning bg-danger" ng-show="nameForm.$error.pattern"> | ||||
|                       Project name must be a lower case DNS name with letters, numbers and dots or dashes such as `example.com` | ||||
|                     </p> | ||||
|                     <p class="help-block">Name of this project</p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </fieldset> | ||||
|           </form> | ||||
| 
 | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| <div ng-init="mode='create'"> | ||||
|   <div ng-controller="Kubernetes.BuildConfigEditController"> | ||||
|     <div class="row"> | ||||
|       <div hawtio-breadcrumbs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div hawtio-tabs></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <button class="btn btn-primary pull-right" | ||||
|           title="Saves changes to this project configuration" | ||||
|           ng-disabled="!entity.metadata.name" | ||||
|           ng-click="save()"> | ||||
|           Save Changes | ||||
|         </button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-md-12"> | ||||
|         <div ng-hide="fetched"> | ||||
|           <div class="align-center"> | ||||
|             <i class="fa fa-spinner fa-spin"></i> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div ng-show="fetched"> | ||||
| 
 | ||||
|           <p class="hero-unit"> | ||||
|             Create a project by entering or copy/pasting the Git URL for a repository, and give the project a name.  By default the name will be based on the repository name. | ||||
|           </p> | ||||
| 
 | ||||
|           <div hawtio-form-2="specConfig" entity="spec"></div> | ||||
| 
 | ||||
|           <form name="nameForm" ng-disabled="config.mode == 0" class="form-horizontal"> | ||||
|             <fieldset> | ||||
|               <div class="row"> | ||||
|                 <div class="clearfix col-md-12"> | ||||
|                   <div class="form-group"> | ||||
|                     <label class="control-label">Name</label> | ||||
|                     <input type="text" class="form-control" pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*" ng-model="entity.metadata.name" required> | ||||
| 
 | ||||
|                     <p class="form-warning bg-danger" ng-show="nameForm.$error.pattern"> | ||||
|                       Project name must be a lower case DNS name with letters, numbers and dots or dashes such as `example.com` | ||||
|                     </p> | ||||
|                     <p class="help-block">Name of this project</p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </fieldset> | ||||
|           </form> | ||||
| 
 | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| @ -1,32 +1,32 @@ | ||||
| <div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div class="fabric-page-header row"> | ||||
| 
 | ||||
|         <div class="pull-left" ng-show="iconURL"> | ||||
|           <div class="app-logo"> | ||||
|             <img ng-src="{{iconURL}}">  | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="pull-left"> | ||||
|             <h2 class="list-inline"><span class="contained c-wide3"> {{displayName || appTitle}}</span></h2> | ||||
|         </div> | ||||
|         <div class="pull-right"> | ||||
|           <button class="btn btn-success pull-right" | ||||
|                   title="Run this application" | ||||
|                   ng-disabled="!config || config.error" | ||||
|                   ng-click="apply()"> | ||||
|             <i class="fa fa-play-circle"></i> Run | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="pull-left col-md-10 profile-summary-wide"> | ||||
|           <div | ||||
|                ng-show="summaryHtml" | ||||
|                ng-bind-html-unsafe="summaryHtml"></div> | ||||
|         </div> | ||||
|       </div> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
| <div> | ||||
|   <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|       <div class="fabric-page-header row"> | ||||
| 
 | ||||
|         <div class="pull-left" ng-show="iconURL"> | ||||
|           <div class="app-logo"> | ||||
|             <img ng-src="{{iconURL}}">  | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="pull-left"> | ||||
|             <h2 class="list-inline"><span class="contained c-wide3"> {{displayName || appTitle}}</span></h2> | ||||
|         </div> | ||||
|         <div class="pull-right"> | ||||
|           <button class="btn btn-success pull-right" | ||||
|                   title="Run this application" | ||||
|                   ng-disabled="!config || config.error" | ||||
|                   ng-click="apply()"> | ||||
|             <i class="fa fa-play-circle"></i> Run | ||||
|           </button> | ||||
|         </div> | ||||
|         <div class="pull-left col-md-10 profile-summary-wide"> | ||||
|           <div | ||||
|                ng-show="summaryHtml" | ||||
|                ng-bind-html-unsafe="summaryHtml"></div> | ||||
|         </div> | ||||
|       </div> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
|  | ||||
| @ -1,15 +1,15 @@ | ||||
| <div class="terminal-window pod-log-window" pod-log-window ng-mousedown="raise()"> | ||||
|   <div class="resize-dot" ng-mousedown="startResize($event)" ng-hide="docked"></div> | ||||
|   <div class="centered scroll-indicator" ng-hide="atBottom" ng-click="atBottom = true"> | ||||
|     <span class="fa fa-caret-down"></span> | ||||
|   </div> | ||||
|   <div class="terminal-title" ng-mousedown="mouseDown($event)" ng-mouseup="mouseUp($event)" ng-mousemove="mouseMove($event)"> | ||||
|     <h5 class="top-bottom-middle">{{containerName}}的汇总日志</h5> | ||||
|     <i class="fa fa-remove pull-right clickable" title="Close and exit this log" ng-click="close()"></i> | ||||
|     <i class="fa fa-square-o pull-right clickable" title="Maximize this log" ng-click="maximize($event)"></i> | ||||
|     <i class="fa fa-sort-desc pull-right clickable" ng-hide="maximized()" title="Minimize this log" ng-click="minimize($event)"></i> | ||||
|   </div> | ||||
|   <!--<div class="terminal-body" scroll-glue ng-model="atBottom" style="overflow-y:hidden"> --> | ||||
|     <textarea style="height:100%; width:100%" disabled="disabled">{{logs}}</textarea> | ||||
|   <!--</div>--> | ||||
| </div> | ||||
| <div class="terminal-window pod-log-window" pod-log-window ng-mousedown="raise()"> | ||||
|   <div class="resize-dot" ng-mousedown="startResize($event)" ng-hide="docked"></div> | ||||
|   <div class="centered scroll-indicator" ng-hide="atBottom" ng-click="atBottom = true"> | ||||
|     <span class="fa fa-caret-down"></span> | ||||
|   </div> | ||||
|   <div class="terminal-title" ng-mousedown="mouseDown($event)" ng-mouseup="mouseUp($event)" ng-mousemove="mouseMove($event)"> | ||||
|     <h5 class="top-bottom-middle">{{containerName}}的汇总日志</h5> | ||||
|     <i class="fa fa-remove pull-right clickable" title="Close and exit this log" ng-click="close()"></i> | ||||
|     <i class="fa fa-square-o pull-right clickable" title="Maximize this log" ng-click="maximize($event)"></i> | ||||
|     <i class="fa fa-sort-desc pull-right clickable" ng-hide="maximized()" title="Minimize this log" ng-click="minimize($event)"></i> | ||||
|   </div> | ||||
|   <!--<div class="terminal-body" scroll-glue ng-model="atBottom" style="overflow-y:hidden"> --> | ||||
|     <textarea style="height:100%; width:100%" disabled="disabled">{{logs}}</textarea> | ||||
|   <!--</div>--> | ||||
| </div> | ||||
|  | ||||