All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit e2d24242 authored by Leigh B Stoller's avatar Leigh B Stoller

Add user/project dashboard pages. The red-dot view adds an admin section

that has nothing in it (yet), and a link to the Emulab page until we have
something in the admin section.
parent a2a114a7
<?php
#
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
function ExperimentList($which, $target)
{
global $urn_mapping, $TBBASE;
global $this_user;
if ($which == "user") {
$target_uuid = $target->uuid();
$whereclause = "where a.creator_uuid='$target_uuid'";
}
else {
$target_pid = $target->pid();
$whereclause = "where a.pid='$target_pid'";
}
$results = array();
$query_result =
DBQueryFatal("select a.*,s.expires,s.hrn,u.email, ".
" (UNIX_TIMESTAMP(now()) > ".
" UNIX_TIMESTAMP(s.expires)) as expired, ".
" truncate(a.physnode_count * ".
" ((UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours, ".
" IFNULL(aggs.count,0) as aggrows, ".
" agg.aggregate_urn as aggrow_urn".
" from apt_instances as a ".
"left join (".
" select uuid, COUNT(*) AS count ".
" from apt_instance_aggregates group by uuid) AS aggs ".
" on aggs.uuid=a.uuid ".
"left join apt_instance_aggregates as agg ".
" on agg.uuid=a.uuid ".
"left join geni.geni_slices as s on ".
" s.uuid=a.slice_uuid ".
"left join geni.geni_users as u on u.uuid=a.creator_uuid ".
"$whereclause");
while ($row = mysql_fetch_array($query_result)) {
$profile_id = $row["profile_id"];
$version = $row["profile_version"];
$uuid = $row["uuid"];
$name = $row["name"];
$status = $row["status"];
$canceled = $row["canceled"];
$created = DateStringGMT($row["created"]);
$expires = DateStringGMT($row["expires"]);
$creator_idx = $row["creator_idx"];
$profile_name = "$profile_id:$version";
$creator_uid = $row["creator"];
$pid = $row["pid"];
$pcount = $row["physnode_count"];
$vcount = $row["virtnode_count"];
$lockdown = $row["admin_lockdown"] || $row["user_lockdown"] ? 1 : 0;
$phours = $row["phours"];
$email = $row["email"];
$blob = array();
# If a guest user, use email instead.
if (isset($email)) {
$blob["creator"] = $email;
}
elseif (ISADMIN() || $which == "project") {
$blob["creator"] =
"<a href='user-dashboard.php?user=$creator_uid'>".
"$creator_uid</a>";
}
else {
$blob["creator"] = $creator_uid;
}
if ($row["expired"]) {
$status = "expired";
}
elseif ($canceled) {
$status = "canceled";
}
$blob["status"] = $status;
$profile = Profile::Lookup($profile_id, $version);
if ($profile) {
$blob["profile_name"] = $profile->name();
$blob["profile_uuid"] = $profile->uuid();
}
else {
$blob["profile_name"] = $profile_name;
}
#
# If arows non-zero, then we use that for aggregate_urn,
# and if its more then 1, we need to consume the extras rows
# to get the rest of the aggregate urns.
#
if ($row["aggrows"] > 0) {
$cluster = $urn_mapping[$row["aggrow_urn"]];
for ($i = 1; $i < $row["aggrows"]; $i++) {
$row = mysql_fetch_array($result);
$cluster .= "," . $urn_mapping[$row["aggrow_urn"]];
}
}
else {
$cluster = $urn_mapping[$row["aggregate_urn"]];
}
$blob["cluster"] = $cluster;
if (ISADMIN() || ISFOREIGN_ADMIN() || $which == "project") {
$blob["name"] = "<a href='status.php?uuid=$uuid'>$name</a>";
}
else {
$blob["name"] = $name;
}
if (ISADMIN() || $which == "user") {
$blob["project"] = "<a href='show-project.php?project=$pid'>".
"$pid</a>";
}
else {
$blob["project"] = $pid;
}
$blob["pcount"] = $pcount;
$blob["phours"] = $phours;
$blob["vcount"] = $vcount;
$blob["created"] = $created;
$blob["expires"] = $expires;
$blob["lockdown"] = $lockdown;
$results["$pid:$name"] = $blob;
}
return $results;
}
function ProfileList($which, $target)
{
global $urn_mapping, $TBBASE;
global $this_user;
if ($which == "user") {
$target_idx = $target->uid_idx();
$whereclause = "where v.creator_idx='$target_idx'";
}
else {
$target_idx = $target->pid_idx();
$whereclause = "where v.pid_idx='$target_idx'";
}
$results = array();
$query_result =
DBQueryFatal("select p.*,v.*,DATE(v.created) as created ".
" from apt_profiles as p ".
"left join apt_profile_versions as v on ".
" v.profileid=p.profileid and ".
" v.version=p.version ".
"$whereclause");
while ($row = mysql_fetch_array($query_result)) {
$idx = $row["profileid"];
$uuid = $row["uuid"];
$version = $row["version"];
$name = $row["name"];
$pid = $row["pid"];
$desc = $row["description"];
$created = DateStringGMT($row["created"]);
$public = $row["public"];
$listed = $row["listed"];
$creator = $row["creator"];
$rspec = $row["rspec"];
$privacy = ($public ? "Public" : "Project");
$desc = "";
$parsed_xml = simplexml_load_string($rspec);
if ($parsed_xml &&
$parsed_xml->rspec_tour && $parsed_xml->rspec_tour->description) {
$desc = $parsed_xml->rspec_tour->description;
# Convert to array to get the one element.
$desc = (array)$desc;
$desc = $desc[0];
}
$blob = array();
$blob["profile_name"] = $name;
$blob["profile_uuid"] = $uuid;
$blob["privacy"] = $privacy;
$blob["description"] = $desc;
$blob["created"] = $created;
$blob["listed"] = ($listed ? "Yes" : "No");
$blob["created"] = $created;
$blob["project"] = $pid;
$blob["creator"] = $creator;
if (ISADMIN() ||
($which == "user" && $creator == $target->uid()) ||
($which == "project" && $creator == $this_user->uid())) {
$blob["link"] =
"<a href='manage_profile.php?action=edit&uuid=$uuid'>$name</a>";
}
else {
$blob["link"] =
"<a href='show-profile.php?uuid=$uuid'>$name</a>";
}
$results["$pid:$name"] = $blob;
}
return $results;
}
# Local Variables:
# mode:php
# End:
?>
require(window.APT_OPTIONS.configObject,
['underscore', 'js/quickvm_sup', 'moment',
'js/lib/text!template/show-project.html',
'js/lib/text!template/experiment-list.html',
'js/lib/text!template/profile-list.html',
'js/lib/text!template/member-list.html',
],
function (_, sup, moment, mainString,
experimentString, profileString, memberString)
{
'use strict';
var mainTemplate = _.template(mainString);
function initialize()
{
window.APT_OPTIONS.initialize(sup);
// Generate the main template.
var html = mainTemplate({
emulablink : window.EMULAB_LINK,
isadmin : window.ISADMIN,
target_project : window.TARGET_PROJECT,
});
$('#main-body').html(html);
LoadExperimentTab();
LoadProfileTab();
LoadMembersTab();
}
function LoadExperimentTab()
{
var callback = function(json) {
console.info(json);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
$('#experiments_loading').addClass("hidden");
$('#experiments_noexperiments').removeClass("hidden");
return;
}
var template = _.template(experimentString);
$('#experiments_content')
.html(template({"experiments" : json.value,
"showCreator" : true,
"showProject" : false}));
// Format dates with moment before display.
$('#experiments_table .format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html()).format("ll"));
}
});
var table = $('#experiments_table')
.tablesorter({
theme : 'green',
});
}
var xmlthing = sup.CallServerMethod(null,
"show-project", "ExperimentList",
{"pid" : window.TARGET_PROJECT});
xmlthing.done(callback);
}
function LoadProfileTab()
{
var callback = function(json) {
console.info(json);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
$('#profiles_noprofiles').removeClass("hidden");
return;
}
var template = _.template(profileString);
$('#profiles_content')
.html(template({"profiles" : json.value,
"showCreator" : true,
"showProject" : false}));
// Format dates with moment before display.
$('#profiles_table .format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html()).format("ll"));
}
});
// Display the topo.
$('.showtopo_modal_button').click(function (event) {
event.preventDefault();
ShowTopology($(this).data("profile"));
});
var table = $('#profiles_table')
.tablesorter({
theme : 'green',
});
}
var xmlthing = sup.CallServerMethod(null,
"show-project", "ProfileList",
{"pid" : window.TARGET_PROJECT});
xmlthing.done(callback);
}
function ShowTopology(profile)
{
var profile;
var index;
var callback = function(json) {
if (json.code) {
alert("Failed to get rspec for topology viewer: " + json.value);
return;
}
sup.ShowModal("#quickvm_topomodal");
$("#quickvm_topomodal").one("shown.bs.modal", function () {
sup.maketopmap('#showtopo_nopicker',
json.value.rspec, false, !window.ISADMIN);
});
};
var $xmlthing = sup.CallServerMethod(null,
"myprofiles",
"GetProfile",
{"uuid" : profile});
$xmlthing.done(callback);
}
function LoadMembersTab()
{
var callback = function(json) {
console.info(json);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
return;
}
var template = _.template(memberString);
$('#members_content')
.html(template({"members" : json.value}));
// Format dates with moment before display.
$('#members_table .format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html()).format("ll"));
}
});
var table = $('#members_table')
.tablesorter({
theme : 'green',
});
}
var xmlthing = sup.CallServerMethod(null,
"show-project", "MemberList",
{"pid" : window.TARGET_PROJECT});
xmlthing.done(callback);
}
$(document).ready(initialize);
});
require(window.APT_OPTIONS.configObject,
['underscore', 'js/quickvm_sup', 'moment',
'js/lib/text!template/user-dashboard.html',
'js/lib/text!template/experiment-list.html',
'js/lib/text!template/profile-list.html',
'js/lib/text!template/project-list.html',
'js/lib/text!template/myaccount-table.html',
],
function (_, sup, moment, mainString,
experimentString, profileString, projectString, myaccountString)
{
'use strict';
var mainTemplate = _.template(mainString);
function initialize()
{
window.APT_OPTIONS.initialize(sup);
// Generate the main template.
var html = mainTemplate({
emulablink : window.EMULAB_LINK,
isadmin : window.ISADMIN,
target_user : window.TARGET_USER,
});
$('#main-body').html(html);
LoadExperimentTab();
// Should we do these on demand?
LoadProfileTab();
LoadProjectsTab();
LoadMyProfileTab();
}
function LoadExperimentTab()
{
var callback = function(json) {
console.info(json);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
$('#experiments_loading').addClass("hidden");
$('#experiments_noexperiments').removeClass("hidden");
return;
}
var template = _.template(experimentString);
$('#experiments_content')
.html(template({"experiments" : json.value,
"showCreator" : false,
"showProject" : true}));
// Format dates with moment before display.
$('#experiments_table .format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html()).format("ll"));
}
});
var table = $('#experiments_table')
.tablesorter({
theme : 'green',
});
}
var xmlthing = sup.CallServerMethod(null,
"user-dashboard", "ExperimentList",
{"uid" : window.TARGET_USER});
xmlthing.done(callback);
}
function LoadProfileTab()
{
var callback = function(json) {
console.info(json);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
$('#profiles_noprofiles').removeClass("hidden");
return;
}
var template = _.template(profileString);
$('#profiles_content')
.html(template({"profiles" : json.value,
"showCreator" : false,
"showProject" : true}));
// Format dates with moment before display.
$('#profiles_table .format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html()).format("ll"));
}
});
// Display the topo.
$('.showtopo_modal_button').click(function (event) {
event.preventDefault();
ShowTopology($(this).data("profile"));
});
var table = $('#profiles_table')
.tablesorter({
theme : 'green',
});
}
var xmlthing = sup.CallServerMethod(null,
"user-dashboard", "ProfileList",
{"uid" : window.TARGET_USER});
xmlthing.done(callback);
}
function ShowTopology(profile)
{
var profile;
var index;
var callback = function(json) {
if (json.code) {
alert("Failed to get rspec for topology viewer: " + json.value);
return;
}
sup.ShowModal("#quickvm_topomodal");
$("#quickvm_topomodal").one("shown.bs.modal", function () {
sup.maketopmap('#showtopo_nopicker',
json.value.rspec, false, !window.ISADMIN);
});
};
var $xmlthing = sup.CallServerMethod(null,
"myprofiles",
"GetProfile",
{"uuid" : profile});
$xmlthing.done(callback);
}
function LoadProjectsTab()
{
var callback = function(json) {
console.info(json);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
return;
}
var template = _.template(projectString);
$('#membership_content')
.html(template({"projects" : json.value}));
var table = $('#projects_table')
.tablesorter({
theme : 'green',
});
}
var xmlthing = sup.CallServerMethod(null,
"user-dashboard", "ProjectList",
{"uid" : window.TARGET_USER});
xmlthing.done(callback);
}
function LoadMyProfileTab()
{
var callback = function(json) {
console.info(json.value);
if (json.code) {
console.info(json.value);
return;
}
if (json.value.length == 0) {
return;
}
var template = _.template(myaccountString);
$('#myprofile_content')
.html(template({"fields" : json.value}));
}
var xmlthing = sup.CallServerMethod(null,
"user-dashboard", "AccountDetails",
{"uid" : window.TARGET_USER});
xmlthing.done(callback);
}
$(document).ready(initialize);
});
<?php
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -198,7 +198,7 @@ function SPITROWS($showall, $name, $result)
$creator = $email;
}
elseif (ISADMIN()) {
$creator = "<a href='$TBBASE/showuser.php3?user=$creator_idx'>".
$creator = "<a href='user-dashboard.php?user=$creator_uid'>".
"$creator_uid</a>";
}
else {
......@@ -259,7 +259,7 @@ function SPITROWS($showall, $name, $result)
echo "<td>$creator</td>";
}
if (ISADMIN()) {
echo " <td><a href='$TBBASE/showproject.php3?pid=$pid'>".
echo " <td><a href='show-project.php?pid=$pid'>".
"$pid</a></td>";
}
else {
......
......@@ -168,8 +168,30 @@ $routing = array("myprofiles" =>
array("file" => "myaccount.ajax",
"guest" => false,
"methods" => array("update" =>
"Do_Update")),
);
"Do_Update")),