Merge branch 'develop' into feature/admin-retheme
# Conflicts: # public/themes/pterodactyl/css/pterodactyl.css
This commit is contained in:
commit
799f2ee6d9
|
@ -1,4 +1,14 @@
|
||||||
/vendor
|
/vendor
|
||||||
*.DS_Store*
|
*.DS_Store*
|
||||||
.env
|
.env
|
||||||
|
.vagrant/*
|
||||||
|
|
||||||
|
composer.lock
|
||||||
|
|
||||||
|
Homestead.yaml
|
||||||
|
Vagrantfile
|
||||||
|
Vagrantfile
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
yarn.lock
|
||||||
node_modules
|
node_modules
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
$(window).load(function () {
|
$(document).ready(function () {
|
||||||
Socket.on('console', function (data) {
|
Socket.on('console', function (data) {
|
||||||
if (data.line.indexOf('You need to agree to the EULA in order to run the server') > -1) {
|
if (~data.line.indexOf('You need to agree to the EULA in order to run the server')) {
|
||||||
swal({
|
swal({
|
||||||
title: 'EULA Acceptance',
|
title: 'EULA Acceptance',
|
||||||
text: 'By pressing \'I Accept\' below you are indicating your agreement to the <a href="https://account.mojang.com/documents/minecraft_eula" target="_blank">Mojang EULA</a>.',
|
text: 'By pressing \'I Accept\' below you are indicating your agreement to the <a href="https://account.mojang.com/documents/minecraft_eula" target="_blank">Mojang EULA</a>.',
|
||||||
|
|
|
@ -245,3 +245,24 @@ span[aria-labelledby="select2-pUserId-container"] {
|
||||||
.nav-tabs-custom.nav-tabs-floating > .nav-tabs > li:first-child.active > a {
|
.nav-tabs-custom.nav-tabs-floating > .nav-tabs > li:first-child.active > a {
|
||||||
border-radius: 0 0 0 3px;
|
border-radius: 0 0 0 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.position-relative {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-notify {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 10px;
|
||||||
|
/* Browsers usually have a 17px scrollbar which is visible in the terminal */
|
||||||
|
padding: 7px 24px 7px 7px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
opacity: .5;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-notify:hover {
|
||||||
|
opacity: .9;
|
||||||
|
}
|
||||||
|
|
|
@ -17,60 +17,75 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
$(document).ready(function () {
|
|
||||||
$('#close_reload').click(function () {
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
$('#do_2fa').submit(function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
$.ajax({
|
var TwoFactorModal = (function () {
|
||||||
type: 'PUT',
|
|
||||||
url: Router.route('account.security.totp'),
|
function bindListeners() {
|
||||||
headers: {
|
$(document).ready(function () {
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
$('#close_reload').click(function () {
|
||||||
}
|
location.reload();
|
||||||
}).done(function (data) {
|
});
|
||||||
var image = new Image();
|
$('#do_2fa').submit(function (event) {
|
||||||
image.src = data.qrImage;
|
event.preventDefault();
|
||||||
$(image).load(function () {
|
|
||||||
$('#hide_img_load').slideUp(function () {
|
$.ajax({
|
||||||
$('#qr_image_insert').attr('src', image.src).slideDown();
|
type: 'PUT',
|
||||||
|
url: Router.route('account.security.totp'),
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||||
|
}
|
||||||
|
}).done(function (data) {
|
||||||
|
var image = new Image();
|
||||||
|
image.src = data.qrImage;
|
||||||
|
$(image).load(function () {
|
||||||
|
$('#hide_img_load').slideUp(function () {
|
||||||
|
$('#qr_image_insert').attr('src', image.src).slideDown();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$('#2fa_secret_insert').html(data.secret);
|
||||||
|
$('#open2fa').modal('show');
|
||||||
|
}).fail(function (jqXHR) {
|
||||||
|
alert('An error occured while attempting to load the 2FA setup modal. Please try again.');
|
||||||
|
console.error(jqXHR);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
$('#2fa_token_verify').submit(function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
$('#submit_action').html('<i class="fa fa-spinner fa-spin"></i> Submit').addClass('disabled');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: Router.route('account.security.totp'),
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
token: $('#2fa_token').val()
|
||||||
|
}
|
||||||
|
}).done(function (data) {
|
||||||
|
$('#notice_box_2fa').hide();
|
||||||
|
if (data === 'true') {
|
||||||
|
$('#notice_box_2fa').html('<div class="alert alert-success">2-Factor Authentication has been enabled on your account. Press \'Close\' below to reload the page.</div>').slideDown();
|
||||||
|
} else {
|
||||||
|
$('#notice_box_2fa').html('<div class="alert alert-danger">The token provided was invalid.</div>').slideDown();
|
||||||
|
}
|
||||||
|
}).fail(function (jqXHR) {
|
||||||
|
$('#notice_box_2fa').html('<div class="alert alert-danger">There was an error while attempting to enable 2-Factor Authentication on this account.</div>').slideDown();
|
||||||
|
console.error(jqXHR);
|
||||||
|
}).always(function () {
|
||||||
|
$('#submit_action').html('Submit').removeClass('disabled');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#2fa_secret_insert').html(data.secret);
|
|
||||||
$('#open2fa').modal('show');
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
alert('An error occured while attempting to load the 2FA setup modal. Please try again.');
|
|
||||||
console.error(jqXHR);
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
return {
|
||||||
$('#2fa_token_verify').submit(function (event) {
|
init: function () {
|
||||||
event.preventDefault();
|
bindListeners();
|
||||||
$('#submit_action').html('<i class="fa fa-spinner fa-spin"></i> Submit').addClass('disabled');
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: Router.route('account.security.totp'),
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
token: $('#2fa_token').val()
|
|
||||||
}
|
|
||||||
}).done(function (data) {
|
|
||||||
$('#notice_box_2fa').hide();
|
|
||||||
if (data === 'true') {
|
|
||||||
$('#notice_box_2fa').html('<div class="alert alert-success">2-Factor Authentication has been enabled on your account. Press \'Close\' below to reload the page.</div>').slideDown();
|
|
||||||
} else {
|
|
||||||
$('#notice_box_2fa').html('<div class="alert alert-danger">The token provided was invalid.</div>').slideDown();
|
|
||||||
}
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
$('#notice_box_2fa').html('<div class="alert alert-danger">There was an error while attempting to enable 2-Factor Authentication on this account.</div>').slideDown();
|
|
||||||
console.error(jqXHR);
|
|
||||||
}).always(function () {
|
|
||||||
$('#submit_action').html('Submit').removeClass('disabled');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TwoFactorModal.init();
|
||||||
|
|
|
@ -17,173 +17,203 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
var CONSOLE_PUSH_COUNT = 50;
|
|
||||||
var CONSOLE_PUSH_FREQ = 200;
|
|
||||||
|
|
||||||
(function initConsole() {
|
var Console = (function () {
|
||||||
window.TerminalQueue = [];
|
var CONSOLE_PUSH_COUNT = 50;
|
||||||
window.Terminal = $('#terminal').terminal(function (command, term) {
|
var CONSOLE_PUSH_FREQ = 200;
|
||||||
Socket.emit('send command', command);
|
|
||||||
}, {
|
|
||||||
greetings: '',
|
|
||||||
name: Pterodactyl.server.uuid,
|
|
||||||
height: 450,
|
|
||||||
exit: false,
|
|
||||||
prompt: Pterodactyl.server.username + ':~$ ',
|
|
||||||
scrollOnEcho: false,
|
|
||||||
scrollBottomOffset: 5,
|
|
||||||
onBlur: function (terminal) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('initial status', function (data) {
|
var terminalQueue;
|
||||||
Terminal.clear();
|
var terminal;
|
||||||
if (data.status === 1 || data.status === 2) {
|
|
||||||
Socket.emit('send server log');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function pushOutputQueue() {
|
var cpuChart;
|
||||||
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
|
var cpuData;
|
||||||
// console throttled warning show
|
var memoryChart;
|
||||||
|
var memoryData;
|
||||||
|
var timeLabels;
|
||||||
|
|
||||||
|
var $terminalNotify;
|
||||||
|
|
||||||
|
function initConsole() {
|
||||||
|
terminalQueue = [];
|
||||||
|
terminal = $('#terminal').terminal(function (command, term) {
|
||||||
|
Socket.emit('send command', command);
|
||||||
|
}, {
|
||||||
|
greetings: '',
|
||||||
|
name: Pterodactyl.server.uuid,
|
||||||
|
height: 450,
|
||||||
|
exit: false,
|
||||||
|
prompt: Pterodactyl.server.username + ':~$ ',
|
||||||
|
scrollOnEcho: false,
|
||||||
|
scrollBottomOffset: 5,
|
||||||
|
onBlur: function (terminal) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$terminalNotify = $('#terminalNotify');
|
||||||
|
$terminalNotify.on('click', function () {
|
||||||
|
terminal.scroll_to_bottom();
|
||||||
|
$terminalNotify.addClass('hidden');
|
||||||
|
})
|
||||||
|
|
||||||
|
terminal.on('scroll', function () {
|
||||||
|
if (terminal.is_bottom()) {
|
||||||
|
$terminalNotify.addClass('hidden');
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TerminalQueue.length > 0) {
|
function initGraphs() {
|
||||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
|
var ctc = $('#chart_cpu');
|
||||||
Terminal.echo(TerminalQueue[0]);
|
timeLabels = [];
|
||||||
TerminalQueue.shift();
|
cpuData = [];
|
||||||
}
|
cpuChart = new Chart(ctc, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: timeLabels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Percent Use",
|
||||||
|
fill: false,
|
||||||
|
lineTension: 0.03,
|
||||||
|
backgroundColor: "#3c8dbc",
|
||||||
|
borderColor: "#3c8dbc",
|
||||||
|
borderCapStyle: 'butt',
|
||||||
|
borderDash: [],
|
||||||
|
borderDashOffset: 0.0,
|
||||||
|
borderJoinStyle: 'miter',
|
||||||
|
pointBorderColor: "#3c8dbc",
|
||||||
|
pointBackgroundColor: "#fff",
|
||||||
|
pointBorderWidth: 1,
|
||||||
|
pointHoverRadius: 5,
|
||||||
|
pointHoverBackgroundColor: "#3c8dbc",
|
||||||
|
pointHoverBorderColor: "rgba(220,220,220,1)",
|
||||||
|
pointHoverBorderWidth: 2,
|
||||||
|
pointRadius: 1,
|
||||||
|
pointHitRadius: 10,
|
||||||
|
data: cpuData,
|
||||||
|
spanGaps: false,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'CPU Usage (as Percent Total)'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
duration: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var ctm = $('#chart_memory');
|
||||||
|
memoryData = [];
|
||||||
|
memoryChart = new Chart(ctm, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: timeLabels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Memory Use",
|
||||||
|
fill: false,
|
||||||
|
lineTension: 0.03,
|
||||||
|
backgroundColor: "#3c8dbc",
|
||||||
|
borderColor: "#3c8dbc",
|
||||||
|
borderCapStyle: 'butt',
|
||||||
|
borderDash: [],
|
||||||
|
borderDashOffset: 0.0,
|
||||||
|
borderJoinStyle: 'miter',
|
||||||
|
pointBorderColor: "#3c8dbc",
|
||||||
|
pointBackgroundColor: "#fff",
|
||||||
|
pointBorderWidth: 1,
|
||||||
|
pointHoverRadius: 5,
|
||||||
|
pointHoverBackgroundColor: "#3c8dbc",
|
||||||
|
pointHoverBorderColor: "rgba(220,220,220,1)",
|
||||||
|
pointHoverBorderWidth: 2,
|
||||||
|
pointRadius: 1,
|
||||||
|
pointHitRadius: 10,
|
||||||
|
data: memoryData,
|
||||||
|
spanGaps: false,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Memory Usage (in Megabytes)'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
duration: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
function addSocketListeners() {
|
||||||
})();
|
// Update Listings on Initial Status
|
||||||
|
Socket.on('initial status', function (data) {
|
||||||
|
updateServerPowerControls(data.status);
|
||||||
|
|
||||||
$(document).ready(function () {
|
terminal.clear();
|
||||||
$('[data-attr="power"]').click(function (event) {
|
if (data.status === 1 || data.status === 2) {
|
||||||
if (! $(this).hasClass('disabled')) {
|
Socket.emit('send server log');
|
||||||
Socket.emit('set status', $(this).data('action'));
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update Listings on Status
|
||||||
|
Socket.on('status', function (data) {
|
||||||
|
updateServerPowerControls(data.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('console', function (data) {
|
||||||
|
terminalQueue.push(data.line);
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('proc', function (proc) {
|
||||||
|
if (cpuData.length > 10) {
|
||||||
|
cpuData.shift();
|
||||||
|
memoryData.shift();
|
||||||
|
timeLabels.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
|
||||||
|
cpuData.push(cpuUse);
|
||||||
|
memoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
|
||||||
|
|
||||||
|
var m = new Date();
|
||||||
|
timeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
||||||
|
|
||||||
|
cpuChart.update();
|
||||||
|
memoryChart.update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushOutputQueue() {
|
||||||
|
if (terminalQueue.length > CONSOLE_PUSH_COUNT) {
|
||||||
|
// console throttled warning show
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
var ctc = $('#chart_cpu');
|
if (terminalQueue.length > 0) {
|
||||||
var timeLabels = [];
|
for (var i = 0; i < CONSOLE_PUSH_COUNT && terminalQueue.length > 0; i++) {
|
||||||
var cpuData = [];
|
terminal.echo(terminalQueue[0]);
|
||||||
var CPUChart = new Chart(ctc, {
|
terminalQueue.shift();
|
||||||
type: 'line',
|
}
|
||||||
data: {
|
|
||||||
labels: timeLabels,
|
// Show
|
||||||
datasets: [
|
if (!terminal.is_bottom()) {
|
||||||
{
|
$terminalNotify.removeClass('hidden');
|
||||||
label: "Percent Use",
|
|
||||||
fill: false,
|
|
||||||
lineTension: 0.03,
|
|
||||||
backgroundColor: "#00A1CB",
|
|
||||||
borderColor: "#00A1CB",
|
|
||||||
borderCapStyle: 'butt',
|
|
||||||
borderDash: [],
|
|
||||||
borderDashOffset: 0.0,
|
|
||||||
borderJoinStyle: 'miter',
|
|
||||||
pointBorderColor: "rgba(75,192,192,1)",
|
|
||||||
pointBackgroundColor: "#fff",
|
|
||||||
pointBorderWidth: 1,
|
|
||||||
pointHoverRadius: 5,
|
|
||||||
pointHoverBackgroundColor: "rgba(75,192,192,1)",
|
|
||||||
pointHoverBorderColor: "rgba(220,220,220,1)",
|
|
||||||
pointHoverBorderWidth: 2,
|
|
||||||
pointRadius: 1,
|
|
||||||
pointHitRadius: 10,
|
|
||||||
data: cpuData,
|
|
||||||
spanGaps: false,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'CPU Usage (as Percent Total)'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
animation: {
|
|
||||||
duration: 1,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
var ctm = $('#chart_memory');
|
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
||||||
var memoryData = [];
|
}
|
||||||
var MemoryChart = new Chart(ctm, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: timeLabels,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Memory Use",
|
|
||||||
fill: false,
|
|
||||||
lineTension: 0.03,
|
|
||||||
backgroundColor: "#01A4A4",
|
|
||||||
borderColor: "#01A4A4",
|
|
||||||
borderCapStyle: 'butt',
|
|
||||||
borderDash: [],
|
|
||||||
borderDashOffset: 0.0,
|
|
||||||
borderJoinStyle: 'miter',
|
|
||||||
pointBorderColor: "rgba(75,192,192,1)",
|
|
||||||
pointBackgroundColor: "#fff",
|
|
||||||
pointBorderWidth: 1,
|
|
||||||
pointHoverRadius: 5,
|
|
||||||
pointHoverBackgroundColor: "rgba(75,192,192,1)",
|
|
||||||
pointHoverBorderColor: "rgba(220,220,220,1)",
|
|
||||||
pointHoverBorderWidth: 2,
|
|
||||||
pointRadius: 1,
|
|
||||||
pointHitRadius: 10,
|
|
||||||
data: memoryData,
|
|
||||||
spanGaps: false,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Memory Usage (in Megabytes)'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
animation: {
|
|
||||||
duration: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Socket.on('proc', function (proc) {
|
|
||||||
if (cpuData.length > 10) {
|
|
||||||
cpuData.shift();
|
|
||||||
memoryData.shift();
|
|
||||||
timeLabels.shift();
|
|
||||||
}
|
|
||||||
|
|
||||||
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
|
|
||||||
cpuData.push(cpuUse);
|
|
||||||
memoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
|
|
||||||
|
|
||||||
var m = new Date();
|
|
||||||
timeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
|
||||||
|
|
||||||
CPUChart.update();
|
|
||||||
MemoryChart.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Listings on Initial Status
|
|
||||||
Socket.on('initial status', function (data) {
|
|
||||||
updateServerPowerControls(data.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Listings on Status
|
|
||||||
Socket.on('status', function (data) {
|
|
||||||
updateServerPowerControls(data.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
function updateServerPowerControls (data) {
|
function updateServerPowerControls (data) {
|
||||||
// Server is On or Starting
|
// Server is On or Starting
|
||||||
|
@ -203,4 +233,33 @@ $(document).ready(function () {
|
||||||
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: function () {
|
||||||
|
|
||||||
|
initConsole();
|
||||||
|
pushOutputQueue();
|
||||||
|
initGraphs();
|
||||||
|
addSocketListeners();
|
||||||
|
|
||||||
|
$('[data-attr="power"]').click(function (event) {
|
||||||
|
if (! $(this).hasClass('disabled')) {
|
||||||
|
Socket.emit('set status', $(this).data('action'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getTerminal: function () {
|
||||||
|
return terminal
|
||||||
|
},
|
||||||
|
|
||||||
|
getTerminalQueue: function () {
|
||||||
|
return terminalQueue
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
Console.init();
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,15 +29,22 @@ class ActionsClass {
|
||||||
this.element = undefined;
|
this.element = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
folder() {
|
folder(path) {
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
let inputValue
|
||||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
if (path) {
|
||||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
inputValue = path
|
||||||
|
} else {
|
||||||
|
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||||
|
const currentName = decodeURIComponent(nameBlock.data('name'));
|
||||||
|
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||||
|
|
||||||
let inputValue = `${currentPath}${currentName}/`;
|
if ($(this.element).data('type') === 'file') {
|
||||||
if ($(this.element).data('type') === 'file') {
|
inputValue = currentPath;
|
||||||
inputValue = currentPath;
|
} else {
|
||||||
|
inputValue = `${currentPath}${currentName}/`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
swal({
|
swal({
|
||||||
type: 'input',
|
type: 'input',
|
||||||
title: 'Create Folder',
|
title: 'Create Folder',
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ContextMenuClass {
|
||||||
$(document).find('#fileOptionMenu').remove();
|
$(document).find('#fileOptionMenu').remove();
|
||||||
if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
|
if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
|
||||||
|
|
||||||
let newFilePath = $('#headerTableRow').attr('data-currentDir');
|
let newFilePath = $('#file_listing').data('current-dir');
|
||||||
if (parent.data('type') === 'folder') {
|
if (parent.data('type') === 'folder') {
|
||||||
const nameBlock = parent.find('td[data-identifier="name"]');
|
const nameBlock = parent.find('td[data-identifier="name"]');
|
||||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||||
|
|
|
@ -44,6 +44,7 @@ class FileManager {
|
||||||
$('#load_files').slideUp(10).html(data).slideDown(10, () => {
|
$('#load_files').slideUp(10).html(data).slideDown(10, () => {
|
||||||
ContextMenu.run();
|
ContextMenu.run();
|
||||||
this.reloadFilesButton();
|
this.reloadFilesButton();
|
||||||
|
this.addFolderButton();
|
||||||
if (_.isFunction(next)) {
|
if (_.isFunction(next)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
@ -82,6 +83,12 @@ class FileManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFolderButton() {
|
||||||
|
$('i[data-action="add-folder"]').unbind().on('click', () => {
|
||||||
|
new ActionsClass().folder($('#file_listing').data('current-dir') || '/');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
decodeHash() {
|
decodeHash() {
|
||||||
return decodeURIComponent(window.location.hash.substring(1));
|
return decodeURIComponent(window.location.hash.substring(1));
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
window.onbeforeunload = function () {
|
window.onbeforeunload = function () {
|
||||||
return 'A file upload in in progress, are you sure you want to continue?';
|
return 'A file upload in in progress, are you sure you want to continue?';
|
||||||
};
|
};
|
||||||
event.file.meta.path = $('#headerTableRow').attr('data-currentdir');
|
event.file.meta.path = $('#file_listing').data('current-dir');
|
||||||
event.file.meta.identifier = Math.random().toString(36).slice(2);
|
event.file.meta.identifier = Math.random().toString(36).slice(2);
|
||||||
|
|
||||||
$('#append_files_to').append('<tr id="file-upload-' + event.file.meta.identifier +'"> \
|
$('#append_files_to').append('<tr id="file-upload-' + event.file.meta.identifier +'"> \
|
||||||
|
|
|
@ -17,83 +17,94 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
(function initSocket() {
|
|
||||||
if (typeof $.notifyDefaults !== 'function') {
|
var Server = (function () {
|
||||||
console.error('Notify does not appear to be loaded.');
|
|
||||||
return;
|
function initSocket() {
|
||||||
|
if (typeof $.notifyDefaults !== 'function') {
|
||||||
|
console.error('Notify does not appear to be loaded.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof io !== 'function') {
|
||||||
|
console.error('Socket.io is reqired to use this panel.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.notifyDefaults({
|
||||||
|
placement: {
|
||||||
|
from: 'bottom',
|
||||||
|
align: 'right'
|
||||||
|
},
|
||||||
|
newest_on_top: true,
|
||||||
|
delay: 2000,
|
||||||
|
animate: {
|
||||||
|
enter: 'animated zoomInDown',
|
||||||
|
exit: 'animated zoomOutDown'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var notifySocketError = false;
|
||||||
|
|
||||||
|
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, {
|
||||||
|
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.io.on('connect_error', function (err) {
|
||||||
|
if(typeof notifySocketError !== 'object') {
|
||||||
|
notifySocketError = $.notify({
|
||||||
|
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
|
||||||
|
}, {
|
||||||
|
type: 'danger',
|
||||||
|
delay: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connected to Socket Successfully
|
||||||
|
Socket.on('connect', function () {
|
||||||
|
if (notifySocketError !== false) {
|
||||||
|
notifySocketError.close();
|
||||||
|
notifySocketError = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('initial status', function (data) {
|
||||||
|
setStatusIcon(data.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('status', function (data) {
|
||||||
|
setStatusIcon(data.status);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof io !== 'function') {
|
function setStatusIcon(status) {
|
||||||
console.error('Socket.io is reqired to use this panel.');
|
switch (status) {
|
||||||
return;
|
case 0:
|
||||||
|
$('#server_status_icon').html('<i class="fa fa-circle text-danger"></i> Offline');
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$('#server_status_icon').html('<i class="fa fa-circle text-success"></i> Online');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Starting');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Stopping');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$.notifyDefaults({
|
return {
|
||||||
placement: {
|
init: function () {
|
||||||
from: 'bottom',
|
initSocket();
|
||||||
align: 'right'
|
|
||||||
},
|
},
|
||||||
newest_on_top: true,
|
|
||||||
delay: 2000,
|
|
||||||
animate: {
|
|
||||||
enter: 'animated zoomInDown',
|
|
||||||
exit: 'animated zoomOutDown'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var notifySocketError = false;
|
setStatusIcon: setStatusIcon,
|
||||||
|
}
|
||||||
|
|
||||||
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, {
|
|
||||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.io.on('connect_error', function (err) {
|
|
||||||
if(typeof notifySocketError !== 'object') {
|
|
||||||
notifySocketError = $.notify({
|
|
||||||
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
|
|
||||||
}, {
|
|
||||||
type: 'danger',
|
|
||||||
delay: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Connected to Socket Successfully
|
|
||||||
Socket.on('connect', function () {
|
|
||||||
if (notifySocketError !== false) {
|
|
||||||
notifySocketError.close();
|
|
||||||
notifySocketError = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('initial status', function (data) {
|
|
||||||
setStatusIcon(data.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('status', function (data) {
|
|
||||||
setStatusIcon(data.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('console', function (data) {
|
|
||||||
TerminalQueue.push(data.line);
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function setStatusIcon(status) {
|
Server.init();
|
||||||
switch (status) {
|
|
||||||
case 0:
|
|
||||||
$('#server_status_icon').html('<i class="fa fa-circle text-danger"></i> Offline');
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
$('#server_status_icon').html('<i class="fa fa-circle text-success"></i> Online');
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Starting');
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Stopping');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,14 +17,16 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
var Status = {
|
|
||||||
0: 'Offline',
|
|
||||||
1: 'Online',
|
|
||||||
2: 'Starting',
|
|
||||||
3: 'Stopping'
|
|
||||||
};
|
|
||||||
|
|
||||||
(function updateServerStatus () {
|
var ServerList = (function () {
|
||||||
|
|
||||||
|
var Status = {
|
||||||
|
0: 'Offline',
|
||||||
|
1: 'Online',
|
||||||
|
2: 'Starting',
|
||||||
|
3: 'Stopping'
|
||||||
|
};
|
||||||
|
|
||||||
$('.dynamic-update').each(function (index, data) {
|
$('.dynamic-update').each(function (index, data) {
|
||||||
var element = $(this);
|
var element = $(this);
|
||||||
var serverShortUUID = $(this).data('server');
|
var serverShortUUID = $(this).data('server');
|
||||||
|
@ -67,16 +69,32 @@ var Status = {
|
||||||
if (cpuMax !== 0) {
|
if (cpuMax !== 0) {
|
||||||
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
||||||
}
|
}
|
||||||
element.find('[data-action="memory"]').html(parseInt(data.proc.memory.total / (1024 * 1024)));
|
if (data.status !== 0) {
|
||||||
element.find('[data-action="cpu"]').html(currentCpu);
|
var cpuMax = element.find('[data-action="cpu"]').data('cpumax');
|
||||||
} else {
|
var currentCpu = data.proc.cpu.total;
|
||||||
element.find('[data-action="memory"]').html('--');
|
if (cpuMax !== 0) {
|
||||||
element.find('[data-action="cpu"]').html('--');
|
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
||||||
}
|
}
|
||||||
}).fail(function (jqXHR) {
|
element.find('[data-action="memory"]').html(parseInt(data.proc.memory.total / (1024 * 1024)));
|
||||||
console.error(jqXHR);
|
element.find('[data-action="cpu"]').html(currentCpu);
|
||||||
element.find('[data-action="status"]').html('<span class="label label-default">Error</span>');
|
} else {
|
||||||
|
element.find('[data-action="memory"]').html('--');
|
||||||
|
element.find('[data-action="cpu"]').html('--');
|
||||||
|
}
|
||||||
|
}).fail(function (jqXHR) {
|
||||||
|
console.error(jqXHR);
|
||||||
|
element.find('[data-action="status"]').html('<span class="label label-default">Error</span>');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
setTimeout(updateServerStatus, 10000);
|
||||||
setTimeout(updateServerStatus, 10000);
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: function () {
|
||||||
|
updateServerStatus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
ServerList.init();
|
||||||
|
|
|
@ -17,86 +17,99 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
(function initTaskFunctions() {
|
|
||||||
$('[data-action="delete-task"]').click(function (event) {
|
var Tasks = (function () {
|
||||||
var self = $(this);
|
|
||||||
swal({
|
function initTaskFunctions() {
|
||||||
type: 'error',
|
$('[data-action="delete-task"]').click(function (event) {
|
||||||
title: 'Delete Task?',
|
var self = $(this);
|
||||||
text: 'Are you sure you want to delete this task? There is no undo.',
|
swal({
|
||||||
showCancelButton: true,
|
type: 'error',
|
||||||
allowOutsideClick: true,
|
title: 'Delete Task?',
|
||||||
closeOnConfirm: false,
|
text: 'Are you sure you want to delete this task? There is no undo.',
|
||||||
confirmButtonText: 'Delete Task',
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#d9534f',
|
allowOutsideClick: true,
|
||||||
showLoaderOnConfirm: true
|
closeOnConfirm: false,
|
||||||
}, function () {
|
confirmButtonText: 'Delete Task',
|
||||||
$.ajax({
|
confirmButtonColor: '#d9534f',
|
||||||
method: 'DELETE',
|
showLoaderOnConfirm: true
|
||||||
url: Router.route('server.tasks.delete', {
|
}, function () {
|
||||||
server: Pterodactyl.server.uuidShort,
|
$.ajax({
|
||||||
id: self.data('id'),
|
method: 'DELETE',
|
||||||
}),
|
url: Router.route('server.tasks.delete', {
|
||||||
headers: {
|
server: Pterodactyl.server.uuidShort,
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
id: self.data('id'),
|
||||||
}
|
}),
|
||||||
}).done(function (data) {
|
headers: {
|
||||||
swal({
|
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||||
type: 'success',
|
}
|
||||||
title: '',
|
}).done(function (data) {
|
||||||
text: 'Task has been deleted.'
|
swal({
|
||||||
});
|
type: 'success',
|
||||||
self.parent().parent().slideUp();
|
title: '',
|
||||||
}).fail(function (jqXHR) {
|
text: 'Task has been deleted.'
|
||||||
console.error(jqXHR);
|
});
|
||||||
swal({
|
self.parent().parent().slideUp();
|
||||||
type: 'error',
|
}).fail(function (jqXHR) {
|
||||||
title: 'Whoops!',
|
console.error(jqXHR);
|
||||||
text: 'An error occured while attempting to delete this task.'
|
swal({
|
||||||
|
type: 'error',
|
||||||
|
title: 'Whoops!',
|
||||||
|
text: 'An error occured while attempting to delete this task.'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
$('[data-action="toggle-task"]').click(function (event) {
|
||||||
$('[data-action="toggle-task"]').click(function (event) {
|
var self = $(this);
|
||||||
var self = $(this);
|
swal({
|
||||||
swal({
|
type: 'info',
|
||||||
type: 'info',
|
title: 'Toggle Task',
|
||||||
title: 'Toggle Task',
|
text: 'This will toggle the selected task.',
|
||||||
text: 'This will toggle the selected task.',
|
showCancelButton: true,
|
||||||
showCancelButton: true,
|
allowOutsideClick: true,
|
||||||
allowOutsideClick: true,
|
closeOnConfirm: false,
|
||||||
closeOnConfirm: false,
|
confirmButtonText: 'Continue',
|
||||||
confirmButtonText: 'Continue',
|
showLoaderOnConfirm: true
|
||||||
showLoaderOnConfirm: true
|
}, function () {
|
||||||
}, function () {
|
$.ajax({
|
||||||
$.ajax({
|
method: 'POST',
|
||||||
method: 'POST',
|
url: Router.route('server.tasks.toggle', {
|
||||||
url: Router.route('server.tasks.toggle', {
|
server: Pterodactyl.server.uuidShort,
|
||||||
server: Pterodactyl.server.uuidShort,
|
id: self.data('id'),
|
||||||
id: self.data('id'),
|
}),
|
||||||
}),
|
headers: {
|
||||||
headers: {
|
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
}
|
||||||
}
|
}).done(function (data) {
|
||||||
}).done(function (data) {
|
swal({
|
||||||
swal({
|
type: 'success',
|
||||||
type: 'success',
|
title: '',
|
||||||
title: '',
|
text: 'Task has been toggled.'
|
||||||
text: 'Task has been toggled.'
|
});
|
||||||
});
|
if (data.status !== 1) {
|
||||||
if (data.status !== 1) {
|
self.parent().parent().addClass('muted muted-hover');
|
||||||
self.parent().parent().addClass('muted muted-hover');
|
} else {
|
||||||
} else {
|
self.parent().parent().removeClass('muted muted-hover');
|
||||||
self.parent().parent().removeClass('muted muted-hover');
|
}
|
||||||
}
|
}).fail(function (jqXHR) {
|
||||||
}).fail(function (jqXHR) {
|
console.error(jqXHR);
|
||||||
console.error(jqXHR);
|
swal({
|
||||||
swal({
|
type: 'error',
|
||||||
type: 'error',
|
title: 'Whoops!',
|
||||||
title: 'Whoops!',
|
text: 'An error occured while attempting to toggle this task.'
|
||||||
text: 'An error occured while attempting to toggle this task.'
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: function () {
|
||||||
|
initTaskFunctions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
Tasks.init();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -212,6 +212,7 @@ return [
|
||||||
'size' => 'Size',
|
'size' => 'Size',
|
||||||
'last_modified' => 'Last Modified',
|
'last_modified' => 'Last Modified',
|
||||||
'add_new' => 'Add New File',
|
'add_new' => 'Add New File',
|
||||||
|
'add_folder' => 'Add New Folder',
|
||||||
'edit' => [
|
'edit' => [
|
||||||
'header' => 'Edit File',
|
'header' => 'Edit File',
|
||||||
'header_sub' => 'Make modifications to a file from the web.',
|
'header_sub' => 'Make modifications to a file from the web.',
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
Copyright © 2015 - {{ date('Y') }} <a href="https://pterodactyl.io/" target="_blank">Pterodactyl Software</a>.<br />
|
Copyright © 2015 - {{ date('Y') }} <a href="https://pterodactyl.io/" target="_blank">Pterodactyl Software</a>.<br />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{!! Theme::js('js/vendor/jquery/jquery.min.js') !!}
|
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
||||||
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
||||||
|
|
||||||
@if(config('app.phrase_in_context')) {!! Theme::js('js/phraseapp.js') !!} @endif
|
@if(config('app.phrase_in_context')) {!! Theme::js('js/phraseapp.js') !!} @endif
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</div>
|
</div>
|
||||||
@section('footer-scripts')
|
@section('footer-scripts')
|
||||||
{!! Theme::js('js/laroute.js') !!}
|
{!! Theme::js('js/laroute.js') !!}
|
||||||
{!! Theme::js('js/vendor/jquery/jquery.min.js') !!}
|
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
||||||
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
||||||
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
|
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
|
||||||
{!! Theme::js('vendor/adminlte/app.min.js') !!}
|
{!! Theme::js('vendor/adminlte/app.min.js') !!}
|
||||||
|
|
|
@ -266,7 +266,7 @@
|
||||||
</div>
|
</div>
|
||||||
@section('footer-scripts')
|
@section('footer-scripts')
|
||||||
{!! Theme::js('js/laroute.js') !!}
|
{!! Theme::js('js/laroute.js') !!}
|
||||||
{!! Theme::js('js/vendor/jquery/jquery.min.js') !!}
|
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
||||||
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
|
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
|
||||||
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
||||||
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
|
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
|
||||||
|
|
|
@ -38,8 +38,10 @@
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
<div class="overlay file-overlay"><i class="fa fa-refresh fa-spin"></i></div>
|
<div class="overlay file-overlay"><i class="fa fa-refresh fa-spin"></i></div>
|
||||||
<div class="box-body table-responsive no-padding" id="load_files">
|
<div id="load_files">
|
||||||
<div class="callout callout-info" style="margin:10px;">@lang('server.files.loading')</div>
|
<div class="box-body table-responsive no-padding">
|
||||||
|
<div class="callout callout-info" style="margin:10px;">@lang('server.files.loading')</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer with-border">
|
<div class="box-footer with-border">
|
||||||
<p class="text-muted small" style="margin: 0 0 2px;">@lang('server.files.path', ['path' => '<code>/home/container</code>', 'size' => '<code>' . $node->upload_size . ' MB</code>'])</p>
|
<p class="text-muted small" style="margin: 0 0 2px;">@lang('server.files.path', ['path' => '<code>/home/container</code>', 'size' => '<code>' . $node->upload_size . ' MB</code>'])</p>
|
||||||
|
|
|
@ -17,148 +17,151 @@
|
||||||
{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}}
|
{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}}
|
||||||
{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}}
|
{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}}
|
||||||
{{-- SOFTWARE. --}}
|
{{-- SOFTWARE. --}}
|
||||||
<table class="table table-hover" id="file_listing">
|
|
||||||
<thead>
|
<div class="box-header">
|
||||||
<tr>
|
<i class="fa fa-refresh muted muted-hover use-pointer" data-action="reload-files"></i>
|
||||||
<th style="width:2%;text-align:center;" class="middle"><i class="fa fa-refresh muted muted-hover use-pointer" data-action="reload-files"></i></th>
|
<code class="box-title">/home/container{{ $directory['header'] }}</code>
|
||||||
<th style="width:55%">@lang('server.files.file_name')</th>
|
<a class="text-muted">
|
||||||
<th style="width:15%">@lang('server.files.size')</th>
|
<i class="fa fa-plus" data-action="add-folder" data-toggle="tooltip" data-placement="top" title="@lang('server.files.add_folder')"></i>
|
||||||
<th style="width:20%">@lang('server.files.last_modified')</th>
|
</a>
|
||||||
<th style="width:8%">
|
<div class="box-tools pull-right">
|
||||||
<label class="btn btn-primary btn-xs btn-file">
|
<a class="btn btn-primary btn-sm" href="/server/{{ $server->uuidShort }}/files/add/@if($directory['header'] !== '')?dir={{ $directory['header'] }}@endif">
|
||||||
Upload <input type="file" id="files_touch_target" style="display: none;"/>
|
<i class="fa fa-file"></i> Create File
|
||||||
</label>
|
</a>
|
||||||
</th>
|
<a class="btn btn-primary btn-sm btn-icon btn-file">
|
||||||
</tr>
|
<i class="fa fa-upload"></i> Upload <input type="file" id="files_touch_target" style="display: none;">
|
||||||
<tr id="headerTableRow" data-currentdir="{{ $directory['header'] }}">
|
</a>
|
||||||
<th class="middle"><i class="fa fa-folder-open"></i></th>
|
</div>
|
||||||
<th colspan="4" class="middle">
|
</div>
|
||||||
<code>/home/container{{ $directory['header'] }}</code>
|
<div class="box-body table-responsive no-padding">
|
||||||
<small>
|
<table class="table table-hover" id="file_listing" data-current-dir="{{ $directory['header'] }}">
|
||||||
<a href="/server/{{ $server->uuidShort }}/files/add/@if($directory['header'] !== '')?dir={{ $directory['header'] }}@endif" class="text-muted">
|
<thead>
|
||||||
<i class="fa fa-plus" data-toggle="tooltip" data-placement="top" title="@lang('server.files.add_new')"></i>
|
<tr>
|
||||||
</a>
|
<th style="width:2%;" class="middle"></th>
|
||||||
</small>
|
<th style="width:55%">@lang('server.files.file_name')</th>
|
||||||
</th>
|
<th style="width:15%" class="hidden-xs">@lang('server.files.size')</th>
|
||||||
</tr>
|
<th style="width:20%" class="hidden-xs">@lang('server.files.last_modified')</th>
|
||||||
</thead>
|
<th style="width:8%"></th>
|
||||||
<tbody id="append_files_to">
|
|
||||||
@if (isset($directory['first']) && $directory['first'] === true)
|
|
||||||
<tr data-type="disabled">
|
|
||||||
<td class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
|
||||||
<td><a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">←</a></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
</thead>
|
||||||
@if (isset($directory['show']) && $directory['show'] === true)
|
<tbody id="append_files_to">
|
||||||
<tr data-type="disabled">
|
@if (isset($directory['first']) && $directory['first'] === true)
|
||||||
<td class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
<tr data-type="disabled">
|
||||||
<td data-name="{{ rawurlencode($directory['link']) }}">
|
<td><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||||
<a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">← {{ $directory['link_show'] }}</a>
|
<td><a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">←</a></a></td>
|
||||||
</td>
|
<td class="hidden-xs"></td>
|
||||||
<td></td>
|
<td class="hidden-xs"></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
</tr>
|
||||||
</tr>
|
@endif
|
||||||
@endif
|
@if (isset($directory['show']) && $directory['show'] === true)
|
||||||
@foreach ($folders as $folder)
|
<tr data-type="disabled">
|
||||||
<tr data-type="folder">
|
<td><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||||
<td data-identifier="type" class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
<td data-name="{{ rawurlencode($directory['link']) }}">
|
||||||
<td data-identifier="name" data-name="{{ rawurlencode($folder['entry']) }}" data-path="@if($folder['directory'] !== ''){{ rawurlencode($folder['directory']) }}@endif/">
|
<a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">← {{ $directory['link_show'] }}</a>
|
||||||
<a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">{{ $folder['entry'] }}</a>
|
</td>
|
||||||
</td>
|
<td class="hidden-xs"></td>
|
||||||
<td data-identifier="size">{{ $folder['size'] }}</td>
|
<td class="hidden-xs"></td>
|
||||||
<td data-identifier="modified">
|
<td></td>
|
||||||
<?php $carbon = Carbon::createFromTimestamp($folder['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
</tr>
|
||||||
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
@endif
|
||||||
{{ $carbon->format('m/d/y H:i:s') }}
|
@foreach ($folders as $folder)
|
||||||
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
<tr data-type="folder">
|
||||||
<em>@lang('server.files.seconds_ago')</em>
|
<td data-identifier="type" class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||||
@else
|
<td data-identifier="name" data-name="{{ rawurlencode($folder['entry']) }}" data-path="@if($folder['directory'] !== ''){{ rawurlencode($folder['directory']) }}@endif/">
|
||||||
{{ $carbon->diffForHumans() }}
|
<a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">{{ $folder['entry'] }}</a>
|
||||||
@endif
|
</td>
|
||||||
</td>
|
<td data-identifier="size" class="hidden-xs">{{ $folder['size'] }}</td>
|
||||||
<td><button class="btn btn-xxs btn-default disable-menu-hide" data-action="toggleMenu" style="padding:2px 6px 0px;"><i class="fa fa-ellipsis-h disable-menu-hide"></i></button></td>
|
<td data-identifier="modified" class="hidden-xs">
|
||||||
</tr>
|
<?php $carbon = Carbon::createFromTimestamp($folder['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
||||||
@endforeach
|
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
||||||
@foreach ($files as $file)
|
{{ $carbon->format('m/d/y H:i:s') }}
|
||||||
<tr data-type="file" data-mime="{{ $file['mime'] }}">
|
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
||||||
<td data-identifier="type" class="middle">
|
<em>@lang('server.files.seconds_ago')</em>
|
||||||
{{-- oh boy --}}
|
@else
|
||||||
@if(in_array($file['mime'], [
|
{{ $carbon->diffForHumans() }}
|
||||||
'application/x-7z-compressed',
|
@endif
|
||||||
'application/zip',
|
</td>
|
||||||
'application/x-compressed-zip',
|
<td><button class="btn btn-xxs btn-default disable-menu-hide" data-action="toggleMenu" style="padding:2px 6px 0px;"><i class="fa fa-ellipsis-h disable-menu-hide"></i></button></td>
|
||||||
'application/x-tar',
|
</tr>
|
||||||
'application/x-gzip',
|
@endforeach
|
||||||
'application/x-bzip',
|
@foreach ($files as $file)
|
||||||
'application/x-bzip2',
|
<tr data-type="file" data-mime="{{ $file['mime'] }}">
|
||||||
'application/java-archive'
|
<td data-identifier="type" class="middle">
|
||||||
]))
|
{{-- oh boy --}}
|
||||||
<i class="fa fa-file-archive-o" style="margin-left: 2px;"></i>
|
@if(in_array($file['mime'], [
|
||||||
@elseif(in_array($file['mime'], [
|
'application/x-7z-compressed',
|
||||||
'application/json',
|
'application/zip',
|
||||||
'application/javascript',
|
'application/x-compressed-zip',
|
||||||
'application/xml',
|
'application/x-tar',
|
||||||
'application/xhtml+xml',
|
'application/x-gzip',
|
||||||
'text/xml',
|
'application/x-bzip',
|
||||||
'text/css',
|
'application/x-bzip2',
|
||||||
'text/html',
|
'application/java-archive'
|
||||||
'text/x-perl',
|
]))
|
||||||
'text/x-shellscript'
|
<i class="fa fa-file-archive-o" style="margin-left: 2px;"></i>
|
||||||
]))
|
@elseif(in_array($file['mime'], [
|
||||||
<i class="fa fa-file-code-o" style="margin-left: 2px;"></i>
|
'application/json',
|
||||||
@elseif(starts_with($file['mime'], 'image'))
|
'application/javascript',
|
||||||
<i class="fa fa-file-image-o" style="margin-left: 2px;"></i>
|
'application/xml',
|
||||||
@elseif(starts_with($file['mime'], 'video'))
|
'application/xhtml+xml',
|
||||||
<i class="fa fa-file-video-o" style="margin-left: 2px;"></i>
|
'text/xml',
|
||||||
@elseif(starts_with($file['mime'], 'video'))
|
'text/css',
|
||||||
<i class="fa fa-file-audio-o" style="margin-left: 2px;"></i>
|
'text/html',
|
||||||
@elseif(starts_with($file['mime'], 'application/vnd.ms-powerpoint'))
|
'text/x-perl',
|
||||||
<i class="fa fa-file-powerpoint-o" style="margin-left: 2px;"></i>
|
'text/x-shellscript'
|
||||||
@elseif(in_array($file['mime'], [
|
]))
|
||||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
<i class="fa fa-file-code-o" style="margin-left: 2px;"></i>
|
||||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
@elseif(starts_with($file['mime'], 'image'))
|
||||||
'application/msword'
|
<i class="fa fa-file-image-o" style="margin-left: 2px;"></i>
|
||||||
]) || starts_with($file['mime'], 'application/vnd.ms-word'))
|
@elseif(starts_with($file['mime'], 'video'))
|
||||||
<i class="fa fa-file-word-o" style="margin-left: 2px;"></i>
|
<i class="fa fa-file-video-o" style="margin-left: 2px;"></i>
|
||||||
@elseif(in_array($file['mime'], [
|
@elseif(starts_with($file['mime'], 'video'))
|
||||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
<i class="fa fa-file-audio-o" style="margin-left: 2px;"></i>
|
||||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
@elseif(starts_with($file['mime'], 'application/vnd.ms-powerpoint'))
|
||||||
]) || starts_with($file['mime'], 'application/vnd.ms-excel'))
|
<i class="fa fa-file-powerpoint-o" style="margin-left: 2px;"></i>
|
||||||
<i class="fa fa-file-excel-o" style="margin-left: 2px;"></i>
|
@elseif(in_array($file['mime'], [
|
||||||
@elseif($file['mime'] === 'application/pdf')
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
<i class="fa fa-file-pdf-o" style="margin-left: 2px;"></i>
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||||
@else
|
'application/msword'
|
||||||
<i class="fa fa-file-text-o" style="margin-left: 2px;"></i>
|
]) || starts_with($file['mime'], 'application/vnd.ms-word'))
|
||||||
@endif
|
<i class="fa fa-file-word-o" style="margin-left: 2px;"></i>
|
||||||
</td>
|
@elseif(in_array($file['mime'], [
|
||||||
<td data-identifier="name" data-name="{{ rawurlencode($file['entry']) }}" data-path="@if($file['directory'] !== ''){{ rawurlencode($file['directory']) }}@endif/">
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
@if(in_array($file['mime'], $editableMime))
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||||
@can('edit-files', $server)
|
]) || starts_with($file['mime'], 'application/vnd.ms-excel'))
|
||||||
<a href="/server/{{ $server->uuidShort }}/files/edit/@if($file['directory'] !== ''){{ rawurlencode($file['directory']) }}/@endif{{ rawurlencode($file['entry']) }}" class="edit_file">{{ $file['entry'] }}</a>
|
<i class="fa fa-file-excel-o" style="margin-left: 2px;"></i>
|
||||||
|
@elseif($file['mime'] === 'application/pdf')
|
||||||
|
<i class="fa fa-file-pdf-o" style="margin-left: 2px;"></i>
|
||||||
|
@else
|
||||||
|
<i class="fa fa-file-text-o" style="margin-left: 2px;"></i>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td data-identifier="name" data-name="{{ rawurlencode($file['entry']) }}" data-path="@if($file['directory'] !== ''){{ rawurlencode($file['directory']) }}@endif/">
|
||||||
|
@if(in_array($file['mime'], $editableMime))
|
||||||
|
@can('edit-files', $server)
|
||||||
|
<a href="/server/{{ $server->uuidShort }}/files/edit/@if($file['directory'] !== ''){{ rawurlencode($file['directory']) }}/@endif{{ rawurlencode($file['entry']) }}" class="edit_file">{{ $file['entry'] }}</a>
|
||||||
|
@else
|
||||||
|
{{ $file['entry'] }}
|
||||||
|
@endcan
|
||||||
@else
|
@else
|
||||||
{{ $file['entry'] }}
|
{{ $file['entry'] }}
|
||||||
@endcan
|
@endif
|
||||||
@else
|
</td>
|
||||||
{{ $file['entry'] }}
|
<td data-identifier="size" class="hidden-xs">{{ $file['size'] }}</td>
|
||||||
@endif
|
<td data-identifier="modified" class="hidden-xs">
|
||||||
</td>
|
<?php $carbon = Carbon::createFromTimestamp($file['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
||||||
<td data-identifier="size">{{ $file['size'] }}</td>
|
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
||||||
<td data-identifier="modified">
|
{{ $carbon->format('m/d/y H:i:s') }}
|
||||||
<?php $carbon = Carbon::createFromTimestamp($file['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
||||||
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
<em>@lang('server.files.seconds_ago')</em>
|
||||||
{{ $carbon->format('m/d/y H:i:s') }}
|
@else
|
||||||
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
{{ $carbon->diffForHumans() }}
|
||||||
<em>@lang('server.files.seconds_ago')</em>
|
@endif
|
||||||
@else
|
</td>
|
||||||
{{ $carbon->diffForHumans() }}
|
<td><button class="btn btn-xxs btn-default disable-menu-hide" data-action="toggleMenu" style="padding:2px 6px 0px;"><i class="fa fa-ellipsis-h disable-menu-hide"></i></button></td>
|
||||||
@endif
|
</tr>
|
||||||
</td>
|
@endforeach
|
||||||
<td><button class="btn btn-xxs btn-default disable-menu-hide" data-action="toggleMenu" style="padding:2px 6px 0px;"><i class="fa fa-ellipsis-h disable-menu-hide"></i></button></td>
|
</tbody>
|
||||||
</tr>
|
</table>
|
||||||
@endforeach
|
</div>
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
|
@ -40,8 +40,11 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-body">
|
<div class="box-body position-relative">
|
||||||
<div id="terminal" style="width:100%;"></div>
|
<div id="terminal" style="width:100%;"></div>
|
||||||
|
<div id="terminalNotify" class="terminal-notify hidden">
|
||||||
|
<i class="fa fa-bell"></i>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer text-center">
|
<div class="box-footer text-center">
|
||||||
@can('power-start', $server)<button class="btn btn-success disabled" data-attr="power" data-action="start">Start</button>@endcan
|
@can('power-start', $server)<button class="btn btn-success disabled" data-attr="power" data-action="start">Start</button>@endcan
|
||||||
|
|
Loading…
Reference in New Issue