last demo import - cleaned
This commit is contained in:
40
views/datacenter.tpl
Normal file
40
views/datacenter.tpl
Normal file
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Machines list</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="10%" height="auto"/></a>
|
||||
<br/>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
139
views/details.tpl
Normal file
139
views/details.tpl
Normal file
@@ -0,0 +1,139 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<link href='/static/fullcalendar/main.css' rel='stylesheet' />
|
||||
<script src='/static/fullcalendar/main.js'></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
$( document ).ready(function() {
|
||||
|
||||
|
||||
|
||||
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
|
||||
;(function() {
|
||||
jQuery.expr[':'].containsNC = function(elem, index, match) {
|
||||
return (elem.textContent || elem.innerText || jQuery(elem).text() || '').toLowerCase().indexOf((match[3] || '').toLowerCase()) >= 0;
|
||||
}
|
||||
}(jQuery));
|
||||
|
||||
$('#filter').on('input',function(e)
|
||||
{
|
||||
if ($('#filter').val())
|
||||
{
|
||||
$('a')
|
||||
.find('span').not(':containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.hide();
|
||||
$('a')
|
||||
.find('span:containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.show();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="40%" height="auto"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection">
|
||||
|
||||
<div class="row collection-item">
|
||||
<div>
|
||||
<img src="data:image/png;base64,{{.data.Logo}}"/>
|
||||
</div>
|
||||
<div id="resourceData">
|
||||
<span rtype="{{.data | getRtype}}" rid="{{.data.ID}}" class="title">{{.data.Name}}</span><br>
|
||||
<span class="small">{{.data.ID}} </span><br/>
|
||||
<span class="small">{{.data.ShortDescription}} </span><br/>
|
||||
<span class="small">[{{.data | getRtype}}]</span><br/>
|
||||
</div>
|
||||
|
||||
<div class="col s1">
|
||||
<a id="addButton" disabled="true" onclick="submitWorkspace()" class="btn tooltipped gray" data-position="bottom" data-tooltip="Add to Workspace" ><i class="material-icons">shopping_cart</i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
{{ template "swagger.tpl" . }}
|
||||
|
||||
<script>
|
||||
elem = document.getElementById("resourceData").querySelector("*[rid]");
|
||||
var rid = elem.getAttribute("rid")
|
||||
var rtype = elem.getAttribute("rtype")
|
||||
|
||||
window.onload = setInitialStatus;
|
||||
|
||||
function setInitialStatus() {
|
||||
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workspace
|
||||
.WorkspaceController_Get_workspace()
|
||||
.then(response => {
|
||||
//console.log(response);
|
||||
if ( response.body[rtype].includes(rid)) {
|
||||
document.getElementById("addButton").setAttribute("disabled", true);
|
||||
} else {
|
||||
document.getElementById("addButton").removeAttribute("disabled");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("ERROR: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: Make this function with callbacks in order to be used by any
|
||||
function submitWorkspace() {
|
||||
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workspace
|
||||
.WorkspaceController_Add_model_to_workspace({id: rid, rtype: rtype})
|
||||
.then(response => {
|
||||
document.getElementById("addButton").setAttribute("disabled", true);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("ERROR: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
13
views/floating_menu.tpl
Normal file
13
views/floating_menu.tpl
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="fixed-action-btn" style="position: absolute; top:20px; right: 24px;">
|
||||
<a class="btn-floating btn-large">
|
||||
<i class="large material-icons">menu</i>
|
||||
</a>
|
||||
<ul>
|
||||
<li><a class="btn-floating tooltipped grey" data-position="left" data-tooltip="Map view" href="/map"><i class="material-icons">public</i></a></li>
|
||||
<li><a class="btn-floating tooltipped red" data-position="left" data-tooltip="My datacenter" href="/datacenter"><i class="material-icons">dns</i></a></li>
|
||||
<li><a class="btn-floating tooltipped orange" data-position="left" data-tooltip="Scheduled tasks" href="/schedule"><i class="material-icons">schedule</i></a></li>
|
||||
<li><a class="btn-floating tooltipped yellow darken-1" data-position="left" data-tooltip="Task workflow editor" href="/workflow"><i class="material-icons">play_arrow</i></a></li>
|
||||
<li><a class="btn-floating tooltipped green" data-position="left" data-tooltip="Workspace" href="/workspace"><i class="material-icons">shopping_cart</i></a></li>
|
||||
<li><a class="btn-floating tooltipped blue" data-position="left" data-tooltip="User" href="/user"><i class="material-icons">person</i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
85
views/identity.tpl
Normal file
85
views/identity.tpl
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
;(function() {
|
||||
jQuery.expr[':'].containsNC = function(elem, index, match) {
|
||||
return (elem.textContent || elem.innerText || jQuery(elem).text() || '').toLowerCase().indexOf((match[3] || '').toLowerCase()) >= 0;
|
||||
}
|
||||
}(jQuery));
|
||||
|
||||
$('#filter').on('input',function(e)
|
||||
{
|
||||
if ($('#filter').val())
|
||||
{
|
||||
$('a')
|
||||
.find('span').not(':containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.hide();
|
||||
$('a')
|
||||
.find('span:containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.show();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="40%" height="auto"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection">
|
||||
{{range $key, $value := .list}}
|
||||
<div class="row collection-item">
|
||||
<a href="/details/{{$value.Id}}">
|
||||
<div class="col s1">
|
||||
<img src="{{$value.Logo}}" style="width: 50%; height: 50%"/>
|
||||
</div>
|
||||
<div class="col s10">
|
||||
<span class="title">{{$value.Name}}</span><br>
|
||||
<span class="small">{{$value.ShortDescription}} </span>
|
||||
<span class="small">[{{$value.Type}}]</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col s1">
|
||||
<a class="btn tooltipped gray" data-position="bottom" data-tooltip="Remove from Workspace" ><i class="material-icons">delete</i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
64
views/index.tpl
Normal file
64
views/index.tpl
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link href="/static/css/material-icons.css" rel="stylesheet">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
$("#local").click( function()
|
||||
{
|
||||
query = $("#search").val()
|
||||
if (query) {
|
||||
window.location="/search?q="+encodeURIComponent($("#search").val());
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="center-align">
|
||||
<img src="/static/img/O-cloud.svg" width="20%" height="auto"/>
|
||||
</div>
|
||||
<div class="input-field col s6 offset-s3">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search" type="text" class="autocomplete">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="center-align">
|
||||
<button class="btn waves-effect tooltipped waves-light btn-small" data-position="bottom" data-tooltip="Search in my local datacenter" id="local" name="local">Local Search<i class="material-icons left">home</i>
|
||||
</button>
|
||||
|
||||
<button class="btn waves-effect tooltipped waves-light btn-small" data-position="bottom" data-tooltip="Distributed search in my partners network" id="network" name="network">Network Search<i class="material-icons left">public</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
63
views/item_add.tpl
Normal file
63
views/item_add.tpl
Normal file
@@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<!-- CSS Styles -->
|
||||
<style>
|
||||
.speech input {border: 0; width: 240px; display: inline-block; height: 30px; visibility:hidden;}
|
||||
.speech img {float: right; width: 40px }
|
||||
</style>
|
||||
|
||||
<!-- Search Form -->
|
||||
<form id="speak" method="post" action="/item/add">
|
||||
<div class="speech">
|
||||
<input type="text" name="q" id="transcript" placeholder="Speak" />
|
||||
<img onclick="startDictation()" src="/static/img/mic.png" />
|
||||
</div>
|
||||
<div id="history">
|
||||
<table class="table is-striped is-fullwidth">
|
||||
<!-- php
|
||||
foreach (array_reverse($rqList) as $rq => $ts)
|
||||
{
|
||||
echo "<tr><td>".date("d/m/Y H:i:s", $ts)."</td><td>".$rq."</td></tr>";
|
||||
}
|
||||
-->
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</body>
|
||||
<!-- HTML5 Speech Recognition API -->
|
||||
<script>
|
||||
function startDictation() {
|
||||
|
||||
if (window.hasOwnProperty('webkitSpeechRecognition')) {
|
||||
|
||||
var recognition = new webkitSpeechRecognition();
|
||||
|
||||
recognition.continuous = false;
|
||||
recognition.interimResults = false;
|
||||
|
||||
recognition.lang = "en-US";
|
||||
recognition.start();
|
||||
|
||||
recognition.onresult = function(e) {
|
||||
document.getElementById('transcript').value
|
||||
= e.results[0][0].transcript;
|
||||
recognition.stop();
|
||||
document.getElementById('speak').submit();
|
||||
};
|
||||
|
||||
recognition.onerror = function(e) {
|
||||
recognition.stop();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
69
views/login.tpl
Normal file
69
views/login.tpl
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-cloud login</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<form action="/login" method="POST" class="col s12">
|
||||
<div class="row">
|
||||
<div class="input-field col s2 offset-s5">
|
||||
<i class="material-icons prefix">account_circle</i>
|
||||
<input name="login" id="login" type="text" class="validate">
|
||||
<label for="login">Login</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s2 offset-s5">
|
||||
<i class="material-icons prefix">vpn_key</i>
|
||||
<input name="password" id="password" type="password" class="validate">
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s2 offset-s6">
|
||||
<button class="btn waves-effect waves-light" type="submit">Local login
|
||||
<i class="material-icons right">send</i>
|
||||
</button>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s2 offset-s6">
|
||||
|
||||
<a class="waves-effect waves-light btn" href="/oidc"><i class="material-icons left">mail</i>O-Mail login</a>
|
||||
|
||||
|
||||
</div> Ò
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
77
views/map.tpl
Normal file
77
views/map.tpl
Normal file
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.map {
|
||||
width: 100%;
|
||||
height:800px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<!--Leaflet-->
|
||||
<link rel="stylesheet" href="/static/css/leaflet.css" />
|
||||
<script src="/static/js/leaflet.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
|
||||
var map = L.map('mapid').setView([43.55, 1.49], 11);
|
||||
var osmLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { // LIGNE 20
|
||||
attribution: '© OpenStreetMap contributors',
|
||||
maxZoom: 19
|
||||
});
|
||||
|
||||
map.addLayer(osmLayer);
|
||||
|
||||
var partners = new L.geoJson();
|
||||
partners.addTo(map);
|
||||
|
||||
$.ajax({
|
||||
dataType: "json",
|
||||
url: "/static/partners.json",
|
||||
success: function(data) {
|
||||
$(data.features).each(function(key, data) {
|
||||
partners.addData(data);
|
||||
});
|
||||
}
|
||||
}).fail(function() {console.log("Failed to load JSON")});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="center-align">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="10%" height="auto"/></a>
|
||||
</div>
|
||||
<div id="mapid" class="map">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
85
views/networks.tpl
Normal file
85
views/networks.tpl
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
;(function() {
|
||||
jQuery.expr[':'].containsNC = function(elem, index, match) {
|
||||
return (elem.textContent || elem.innerText || jQuery(elem).text() || '').toLowerCase().indexOf((match[3] || '').toLowerCase()) >= 0;
|
||||
}
|
||||
}(jQuery));
|
||||
|
||||
$('#filter').on('input',function(e)
|
||||
{
|
||||
if ($('#filter').val())
|
||||
{
|
||||
$('a')
|
||||
.find('span').not(':containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.hide();
|
||||
$('a')
|
||||
.find('span:containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.show();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="40%" height="auto"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection">
|
||||
{{range $key, $value := .list}}
|
||||
<div class="row collection-item">
|
||||
<a href="/details/{{$value.Id}}">
|
||||
<div class="col s1">
|
||||
<img src="{{$value.Logo}}" style="width: 50%; height: 50%"/>
|
||||
</div>
|
||||
<div class="col s10">
|
||||
<span class="title">{{$value.Name}}</span><br>
|
||||
<span class="small">{{$value.ShortDescription}} </span>
|
||||
<span class="small">[{{$value.Type}}]</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col s1">
|
||||
<a class="btn tooltipped gray" data-position="bottom" data-tooltip="Remove from Workspace" ><i class="material-icons">delete</i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
315
views/schedule.tpl
Normal file
315
views/schedule.tpl
Normal file
@@ -0,0 +1,315 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
#calendar {
|
||||
position: fixed;
|
||||
top: 15%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.popper, .tooltip {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
background: #FFC107;
|
||||
color: black;
|
||||
width: 250px;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 2px rgba(0,0,0,0.5);
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.style5 .tooltip {
|
||||
background: #1E252B;
|
||||
color: #FFFFFF;
|
||||
max-width: 200px;
|
||||
width: auto;
|
||||
font-size: .8rem;
|
||||
padding: .5em 1em;
|
||||
}
|
||||
.popper .popper__arrow,
|
||||
.tooltip .tooltip-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-arrow,
|
||||
.popper .popper__arrow {
|
||||
border-color: #FFC107;
|
||||
}
|
||||
.style5 .tooltip .tooltip-arrow {
|
||||
border-color: #1E252B;
|
||||
}
|
||||
.popper[x-placement^="top"],
|
||||
.tooltip[x-placement^="top"] {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.popper[x-placement^="top"] .popper__arrow,
|
||||
.tooltip[x-placement^="top"] .tooltip-arrow {
|
||||
border-width: 5px 5px 0 5px;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
bottom: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.popper[x-placement^="bottom"],
|
||||
.tooltip[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.tooltip[x-placement^="bottom"] .tooltip-arrow,
|
||||
.popper[x-placement^="bottom"] .popper__arrow {
|
||||
border-width: 0 5px 5px 5px;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
top: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.tooltip[x-placement^="right"],
|
||||
.popper[x-placement^="right"] {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.popper[x-placement^="right"] .popper__arrow,
|
||||
.tooltip[x-placement^="right"] .tooltip-arrow {
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-left-color: transparent;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
left: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.popper[x-placement^="left"],
|
||||
.tooltip[x-placement^="left"] {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.popper[x-placement^="left"] .popper__arrow,
|
||||
.tooltip[x-placement^="left"] .tooltip-arrow {
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-top-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
right: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<link href='/static/fullcalendar/main.css' rel='stylesheet' />
|
||||
<script type="text/javascript" src="/static/js/popper.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/tooltip.min.js"></script>
|
||||
<script src='/static/fullcalendar/main.js'></script>
|
||||
{{ template "swagger.tpl" . }}
|
||||
<script type = "text/javascript">
|
||||
|
||||
window.onload = initCalendar
|
||||
|
||||
function initCalendar() {
|
||||
|
||||
var data = [];
|
||||
var date = new Date().toISOString();
|
||||
|
||||
var d = new Date();
|
||||
var dateMore = d.setDate(d.getDate() + 35);
|
||||
dateMore = new Date(dateMore).toISOString()
|
||||
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.schedule
|
||||
.ScheduleController_Get_schedules({
|
||||
startDate: date,
|
||||
stopDate: dateMore
|
||||
})
|
||||
.then(response => {
|
||||
|
||||
response.body
|
||||
.forEach(elem => {
|
||||
data.push(elem)
|
||||
displayData = elem.Workflow.toString().split('.')
|
||||
})
|
||||
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
height: '85%',
|
||||
selectable: true,
|
||||
firstDay: 1,
|
||||
eventDidMount: function(info) {
|
||||
var tooltip = new Tooltip(info.el, {
|
||||
title: info.event.extendedProps.description,
|
||||
placement: 'top',
|
||||
trigger: 'hover',
|
||||
container: 'body'
|
||||
});
|
||||
},
|
||||
views: {
|
||||
dayGrid: {
|
||||
titleFormat: {
|
||||
month: 'long',
|
||||
year: 'numeric'
|
||||
}
|
||||
},
|
||||
timeGrid: {
|
||||
titleFormat: {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: 'numeric'
|
||||
},
|
||||
},
|
||||
},
|
||||
customButtons: {
|
||||
nextEvent: {
|
||||
text: 'Next Event',
|
||||
click: function () {
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.schedule
|
||||
.ScheduleController_Get_next_schedule({
|
||||
baseDate: date
|
||||
})
|
||||
.then(response => {
|
||||
if (response.body == null) {
|
||||
calendar.gotoDate(date)
|
||||
alert("No next schedules")
|
||||
} else {
|
||||
calendar.gotoDate(response.body)
|
||||
date = new Date(response.body)
|
||||
date.setDate(date.getDate() + 1)
|
||||
}
|
||||
})
|
||||
.catch((error) => {});
|
||||
});
|
||||
}
|
||||
},
|
||||
previousEvent: {
|
||||
text: 'Previous Event',
|
||||
click: function () {
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.schedule
|
||||
.ScheduleController_Get_previous_schedule({
|
||||
baseDate: date
|
||||
})
|
||||
.then(response => {
|
||||
if (response.body == null) {
|
||||
calendar.gotoDate(date)
|
||||
alert("No previous schedules")
|
||||
} else {
|
||||
calendar.gotoDate(response.body)
|
||||
date = new Date(response.body)
|
||||
date.setDate(date.getDate() - 1)
|
||||
}
|
||||
})
|
||||
.catch((error) => {});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
headerToolbar: {
|
||||
left: ',previousEvent, ,prev, ,today, ,next, ,nextEvent,',
|
||||
center: 'title',
|
||||
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
|
||||
},
|
||||
initialView: 'dayGridMonth',
|
||||
})
|
||||
var eventTitle;
|
||||
var eventStart;
|
||||
var eventEnd;
|
||||
|
||||
data.forEach(elem => {
|
||||
eventTitle = elem.Workflow.split(".")[2]
|
||||
eventStart = elem.StartDate
|
||||
eventEnd = elem.StopDate
|
||||
var cpus = elem.ResourceQty.cpus;
|
||||
var gpus = elem.ResourceQty.gpus;
|
||||
var ram = elem.ResourceQty.ram;
|
||||
calendar.addEvent({
|
||||
title: eventTitle,
|
||||
description:
|
||||
'cpus: ' + cpus + ' | ' +
|
||||
'gpus: ' + gpus + ' | ' +
|
||||
'ram: ' + ram ,
|
||||
start: eventStart,
|
||||
end: eventEnd,
|
||||
backgroundColor: stringToColour(eventTitle),
|
||||
borderColor: stringToColour(eventTitle),
|
||||
textColor: '',
|
||||
});
|
||||
});
|
||||
calendar.render();
|
||||
})
|
||||
.catch((error) => {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
initialView: 'dayGridMonth'
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Determine color of eventTitle
|
||||
var stringToColour = function (str) {
|
||||
var hash = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
var colour = '#';
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var value = (hash >> (i * 8)) & 0xFF;
|
||||
colour += ('00' + value.toString(16)).substr(-2);
|
||||
}
|
||||
return colour;
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="40%" height="auto"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div id='calendar'></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
152
views/search.tpl
Normal file
152
views/search.tpl
Normal file
@@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
;(function() {
|
||||
jQuery.expr[':'].containsNC = function(elem, index, match) {
|
||||
return (elem.textContent || elem.innerText || jQuery(elem).text() || '').toLowerCase().indexOf((match[3] || '').toLowerCase()) >= 0;
|
||||
}
|
||||
}(jQuery));
|
||||
|
||||
$('#filter').on('input',function(e)
|
||||
{
|
||||
if ($('#filter').val())
|
||||
{
|
||||
$('a')
|
||||
.find('span').not(':containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.hide();
|
||||
$('a')
|
||||
.find('span:containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.show();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="40%" height="auto"/></a>
|
||||
</div>
|
||||
<div class="input-field col s8 offset-s0">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search" type="text">
|
||||
<label for="search">Search</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="parentResults" class="collection">
|
||||
{{range $key, $value := .list | searchResourceToList}}
|
||||
<div class="row collection-item">
|
||||
<a href="/details/{{$value | getRtype}}/{{$value | getID}}">
|
||||
<div class="col s1">
|
||||
<img src="data:image/png;base64,{{$value | getLogo}}" style="width: 50%; height: 50%"/>
|
||||
</div>
|
||||
<div class="col s10">
|
||||
<span rtype="{{$value | getRtype}}" rid="{{$value | getID}}" class="title">{{$value | getName}}</span><br>
|
||||
<span class="small">{{$value | getShortDescription}} </span>
|
||||
<span class="small">[{{$value | getType}}]</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col s1">
|
||||
<a id="addButton" onclick="submitWorkspace()" class="btn tooltipped gray waves-effect waves-light" data-position="bottom" data-tooltip="Add to Workspace" ><i class="material-icons">shopping_cart</i></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
{{ template "swagger.tpl" . }}
|
||||
|
||||
<script>
|
||||
|
||||
window.onload = setInitialStatus;
|
||||
|
||||
function setInitialStatus() {
|
||||
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workspace
|
||||
.WorkspaceController_Get_workspace()
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
Array.from(document.getElementById("parentResults").children).forEach((item) => {
|
||||
elem = item.querySelector("*[rid]")
|
||||
rid = elem.getAttribute("rid")
|
||||
rtype = elem.getAttribute("rtype")
|
||||
|
||||
if ( response.body[rtype].includes(rid)) {
|
||||
item.querySelector("*[id=addButton]").setAttribute("disabled", true);
|
||||
} else {
|
||||
item.querySelector("*[id=addButton]").removeAttribute("disabled");
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("ERROR: " + error)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function submitWorkspace() {
|
||||
var shopButton = event.target
|
||||
var elem = shopButton.closest(".collection-item").querySelector("*[rid]")
|
||||
var rid = elem.getAttribute("rid")
|
||||
var rtype = elem.getAttribute("rtype")
|
||||
//console.log(elem)
|
||||
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workspace
|
||||
.WorkspaceController_Add_model_to_workspace({id: rid, rtype: rtype})
|
||||
.then(response => {
|
||||
shopButton.parentNode.setAttribute("disabled", true);
|
||||
shopButton.setAttribute("disabled", true);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("ERROR: " + error)
|
||||
M.toast({html: 'already use!'});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
46
views/swagger.tpl
Normal file
46
views/swagger.tpl
Normal file
@@ -0,0 +1,46 @@
|
||||
<script src="/static/js/swagger-client.browser.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
const swg_proto = "http://"
|
||||
const swg_port = "49618"
|
||||
const swg_suffix = "/swagger/swagger.json"
|
||||
|
||||
var specUrl = swg_proto + window.location.hostname + ":" + swg_port + swg_suffix
|
||||
|
||||
/**
|
||||
switch (window.location.hostname) {
|
||||
case 'localhost':
|
||||
case '127.0.0.1':
|
||||
var specUrl = 'http://localhost:49618/swagger/swagger.json';
|
||||
break;
|
||||
|
||||
default:
|
||||
var specUrl = 'https://' + window.location.hostname + ':8443/swagger.json';
|
||||
break;
|
||||
}
|
||||
**/
|
||||
|
||||
var oc_catalog_api = new SwaggerClient(specUrl)
|
||||
.then(client => {
|
||||
return client;
|
||||
})
|
||||
.catch(err => {
|
||||
alert("NO API AVAILABLE (" + specUrl + ") :" + err) // we will see what to do with it later
|
||||
});
|
||||
|
||||
|
||||
function WorkspaceAddElement(rid, rtype, callback) {
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workspace
|
||||
.WorkspaceController_Add_model_to_workspace({id: rid, rtype: rtype})
|
||||
.then(callback)
|
||||
.catch((error) => {
|
||||
console.log("ERROR: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
154
views/templating.go
Normal file
154
views/templating.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package views
|
||||
|
||||
import (
|
||||
OCCatalog_cli "oc-search/api-client/oc-catalog"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
func init() {
|
||||
beego.AddFuncMap("getID", getID)
|
||||
beego.AddFuncMap("getShortDescription", getShortDescription)
|
||||
beego.AddFuncMap("getName", getName)
|
||||
beego.AddFuncMap("getType", getType)
|
||||
beego.AddFuncMap("getLogo", getLogo)
|
||||
beego.AddFuncMap("getRtype", getRtype)
|
||||
beego.AddFuncMap("searchResourceToList", searchResourceToList)
|
||||
}
|
||||
|
||||
func getRtype(in interface{}) (out string) {
|
||||
switch in.(type) {
|
||||
case OCCatalog_cli.ModelsDataModel:
|
||||
out = "data"
|
||||
case OCCatalog_cli.ModelsComputingModel:
|
||||
out = "computing"
|
||||
case OCCatalog_cli.ModelsDatacenterModel:
|
||||
out = "datacenter"
|
||||
case OCCatalog_cli.ModelsStorageModel:
|
||||
out = "storage"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getID(in interface{}) (out string) {
|
||||
switch in.(type) {
|
||||
case OCCatalog_cli.ModelsDataModel:
|
||||
out = in.(OCCatalog_cli.ModelsDataModel).ID
|
||||
case OCCatalog_cli.ModelsComputingModel:
|
||||
out = in.(OCCatalog_cli.ModelsComputingModel).ID
|
||||
case OCCatalog_cli.ModelsDatacenterModel:
|
||||
out = in.(OCCatalog_cli.ModelsDatacenterModel).ID
|
||||
case OCCatalog_cli.ModelsStorageModel:
|
||||
out = in.(OCCatalog_cli.ModelsStorageModel).ID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getLogo(in interface{}) (out string) {
|
||||
switch in.(type) {
|
||||
case OCCatalog_cli.ModelsDataModel:
|
||||
out = in.(OCCatalog_cli.ModelsDataModel).Logo
|
||||
case OCCatalog_cli.ModelsComputingModel:
|
||||
out = in.(OCCatalog_cli.ModelsComputingModel).Logo
|
||||
case OCCatalog_cli.ModelsDatacenterModel:
|
||||
out = in.(OCCatalog_cli.ModelsDatacenterModel).Logo
|
||||
case OCCatalog_cli.ModelsStorageModel:
|
||||
out = in.(OCCatalog_cli.ModelsStorageModel).Logo
|
||||
default:
|
||||
logs.Warn("Unable to parse Logo")
|
||||
}
|
||||
|
||||
//TODO: Find a hybrid aproach for images as src and base64
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getName(in interface{}) (out string) {
|
||||
switch in.(type) {
|
||||
case OCCatalog_cli.ModelsDataModel:
|
||||
out = in.(OCCatalog_cli.ModelsDataModel).Name
|
||||
case OCCatalog_cli.ModelsComputingModel:
|
||||
out = in.(OCCatalog_cli.ModelsComputingModel).Name
|
||||
case OCCatalog_cli.ModelsDatacenterModel:
|
||||
out = in.(OCCatalog_cli.ModelsDatacenterModel).Name
|
||||
case OCCatalog_cli.ModelsStorageModel:
|
||||
out = in.(OCCatalog_cli.ModelsStorageModel).Name
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getShortDescription(in interface{}) (out string) {
|
||||
switch in.(type) {
|
||||
case OCCatalog_cli.ModelsDataModel:
|
||||
out = in.(OCCatalog_cli.ModelsDataModel).ShortDescription
|
||||
case OCCatalog_cli.ModelsComputingModel:
|
||||
out = in.(OCCatalog_cli.ModelsComputingModel).ShortDescription
|
||||
case OCCatalog_cli.ModelsDatacenterModel:
|
||||
out = in.(OCCatalog_cli.ModelsDatacenterModel).ShortDescription
|
||||
case OCCatalog_cli.ModelsStorageModel:
|
||||
out = in.(OCCatalog_cli.ModelsStorageModel).ShortDescription
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func searchResourceToList(in interface{}) (out []interface{}) {
|
||||
out = []interface{}{}
|
||||
|
||||
obj := in.(OCCatalog_cli.ModelsSearchResult)
|
||||
|
||||
// Data
|
||||
if len(obj.Data) > 0 {
|
||||
ArrInterface := make([]interface{}, len(obj.Data))
|
||||
for i := range obj.Data {
|
||||
ArrInterface[i] = obj.Data[i]
|
||||
}
|
||||
out = append(out, ArrInterface...)
|
||||
}
|
||||
|
||||
// Computing
|
||||
if len(obj.Computing) > 0 {
|
||||
ArrInterface := make([]interface{}, len(obj.Computing))
|
||||
for i := range obj.Computing {
|
||||
ArrInterface[i] = obj.Computing[i]
|
||||
}
|
||||
out = append(out, ArrInterface...)
|
||||
}
|
||||
|
||||
// Storage
|
||||
if len(obj.Storage) > 0 {
|
||||
ArrInterface := make([]interface{}, len(obj.Storage))
|
||||
for i := range obj.Storage {
|
||||
ArrInterface[i] = obj.Storage[i]
|
||||
}
|
||||
out = append(out, ArrInterface...)
|
||||
}
|
||||
|
||||
// Datacenter
|
||||
if len(obj.Datacenter) > 0 {
|
||||
ArrInterface := make([]interface{}, len(obj.Datacenter))
|
||||
for i := range obj.Datacenter {
|
||||
ArrInterface[i] = obj.Datacenter[i]
|
||||
}
|
||||
out = append(out, ArrInterface...)
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func getType(in interface{}) (out string) {
|
||||
//FIXME: We should use types
|
||||
switch in.(type) {
|
||||
case OCCatalog_cli.ModelsDataModel:
|
||||
out = "data"
|
||||
case OCCatalog_cli.ModelsComputingModel:
|
||||
out = "computing"
|
||||
case OCCatalog_cli.ModelsDatacenterModel:
|
||||
out = "datacenter"
|
||||
case OCCatalog_cli.ModelsStorageModel:
|
||||
out = "storage"
|
||||
}
|
||||
return
|
||||
}
|
||||
40
views/user.tpl
Normal file
40
views/user.tpl
Normal file
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Machines list</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="10%" height="auto"/></a>
|
||||
<br/>
|
||||
{{.login}}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
290
views/workflow.tpl
Normal file
290
views/workflow.tpl
Normal file
@@ -0,0 +1,290 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>workflow editor</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/mxgraph/examples/grapheditor/www/styles/grapheditor.css">
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
// Parses URL parameters. Supported parameters are:
|
||||
// - lang=xy: Specifies the language of the user interface.
|
||||
// - touch=1: Enables a touch-style user interface.
|
||||
// - storage=local: Enables HTML5 local storage.
|
||||
// - chrome=0: Chromeless mode.
|
||||
var urlParams = (function (url) {
|
||||
var result = new Object();
|
||||
var idx = url.lastIndexOf('?');
|
||||
|
||||
if (idx > 0) {
|
||||
var params = url.substring(idx + 1).split('&');
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
idx = params[i].indexOf('=');
|
||||
|
||||
if (idx > 0) {
|
||||
result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
})(window.location.href);
|
||||
mxBasePath = '/static/mxgraph/src';
|
||||
// Default resources are included in grapheditor resources
|
||||
mxLoadResources = false;
|
||||
</script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Init.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/deflate/pako.min.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/deflate/base64.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/jscolor/jscolor.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/sanitizer/sanitizer.min.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/src/js/mxClient.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/EditorUi.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Editor.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Sidebar.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Graph.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Format.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Shapes.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Actions.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Menus.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Toolbar.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Dialogs.js"></script>
|
||||
<script type="text/javascript" src="/static/mxgraph/examples/grapheditor/www/js/Swagger.js"></script>
|
||||
|
||||
{{ template "swagger.tpl" . }}
|
||||
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="/static/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<style>
|
||||
.refresh {
|
||||
margin-right: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.load {
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="geEditor">
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="center-align">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="20%" height="auto" /></a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="geEditor">
|
||||
<script type="text/javascript">
|
||||
var MX_EDITORUI
|
||||
var OC_WORKSPACE
|
||||
var cursorX;
|
||||
var cursorY;
|
||||
document.onmousemove = function(e){
|
||||
cursorX = e.pageX;
|
||||
cursorY = e.pageY;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Extends EditorUi to update I/O action states based on availability of backend
|
||||
function LoadWorkloadWindow(ProjectName, XMLdata) {
|
||||
|
||||
OC_CATALOG_API = oc_catalog_api
|
||||
OC_PROJECT_NAME = ProjectName
|
||||
|
||||
Editor.useLocalStorage = false;
|
||||
var editorUiInit = EditorUi.prototype.init;
|
||||
|
||||
EditorUi.prototype.init = function () {
|
||||
editorUiInit.apply(this, arguments);
|
||||
this.actions.get('export').setEnabled(false);
|
||||
|
||||
// Updates action states which require a backend
|
||||
if (!Editor.useLocalStorage) {
|
||||
mxUtils.post(OPEN_URL, '', mxUtils.bind(this, function (req) {
|
||||
var enabled = req.getStatus() != 404;
|
||||
this.actions.get('open').setEnabled(enabled || Graph.fileSupport);
|
||||
this.actions.get('import').setEnabled(enabled || Graph.fileSupport);
|
||||
this.actions.get('save').setEnabled(enabled);
|
||||
this.actions.get('saveAs').setEnabled(enabled);
|
||||
this.actions.get('export').setEnabled(enabled);
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
// Adds required resources (disables loading of fallback properties, this can only
|
||||
// be used if we know that all keys are defined in the language specific file)
|
||||
mxResources.loadDefaultBundle = false;
|
||||
var bundle = mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) ||
|
||||
mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage);
|
||||
|
||||
// Fixes possible asynchronous requests
|
||||
mxUtils.getAll([bundle, STYLE_PATH + '/default.xml'], function (xhr) {
|
||||
// Adds bundle text to resources
|
||||
mxResources.parse(xhr[0].getText());
|
||||
|
||||
// Configures the default graph theme
|
||||
var themes = new Object();
|
||||
themes[Graph.prototype.defaultThemeName] = xhr[1].getDocumentElement();
|
||||
|
||||
// Main
|
||||
MX_EDITORUI = new EditorUi(new Editor(urlParams['chrome'] == '0', themes));
|
||||
if (XMLdata != null) {
|
||||
MX_EDITORUI.editor.setGraphXml(mxUtils.parseXml(XMLdata).documentElement);
|
||||
}
|
||||
}, function () {
|
||||
document.body.innerHTML = '<center style="margin-top:10%;">Error loading resource files. Please check browser console.</center>';
|
||||
});
|
||||
};
|
||||
$(document).ready(function () {
|
||||
refreshProjects()
|
||||
// LoadSavedData('test_project')
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({ direction: 'bottom' });
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
<select class="form-select col m4 offset-m4" id="inlineFormSelectPref">
|
||||
<!-- <option selected>Choose...</option> -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="btns center-align">
|
||||
<span type="button" onclick="refreshProjects()" class="refresh btn btn-secondary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
||||
class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd"
|
||||
d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
||||
<path
|
||||
d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span id="loadButton" type="submit" onclick="LoadSelectedProject()" class="load btn btn-primary disabled">Load</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>
|
||||
<input class="col m4 offset-m4" id="new_workflow_name" type="text" placeholder="New Workflow Name">
|
||||
</div>
|
||||
<div class="center-align">
|
||||
<button type="button" class="btn btn-success" onclick="CreateNewWorkflow()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
||||
class="bi bi-plus" viewBox="0 0 16 16">
|
||||
<path
|
||||
d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
function LoadSavedData(PrjName) {
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workflow
|
||||
.WorkflowController_Get_mxGraph_last_status({
|
||||
workflowName: PrjName
|
||||
})
|
||||
.then(response => {
|
||||
console.log(response)
|
||||
LoadWorkloadWindow(PrjName, response.body)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("Workflow get XML error: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function CreateNewWorkflow() {
|
||||
//debugger
|
||||
var select = document.getElementById("new_workflow_name");
|
||||
var NewProjectName = select.value;
|
||||
if (!!NewProjectName) {
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workflow
|
||||
.WorkflowController_Create_a_new_workflow({
|
||||
workflowName: NewProjectName
|
||||
})
|
||||
.then(response => {
|
||||
// console.log(response)
|
||||
refreshProjects(NewProjectName)
|
||||
select.value = "";
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("Workflow create projects error: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function LoadSelectedProject() {
|
||||
var select = document.getElementById("inlineFormSelectPref");
|
||||
var projectName = select.value;
|
||||
if (!!projectName) {
|
||||
LoadSavedData(projectName)
|
||||
}
|
||||
}
|
||||
|
||||
function populateProjectOptions(arrayProjectNames, focusValue) {
|
||||
var select = document.getElementById("inlineFormSelectPref");
|
||||
select.innerHTML = '' // clear previous options
|
||||
|
||||
arrayProjectNames.forEach(elem => {
|
||||
var option = document.createElement("option");
|
||||
if (elem == focusValue) {
|
||||
option.selected="selected"
|
||||
}
|
||||
|
||||
option.value = elem
|
||||
option.text = elem
|
||||
select.appendChild(option)
|
||||
})
|
||||
|
||||
if (arrayProjectNames !== null && arrayProjectNames.length > 0) {
|
||||
document.getElementById("loadButton").classList.remove("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
function refreshProjects(focusValue) {
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workflow
|
||||
.WorkflowController_List_workflows()
|
||||
.then(response => {
|
||||
// console.log(response)
|
||||
populateProjectOptions(response.body, focusValue)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("Workflow list projects error: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
114
views/workspace.tpl
Normal file
114
views/workspace.tpl
Normal file
@@ -0,0 +1,114 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>o-search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!--Import Google Icon Font-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/material-icons.css">
|
||||
<!--Import materialize.css-->
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/materialize.min.css" media="screen,projection" />
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
.small {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
$('.tooltipped').tooltip();
|
||||
$('.fixed-action-btn').floatingActionButton({direction: 'bottom'});
|
||||
;(function() {
|
||||
jQuery.expr[':'].containsNC = function(elem, index, match) {
|
||||
return (elem.textContent || elem.innerText || jQuery(elem).text() || '').toLowerCase().indexOf((match[3] || '').toLowerCase()) >= 0;
|
||||
}
|
||||
}(jQuery));
|
||||
|
||||
$('#filter').on('input',function(e)
|
||||
{
|
||||
if ($('#filter').val())
|
||||
{
|
||||
$('a')
|
||||
.find('span').not(':containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.hide();
|
||||
$('a')
|
||||
.find('span:containsNC('+$('#filter').val()+')')
|
||||
.parent()
|
||||
//.css('outline', '3px solid red');
|
||||
.show();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "floating_menu.tpl" . }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
<a href="/"><img src="/static/img/O-cloud.svg" width="40%" height="auto"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<h4>Workspace</h4>
|
||||
</div>
|
||||
<div class="collection">
|
||||
{{range $key, $value := .list}}
|
||||
<div class="row collection-item">
|
||||
<a href="/details/{{$value | getRtype}}/{{$value | getID}}">
|
||||
<div class="col s1">
|
||||
<img src="data:image/png;base64,{{$value | getLogo}}" style="width: 50%; height: 50%"/>
|
||||
</div>
|
||||
<div class="col s10">
|
||||
<span rtype="{{$value | getRtype}}" rid="{{$value | getID}}" class="title">{{$value | getName}}</span><br>
|
||||
<span class="small">{{$value | getShortDescription}} </span>
|
||||
<span class="small">[{{$value | getType}}]</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col s1">
|
||||
<a id="removeButton" onclick="removeWorkspace()" class="btn tooltipped red" data-position="bottom" data-tooltip="Remove from Workspace" ><i class="material-icons">delete</i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/materialize.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
{{ template "swagger.tpl" . }}
|
||||
|
||||
<script>
|
||||
function removeWorkspace() {
|
||||
var item = event.srcElement.closest(".collection-item")
|
||||
var elem = item.querySelector("*[rid]")
|
||||
var rid = elem.getAttribute("rid")
|
||||
var rtype = elem.getAttribute("rtype")
|
||||
//console.log(elem)
|
||||
|
||||
|
||||
oc_catalog_api.then(client => {
|
||||
client.apis
|
||||
.workspace
|
||||
.WorkspaceController_Delete_element_from_user_workspace({id: rid, rtype: rtype})
|
||||
.then(response => {
|
||||
item.remove()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("ERROR: " + error)
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user