Compare commits
12 Commits
148c9cd0db
...
f1b59439eb
Author | SHA1 | Date | |
---|---|---|---|
f1b59439eb | |||
555a2e8969 | |||
88b8cf319c | |||
19e234d02f | |||
d447511557 | |||
a82a658922 | |||
166295e046 | |||
ced38b68e9 | |||
bd9a85a068 | |||
ac999c9704 | |||
5eb587aba5 | |||
99e0e497c2 |
@ -1,4 +1,4 @@
|
|||||||
Full disclosure: I am an employee of Linode, however this project is being developed independently in my own free time and is not associated in any way with Linode, LLC. Only publicly-available documentation and information is being used in the development of this project.
|
Full disclosure: I am an employee of Linode/Akamai, however this project is being developed independently in my own free time and is not associated in any way with Linode, LLC or Akamai Technologies, Inc. Only publicly-available documentation and information is being used in the development of this project.
|
||||||
|
|
||||||
# Linode Manager Classic
|
# Linode Manager Classic
|
||||||
LMC is a modern recreation of Linode's original manager interface that many people know and love. It is implemented as a client-side browser app using just vanilla HTML5, CSS3, and JavaScript (no 3rd-party libraries or other external dependencies). It uses Linode's OAuth provider for authentication and interfaces with APIv4.
|
LMC is a modern recreation of Linode's original manager interface that many people know and love. It is implemented as a client-side browser app using just vanilla HTML5, CSS3, and JavaScript (no 3rd-party libraries or other external dependencies). It uses Linode's OAuth provider for authentication and interfaces with APIv4.
|
||||||
@ -12,14 +12,14 @@ This project is currently a work in progress. The following list provides a high
|
|||||||
|
|
||||||
- [x] OAuth Authentication/Login/Logout
|
- [x] OAuth Authentication/Login/Logout
|
||||||
- [x] Gravatar
|
- [x] Gravatar
|
||||||
- [x] Linodes (including the dashboard and all related subpages, but not including graphs)
|
- [x] Linodes
|
||||||
- [x] Block Storage (Volumes)
|
- [x] Block Storage (Volumes)
|
||||||
- [x] Images
|
- [x] Images
|
||||||
- [x] DNS
|
- [x] DNS
|
||||||
- [x] Account Details (excluding PayPal support)
|
- [x] Account Details (excluding PayPal support)
|
||||||
- [x] User Profile Settings
|
- [x] User Profile Settings
|
||||||
|
- [x] Graphs
|
||||||
- [ ] PayPal payments
|
- [ ] PayPal payments
|
||||||
- [ ] Graphs
|
|
||||||
- [ ] StackScripts
|
- [ ] StackScripts
|
||||||
- [ ] NodeBalancers
|
- [ ] NodeBalancers
|
||||||
- [ ] Longview
|
- [ ] Longview
|
||||||
@ -34,4 +34,4 @@ Before reporting an issue, please search the issue tracker to see if the issue h
|
|||||||
The best way to contribute is by opening issues on the issue tracker. For simple fixes or adjustments I might accept a PR, but for the time being I would prefer to maintain this project as a solo effort. I may change my mind in the future.
|
The best way to contribute is by opening issues on the issue tracker. For simple fixes or adjustments I might accept a PR, but for the time being I would prefer to maintain this project as a solo effort. I may change my mind in the future.
|
||||||
|
|
||||||
## Self-hosting
|
## Self-hosting
|
||||||
In order to self-host this application, you must first create your own OAuth client using your existing Linode account (instructions for doing this in Linode's new manager can be found [here](https://github.com/linode/manager/blob/develop/CREATE_CLIENT.md)). When creating the OAuth client, use the URL where you will be hosting the app as the Callback URL. Then you can clone this repository into your webroot and copy the `clientID.js.example` file to `clientID.js` and fill in the empty string with your Client ID. You must ensure that Server Side Includes (SSI) is enabled in your web server. Optionally, you can configure your web server to use the `404.html` file as a custom error document.
|
In order to self-host this application, you must first create your own OAuth client using your existing Linode account. When creating the OAuth client, use the URL where you will be hosting the app as the Callback URL. Then you can clone this repository into your webroot and copy the [clientID.js.example](clientID.js.example) file to `clientID.js` and fill in the empty string with your Client ID. You must ensure that Server Side Includes (SSI) is enabled in your web server. Optionally, you can configure your web server to use the [404.html](404.html) file as a custom error document.
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#backups-enable-all {
|
#backups-enable-all {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/account/settings">Settings</a> » <span class="top-links-title">Backup Enrollment</span></div>
|
||||||
<div id="backups-enable-all">
|
<div id="backups-enable-all">
|
||||||
<h2>Backup Enrollment</h2>
|
<h2>Backup Enrollment</h2>
|
||||||
<p>This will enable the Linode Backup Service for <strong><span class="linode-count"></span></strong> Linodes, for a total additional cost of <strong>$<span id="cost"></span></strong>/month.</p>
|
<p>This will enable the Linode Backup Service for <strong><span class="linode-count"></span></strong> Linodes, for a total additional cost of <strong>$<span id="cost"></span></strong>/month.</p>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#billing-history {
|
#billing-history {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#current {
|
#current {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Billing History</span></div>
|
||||||
<div id="billing-history">
|
<div id="billing-history">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#cancel {
|
#cancel {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#cancel-note {
|
#cancel-note {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Cancel Account</span></div>
|
||||||
<div id="cancel">
|
<div id="cancel">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#contact {
|
#contact {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody tr td:first-of-type {
|
tbody tr td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Contact Info</span></div>
|
||||||
<div id="contact">
|
<div id="contact">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#creditcard {
|
#creditcard {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Update Credit Card</span></div>
|
||||||
<div id="creditcard">
|
<div id="creditcard">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/account/billing_history">Billing History</a> » <span class="top-links-title">Invoice</span></div>
|
||||||
<div id="invoice">
|
<div id="invoice">
|
||||||
<table id="invoice-table" class="lmc-table">
|
<table id="invoice-table" class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#invoice {
|
#invoice {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#invoice-table td:nth-of-type(4) {
|
#invoice-table td:nth-of-type(4) {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Make a Payment</span></div>
|
||||||
<div id="make-a-payment">
|
<div id="make-a-payment">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -34,7 +34,7 @@ input[type="number"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#make-a-payment {
|
#make-a-payment {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/account/oauth_apps">OAuth Apps</a> » <span class="top-links-title">Add/Edit OAuth App</span></div>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">OAuth Apps</span></div>
|
||||||
<div id="oauth_apps">
|
<div id="oauth_apps">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#oauth_apps {
|
#oauth_apps {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td:nth-of-type(6) {
|
td:nth-of-type(6) {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/account/billing_history">Billing History</a> » <span class="top-links-title">Payment</span></div>
|
||||||
<div id="paymentreceipt">
|
<div id="paymentreceipt">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#paymentreceipt {
|
#paymentreceipt {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#paymentreceipt p {
|
#paymentreceipt p {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/account/billing_history">Billing History</a> » <span class="top-links-title">Yearly Payments</span></div>
|
||||||
<div id="paymentreceiptyear">
|
<div id="paymentreceiptyear">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#paymentreceiptyear {
|
#paymentreceiptyear {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#paymentreceiptyear p {
|
#paymentreceiptyear p {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Settings</span></div>
|
||||||
<div id="settings">
|
<div id="settings">
|
||||||
<p id="saved">Settings saved!</p>
|
<p id="saved">Settings saved!</p>
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#settings {
|
#settings {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
18
global.css
18
global.css
@ -77,6 +77,24 @@ header {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lmc-graph canvas {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lmc-graph h4 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lmc-graph table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lmc-graph-color {
|
||||||
|
height: 15px;
|
||||||
|
display: inline-block;
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.lmc-table {
|
.lmc-table {
|
||||||
background-color: #CECECE;
|
background-color: #CECECE;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
73
global.js
73
global.js
@ -52,7 +52,19 @@ var regionNames = {
|
|||||||
"ap-southeast": "Sydney, NSW, AU",
|
"ap-southeast": "Sydney, NSW, AU",
|
||||||
"philadelphia": "Philadelphia, PA, USA",
|
"philadelphia": "Philadelphia, PA, USA",
|
||||||
"absecon": "Absecon, NJ, USA",
|
"absecon": "Absecon, NJ, USA",
|
||||||
"us-iad": "Washington DC, USA"
|
"us-iad": "Washington DC, USA",
|
||||||
|
"us-ord": "Chicago, IL, USA",
|
||||||
|
"fr-par": "Paris, FR",
|
||||||
|
"in-maa": "Chennai, IN",
|
||||||
|
"us-sea": "Seattle, WA, USA",
|
||||||
|
"br-gru": "San Paulo, BR",
|
||||||
|
"nl-ams": "Amsterdam, NL",
|
||||||
|
"se-sto": "Stockholm, SE",
|
||||||
|
"jp-osa": "Osaka, JP",
|
||||||
|
"it-mil": "Milan, IT",
|
||||||
|
"id-cgk": "Jakarta, ID",
|
||||||
|
"us-lax": "Los Angeles, CA, USA",
|
||||||
|
"us-mia": "Miami, FL, USA"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Human-readable event titles
|
// Human-readable event titles
|
||||||
@ -452,6 +464,63 @@ function displayUser(response)
|
|||||||
profilePic.style = "display: initial;";
|
profilePic.style = "display: initial;";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw timeseries data with the given canvas in the given color and fill
|
||||||
|
// series is an array of objects, with each object containing the color/fill settings and an array of data points
|
||||||
|
function drawSeries(series, canvas)
|
||||||
|
{
|
||||||
|
// Compute scale and totals
|
||||||
|
var xMin = series[0].points[0][0];
|
||||||
|
var xMax = series[0].points[series[0].points.length - 1][0];
|
||||||
|
var yMax = 0;
|
||||||
|
for (var i = 0; i < series.length; i++) {
|
||||||
|
xMin = Math.min(xMin, series[i].points[0][0]);
|
||||||
|
xMax = Math.max(xMax, series[i].points[series[i].points.length - 1][0]);
|
||||||
|
series[i].max = 0, series[i].avg = 0;
|
||||||
|
for (var j = 0; j < series[i].points.length; j++) {
|
||||||
|
series[i].max = Math.max(series[i].max, series[i].points[j][1]);
|
||||||
|
series[i].avg += series[i].points[j][1];
|
||||||
|
}
|
||||||
|
series[i].avg /= series[i].points.length;
|
||||||
|
yMax = Math.max(yMax, series[i].max);
|
||||||
|
}
|
||||||
|
xMax -= xMin;
|
||||||
|
|
||||||
|
// Setup drawing context
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
|
||||||
|
// Clear the canvas
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
for (var i = 0; i < series.length; i++) {
|
||||||
|
ctx.fillStyle = series[i].color;
|
||||||
|
ctx.strokeStyle = series[i].color;
|
||||||
|
|
||||||
|
// Draw data
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo((series[i].points[0][0] - xMin) / xMax * canvas.width, canvas.height - (series[i].points[0][1] / yMax * canvas.height));
|
||||||
|
for (var j = 1; j < series[i].points.length; j++)
|
||||||
|
ctx.lineTo((series[i].points[j][0] - xMin) / xMax * canvas.width, canvas.height - (series[i].points[j][1] / yMax * canvas.height));
|
||||||
|
if (series[i].fill) {
|
||||||
|
ctx.lineTo((series[i].points[series[i].points.length-1][0] - xMin) / xMax * canvas.width, canvas.height);
|
||||||
|
ctx.lineTo((series[i].points[0][0] - xMin) / xMax * canvas.width, canvas.height);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
} else {
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw axis lines
|
||||||
|
ctx.strokeStyle = "black";
|
||||||
|
ctx.lineWidth = 2.5;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, 0);
|
||||||
|
ctx.lineTo(0, canvas.height);
|
||||||
|
ctx.lineTo(canvas.width, canvas.height);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
// Return an MD5 hash of the given string
|
// Return an MD5 hash of the given string
|
||||||
function md5(str, binary)
|
function md5(str, binary)
|
||||||
{
|
{
|
||||||
@ -793,4 +862,4 @@ function translateKernel(slug, element)
|
|||||||
apiGet("/linode/kernels/" + slug, callback, null);
|
apiGet("/linode/kernels/" + slug, callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { settings, elements, regionNames, apiDelete, apiGet, apiPost, apiPut, md5, migrateETA, oauthPost, oauthScopes, objPut, parseParams, setupHeader, eventTitles, timeString, translateKernel };
|
export { settings, elements, regionNames, apiDelete, apiGet, apiPost, apiPut, drawSeries, md5, migrateETA, oauthPost, oauthScopes, objPut, parseParams, setupHeader, eventTitles, timeString, translateKernel };
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
<a class="subnav-link" href="/linodes/rescue?lid=0">Rescue</a>
|
<a class="subnav-link" href="/linodes/rescue?lid=0">Rescue</a>
|
||||||
<a class="subnav-link" href="/linodes/resize?lid=0">Resize</a>
|
<a class="subnav-link" href="/linodes/resize?lid=0">Resize</a>
|
||||||
<a class="subnav-link" href="/linodes/clone?lid=0">Clone</a>
|
<a class="subnav-link" href="/linodes/clone?lid=0">Clone</a>
|
||||||
<a class="subnav-link" href="/linodes/graphs?lid=0">Graphs</a>
|
|
||||||
<a class="subnav-link" href="/linodes/backups?lid=0">Backups</a>
|
<a class="subnav-link" href="/linodes/backups?lid=0">Backups</a>
|
||||||
<a class="subnav-link" href="/linodes/settings?lid=0">Settings</a>
|
<a class="subnav-link" href="/linodes/settings?lid=0">Settings</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -57,7 +57,7 @@ h3 {
|
|||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 135px;
|
width: 145px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance-type h3 {
|
.instance-type h3 {
|
||||||
|
@ -49,7 +49,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
</div>
|
</div>
|
||||||
<div class="instance-category">
|
<div class="instance-category">
|
||||||
<h3>High Memory Instances</h3>
|
<h3>High Memory Instances</h3>
|
||||||
<p>High Memory instances favor RAM over other resources, and can be good for memory hungry use cases like caching and in-memory databases.</p>
|
<p>High Memory instances favor RAM over other resources, and can be good for memory hungry use cases like caching and in-memory databases. All High Memory plans use dedicated CPU cores.</p>
|
||||||
<div id="highmem"></div>
|
<div id="highmem"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="instance-category">
|
<div class="instance-category">
|
||||||
@ -57,6 +57,11 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<p>Linodes with dedicated GPUs accelerate highly specialized applications such as machine learning, AI, and video transcoding.</p>
|
<p>Linodes with dedicated GPUs accelerate highly specialized applications such as machine learning, AI, and video transcoding.</p>
|
||||||
<div id="gpu"></div>
|
<div id="gpu"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="instance-category">
|
||||||
|
<h3>Premium Instances</h3>
|
||||||
|
<p>Premium CPU instances guarantee a minimum processor generation of AMD EPYC™ Milan or newer to ensure consistent high performance for more demanding workloads.</p>
|
||||||
|
<div id="premium"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="location">
|
<div id="location">
|
||||||
<h2>Location</h2>
|
<h2>Location</h2>
|
||||||
|
@ -25,10 +25,18 @@
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
#config-table tr:last-of-type {
|
#config-table tr:last-of-type {
|
||||||
border-bottom: 1px solid #E8E8E8;
|
border-bottom: 1px solid #E8E8E8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cpu-color {
|
||||||
|
background-color: #03C;
|
||||||
|
}
|
||||||
|
|
||||||
.disk-icon {
|
.disk-icon {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
width: 26px;
|
width: 26px;
|
||||||
@ -42,12 +50,51 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#graph-range {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
border-bottom: 1px solid #E8E8E8;
|
border-bottom: 1px solid #E8E8E8;
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
margin-bottom: 50px;
|
}
|
||||||
|
|
||||||
|
#io-rate-color {
|
||||||
|
background-color: #FFD04B;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv4-in-color {
|
||||||
|
background-color: #03C;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv4-out-color {
|
||||||
|
background-color: #32CD32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv4-privin-color {
|
||||||
|
background-color: #C09;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv4-privout-color {
|
||||||
|
background-color: #FF9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv6-in-color {
|
||||||
|
background-color: #03C;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv6-out-color {
|
||||||
|
background-color: #32CD32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv6-privin-color {
|
||||||
|
background-color: #C09;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv6-privout-color {
|
||||||
|
background-color: #FF9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.job-failed {
|
.job-failed {
|
||||||
@ -202,6 +249,10 @@ h3 {
|
|||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#swap-rate-color {
|
||||||
|
background-color: #FA373E;
|
||||||
|
}
|
||||||
|
|
||||||
#upgrade {
|
#upgrade {
|
||||||
background-color: #F0F0F0;
|
background-color: #F0F0F0;
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParams, setupHeader, timeString, translateKernel } from "/global.js";
|
import { settings, elements, apiDelete, apiGet, apiPost, drawSeries, eventTitles, parseParams, setupHeader, timeString, translateKernel } from "/global.js";
|
||||||
|
|
||||||
(function()
|
(function()
|
||||||
{
|
{
|
||||||
@ -26,6 +26,10 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
elements.configRadioName = "config-radio";
|
elements.configRadioName = "config-radio";
|
||||||
elements.configRemovePrefix = "config-remove-";
|
elements.configRemovePrefix = "config-remove-";
|
||||||
elements.configTable = "config-table";
|
elements.configTable = "config-table";
|
||||||
|
elements.cpuAvg = "cpu-avg";
|
||||||
|
elements.cpuGraph = "cpu-graph";
|
||||||
|
elements.cpuLast = "cpu-last";
|
||||||
|
elements.cpuMax = "cpu-max";
|
||||||
elements.diskIcon = "disk-icon";
|
elements.diskIcon = "disk-icon";
|
||||||
elements.diskIconImg = "/img/disk.gif";
|
elements.diskIconImg = "/img/disk.gif";
|
||||||
elements.diskRemovePrefix = "disk-remove-";
|
elements.diskRemovePrefix = "disk-remove-";
|
||||||
@ -34,7 +38,44 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
elements.eventRowPrefix = "event-row-";
|
elements.eventRowPrefix = "event-row-";
|
||||||
elements.eventTable = "event-table";
|
elements.eventTable = "event-table";
|
||||||
elements.extraEvent = "extra-event";
|
elements.extraEvent = "extra-event";
|
||||||
|
elements.graphRange = "graph-range";
|
||||||
elements.info = "info";
|
elements.info = "info";
|
||||||
|
elements.ioGraph = "io-graph";
|
||||||
|
elements.ioRateAvg = "io-rate-avg";
|
||||||
|
elements.ioRateLast = "io-rate-last";
|
||||||
|
elements.ioRateMax = "io-rate-max";
|
||||||
|
elements.ipv4Graph = "ipv4-graph";
|
||||||
|
elements.ipv4InAvg = "ipv4-in-avg";
|
||||||
|
elements.ipv4InLast = "ipv4-in-last";
|
||||||
|
elements.ipv4InMax = "ipv4-in-max";
|
||||||
|
elements.ipv4OutAvg = "ipv4-out-avg";
|
||||||
|
elements.ipv4OutLast = "ipv4-out-last";
|
||||||
|
elements.ipv4OutMax = "ipv4-out-max";
|
||||||
|
elements.ipv4PrivInAvg = "ipv4-privin-avg";
|
||||||
|
elements.ipv4PrivInLast = "ipv4-privin-last";
|
||||||
|
elements.ipv4PrivInMax = "ipv4-privin-max";
|
||||||
|
elements.ipv4PrivOutAvg = "ipv4-privout-avg";
|
||||||
|
elements.ipv4PrivOutLast = "ipv4-privout-last";
|
||||||
|
elements.ipv4PrivOutMax = "ipv4-privout-max";
|
||||||
|
elements.ipv4Total = "ipv4-total";
|
||||||
|
elements.ipv4TotalIn = "ipv4-total-in";
|
||||||
|
elements.ipv4TotalOut = "ipv4-total-out";
|
||||||
|
elements.ipv6Graph = "ipv6-graph";
|
||||||
|
elements.ipv6InAvg = "ipv6-in-avg";
|
||||||
|
elements.ipv6InLast = "ipv6-in-last";
|
||||||
|
elements.ipv6InMax = "ipv6-in-max";
|
||||||
|
elements.ipv6OutAvg = "ipv6-out-avg";
|
||||||
|
elements.ipv6OutLast = "ipv6-out-last";
|
||||||
|
elements.ipv6OutMax = "ipv6-out-max";
|
||||||
|
elements.ipv6PrivInAvg = "ipv6-privin-avg";
|
||||||
|
elements.ipv6PrivInLast = "ipv6-privin-last";
|
||||||
|
elements.ipv6PrivInMax = "ipv6-privin-max";
|
||||||
|
elements.ipv6PrivOutAvg = "ipv6-privout-avg";
|
||||||
|
elements.ipv6PrivOutLast = "ipv6-privout-last";
|
||||||
|
elements.ipv6PrivOutMax = "ipv6-privout-max";
|
||||||
|
elements.ipv6Total = "ipv6-total";
|
||||||
|
elements.ipv6TotalIn = "ipv6-total-in";
|
||||||
|
elements.ipv6TotalOut = "ipv6-total-out";
|
||||||
elements.jobFailed = "job-failed";
|
elements.jobFailed = "job-failed";
|
||||||
elements.jobInfo = "job-info";
|
elements.jobInfo = "job-info";
|
||||||
elements.jobNotice = "job-notice";
|
elements.jobNotice = "job-notice";
|
||||||
@ -64,6 +105,9 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
elements.storageFree = "storage-free";
|
elements.storageFree = "storage-free";
|
||||||
elements.storageTotal = "storage-total";
|
elements.storageTotal = "storage-total";
|
||||||
elements.storageUsed = "storage-used";
|
elements.storageUsed = "storage-used";
|
||||||
|
elements.swapRateAvg = "swap-rate-avg";
|
||||||
|
elements.swapRateLast = "swap-rate-last";
|
||||||
|
elements.swapRateMax = "swap-rate-max";
|
||||||
elements.transferMonthly = "transfer-monthly";
|
elements.transferMonthly = "transfer-monthly";
|
||||||
elements.transferOverage = "transfer-overage";
|
elements.transferOverage = "transfer-overage";
|
||||||
elements.transferUsed = "transfer-used";
|
elements.transferUsed = "transfer-used";
|
||||||
@ -80,6 +124,7 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
data.linodeTransfer = {};
|
data.linodeTransfer = {};
|
||||||
data.notifications = [];
|
data.notifications = [];
|
||||||
data.plan = {};
|
data.plan = {};
|
||||||
|
data.stats = {};
|
||||||
data.volumes = [];
|
data.volumes = [];
|
||||||
|
|
||||||
// Static references to UI elements
|
// Static references to UI elements
|
||||||
@ -87,9 +132,50 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
ui.backups = {};
|
ui.backups = {};
|
||||||
ui.boot = {};
|
ui.boot = {};
|
||||||
ui.configTable = {};
|
ui.configTable = {};
|
||||||
|
ui.cpuAvg = {};
|
||||||
|
ui.cpuGraph = {};
|
||||||
|
ui.cpuLast = {};
|
||||||
|
ui.cpuMax = {};
|
||||||
ui.diskTable = {};
|
ui.diskTable = {};
|
||||||
ui.diskUsage = {};
|
ui.diskUsage = {};
|
||||||
ui.eventTable = {};
|
ui.eventTable = {};
|
||||||
|
ui.graphRange = {};
|
||||||
|
ui.ioGraph = {};
|
||||||
|
ui.ioRateAvg = {};
|
||||||
|
ui.ioRateLast = {};
|
||||||
|
ui.ioRateMax = {};
|
||||||
|
ui.ipv4Graph = {};
|
||||||
|
ui.ipv4InAvg = {};
|
||||||
|
ui.ipv4InLast = {};
|
||||||
|
ui.ipv4InMax = {};
|
||||||
|
ui.ipv4OutAvg = {};
|
||||||
|
ui.ipv4OutLast = {};
|
||||||
|
ui.ipv4OutMax = {};
|
||||||
|
ui.ipv4PrivInAvg = {};
|
||||||
|
ui.ipv4PrivInLast = {};
|
||||||
|
ui.ipv4PrivInMax = {};
|
||||||
|
ui.ipv4PrivOutAvg = {};
|
||||||
|
ui.ipv4PrivOutLast = {};
|
||||||
|
ui.ipv4PrivOutMax = {};
|
||||||
|
ui.ipv4Total = {};
|
||||||
|
ui.ipv4TotalIn = {};
|
||||||
|
ui.ipv4TotalOut = {};
|
||||||
|
ui.ipv6Graph = {};
|
||||||
|
ui.ipv6InAvg = {};
|
||||||
|
ui.ipv6InLast = {};
|
||||||
|
ui.ipv6InMax = {};
|
||||||
|
ui.ipv6OutAvg = {};
|
||||||
|
ui.ipv6OutLast = {};
|
||||||
|
ui.ipv6OutMax = {};
|
||||||
|
ui.ipv6PrivInAvg = {};
|
||||||
|
ui.ipv6PrivInLast = {};
|
||||||
|
ui.ipv6PrivInMax = {};
|
||||||
|
ui.ipv6PrivOutAvg = {};
|
||||||
|
ui.ipv6PrivOutLast = {};
|
||||||
|
ui.ipv6PrivOutMax = {};
|
||||||
|
ui.ipv6Total = {};
|
||||||
|
ui.ipv6TotalIn = {};
|
||||||
|
ui.ipv6TotalOut = {};
|
||||||
ui.jobProgress = {};
|
ui.jobProgress = {};
|
||||||
ui.jobProgressRow = {};
|
ui.jobProgressRow = {};
|
||||||
ui.lastBackup = {};
|
ui.lastBackup = {};
|
||||||
@ -110,6 +196,9 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
ui.storageFree = {};
|
ui.storageFree = {};
|
||||||
ui.storageTotal = {};
|
ui.storageTotal = {};
|
||||||
ui.storageUsed = {};
|
ui.storageUsed = {};
|
||||||
|
ui.swapRateAvg = {};
|
||||||
|
ui.swapRateLast = {};
|
||||||
|
ui.swapRateMax = {};
|
||||||
ui.transferMonthly = {};
|
ui.transferMonthly = {};
|
||||||
ui.transferOverage = {};
|
ui.transferOverage = {};
|
||||||
ui.transferUsed = {};
|
ui.transferUsed = {};
|
||||||
@ -120,6 +209,7 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
var state = {};
|
var state = {};
|
||||||
state.diskRefresh = false;
|
state.diskRefresh = false;
|
||||||
state.eventsComplete = 0;
|
state.eventsComplete = 0;
|
||||||
|
state.haveRanges = false;
|
||||||
state.linodeRefresh = false;
|
state.linodeRefresh = false;
|
||||||
state.showExtraEvents = false;
|
state.showExtraEvents = false;
|
||||||
|
|
||||||
@ -143,8 +233,8 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
apiPost("/linode/instances/" + data.params.lid + "/boot", request, callback);
|
apiPost("/linode/instances/" + data.params.lid + "/boot", request, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convert a byte count into a "friendly" byte string (KB, MB, GB, etc)
|
// Convert an unqualified count into a string with an SI prefix (i.e. bytes to MB/GB/etc)
|
||||||
var byteString = function(count)
|
var countSI = function(count)
|
||||||
{
|
{
|
||||||
var prefix = "KMGTPEZY";
|
var prefix = "KMGTPEZY";
|
||||||
var unit = "";
|
var unit = "";
|
||||||
@ -158,7 +248,7 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return count.toFixed(2) + " " + unit + "B";
|
return count.toFixed(2) + " " + unit;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a config profile table row
|
// Generate a config profile table row
|
||||||
@ -525,6 +615,33 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
if (data.linode.type && !data.plan.id)
|
if (data.linode.type && !data.plan.id)
|
||||||
apiGet("/linode/types/" + data.linode.type, displayPlan, null);
|
apiGet("/linode/types/" + data.linode.type, displayPlan, null);
|
||||||
|
|
||||||
|
// Populate graph range picker
|
||||||
|
if (!state.haveRanges) {
|
||||||
|
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||||
|
var created = new Date(data.linode.created + "Z");
|
||||||
|
var now = new Date();
|
||||||
|
var last30 = document.createElement("option");
|
||||||
|
last30.value = "/" + now.getFullYear() + "/" + (now.getMonth() + 1).toString().padStart(2, "0");
|
||||||
|
last30.innerHTML = "Last 30 Days";
|
||||||
|
ui.graphRange.appendChild(last30);
|
||||||
|
|
||||||
|
while (!(now.getFullYear() == created.getFullYear() && now.getMonth() == created.getMonth())) {
|
||||||
|
if (now.getMonth() == 0) {
|
||||||
|
now.setMonth(11);
|
||||||
|
now.setFullYear(now.getFullYear() - 1);
|
||||||
|
} else {
|
||||||
|
now.setMonth(now.getMonth() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var yearMonth = document.createElement("option");
|
||||||
|
yearMonth.value = "/" + now.getFullYear() + "/" + (now.getMonth() + 1).toString().padStart(2, "0");
|
||||||
|
yearMonth.innerHTML = months[now.getMonth()] + " " + now.getFullYear();
|
||||||
|
ui.graphRange.appendChild(yearMonth);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.haveRanges = true;
|
||||||
|
}
|
||||||
|
|
||||||
state.linodeRefresh = false;
|
state.linodeRefresh = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -662,6 +779,159 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
ui.upgrade.style.display = "block";
|
ui.upgrade.style.display = "block";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Show stats graphs
|
||||||
|
var displayStats = function(response)
|
||||||
|
{
|
||||||
|
// Insert dummy points in case of blank data
|
||||||
|
if (!response.data.cpu.length)
|
||||||
|
response.data.cpu = [[0,0]];
|
||||||
|
if (!response.data.io.io.length)
|
||||||
|
response.data.io.io = [[0,0]];
|
||||||
|
if (!response.data.io.swap.length)
|
||||||
|
response.data.io.swap = [[0,0]];
|
||||||
|
if (!response.data.netv4.private_out.length)
|
||||||
|
response.data.netv4.private_out = [[0,0]];
|
||||||
|
if (!response.data.netv4.private_in.length)
|
||||||
|
response.data.netv4.private_in = [[0,0]];
|
||||||
|
if (!response.data.netv4.out.length)
|
||||||
|
response.data.netv4.out = [[0,0]];
|
||||||
|
if (!response.data.netv4.in.length)
|
||||||
|
response.data.netv4.in = [[0,0]];
|
||||||
|
if (!response.data.netv6.private_out.length)
|
||||||
|
response.data.netv6.private_out = [[0,0]];
|
||||||
|
if (!response.data.netv6.private_in.length)
|
||||||
|
response.data.netv6.private_in = [[0,0]];
|
||||||
|
if (!response.data.netv6.out.length)
|
||||||
|
response.data.netv6.out = [[0,0]];
|
||||||
|
if (!response.data.netv6.in.length)
|
||||||
|
response.data.netv6.in = [[0,0]];
|
||||||
|
|
||||||
|
data.stats.cpu = [{
|
||||||
|
"color": "#03C",
|
||||||
|
"fill": false,
|
||||||
|
"points": response.data.cpu
|
||||||
|
}];
|
||||||
|
data.stats.io = [
|
||||||
|
{
|
||||||
|
"color": "#FFD04B",
|
||||||
|
"fill": true,
|
||||||
|
"points": response.data.io.io
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#FA373E",
|
||||||
|
"fill": false,
|
||||||
|
"points": response.data.io.swap
|
||||||
|
}
|
||||||
|
];
|
||||||
|
data.stats.netv4 = [
|
||||||
|
{
|
||||||
|
"color": "#FF9",
|
||||||
|
"fill": true,
|
||||||
|
"points": response.data.netv4.private_out
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#C09",
|
||||||
|
"fill": false,
|
||||||
|
"points": response.data.netv4.private_in
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#32CD32",
|
||||||
|
"fill": true,
|
||||||
|
"points": response.data.netv4.out
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#03C",
|
||||||
|
"fill": false,
|
||||||
|
"points": response.data.netv4.in
|
||||||
|
}
|
||||||
|
];
|
||||||
|
data.stats.netv6 = [
|
||||||
|
{
|
||||||
|
"color": "#FF9",
|
||||||
|
"fill": true,
|
||||||
|
"points": response.data.netv6.private_out
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#C09",
|
||||||
|
"fill": false,
|
||||||
|
"points": response.data.netv6.private_in
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#32CD32",
|
||||||
|
"fill": true,
|
||||||
|
"points": response.data.netv6.out
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#03C",
|
||||||
|
"fill": false,
|
||||||
|
"points": response.data.netv6.in
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Draw graphs
|
||||||
|
drawSeries(data.stats.cpu, ui.cpuGraph);
|
||||||
|
drawSeries(data.stats.io, ui.ioGraph);
|
||||||
|
drawSeries(data.stats.netv4, ui.ipv4Graph);
|
||||||
|
drawSeries(data.stats.netv6, ui.ipv6Graph);
|
||||||
|
|
||||||
|
// Compute traffic totals
|
||||||
|
var ipv4Out = data.stats.netv4[0].avg * (data.stats.netv4[0].points[data.stats.netv4[0].points.length-1][0] - data.stats.netv4[0].points[0][0]) / 1000;
|
||||||
|
ipv4Out += data.stats.netv4[2].avg * (data.stats.netv4[2].points[data.stats.netv4[2].points.length-1][0] - data.stats.netv4[2].points[0][0]) / 1000;
|
||||||
|
ipv4Out /= 8;
|
||||||
|
var ipv4In = data.stats.netv4[1].avg * (data.stats.netv4[1].points[data.stats.netv4[1].points.length-1][0] - data.stats.netv4[1].points[0][0]) / 1000;
|
||||||
|
ipv4In += data.stats.netv4[3].avg * (data.stats.netv4[3].points[data.stats.netv4[3].points.length-1][0] - data.stats.netv4[3].points[0][0]) / 1000;
|
||||||
|
ipv4In /= 8;
|
||||||
|
var ipv6Out = data.stats.netv6[0].avg * (data.stats.netv6[0].points[data.stats.netv6[0].points.length-1][0] - data.stats.netv6[0].points[0][0]) / 1000;
|
||||||
|
ipv6Out += data.stats.netv6[2].avg * (data.stats.netv6[2].points[data.stats.netv6[2].points.length-1][0] - data.stats.netv6[2].points[0][0]) / 1000;
|
||||||
|
ipv6Out /= 8;
|
||||||
|
var ipv6In = data.stats.netv6[1].avg * (data.stats.netv6[1].points[data.stats.netv6[1].points.length-1][0] - data.stats.netv6[1].points[0][0]) / 1000;
|
||||||
|
ipv6In += data.stats.netv6[3].avg * (data.stats.netv6[3].points[data.stats.netv6[3].points.length-1][0] - data.stats.netv6[3].points[0][0]) / 1000;
|
||||||
|
ipv6In /= 8;
|
||||||
|
|
||||||
|
// Update tables
|
||||||
|
ui.cpuMax.innerHTML = data.stats.cpu[0].max + "%";
|
||||||
|
ui.cpuAvg.innerHTML = data.stats.cpu[0].avg.toFixed(2) + "%";
|
||||||
|
ui.cpuLast.innerHTML = data.stats.cpu[0].points[data.stats.cpu[0].points.length - 1][1] + "%";
|
||||||
|
ui.ioRateMax.innerHTML = data.stats.io[0].max;
|
||||||
|
ui.ioRateAvg.innerHTML = data.stats.io[0].avg.toFixed(2);
|
||||||
|
ui.ioRateLast.innerHTML = data.stats.io[0].points[data.stats.io[0].points.length - 1][1];
|
||||||
|
ui.swapRateMax.innerHTML = data.stats.io[1].max;
|
||||||
|
ui.swapRateAvg.innerHTML = data.stats.io[1].avg.toFixed(2);
|
||||||
|
ui.swapRateLast.innerHTML = data.stats.io[1].points[data.stats.io[1].points.length - 1][1];
|
||||||
|
ui.ipv4PrivOutMax.innerHTML = countSI(data.stats.netv4[0].max) + "b/s";
|
||||||
|
ui.ipv4PrivOutAvg.innerHTML = countSI(data.stats.netv4[0].avg) + "b/s";
|
||||||
|
ui.ipv4PrivOutLast.innerHTML = countSI(data.stats.netv4[0].points[data.stats.netv4[0].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv4PrivInMax.innerHTML = countSI(data.stats.netv4[1].max) + "b/s";
|
||||||
|
ui.ipv4PrivInAvg.innerHTML = countSI(data.stats.netv4[1].avg) + "b/s";
|
||||||
|
ui.ipv4PrivInLast.innerHTML = countSI(data.stats.netv4[1].points[data.stats.netv4[1].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv4OutMax.innerHTML = countSI(data.stats.netv4[2].max) + "b/s";
|
||||||
|
ui.ipv4OutAvg.innerHTML = countSI(data.stats.netv4[2].avg) + "b/s";
|
||||||
|
ui.ipv4OutLast.innerHTML = countSI(data.stats.netv4[2].points[data.stats.netv4[2].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv4InMax.innerHTML = countSI(data.stats.netv4[3].max) + "b/s";
|
||||||
|
ui.ipv4InAvg.innerHTML = countSI(data.stats.netv4[3].avg) + "b/s";
|
||||||
|
ui.ipv4InLast.innerHTML = countSI(data.stats.netv4[3].points[data.stats.netv4[3].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv4TotalIn.innerHTML = countSI(ipv4In) + "B";
|
||||||
|
ui.ipv4TotalOut.innerHTML = countSI(ipv4Out) + "B";
|
||||||
|
ui.ipv4Total.innerHTML = countSI(ipv4In + ipv4Out) + "B";
|
||||||
|
ui.ipv6PrivOutMax.innerHTML = countSI(data.stats.netv6[0].max) + "b/s";
|
||||||
|
ui.ipv6PrivOutAvg.innerHTML = countSI(data.stats.netv6[0].avg) + "b/s";
|
||||||
|
ui.ipv6PrivOutLast.innerHTML = countSI(data.stats.netv6[0].points[data.stats.netv6[0].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv6PrivInMax.innerHTML = countSI(data.stats.netv6[1].max) + "b/s";
|
||||||
|
ui.ipv6PrivInAvg.innerHTML = countSI(data.stats.netv6[1].avg) + "b/s";
|
||||||
|
ui.ipv6PrivInLast.innerHTML = countSI(data.stats.netv6[1].points[data.stats.netv6[1].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv6OutMax.innerHTML = countSI(data.stats.netv6[2].max) + "b/s";
|
||||||
|
ui.ipv6OutAvg.innerHTML = countSI(data.stats.netv6[2].avg) + "b/s";
|
||||||
|
ui.ipv6OutLast.innerHTML = countSI(data.stats.netv6[2].points[data.stats.netv6[2].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv6InMax.innerHTML = countSI(data.stats.netv6[3].max) + "b/s";
|
||||||
|
ui.ipv6InAvg.innerHTML = countSI(data.stats.netv6[3].avg) + "b/s";
|
||||||
|
ui.ipv6InLast.innerHTML = countSI(data.stats.netv6[3].points[data.stats.netv6[3].points.length - 1][1]) + "b/s";
|
||||||
|
ui.ipv6TotalIn.innerHTML = countSI(ipv6In) + "B";
|
||||||
|
ui.ipv6TotalOut.innerHTML = countSI(ipv6Out) + "B";
|
||||||
|
ui.ipv6Total.innerHTML = countSI(ipv6In + ipv6Out) + "B";
|
||||||
|
|
||||||
|
ui.graphRange.disabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
// Show storage totals
|
// Show storage totals
|
||||||
var displayStorage = function()
|
var displayStorage = function()
|
||||||
{
|
{
|
||||||
@ -686,7 +956,7 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
|
|
||||||
// Display network transfer info
|
// Display network transfer info
|
||||||
ui.transferMonthly.innerHTML = data.linodeTransfer.quota + " GB";
|
ui.transferMonthly.innerHTML = data.linodeTransfer.quota + " GB";
|
||||||
ui.transferUsed.innerHTML = byteString(data.linodeTransfer.used);
|
ui.transferUsed.innerHTML = countSI(data.linodeTransfer.used) + "B";
|
||||||
ui.transferOverage.innerHTML = data.linodeTransfer.billable + " GB";
|
ui.transferOverage.innerHTML = data.linodeTransfer.billable + " GB";
|
||||||
ui.netUsage.value = ((data.linodeTransfer.used / 1024 / 1024 / 1024) / data.linodeTransfer.quota * 100).toFixed(0);
|
ui.netUsage.value = ((data.linodeTransfer.used / 1024 / 1024 / 1024) / data.linodeTransfer.quota * 100).toFixed(0);
|
||||||
ui.netUsage.innerHTML = ui.netUsage.value + "%";
|
ui.netUsage.innerHTML = ui.netUsage.value + "%";
|
||||||
@ -786,43 +1056,25 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
anchors[i].href = anchors[i].href.replace("lid=0", "lid=" + data.params.lid);
|
anchors[i].href = anchors[i].href.replace("lid=0", "lid=" + data.params.lid);
|
||||||
|
|
||||||
// Get element references
|
// Get element references
|
||||||
ui.backups = document.getElementById(elements.backups);
|
for (var i in ui)
|
||||||
ui.boot = document.getElementById(elements.boot);
|
ui[i] = document.getElementById(elements[i]);
|
||||||
ui.configTable = document.getElementById(elements.configTable);
|
|
||||||
ui.diskTable = document.getElementById(elements.diskTable);
|
|
||||||
ui.diskUsage = document.getElementById(elements.diskUsage);
|
|
||||||
ui.eventTable = document.getElementById(elements.eventTable);
|
|
||||||
ui.jobProgress = document.getElementById(elements.jobProgress);
|
|
||||||
ui.jobProgressRow = document.getElementById(elements.jobProgressRow);
|
|
||||||
ui.lastBackup = document.getElementById(elements.lastBackup);
|
|
||||||
ui.lastBackupTime = document.getElementById(elements.lastBackupTime);
|
|
||||||
ui.linodeLabel = document.getElementById(elements.linodeLabel);
|
|
||||||
ui.linodeTag = document.getElementById(elements.linodeTag);
|
|
||||||
ui.linodeTagLink = document.getElementById(elements.linodeTagLink);
|
|
||||||
ui.loadingConfigs = document.getElementById(elements.loadingConfigs);
|
|
||||||
ui.loadingDisks = document.getElementById(elements.loadingDisks);
|
|
||||||
ui.loadingJobs = document.getElementById(elements.loadingJobs);
|
|
||||||
ui.loadingVolumes = document.getElementById(elements.loadingVolumes);
|
|
||||||
ui.moreJobs = document.getElementById(elements.moreJobs);
|
|
||||||
ui.netUsage = document.getElementById(elements.netUsage);
|
|
||||||
ui.notifications = document.getElementById(elements.notifications);
|
|
||||||
ui.reboot = document.getElementById(elements.reboot);
|
|
||||||
ui.serverStatus = document.getElementById(elements.serverStatus);
|
|
||||||
ui.shutDown = document.getElementById(elements.shutDown);
|
|
||||||
ui.storageFree = document.getElementById(elements.storageFree);
|
|
||||||
ui.storageTotal = document.getElementById(elements.storageTotal);
|
|
||||||
ui.storageUsed = document.getElementById(elements.storageUsed);
|
|
||||||
ui.transferMonthly = document.getElementById(elements.transferMonthly);
|
|
||||||
ui.transferOverage = document.getElementById(elements.transferOverage);
|
|
||||||
ui.transferUsed = document.getElementById(elements.transferUsed);
|
|
||||||
ui.upgrade = document.getElementById(elements.upgrade);
|
|
||||||
ui.volumeTable = document.getElementById(elements.volumeTable);
|
|
||||||
|
|
||||||
// Attach button handlers
|
// Attach button handlers
|
||||||
ui.boot.addEventListener("click", bootLinode);
|
ui.boot.addEventListener("click", bootLinode);
|
||||||
ui.moreJobs.addEventListener("click", toggleEvents);
|
ui.moreJobs.addEventListener("click", toggleEvents);
|
||||||
ui.reboot.addEventListener("click", rebootLinode);
|
ui.reboot.addEventListener("click", rebootLinode);
|
||||||
ui.shutDown.addEventListener("click", shutDownLinode);
|
ui.shutDown.addEventListener("click", shutDownLinode);
|
||||||
|
ui.graphRange.addEventListener("input", updateGraphs);
|
||||||
|
|
||||||
|
// Set graph resolutions
|
||||||
|
ui.cpuGraph.height = ui.cpuGraph.clientHeight;
|
||||||
|
ui.cpuGraph.width = ui.cpuGraph.clientWidth;
|
||||||
|
ui.ioGraph.height = ui.ioGraph.clientHeight;
|
||||||
|
ui.ioGraph.width = ui.ioGraph.clientWidth;
|
||||||
|
ui.ipv4Graph.height = ui.ipv4Graph.clientHeight;
|
||||||
|
ui.ipv4Graph.width = ui.ipv4Graph.clientWidth;
|
||||||
|
ui.ipv6Graph.height = ui.ipv6Graph.clientHeight;
|
||||||
|
ui.ipv6Graph.width = ui.ipv6Graph.clientWidth;
|
||||||
|
|
||||||
// Get data from the API
|
// Get data from the API
|
||||||
apiGet("/linode/instances/" + data.params.lid, displayDetails, null);
|
apiGet("/linode/instances/" + data.params.lid, displayDetails, null);
|
||||||
@ -836,6 +1088,7 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
};
|
};
|
||||||
apiGet("/account/events", displayEvents, filter);
|
apiGet("/account/events", displayEvents, filter);
|
||||||
apiGet("/account/notifications", displayNotifications, null);
|
apiGet("/account/notifications", displayNotifications, null);
|
||||||
|
apiGet("/linode/instances/" + data.params.lid + "/stats", displayStats, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Button handler for shutdown button
|
// Button handler for shutdown button
|
||||||
@ -908,6 +1161,16 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
|
|||||||
window.setTimeout(getEvent, settings.refreshRate, event.id);
|
window.setTimeout(getEvent, settings.refreshRate, event.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Re-populate graphs with selected range
|
||||||
|
var updateGraphs = function(event)
|
||||||
|
{
|
||||||
|
if (event.currentTarget.disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
apiGet("/linode/instances/" + data.params.lid + "/stats" + ui.graphRange.value, displayStats, null);
|
||||||
|
ui.graphRange.disabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
// Attach onload handler
|
// Attach onload handler
|
||||||
window.addEventListener("load", setup);
|
window.addEventListener("load", setup);
|
||||||
})();
|
})();
|
||||||
|
@ -109,6 +109,145 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h3>Graphs</h3>
|
<h3>Graphs</h3>
|
||||||
|
<select disabled id="graph-range">
|
||||||
|
<option selected value="">Last 24 Hours</option>
|
||||||
|
</select>
|
||||||
|
<div class="lmc-graph">
|
||||||
|
<h4>CPU (%)</h4>
|
||||||
|
<canvas id="cpu-graph"></canvas>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>Max</td>
|
||||||
|
<td>Avg</td>
|
||||||
|
<td>Last</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><div id="cpu-color" class="lmc-graph-color"></div> CPU %</td>
|
||||||
|
<td id="cpu-max"></td>
|
||||||
|
<td id="cpu-avg"></td>
|
||||||
|
<td id="cpu-last"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h4>Disk I/O (blocks/s)</h4>
|
||||||
|
<canvas id="io-graph"></canvas>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>Max</td>
|
||||||
|
<td>Avg</td>
|
||||||
|
<td>Last</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><div id="io-rate-color" class="lmc-graph-color"></div> I/O Rate</td>
|
||||||
|
<td id="io-rate-max"></td>
|
||||||
|
<td id="io-rate-avg"></td>
|
||||||
|
<td id="io-rate-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="swap-rate-color" class="lmc-graph-color"></div> Swap Rate</td>
|
||||||
|
<td id="swap-rate-max"></td>
|
||||||
|
<td id="swap-rate-avg"></td>
|
||||||
|
<td id="swap-rate-last"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h4>Network - IPv4 (bits/s)</h4>
|
||||||
|
<canvas id="ipv4-graph"></canvas>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>Max</td>
|
||||||
|
<td>Avg</td>
|
||||||
|
<td>Last</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv4-privout-color" class="lmc-graph-color"></div> Private Out</td>
|
||||||
|
<td id="ipv4-privout-max"></td>
|
||||||
|
<td id="ipv4-privout-avg"></td>
|
||||||
|
<td id="ipv4-privout-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv4-privin-color" class="lmc-graph-color"></div> Private In</td>
|
||||||
|
<td id="ipv4-privin-max"></td>
|
||||||
|
<td id="ipv4-privin-avg"></td>
|
||||||
|
<td id="ipv4-privin-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv4-out-color" class="lmc-graph-color"></div> Public Out</td>
|
||||||
|
<td id="ipv4-out-max"></td>
|
||||||
|
<td id="ipv4-out-avg"</td>
|
||||||
|
<td id="ipv4-out-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv4-in-color" class="lmc-graph-color"></div> Public In</td>
|
||||||
|
<td id="ipv4-in-max"></td>
|
||||||
|
<td id="ipv4-in-avg"></td>
|
||||||
|
<td id="ipv4-in-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Traffic</td>
|
||||||
|
<td>In: <span id="ipv4-total-in"></span></td>
|
||||||
|
<td>Out: <span id="ipv4-total-out"></span></td>
|
||||||
|
<td>Combined: <span id="ipv4-total"></span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h4>Network - IPv6 (bits/s)</h4>
|
||||||
|
<canvas id="ipv6-graph"></canvas>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>Max</td>
|
||||||
|
<td>Avg</td>
|
||||||
|
<td>Last</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv6-privout-color" class="lmc-graph-color"></div> Private Out</td>
|
||||||
|
<td id="ipv6-privout-max"></td>
|
||||||
|
<td id="ipv6-privout-avg"></td>
|
||||||
|
<td id="ipv6-privout-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv6-privin-color" class="lmc-graph-color"></div> Private In</td>
|
||||||
|
<td id="ipv6-privin-max"></td>
|
||||||
|
<td id="ipv6-privin-avg"></td>
|
||||||
|
<td id="ipv6-privin-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv6-out-color" class="lmc-graph-color"></div> Public Out</td>
|
||||||
|
<td id="ipv6-out-max"></td>
|
||||||
|
<td id="ipv6-out-avg"</td>
|
||||||
|
<td id="ipv6-out-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><div id="ipv6-in-color" class="lmc-graph-color"></div> Public In</td>
|
||||||
|
<td id="ipv6-in-max"></td>
|
||||||
|
<td id="ipv6-in-avg"></td>
|
||||||
|
<td id="ipv6-in-last"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total Traffic</td>
|
||||||
|
<td>In: <span id="ipv6-total-in"></span></td>
|
||||||
|
<td>Out: <span id="ipv6-total-out"></span></td>
|
||||||
|
<td>Combined: <span id="ipv6-total"></span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="linode-sidebar">
|
<div id="linode-sidebar">
|
||||||
<div class="sidebar-box">
|
<div class="sidebar-box">
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Linode Manager Classic.
|
|
||||||
*
|
|
||||||
* Linode Manager Classic is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Linode Manager Classic 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@import url('/global.css');
|
|
||||||
|
|
||||||
#graphs {
|
|
||||||
padding: 0px 15px 15px;
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Linode Manager Classic.
|
|
||||||
*
|
|
||||||
* Linode Manager Classic is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Linode Manager Classic 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { settings, elements, apiGet, parseParams, setupHeader } from "/global.js";
|
|
||||||
|
|
||||||
(function()
|
|
||||||
{
|
|
||||||
// Element names specific to this page
|
|
||||||
elements.linodeLabel = "linode-label";
|
|
||||||
elements.linodeTag = "linode-tag";
|
|
||||||
elements.linodeTagLink = "linode-tag-link";
|
|
||||||
|
|
||||||
// Data recieved from API calls
|
|
||||||
var data = {};
|
|
||||||
data.linode = {};
|
|
||||||
|
|
||||||
// Static references to UI elements
|
|
||||||
var ui = {};
|
|
||||||
ui.linodeLabel = {};
|
|
||||||
ui.linodeTag = {};
|
|
||||||
ui.linodeTagLink = {};
|
|
||||||
|
|
||||||
// Callback for linode details API call
|
|
||||||
var displayDetails = function(response)
|
|
||||||
{
|
|
||||||
data.linode = response;
|
|
||||||
|
|
||||||
// Set page title and header stuff
|
|
||||||
document.title += " // " + data.linode.label;
|
|
||||||
ui.linodeLabel.innerHTML = data.linode.label;
|
|
||||||
if (data.linode.tags.length == 1) {
|
|
||||||
ui.linodeTagLink.href = "/linodes?tag=" + data.linode.tags[0];
|
|
||||||
ui.linodeTagLink.innerHTML = "(" + data.linode.tags[0] + ")";
|
|
||||||
ui.linodeTag.style.display = "inline";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initial setup
|
|
||||||
var setup = function()
|
|
||||||
{
|
|
||||||
// Parse URL parameters
|
|
||||||
data.params = parseParams();
|
|
||||||
|
|
||||||
// We need a Linode ID, so die if we don't have it
|
|
||||||
if (!data.params.lid) {
|
|
||||||
alert("No Linode ID supplied!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setupHeader();
|
|
||||||
|
|
||||||
// Update links on page to include proper Linode ID
|
|
||||||
var anchors = document.getElementsByTagName("a");
|
|
||||||
for (var i = 0; i < anchors.length; i++)
|
|
||||||
anchors[i].href = anchors[i].href.replace("lid=0", "lid=" + data.params.lid);
|
|
||||||
|
|
||||||
// Get element references
|
|
||||||
ui.linodeLabel = document.getElementById(elements.linodeLabel);
|
|
||||||
ui.linodeTag = document.getElementById(elements.linodeTag);
|
|
||||||
ui.linodeTagLink = document.getElementById(elements.linodeTagLink);
|
|
||||||
|
|
||||||
// Get data from API
|
|
||||||
apiGet("/linode/instances/" + data.params.lid, displayDetails, null);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Attach onload handler
|
|
||||||
window.addEventListener("load", setup);
|
|
||||||
})();
|
|
@ -1,35 +0,0 @@
|
|||||||
<!--
|
|
||||||
This file is part of Linode Manager Classic.
|
|
||||||
|
|
||||||
Linode Manager Classic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Linode Manager Classic 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 General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<title>LMC - Graphs</title>
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="graphs.css" />
|
|
||||||
<script src="graphs.js" type="module"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!--#include virtual="/include/header.html"-->
|
|
||||||
<!--#include virtual="/include/linode_subnav.html"-->
|
|
||||||
<div id="main-content" class="wrapper">
|
|
||||||
<div id="top-links"><a href="/linodes">Linodes</a> » <span id="linode-tag"><a id="linode-tag-link" href=""></a> » </span><a id="linode-label" href="/linodes/dashboard?lid=0"></a> » <span class="top-links-title">Graphs</span></div>
|
|
||||||
<div id="graphs">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -44,24 +44,6 @@ import { settings, elements, apiGet, parseParams, setupHeader } from "/global.js
|
|||||||
data.linode = {};
|
data.linode = {};
|
||||||
data.netInfo = {};
|
data.netInfo = {};
|
||||||
|
|
||||||
// LISH uses different DC names than the API uses, so we need to translate them
|
|
||||||
data.lishDCs = {
|
|
||||||
"us-central": "dallas",
|
|
||||||
"us-west": "fremont",
|
|
||||||
"us-southeast": "atlanta",
|
|
||||||
"us-east": "newark",
|
|
||||||
"us-east-1b": "cjj2",
|
|
||||||
"eu-west": "london",
|
|
||||||
"ap-south": "singapore",
|
|
||||||
"eu-central": "frankfurt",
|
|
||||||
"ap-northeast": "shg1",
|
|
||||||
"ap-northeast-1a": "shg1",
|
|
||||||
"ca-central": "tor1",
|
|
||||||
"ap-west": "mum1",
|
|
||||||
"ap-southeast": "syd1",
|
|
||||||
"philadelphia": "phl1"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Static references to UI elements
|
// Static references to UI elements
|
||||||
var ui = {};
|
var ui = {};
|
||||||
ui.ipFailover = {};
|
ui.ipFailover = {};
|
||||||
@ -113,8 +95,8 @@ import { settings, elements, apiGet, parseParams, setupHeader } from "/global.js
|
|||||||
apiGet("/regions/" + data.linode.region, displayResolvers, null);
|
apiGet("/regions/" + data.linode.region, displayResolvers, null);
|
||||||
|
|
||||||
// Update the LISH link
|
// Update the LISH link
|
||||||
ui.lishLink.href = ui.lishLink.href.replace("lish-", "lish-" + data.lishDCs[data.linode.region]);
|
ui.lishLink.href = ui.lishLink.href.replace("lish-", "lish-" + data.linode.region);
|
||||||
ui.lishLink.innerHTML = ui.lishLink.innerHTML.replace("lish-", "lish-" + data.lishDCs[data.linode.region]);
|
ui.lishLink.innerHTML = ui.lishLink.innerHTML.replace("lish-", "lish-" + data.linode.region);
|
||||||
ui.lishLink.innerHTML += " " + data.linode.label;
|
ui.lishLink.innerHTML += " " + data.linode.label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#add {
|
#add {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lmc-table>tbody:not(.lmc-tbody-head)>tr>td:first-of-type {
|
.lmc-table>tbody:not(.lmc-tbody-head)>tr>td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <a href="/profile/api">API Keys</a> » <span class="top-links-title">Add</span></div>
|
||||||
<div id="add">
|
<div id="add">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#api {
|
#api {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-img {
|
.app-img {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <span class="top-links-title">API Keys</span></div>
|
||||||
<div id="api">
|
<div id="api">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#auth {
|
#auth {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <span class="top-links-title">Password & Authentication</span></div>
|
||||||
<div id="auth">
|
<div id="auth">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <span class="top-links-title">Lish Settings</span></div>
|
||||||
<div id="lish">
|
<div id="lish">
|
||||||
<p id="settings-saved">Settings saved.</p>
|
<p id="settings-saved">Settings saved.</p>
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#lish {
|
#lish {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#keys {
|
#keys {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <span class="top-links-title">Referrals</span></div>
|
||||||
<div id="referrals">
|
<div id="referrals">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#referrals {
|
#referrals {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#add {
|
#add {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <a href="/profile/ssh">SSH Keys</a> » <span class="top-links-title">Add</span></div>
|
||||||
<div id="add">
|
<div id="add">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <span class="top-links-title">SSH Keys</span></div>
|
||||||
<div id="ssh">
|
<div id="ssh">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/profile_subnav.html"-->
|
<!--#include virtual="/include/profile_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/profile">My Profile</a> » <a href="/profile/ssh">SSH Keys</a> » <span class="top-links-title">Remove</span></div>
|
||||||
<div id="remove">
|
<div id="remove">
|
||||||
<p>Are you sure you want to delete the key <strong id="label"></strong>?</p>
|
<p>Are you sure you want to delete the key <strong id="label"></strong>?</p>
|
||||||
<button disabled id="remove-button" type="button">Yes, delete this sucker</button>
|
<button disabled id="remove-button" type="button">Yes, delete this sucker</button>
|
||||||
|
@ -18,5 +18,5 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#remove {
|
#remove {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ssh {
|
#ssh {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td:nth-of-type(4) {
|
td:nth-of-type(4) {
|
||||||
|
@ -48,5 +48,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#twofactor {
|
#twofactor {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#add {
|
#add {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/user">Users</a> » <span class="top-links-title">Add</span></div>
|
||||||
<div id="add">
|
<div id="add">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#edit {
|
#edit {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
tbody:not(.lmc-tbody-head) tr td:first-of-type {
|
||||||
|
@ -25,6 +25,7 @@ import { settings, elements, apiGet, apiPut, md5, parseParams, setupHeader } fro
|
|||||||
elements.restrictedNo = "restricted-no";
|
elements.restrictedNo = "restricted-no";
|
||||||
elements.restrictedYes = "restricted-yes";
|
elements.restrictedYes = "restricted-yes";
|
||||||
elements.saveButton = "save-button";
|
elements.saveButton = "save-button";
|
||||||
|
elements.topUserLabel = "top-user-label";
|
||||||
elements.user = "user";
|
elements.user = "user";
|
||||||
elements.userLabel = "user-label";
|
elements.userLabel = "user-label";
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ import { settings, elements, apiGet, apiPut, md5, parseParams, setupHeader } fro
|
|||||||
ui.restrictedNo = {};
|
ui.restrictedNo = {};
|
||||||
ui.restrictedYes = {};
|
ui.restrictedYes = {};
|
||||||
ui.saveButton = {};
|
ui.saveButton = {};
|
||||||
|
ui.topUserLabel = {};
|
||||||
ui.user = {};
|
ui.user = {};
|
||||||
ui.userLabel = {};
|
ui.userLabel = {};
|
||||||
|
|
||||||
@ -98,10 +100,12 @@ import { settings, elements, apiGet, apiPut, md5, parseParams, setupHeader } fro
|
|||||||
ui.restrictedNo = document.getElementById(elements.restrictedNo);
|
ui.restrictedNo = document.getElementById(elements.restrictedNo);
|
||||||
ui.restrictedYes = document.getElementById(elements.restrictedYes);
|
ui.restrictedYes = document.getElementById(elements.restrictedYes);
|
||||||
ui.saveButton = document.getElementById(elements.saveButton);
|
ui.saveButton = document.getElementById(elements.saveButton);
|
||||||
|
ui.topUserLabel = document.getElementById(elements.topUserLabel);
|
||||||
ui.user = document.getElementById(elements.user);
|
ui.user = document.getElementById(elements.user);
|
||||||
ui.userLabel = document.getElementById(elements.userLabel);
|
ui.userLabel = document.getElementById(elements.userLabel);
|
||||||
|
|
||||||
// Populate username where we need it
|
// Populate username where we need it
|
||||||
|
ui.topUserLabel.innerHTML = data.params.user;
|
||||||
ui.userLabel.innerHTML = data.params.user;
|
ui.userLabel.innerHTML = data.params.user;
|
||||||
ui.pwReset.href += data.params.user;
|
ui.pwReset.href += data.params.user;
|
||||||
document.title += " - " + data.params.user;
|
document.title += " - " + data.params.user;
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/user">Users</a> » <span id="top-user-label" class="top-links-title"></span></div>
|
||||||
<div id="edit">
|
<div id="edit">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#grants {
|
#grants {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
@ -40,6 +40,7 @@ import { settings, elements, apiGet, apiPut, parseParams, setupHeader } from "/g
|
|||||||
elements.grantTables.stackscript = "ss-grants";
|
elements.grantTables.stackscript = "ss-grants";
|
||||||
elements.grantTables.volume = "volume-grants";
|
elements.grantTables.volume = "volume-grants";
|
||||||
elements.modifyLV = "modify-lv";
|
elements.modifyLV = "modify-lv";
|
||||||
|
elements.topUserLink = "top-user-link";
|
||||||
elements.updateButton = "update-button";
|
elements.updateButton = "update-button";
|
||||||
|
|
||||||
// Data received from API calls
|
// Data received from API calls
|
||||||
@ -66,6 +67,7 @@ import { settings, elements, apiGet, apiPut, parseParams, setupHeader } from "/g
|
|||||||
ui.grantTables.stackscript = {};
|
ui.grantTables.stackscript = {};
|
||||||
ui.grantTables.volume = {};
|
ui.grantTables.volume = {};
|
||||||
ui.modifyLV = {};
|
ui.modifyLV = {};
|
||||||
|
ui.topUserLink = {};
|
||||||
ui.updateButton = {};
|
ui.updateButton = {};
|
||||||
|
|
||||||
// Creates a row for a grant table
|
// Creates a row for a grant table
|
||||||
@ -254,10 +256,13 @@ import { settings, elements, apiGet, apiPut, parseParams, setupHeader } from "/g
|
|||||||
for (var i in ui.grantTables)
|
for (var i in ui.grantTables)
|
||||||
ui.grantTables[i] = document.getElementById(elements.grantTables[i]);
|
ui.grantTables[i] = document.getElementById(elements.grantTables[i]);
|
||||||
ui.modifyLV = document.getElementById(elements.modifyLV);
|
ui.modifyLV = document.getElementById(elements.modifyLV);
|
||||||
|
ui.topUserLink = document.getElementById(elements.topUserLink);
|
||||||
ui.updateButton = document.getElementById(elements.updateButton);
|
ui.updateButton = document.getElementById(elements.updateButton);
|
||||||
|
|
||||||
// Populate username where we need it
|
// Populate username where we need it
|
||||||
document.title += " - " + data.params.user;
|
document.title += " - " + data.params.user;
|
||||||
|
ui.topUserLink.href = "/user/edit?user=" + data.params.user;
|
||||||
|
ui.topUserLink.innerHTML = data.params.user;
|
||||||
|
|
||||||
// Attach event handlers
|
// Attach event handlers
|
||||||
ui.updateButton.addEventListener("click", handleUpdate);
|
ui.updateButton.addEventListener("click", handleUpdate);
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/user">Users</a> » <a id="top-user-link"></a> » <span class="top-links-title">Grants</span></div>
|
||||||
<div id="grants">
|
<div id="grants">
|
||||||
<h2>Global Grants</h2>
|
<h2>Global Grants</h2>
|
||||||
<input id="create-linode" type="checkbox" /> <label for="create-linode">Can add Linodes to this account ($)</label><br />
|
<input id="create-linode" type="checkbox" /> <label for="create-linode">Can add Linodes to this account ($)</label><br />
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <span class="top-links-title">Users</span></div>
|
||||||
<div id="user">
|
<div id="user">
|
||||||
<table class="lmc-table">
|
<table class="lmc-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,6 +27,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<!--#include virtual="/include/header.html"-->
|
<!--#include virtual="/include/header.html"-->
|
||||||
<!--#include virtual="/include/account_subnav.html"-->
|
<!--#include virtual="/include/account_subnav.html"-->
|
||||||
<div id="main-content" class="wrapper">
|
<div id="main-content" class="wrapper">
|
||||||
|
<div id="top-links"><a href="/account">Account</a> » <a href="/user">Users</a> » <a id="top-user-link" href=""></a> » <span class="top-links-title">Remove</span></div>
|
||||||
<div id="remove">
|
<div id="remove">
|
||||||
<p>Are you sure you want to delete the user '<span id="user-label"></span>'?</p>
|
<p>Are you sure you want to delete the user '<span id="user-label"></span>'?</p>
|
||||||
<button id="delete-button" type="button">Yes, Delete!</button> <button id="cancel-button" type="button">Cancel</button>
|
<button id="delete-button" type="button">Yes, Delete!</button> <button id="cancel-button" type="button">Cancel</button>
|
||||||
|
@ -18,5 +18,5 @@
|
|||||||
@import url('/global.css');
|
@import url('/global.css');
|
||||||
|
|
||||||
#remove {
|
#remove {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import { settings, elements, apiDelete, parseParams, setupHeader } from "/global
|
|||||||
// Element names specific to this page
|
// Element names specific to this page
|
||||||
elements.cancelButton = "cancel-button";
|
elements.cancelButton = "cancel-button";
|
||||||
elements.deleteButton = "delete-button";
|
elements.deleteButton = "delete-button";
|
||||||
|
elements.topUserLink = "top-user-link";
|
||||||
elements.userLabel = "user-label";
|
elements.userLabel = "user-label";
|
||||||
|
|
||||||
// Data received from API calls
|
// Data received from API calls
|
||||||
@ -31,6 +32,7 @@ import { settings, elements, apiDelete, parseParams, setupHeader } from "/global
|
|||||||
var ui = {};
|
var ui = {};
|
||||||
ui.cancelButton = {};
|
ui.cancelButton = {};
|
||||||
ui.deleteButton = {};
|
ui.deleteButton = {};
|
||||||
|
ui.topUserLink = {};
|
||||||
ui.userLabel = {};
|
ui.userLabel = {};
|
||||||
|
|
||||||
// Click handler for delete button
|
// Click handler for delete button
|
||||||
@ -66,9 +68,12 @@ import { settings, elements, apiDelete, parseParams, setupHeader } from "/global
|
|||||||
// Get element references
|
// Get element references
|
||||||
ui.cancelButton = document.getElementById(elements.cancelButton);
|
ui.cancelButton = document.getElementById(elements.cancelButton);
|
||||||
ui.deleteButton = document.getElementById(elements.deleteButton);
|
ui.deleteButton = document.getElementById(elements.deleteButton);
|
||||||
|
ui.topUserLink = document.getElementById(elements.topUserLink);
|
||||||
ui.userLabel = document.getElementById(elements.userLabel);
|
ui.userLabel = document.getElementById(elements.userLabel);
|
||||||
|
|
||||||
// Populate username where we need it
|
// Populate username where we need it
|
||||||
|
ui.topUserLink.href = "/user/edit?user=" + data.params.user;
|
||||||
|
ui.topUserLink.innerHTML = data.params.user;
|
||||||
ui.userLabel.innerHTML = data.params.user;
|
ui.userLabel.innerHTML = data.params.user;
|
||||||
|
|
||||||
// Attach event handlers
|
// Attach event handlers
|
||||||
|
@ -28,5 +28,5 @@ td:nth-of-type(4) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#user {
|
#user {
|
||||||
padding: 15px 15px 15px;
|
padding: 0 15px 15px;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user