Update all places in the code referencing named routes using JS that doesn't exist now
This commit is contained in:
parent
14b1f13fe0
commit
447c4291ad
20 changed files with 12 additions and 2115 deletions
|
@ -39,7 +39,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$('#pUserId').select2({
|
$('#pUserId').select2({
|
||||||
ajax: {
|
ajax: {
|
||||||
url: Router.route('admin.users.json'),
|
url: '/admin/users/accounts.json',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
delay: 250,
|
delay: 250,
|
||||||
data: function (params) {
|
data: function (params) {
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
var TwoFactorModal = (function () {
|
|
||||||
|
|
||||||
function bindListeners() {
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('#close_reload').click(function () {
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
$('#do_2fa').submit(function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
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).on('load', function () {
|
|
||||||
$('#hide_img_load').slideUp(function () {
|
|
||||||
$('#qr_image_insert').attr('src', image.src).slideDown();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$('#open2fa').modal('show');
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
alert('An error occurred 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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: function () {
|
|
||||||
bindListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
TwoFactorModal.init();
|
|
|
@ -1,392 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count || 50;
|
|
||||||
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq || 200;
|
|
||||||
var CONSOLE_OUTPUT_LIMIT = Pterodactyl.config.console_limit || 2000;
|
|
||||||
|
|
||||||
var KEYCODE_UP_ARROW = 38;
|
|
||||||
var KEYCODE_DOWN_ARROW = 40;
|
|
||||||
|
|
||||||
var AnsiUp = new AnsiUp;
|
|
||||||
AnsiUp.use_classes = true;
|
|
||||||
|
|
||||||
var $terminal = $('#terminal');
|
|
||||||
var $terminalInput = $('.terminal_input--input');
|
|
||||||
var $scrollNotify = $('#terminalNotify');
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
var storage = window.localStorage;
|
|
||||||
var activeHx = [];
|
|
||||||
var currentHxIndex = 0;
|
|
||||||
var currentKeyCount = 0;
|
|
||||||
|
|
||||||
var storedConsoleHistory = storage.getItem('console_hx_' + Pterodactyl.server.uuid);
|
|
||||||
try {
|
|
||||||
activeHx = JSON.parse(storedConsoleHistory) || [];
|
|
||||||
currentKeyCount = activeHx.length - 1;
|
|
||||||
} catch (ex) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
$terminalInput.focus();
|
|
||||||
$('.terminal_input--prompt, #terminal_input, #terminalNotify').on('click', function () {
|
|
||||||
$terminalInput.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
$terminalInput.on('keyup', function (e) {
|
|
||||||
if (e.which === KEYCODE_DOWN_ARROW || e.which === KEYCODE_UP_ARROW) {
|
|
||||||
var value = consoleHistory(e.which);
|
|
||||||
|
|
||||||
if (value !== false) {
|
|
||||||
$terminalInput.val(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.which === 27) {
|
|
||||||
$(this).val('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.which === 13) {
|
|
||||||
saveToHistory($(this).val());
|
|
||||||
Socket.emit((ConsoleServerStatus !== 0) ? 'send command' : 'set state', $(this).val());
|
|
||||||
|
|
||||||
$(this).val('');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function consoleHistory(key) {
|
|
||||||
// Get previous
|
|
||||||
if (key === KEYCODE_UP_ARROW) {
|
|
||||||
// currentHxIndex++;
|
|
||||||
var index = activeHx.length - (currentHxIndex + 1);
|
|
||||||
|
|
||||||
if (typeof activeHx[index - 1] === 'undefined') {
|
|
||||||
return activeHx[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
currentHxIndex++;
|
|
||||||
return activeHx[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get more recent
|
|
||||||
if (key === KEYCODE_DOWN_ARROW) {
|
|
||||||
var index = activeHx.length - currentHxIndex;
|
|
||||||
|
|
||||||
if (typeof activeHx[index + 1] === 'undefined') {
|
|
||||||
return activeHx[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
currentHxIndex--;
|
|
||||||
return activeHx[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveToHistory(command) {
|
|
||||||
if (command.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeHx.length >= 50) {
|
|
||||||
activeHx.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentHxIndex = 0;
|
|
||||||
currentKeyCount++;
|
|
||||||
activeHx[currentKeyCount] = command;
|
|
||||||
|
|
||||||
storage.setItem('console_hx_' + Pterodactyl.server.uuid, JSON.stringify(activeHx));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$terminal.on('scroll', function () {
|
|
||||||
if (isTerminalScrolledDown()) {
|
|
||||||
$scrollNotify.addClass('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function isTerminalScrolledDown() {
|
|
||||||
return $terminal.scrollTop() + $terminal.innerHeight() + 50 > $terminal[0].scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.scrollToBottom = function () {
|
|
||||||
$terminal.scrollTop($terminal[0].scrollHeight);
|
|
||||||
};
|
|
||||||
|
|
||||||
function pushToTerminal(string) {
|
|
||||||
$terminal.append('<div class="cmd">' + AnsiUp.ansi_to_html(string + '\u001b[0m') + '</div>');
|
|
||||||
}
|
|
||||||
|
|
||||||
(function initConsole() {
|
|
||||||
window.TerminalQueue = [];
|
|
||||||
window.ConsoleServerStatus = 0;
|
|
||||||
window.ConsoleElements = 0;
|
|
||||||
|
|
||||||
$scrollNotify.on('click', function () {
|
|
||||||
window.scrollToBottom();
|
|
||||||
$scrollNotify.addClass('hidden');
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function pushOutputQueue() {
|
|
||||||
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
|
|
||||||
// console throttled warning show
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TerminalQueue.length > 0) {
|
|
||||||
var scrolledDown = isTerminalScrolledDown();
|
|
||||||
|
|
||||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
|
|
||||||
pushToTerminal(TerminalQueue[0]);
|
|
||||||
|
|
||||||
window.ConsoleElements++;
|
|
||||||
TerminalQueue.shift();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scrolledDown) {
|
|
||||||
window.scrollToBottom();
|
|
||||||
} else if ($scrollNotify.hasClass('hidden')) {
|
|
||||||
$scrollNotify.removeClass('hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
var removeElements = window.ConsoleElements - CONSOLE_OUTPUT_LIMIT;
|
|
||||||
if (removeElements > 0) {
|
|
||||||
$('#terminal').find('.cmd').slice(0, removeElements).remove();
|
|
||||||
window.ConsoleElements = window.ConsoleElements - removeElements;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function setupSocketListeners() {
|
|
||||||
// Update Listings on Initial Status
|
|
||||||
Socket.on('initial status', function (data) {
|
|
||||||
ConsoleServerStatus = data.status;
|
|
||||||
updateServerPowerControls(data.status);
|
|
||||||
|
|
||||||
if (data.status === 1 || data.status === 2) {
|
|
||||||
Socket.emit('send server log');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Listings on Status
|
|
||||||
Socket.on('status', function (data) {
|
|
||||||
ConsoleServerStatus = data.status;
|
|
||||||
updateServerPowerControls(data.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skips the queue so we don't wait
|
|
||||||
// 10 minutes to load the log...
|
|
||||||
Socket.on('server log', function (data) {
|
|
||||||
$('#terminal').html('');
|
|
||||||
data.split(/\n/g).forEach(function (item) {
|
|
||||||
pushToTerminal(item);
|
|
||||||
});
|
|
||||||
window.scrollToBottom();
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('console', function (data) {
|
|
||||||
if(data.line) {
|
|
||||||
data.line.split(/\n/g).forEach(function (item) {
|
|
||||||
TerminalQueue.push(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
function updateServerPowerControls (data) {
|
|
||||||
// Server is On or Starting
|
|
||||||
if(data == 1 || data == 2) {
|
|
||||||
$('[data-attr="power"][data-action="start"]').addClass('disabled');
|
|
||||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').removeClass('disabled');
|
|
||||||
} else {
|
|
||||||
if (data == 0) {
|
|
||||||
$('[data-attr="power"][data-action="start"]').removeClass('disabled');
|
|
||||||
}
|
|
||||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').addClass('disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data !== 0) {
|
|
||||||
$('[data-attr="power"][data-action="kill"]').removeClass('disabled');
|
|
||||||
} else {
|
|
||||||
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('[data-attr="power"]').click(function (event) {
|
|
||||||
if (! $(this).hasClass('disabled')) {
|
|
||||||
Socket.emit('set state', $(this).data('action'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
(function setupChartElements() {
|
|
||||||
if (typeof SkipConsoleCharts !== 'undefined') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)));
|
|
||||||
|
|
||||||
TimeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
|
||||||
|
|
||||||
|
|
||||||
// memory.cmax is the maximum given by the container
|
|
||||||
// memory.amax is given by the json config
|
|
||||||
// use the maximum of both
|
|
||||||
// with no limit memory.cmax will always be higher
|
|
||||||
// but with limit memory.amax is sometimes still smaller than memory.total
|
|
||||||
MemoryChart.config.options.scales.yAxes[0].ticks.max = Math.max(proc.data.memory.cmax, proc.data.memory.amax) / (1000 * 1000);
|
|
||||||
|
|
||||||
if (Pterodactyl.server.cpu > 0) {
|
|
||||||
// if there is a cpu limit defined use 100% as maximum
|
|
||||||
CPUChart.config.options.scales.yAxes[0].ticks.max = 100;
|
|
||||||
} else {
|
|
||||||
// if there is no cpu limit defined use linux percentage
|
|
||||||
// and find maximum in all values
|
|
||||||
var maxCpu = 1;
|
|
||||||
for(var i = 0; i < CPUData.length; i++) {
|
|
||||||
maxCpu = Math.max(maxCpu, parseFloat(CPUData[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
maxCpu = Math.ceil(maxCpu / 100) * 100;
|
|
||||||
CPUChart.config.options.scales.yAxes[0].ticks.max = maxCpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CPUChart.update();
|
|
||||||
MemoryChart.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
var ctc = $('#chart_cpu');
|
|
||||||
var TimeLabels = [];
|
|
||||||
var CPUData = [];
|
|
||||||
var 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,
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
yAxes: [{
|
|
||||||
ticks: {
|
|
||||||
beginAtZero: true
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
yAxes: [{
|
|
||||||
ticks: {
|
|
||||||
beginAtZero: true
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
});
|
|
|
@ -1,131 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
(function () {
|
|
||||||
window.Editor = ace.edit('editor');
|
|
||||||
var Whitespace = ace.require('ace/ext/whitespace');
|
|
||||||
var Modelist = ace.require('ace/ext/modelist');
|
|
||||||
|
|
||||||
Editor.setTheme('ace/theme/chrome');
|
|
||||||
Editor.getSession().setUseWrapMode(true);
|
|
||||||
Editor.setShowPrintMargin(false);
|
|
||||||
|
|
||||||
if (typeof Pterodactyl !== 'undefined') {
|
|
||||||
if(typeof Pterodactyl.stat !== 'undefined') {
|
|
||||||
Editor.getSession().setMode(Modelist.getModeForPath(Pterodactyl.stat.name).mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Editor.commands.addCommand({
|
|
||||||
name: 'save',
|
|
||||||
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
|
||||||
exec: function(editor) {
|
|
||||||
if ($('#save_file').length) {
|
|
||||||
save();
|
|
||||||
} else if ($('#create_file').length) {
|
|
||||||
create();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
readOnly: false
|
|
||||||
});
|
|
||||||
|
|
||||||
Editor.commands.addCommands(Whitespace.commands);
|
|
||||||
|
|
||||||
Whitespace.detectIndentation(Editor.session);
|
|
||||||
|
|
||||||
$('#save_file').on('click', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
save();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#create_file').on('click', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
create();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#aceMode').on('change', event => {
|
|
||||||
Editor.getSession().setMode('ace/mode/' + $('#aceMode').val());
|
|
||||||
});
|
|
||||||
|
|
||||||
function create() {
|
|
||||||
if (_.isEmpty($('#file_name').val())) {
|
|
||||||
$.notify({
|
|
||||||
message: 'No filename was passed.'
|
|
||||||
}, {
|
|
||||||
type: 'danger'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('#create_file').html('<i class="fa fa-spinner fa fa-spin"></i> Creating File').addClass('disabled');
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: Router.route('server.files.save', { server: Pterodactyl.server.uuidShort }),
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
file: $('#file_name').val(),
|
|
||||||
contents: Editor.getValue()
|
|
||||||
}
|
|
||||||
}).done(function (data) {
|
|
||||||
window.location.replace(Router.route('server.files.edit', {
|
|
||||||
server: Pterodactyl.server.uuidShort,
|
|
||||||
file: $('#file_name').val(),
|
|
||||||
}));
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
$.notify({
|
|
||||||
message: jqXHR.responseText
|
|
||||||
}, {
|
|
||||||
type: 'danger'
|
|
||||||
});
|
|
||||||
}).always(function () {
|
|
||||||
$('#create_file').html('Create File').removeClass('disabled');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function save() {
|
|
||||||
var fileName = $('input[name="file"]').val();
|
|
||||||
$('#save_file').html('<i class="fa fw-fw fa-spinner fa-spin"></i> Saving File').addClass('disabled');
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: Router.route('server.files.save', { server: Pterodactyl.server.uuidShort }),
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
file: fileName,
|
|
||||||
contents: Editor.getValue()
|
|
||||||
}
|
|
||||||
}).done(function (data) {
|
|
||||||
$.notify({
|
|
||||||
message: 'File was successfully saved.'
|
|
||||||
}, {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
$.notify({
|
|
||||||
message: jqXHR.responseText
|
|
||||||
}, {
|
|
||||||
type: 'danger'
|
|
||||||
});
|
|
||||||
}).always(function () {
|
|
||||||
$('#save_file').html('<i class="fa fa-fw fa-save"></i> Save File').removeClass('disabled');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,549 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
class ActionsClass {
|
|
||||||
constructor(element, menu) {
|
|
||||||
this.element = element;
|
|
||||||
this.menu = menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this.element = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
sanitizedString(value) {
|
|
||||||
return $('<div>').text(value).html();
|
|
||||||
}
|
|
||||||
|
|
||||||
folder(path) {
|
|
||||||
let inputValue
|
|
||||||
if (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'));
|
|
||||||
|
|
||||||
if ($(this.element).data('type') === 'file') {
|
|
||||||
inputValue = currentPath;
|
|
||||||
} else {
|
|
||||||
inputValue = `${currentPath}${currentName}/`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'input',
|
|
||||||
title: 'Create Folder',
|
|
||||||
text: 'Please enter the path and folder name below.',
|
|
||||||
showCancelButton: true,
|
|
||||||
showConfirmButton: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
showLoaderOnConfirm: true,
|
|
||||||
inputValue: inputValue
|
|
||||||
}, (val) => {
|
|
||||||
if (val === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/folder`,
|
|
||||||
timeout: 10000,
|
|
||||||
data: JSON.stringify({
|
|
||||||
path: val,
|
|
||||||
}),
|
|
||||||
}).done(data => {
|
|
||||||
swal.close();
|
|
||||||
Files.list();
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
var error = 'An error occurred while trying to process this request.';
|
|
||||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
|
||||||
error = jqXHR.responseJSON.error;
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: '',
|
|
||||||
text: error,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
move() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
|
||||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'input',
|
|
||||||
title: 'Move File',
|
|
||||||
text: 'Please enter the new path for the file below.',
|
|
||||||
showCancelButton: true,
|
|
||||||
showConfirmButton: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
showLoaderOnConfirm: true,
|
|
||||||
inputValue: `${currentPath}${currentName}`,
|
|
||||||
}, (val) => {
|
|
||||||
if (val === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/move`,
|
|
||||||
timeout: 10000,
|
|
||||||
data: JSON.stringify({
|
|
||||||
from: `${currentPath}${currentName}`,
|
|
||||||
to: `${val}`,
|
|
||||||
}),
|
|
||||||
}).done(data => {
|
|
||||||
nameBlock.parent().addClass('warning').delay(200).fadeOut();
|
|
||||||
swal.close();
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
var error = 'An error occurred while trying to process this request.';
|
|
||||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
|
||||||
error = jqXHR.responseJSON.error;
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: '',
|
|
||||||
text: error,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
rename() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const currentLink = nameBlock.find('a');
|
|
||||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
|
||||||
const attachEditor = `
|
|
||||||
<input class="form-control input-sm" type="text" value="${currentName}" />
|
|
||||||
<span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span>
|
|
||||||
`;
|
|
||||||
|
|
||||||
nameBlock.html(attachEditor);
|
|
||||||
const inputField = nameBlock.find('input');
|
|
||||||
const inputLoader = nameBlock.find('.input-loader');
|
|
||||||
|
|
||||||
inputField.focus();
|
|
||||||
inputField.on('blur keydown', e => {
|
|
||||||
// Save Field
|
|
||||||
if (
|
|
||||||
(e.type === 'keydown' && e.which === 27)
|
|
||||||
|| e.type === 'blur'
|
|
||||||
|| (e.type === 'keydown' && e.which === 13 && currentName === inputField.val())
|
|
||||||
) {
|
|
||||||
if (!_.isEmpty(currentLink)) {
|
|
||||||
nameBlock.html(currentLink);
|
|
||||||
} else {
|
|
||||||
nameBlock.html(currentName);
|
|
||||||
}
|
|
||||||
inputField.remove();
|
|
||||||
ContextMenu.unbind().run();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.type === 'keydown' && e.which !== 13) return;
|
|
||||||
|
|
||||||
inputLoader.show();
|
|
||||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/rename`,
|
|
||||||
timeout: 10000,
|
|
||||||
data: JSON.stringify({
|
|
||||||
from: `${currentPath}${currentName}`,
|
|
||||||
to: `${currentPath}${inputField.val()}`,
|
|
||||||
}),
|
|
||||||
}).done(data => {
|
|
||||||
nameBlock.attr('data-name', inputField.val());
|
|
||||||
if (!_.isEmpty(currentLink)) {
|
|
||||||
let newLink = currentLink.attr('href');
|
|
||||||
if (nameBlock.parent().data('type') !== 'folder') {
|
|
||||||
newLink = newLink.substr(0, newLink.lastIndexOf('/')) + '/' + inputField.val();
|
|
||||||
}
|
|
||||||
currentLink.attr('href', newLink);
|
|
||||||
nameBlock.html(
|
|
||||||
currentLink.html(inputField.val())
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
nameBlock.html(inputField.val());
|
|
||||||
}
|
|
||||||
inputField.remove();
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
var error = 'An error occurred while trying to process this request.';
|
|
||||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
|
||||||
error = jqXHR.responseJSON.error;
|
|
||||||
}
|
|
||||||
nameBlock.addClass('has-error').delay(2000).queue(() => {
|
|
||||||
nameBlock.removeClass('has-error').dequeue();
|
|
||||||
});
|
|
||||||
inputField.popover({
|
|
||||||
animation: true,
|
|
||||||
placement: 'top',
|
|
||||||
content: error,
|
|
||||||
title: 'Save Error'
|
|
||||||
}).popover('show');
|
|
||||||
}).always(() => {
|
|
||||||
inputLoader.remove();
|
|
||||||
ContextMenu.unbind().run();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
copy() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
|
||||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'input',
|
|
||||||
title: 'Copy File',
|
|
||||||
text: 'Please enter the new path for the copied file below.',
|
|
||||||
showCancelButton: true,
|
|
||||||
showConfirmButton: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
showLoaderOnConfirm: true,
|
|
||||||
inputValue: `${currentPath}${currentName}`,
|
|
||||||
}, (val) => {
|
|
||||||
if (val === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/copy`,
|
|
||||||
timeout: 10000,
|
|
||||||
data: JSON.stringify({
|
|
||||||
from: `${currentPath}${currentName}`,
|
|
||||||
to: `${val}`,
|
|
||||||
}),
|
|
||||||
}).done(data => {
|
|
||||||
swal({
|
|
||||||
type: 'success',
|
|
||||||
title: '',
|
|
||||||
text: 'File successfully copied.'
|
|
||||||
});
|
|
||||||
Files.list();
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
var error = 'An error occurred while trying to process this request.';
|
|
||||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
|
||||||
error = jqXHR.responseJSON.error;
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: '',
|
|
||||||
text: error,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
download() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const fileName = decodeURIComponent(nameBlock.attr('data-name'));
|
|
||||||
const filePath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
|
|
||||||
window.location = `/server/${Pterodactyl.server.uuidShort}/files/download/${filePath}${fileName}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const delPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
const delName = decodeURIComponent(nameBlock.data('name'));
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'warning',
|
|
||||||
title: '',
|
|
||||||
text: 'Are you sure you want to delete <code>' + this.sanitizedString(delName) + '</code>?',
|
|
||||||
html: true,
|
|
||||||
showCancelButton: true,
|
|
||||||
showConfirmButton: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
showLoaderOnConfirm: true
|
|
||||||
}, () => {
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,
|
|
||||||
timeout: 10000,
|
|
||||||
data: JSON.stringify({
|
|
||||||
items: [`${delPath}${delName}`]
|
|
||||||
}),
|
|
||||||
}).done(data => {
|
|
||||||
nameBlock.parent().addClass('warning').delay(200).fadeOut();
|
|
||||||
swal({
|
|
||||||
type: 'success',
|
|
||||||
title: 'File Deleted'
|
|
||||||
});
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
html: true,
|
|
||||||
text: 'An error occurred while attempting to delete this file. Please try again.',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleMassActions() {
|
|
||||||
if ($('#file_listing input[type="checkbox"]:checked').length) {
|
|
||||||
$('#mass_actions').removeClass('disabled');
|
|
||||||
} else {
|
|
||||||
$('#mass_actions').addClass('disabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleHighlight(event) {
|
|
||||||
const parent = $(event.currentTarget);
|
|
||||||
const item = $(event.currentTarget).find('input');
|
|
||||||
|
|
||||||
if($(item).is(':checked')) {
|
|
||||||
$(item).prop('checked', false);
|
|
||||||
parent.removeClass('warning').delay(200);
|
|
||||||
} else {
|
|
||||||
$(item).prop('checked', true);
|
|
||||||
parent.addClass('warning').delay(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
highlightAll(event) {
|
|
||||||
let parent;
|
|
||||||
const item = $(event.currentTarget).find('input');
|
|
||||||
|
|
||||||
if($(item).is(':checked')) {
|
|
||||||
$('#file_listing input[type=checkbox]').prop('checked', false);
|
|
||||||
$('#file_listing input[data-action="addSelection"]').each(function() {
|
|
||||||
parent = $(this).closest('tr');
|
|
||||||
parent.removeClass('warning').delay(200);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#file_listing input[type=checkbox]').prop('checked', true);
|
|
||||||
$('#file_listing input[data-action="addSelection"]').each(function() {
|
|
||||||
parent = $(this).closest('tr');
|
|
||||||
parent.addClass('warning').delay(200);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteSelected() {
|
|
||||||
let selectedItems = [];
|
|
||||||
let selectedItemsElements = [];
|
|
||||||
let parent;
|
|
||||||
let nameBlock;
|
|
||||||
let delLocation;
|
|
||||||
|
|
||||||
$('#file_listing input[data-action="addSelection"]:checked').each(function() {
|
|
||||||
parent = $(this).closest('tr');
|
|
||||||
nameBlock = $(parent).find('td[data-identifier="name"]');
|
|
||||||
delLocation = decodeURIComponent(nameBlock.data('path')) + decodeURIComponent(nameBlock.data('name'));
|
|
||||||
|
|
||||||
selectedItems.push(delLocation);
|
|
||||||
selectedItemsElements.push(parent);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (selectedItems.length != 0)
|
|
||||||
{
|
|
||||||
let formattedItems = "";
|
|
||||||
let i = 0;
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
$.each(selectedItems, function(key, value) {
|
|
||||||
formattedItems += ("<code>" + self.sanitizedString(value) + "</code>, ");
|
|
||||||
i++;
|
|
||||||
return i < 5;
|
|
||||||
});
|
|
||||||
|
|
||||||
formattedItems = formattedItems.slice(0, -2);
|
|
||||||
if (selectedItems.length > 5) {
|
|
||||||
formattedItems += ', and ' + (selectedItems.length - 5) + ' other(s)';
|
|
||||||
}
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'warning',
|
|
||||||
title: '',
|
|
||||||
text: 'Are you sure you want to delete the following files: ' + formattedItems + '?',
|
|
||||||
html: true,
|
|
||||||
showCancelButton: true,
|
|
||||||
showConfirmButton: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
showLoaderOnConfirm: true
|
|
||||||
}, () => {
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,
|
|
||||||
timeout: 10000,
|
|
||||||
data: JSON.stringify({
|
|
||||||
items: selectedItems
|
|
||||||
}),
|
|
||||||
}).done(data => {
|
|
||||||
$('#file_listing input:checked').each(function() {
|
|
||||||
$(this).prop('checked', false);
|
|
||||||
});
|
|
||||||
|
|
||||||
$.each(selectedItemsElements, function() {
|
|
||||||
$(this).addClass('warning').delay(200).fadeOut();
|
|
||||||
})
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'success',
|
|
||||||
title: 'Files Deleted'
|
|
||||||
});
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
html: true,
|
|
||||||
text: 'An error occurred while attempting to delete these files. Please try again.',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
swal({
|
|
||||||
type: 'warning',
|
|
||||||
title: '',
|
|
||||||
text: 'Please select files/folders to delete.',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
decompress() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const compPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
const compName = decodeURIComponent(nameBlock.data('name'));
|
|
||||||
|
|
||||||
swal({
|
|
||||||
title: '<i class="fa fa-refresh fa-spin"></i> Decompressing...',
|
|
||||||
text: 'This might take a few seconds to complete.',
|
|
||||||
html: true,
|
|
||||||
allowOutsideClick: false,
|
|
||||||
allowEscapeKey: false,
|
|
||||||
showConfirmButton: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/decompress`,
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
data: JSON.stringify({
|
|
||||||
files: `${compPath}${compName}`
|
|
||||||
})
|
|
||||||
}).done(data => {
|
|
||||||
swal.close();
|
|
||||||
Files.list(compPath);
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
var error = 'An error occurred while trying to process this request.';
|
|
||||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
|
||||||
error = jqXHR.responseJSON.error;
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
html: true,
|
|
||||||
text: error
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
compress() {
|
|
||||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
|
||||||
const compPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
const compName = decodeURIComponent(nameBlock.data('name'));
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/compress`,
|
|
||||||
headers: {
|
|
||||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
|
||||||
'X-Access-Server': Pterodactyl.server.uuid,
|
|
||||||
},
|
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
data: JSON.stringify({
|
|
||||||
files: `${compPath}${compName}`,
|
|
||||||
to: compPath.toString()
|
|
||||||
})
|
|
||||||
}).done(data => {
|
|
||||||
Files.list(compPath, err => {
|
|
||||||
if (err) return;
|
|
||||||
const fileListing = $('#file_listing').find(`[data-name="${data.saved_as}"]`).parent();
|
|
||||||
fileListing.addClass('success pulsate').delay(3000).queue(() => {
|
|
||||||
fileListing.removeClass('success pulsate').dequeue();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
console.error(jqXHR);
|
|
||||||
var error = 'An error occurred while trying to process this request.';
|
|
||||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
|
||||||
error = jqXHR.responseJSON.error;
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
html: true,
|
|
||||||
text: this.sanitizedString(error)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
class ContextMenuClass {
|
|
||||||
constructor() {
|
|
||||||
this.activeLine = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
run() {
|
|
||||||
this.directoryClick();
|
|
||||||
this.rightClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
makeMenu(parent) {
|
|
||||||
$(document).find('#fileOptionMenu').remove();
|
|
||||||
if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
|
|
||||||
|
|
||||||
let newFilePath = $('#file_listing').data('current-dir');
|
|
||||||
if (parent.data('type') === 'folder') {
|
|
||||||
const nameBlock = parent.find('td[data-identifier="name"]');
|
|
||||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
|
||||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
|
||||||
newFilePath = `${currentPath}${currentName}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let buildMenu = '<ul id="fileOptionMenu" class="dropdown-menu" role="menu" style="display:none" >';
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.moveFiles) {
|
|
||||||
buildMenu += '<li data-action="rename"><a tabindex="-1" href="#"><i class="fa fa-fw fa-pencil-square-o"></i> Rename</a></li> \
|
|
||||||
<li data-action="move"><a tabindex="-1" href="#"><i class="fa fa-fw fa-arrow-right"></i> Move</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.copyFiles) {
|
|
||||||
buildMenu += '<li data-action="copy"><a tabindex="-1" href="#"><i class="fa fa-fw fa-clone"></i> Copy</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.compressFiles) {
|
|
||||||
buildMenu += '<li data-action="compress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-file-archive-o"></i> Compress</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.decompressFiles) {
|
|
||||||
buildMenu += '<li data-action="decompress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-expand"></i> Decompress</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.createFiles) {
|
|
||||||
buildMenu += '<li class="divider"></li> \
|
|
||||||
<li data-action="file"><a href="/server/'+ Pterodactyl.server.uuidShort +'/files/add/?dir=' + $('<div>').text(newFilePath).html() + '" class="text-muted"><i class="fa fa-fw fa-plus"></i> New File</a></li> \
|
|
||||||
<li data-action="folder"><a tabindex="-1" href="#"><i class="fa fa-fw fa-folder"></i> New Folder</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.downloadFiles || Pterodactyl.permissions.deleteFiles) {
|
|
||||||
buildMenu += '<li class="divider"></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.downloadFiles) {
|
|
||||||
buildMenu += '<li data-action="download" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-download"></i> Download</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.deleteFiles) {
|
|
||||||
buildMenu += '<li data-action="delete" class="bg-danger"><a tabindex="-1" href="#"><i class="fa fa-fw fa-trash-o"></i> Delete</a></li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
buildMenu += '</ul>';
|
|
||||||
return buildMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
rightClick() {
|
|
||||||
$('[data-action="toggleMenu"]').on('mousedown', event => {
|
|
||||||
event.preventDefault();
|
|
||||||
if ($(document).find('#fileOptionMenu').is(':visible')) {
|
|
||||||
$('body').trigger('click');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.showMenu(event);
|
|
||||||
});
|
|
||||||
$('#file_listing > tbody td').on('contextmenu', event => {
|
|
||||||
this.showMenu(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showMenu(event) {
|
|
||||||
const parent = $(event.target).closest('tr');
|
|
||||||
const menu = $(this.makeMenu(parent));
|
|
||||||
|
|
||||||
if (parent.data('type') === 'disabled') return;
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
$(menu).appendTo('body');
|
|
||||||
$(menu).data('invokedOn', $(event.target)).show().css({
|
|
||||||
position: 'absolute',
|
|
||||||
left: event.pageX - 150,
|
|
||||||
top: event.pageY,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.activeLine = parent;
|
|
||||||
this.activeLine.addClass('active');
|
|
||||||
|
|
||||||
// Handle Events
|
|
||||||
const Actions = new ActionsClass(parent, menu);
|
|
||||||
if (Pterodactyl.permissions.moveFiles) {
|
|
||||||
$(menu).find('li[data-action="move"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.move();
|
|
||||||
});
|
|
||||||
$(menu).find('li[data-action="rename"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.rename();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.copyFiles) {
|
|
||||||
$(menu).find('li[data-action="copy"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.copy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.compressFiles) {
|
|
||||||
if (parent.data('type') === 'folder') {
|
|
||||||
$(menu).find('li[data-action="compress"]').removeClass('hidden');
|
|
||||||
}
|
|
||||||
$(menu).find('li[data-action="compress"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.compress();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.decompressFiles) {
|
|
||||||
if (_.without(['application/zip', 'application/gzip', 'application/x-gzip'], parent.data('mime')).length < 3) {
|
|
||||||
$(menu).find('li[data-action="decompress"]').removeClass('hidden');
|
|
||||||
}
|
|
||||||
$(menu).find('li[data-action="decompress"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.decompress();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.createFiles) {
|
|
||||||
$(menu).find('li[data-action="folder"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.folder();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.downloadFiles) {
|
|
||||||
if (parent.data('type') === 'file') {
|
|
||||||
$(menu).find('li[data-action="download"]').removeClass('hidden');
|
|
||||||
}
|
|
||||||
$(menu).find('li[data-action="download"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.download();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pterodactyl.permissions.deleteFiles) {
|
|
||||||
$(menu).find('li[data-action="delete"]').unbind().on('click', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
Actions.delete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).unbind().on('click', event => {
|
|
||||||
if($(event.target).is('.disable-menu-hide')) {
|
|
||||||
event.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$(menu).unbind().remove();
|
|
||||||
if(!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
directoryClick() {
|
|
||||||
$('a[data-action="directory-view"]').on('click', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const path = $(this).parent().data('path') || '';
|
|
||||||
const name = $(this).parent().data('name') || '';
|
|
||||||
|
|
||||||
window.location.hash = encodeURIComponent(path + name);
|
|
||||||
Files.list();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.ContextMenu = new ContextMenuClass;
|
|
|
@ -1,139 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
class FileManager {
|
|
||||||
constructor() {
|
|
||||||
this.list(this.decodeHash());
|
|
||||||
}
|
|
||||||
|
|
||||||
list(path, next) {
|
|
||||||
if (_.isUndefined(path)) {
|
|
||||||
path = this.decodeHash();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loader(true);
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: Pterodactyl.meta.directoryList,
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-Token': Pterodactyl.meta.csrftoken,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
directory: path,
|
|
||||||
},
|
|
||||||
}).done(data => {
|
|
||||||
this.loader(false);
|
|
||||||
$('#load_files').slideUp(10).html(data).slideDown(10, () => {
|
|
||||||
ContextMenu.run();
|
|
||||||
this.reloadFilesButton();
|
|
||||||
this.addFolderButton();
|
|
||||||
this.selectItem();
|
|
||||||
this.selectAll();
|
|
||||||
this.selectiveDeletion();
|
|
||||||
this.selectRow();
|
|
||||||
if (_.isFunction(next)) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('#internal_alert').slideUp();
|
|
||||||
|
|
||||||
if (typeof Siofu === 'object') {
|
|
||||||
Siofu.listenOnInput(document.getElementById("files_touch_target"));
|
|
||||||
}
|
|
||||||
}).fail(jqXHR => {
|
|
||||||
this.loader(false);
|
|
||||||
if (_.isFunction(next)) {
|
|
||||||
return next(new Error('Failed to load file listing.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((path !== '' && path !== '/') && jqXHR.status === 404) {
|
|
||||||
return this.list('', next);
|
|
||||||
}
|
|
||||||
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'File Error',
|
|
||||||
text: jqXHR.responseJSON.errors[0].detail || 'An error occurred while attempting to process this request. Please try again.',
|
|
||||||
});
|
|
||||||
console.error(jqXHR);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
loader(show) {
|
|
||||||
if (show){
|
|
||||||
$('.file-overlay').fadeIn(100);
|
|
||||||
} else {
|
|
||||||
$('.file-overlay').fadeOut(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadFilesButton() {
|
|
||||||
$('i[data-action="reload-files"]').unbind().on('click', () => {
|
|
||||||
$('i[data-action="reload-files"]').addClass('fa-spin');
|
|
||||||
this.list();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
selectItem() {
|
|
||||||
$('[data-action="addSelection"]').on('click', event => {
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
selectAll() {
|
|
||||||
$('[data-action="selectAll"]').on('click', event => {
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
selectiveDeletion() {
|
|
||||||
$('[data-action="selective-deletion"]').on('mousedown', event => {
|
|
||||||
new ActionsClass().deleteSelected();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addFolderButton() {
|
|
||||||
$('[data-action="add-folder"]').unbind().on('click', () => {
|
|
||||||
new ActionsClass().folder($('#file_listing').data('current-dir') || '/');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
selectRow() {
|
|
||||||
$('#file_listing tr').on('mousedown', event => {
|
|
||||||
if (event.which === 1) {
|
|
||||||
if ($(event.target).is('th') || $(event.target).is('input[data-action="selectAll"]')) {
|
|
||||||
new ActionsClass().highlightAll(event);
|
|
||||||
} else if ($(event.target).is('td') || $(event.target).is('input[data-action="addSelection"]')) {
|
|
||||||
new ActionsClass().toggleHighlight(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
new ActionsClass().toggleMassActions();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
decodeHash() {
|
|
||||||
return decodeURIComponent(window.location.hash.substring(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
window.Files = new FileManager;
|
|
|
@ -1,162 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
(function initUploader() {
|
|
||||||
var notifyUploadSocketError = false;
|
|
||||||
uploadSocket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/v1/upload/' + Pterodactyl.server.uuid, {
|
|
||||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadSocket.io.on('connect_error', function (err) {
|
|
||||||
if(typeof notifyUploadSocketError !== 'object') {
|
|
||||||
notifyUploadSocketError = $.notify({
|
|
||||||
message: 'There was an error attempting to establish a connection to the uploader endpoint.<br /><br />' + err,
|
|
||||||
}, {
|
|
||||||
type: 'danger',
|
|
||||||
delay: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadSocket.on('error', err => {
|
|
||||||
Siofu.destroy();
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
uploadSocket.on('connect', function () {
|
|
||||||
if (notifyUploadSocketError !== false) {
|
|
||||||
notifyUploadSocketError.close();
|
|
||||||
notifyUploadSocketError = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
window.Siofu = new SocketIOFileUpload(uploadSocket);
|
|
||||||
Siofu.listenOnDrop(document.getElementById("load_files"));
|
|
||||||
|
|
||||||
if (document.getElementById("files_touch_target")) {
|
|
||||||
Siofu.listenOnInput(document.getElementById("files_touch_target"));
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('dragover', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
window.addEventListener('drop', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
window.foldersDetectedInDrag = function (event) {
|
|
||||||
var folderDetected = false;
|
|
||||||
var files = event.dataTransfer.files;
|
|
||||||
for (var i = 0, f; f = files[i]; i++) {
|
|
||||||
if (!f.type && f.size === 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return folderDetected;
|
|
||||||
};
|
|
||||||
|
|
||||||
var dropCounter = 0;
|
|
||||||
$('#load_files').bind({
|
|
||||||
dragenter: function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
dropCounter++;
|
|
||||||
$(this).addClass('hasFileHover');
|
|
||||||
},
|
|
||||||
dragleave: function (event) {
|
|
||||||
dropCounter--;
|
|
||||||
if (dropCounter === 0) {
|
|
||||||
$(this).removeClass('hasFileHover');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
drop: function (event) {
|
|
||||||
if (window.foldersDetectedInDrag(event.originalEvent)) {
|
|
||||||
$.notify({
|
|
||||||
message: 'Folder uploads are not supported. Please use SFTP to upload whole directories.',
|
|
||||||
}, {
|
|
||||||
type: 'warning',
|
|
||||||
delay: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dropCounter = 0;
|
|
||||||
$(this).removeClass('hasFileHover');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Siofu.addEventListener('start', function (event) {
|
|
||||||
window.onbeforeunload = function () {
|
|
||||||
return 'A file upload in in progress, are you sure you want to continue?';
|
|
||||||
};
|
|
||||||
event.file.meta.path = $('#file_listing').data('current-dir');
|
|
||||||
event.file.meta.identifier = Math.random().toString(36).slice(2);
|
|
||||||
|
|
||||||
$('#append_files_to').append('<tr id="file-upload-' + event.file.meta.identifier +'"> \
|
|
||||||
<td><i class="fa fa-file-text-o" style="margin-left: 2px;"></i></td> \
|
|
||||||
<td>' + event.file.name + '</td> \
|
|
||||||
<td colspan=2"> </td> \
|
|
||||||
</tr><tr> \
|
|
||||||
<td colspan="5" class="has-progress"> \
|
|
||||||
<div class="progress progress-table-bottom active"> \
|
|
||||||
<div class="progress-bar progress-bar-info prog-bar-' + event.file.meta.identifier +'" style="width: 0%"></div> \
|
|
||||||
</div> \
|
|
||||||
</td> \
|
|
||||||
</tr>\
|
|
||||||
');
|
|
||||||
});
|
|
||||||
|
|
||||||
Siofu.addEventListener('progress', function(event) {
|
|
||||||
window.onbeforeunload = function () {
|
|
||||||
return 'A file upload in in progress, are you sure you want to continue?';
|
|
||||||
};
|
|
||||||
var percent = event.bytesLoaded / event.file.size * 100;
|
|
||||||
if (percent >= 100) {
|
|
||||||
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-success').parent().removeClass('active');
|
|
||||||
} else {
|
|
||||||
$('.prog-bar-' + event.file.meta.identifier).css('width', percent + '%');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Do something when a file is uploaded:
|
|
||||||
Siofu.addEventListener('complete', function(event) {
|
|
||||||
window.onbeforeunload = function () {};
|
|
||||||
if (!event.success) {
|
|
||||||
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-danger');
|
|
||||||
$.notify({
|
|
||||||
message: 'An error was encountered while attempting to upload this file.'
|
|
||||||
}, {
|
|
||||||
type: 'danger',
|
|
||||||
delay: 5000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Siofu.addEventListener('error', function(event) {
|
|
||||||
window.onbeforeunload = function () {};
|
|
||||||
console.error(event);
|
|
||||||
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-danger');
|
|
||||||
$.notify({
|
|
||||||
message: 'An error was encountered while attempting to upload this file: <strong>' + event.message + '.</strong>',
|
|
||||||
}, {
|
|
||||||
type: 'danger',
|
|
||||||
delay: 8000
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,131 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
$('#console-popout').on('click', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
window.open($(this).attr('href'), 'Pterodactyl Console', 'width=800,height=400');
|
|
||||||
});
|
|
||||||
var Server = (function () {
|
|
||||||
|
|
||||||
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 required to use this panel.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.notifyDefaults({
|
|
||||||
placement: {
|
|
||||||
from: 'bottom',
|
|
||||||
align: 'right'
|
|
||||||
},
|
|
||||||
newest_on_top: true,
|
|
||||||
delay: 2000,
|
|
||||||
offset: {
|
|
||||||
x: 20,
|
|
||||||
y: 60,
|
|
||||||
},
|
|
||||||
animate: {
|
|
||||||
enter: 'animated bounceInUp',
|
|
||||||
exit: 'animated bounceOutDown'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var notifySocketError = false;
|
|
||||||
|
|
||||||
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/v1/ws/' + Pterodactyl.server.uuid, {
|
|
||||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setStatusIcon(999);
|
|
||||||
});
|
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setStatusIcon(999);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setStatusIcon(status) {
|
|
||||||
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:
|
|
||||||
$('#server_status_icon').html('<i class="fa fa-question-circle text-danger"></i> Connection Error');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: function () {
|
|
||||||
initSocket();
|
|
||||||
},
|
|
||||||
|
|
||||||
setStatusIcon: setStatusIcon,
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
Server.init();
|
|
|
@ -1,94 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
(function updateServerStatus() {
|
|
||||||
var Status = {
|
|
||||||
0: 'Offline',
|
|
||||||
1: 'Online',
|
|
||||||
2: 'Starting',
|
|
||||||
3: 'Stopping'
|
|
||||||
};
|
|
||||||
$('.dynamic-update').each(function (index, data) {
|
|
||||||
var element = $(this);
|
|
||||||
var serverShortUUID = $(this).data('server');
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'GET',
|
|
||||||
url: Router.route('index.status', { server: serverShortUUID }),
|
|
||||||
timeout: 5000,
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
}
|
|
||||||
}).done(function (data) {
|
|
||||||
if (typeof data.status === 'undefined') {
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-default">Error</span>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (data.status) {
|
|
||||||
case 0:
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-danger">Offline</span>');
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-success">Online</span>');
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-info">Starting</span>');
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-info">Stopping</span>');
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-warning">Installing</span>');
|
|
||||||
break;
|
|
||||||
case 30:
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-warning">Suspended</span>');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (data.status > 0 && data.status < 4) {
|
|
||||||
var cpuMax = element.find('[data-action="cpu"]').data('cpumax');
|
|
||||||
var currentCpu = data.proc.cpu.total;
|
|
||||||
if (cpuMax !== 0) {
|
|
||||||
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
|
||||||
}
|
|
||||||
if (data.status !== 0) {
|
|
||||||
var cpuMax = element.find('[data-action="cpu"]').data('cpumax');
|
|
||||||
var currentCpu = data.proc.cpu.total;
|
|
||||||
if (cpuMax !== 0) {
|
|
||||||
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
|
||||||
}
|
|
||||||
element.find('[data-action="memory"]').html(parseInt(data.proc.memory.total / (1024 * 1024)));
|
|
||||||
element.find('[data-action="cpu"]').html(currentCpu);
|
|
||||||
element.find('[data-action="disk"]').html(parseInt(data.proc.disk.used));
|
|
||||||
} else {
|
|
||||||
element.find('[data-action="memory"]').html('--');
|
|
||||||
element.find('[data-action="cpu"]').html('--');
|
|
||||||
element.find('[data-action="disk"]').html('--');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
if (jqXHR.status === 504) {
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-default">Gateway Timeout</span>');
|
|
||||||
} else {
|
|
||||||
element.find('[data-action="status"]').html('<span class="label label-default">Error</span>');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).promise().done(function () {
|
|
||||||
setTimeout(updateServerStatus, 10000);
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,144 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
|
||||||
$('[data-action="delete-schedule"]').click(function () {
|
|
||||||
var self = $(this);
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Delete Schedule?',
|
|
||||||
text: 'Are you sure you want to delete this schedule? There is no undo.',
|
|
||||||
showCancelButton: true,
|
|
||||||
allowOutsideClick: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
confirmButtonText: 'Delete Schedule',
|
|
||||||
confirmButtonColor: '#d9534f',
|
|
||||||
showLoaderOnConfirm: true
|
|
||||||
}, function () {
|
|
||||||
$.ajax({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: Router.route('server.schedules.view', {
|
|
||||||
server: Pterodactyl.server.uuidShort,
|
|
||||||
schedule: self.data('schedule-id'),
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
}
|
|
||||||
}).done(function (data) {
|
|
||||||
swal({
|
|
||||||
type: 'success',
|
|
||||||
title: '',
|
|
||||||
text: 'Schedule has been deleted.'
|
|
||||||
});
|
|
||||||
self.parent().parent().slideUp();
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
console.error(jqXHR);
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
text: 'An error occurred while attempting to delete this schedule.'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('[data-action="trigger-schedule"]').click(function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
var self = $(this);
|
|
||||||
swal({
|
|
||||||
type: 'info',
|
|
||||||
title: 'Trigger Schedule',
|
|
||||||
text: 'This will run the selected schedule now.',
|
|
||||||
showCancelButton: true,
|
|
||||||
allowOutsideClick: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
confirmButtonText: 'Continue',
|
|
||||||
showLoaderOnConfirm: true
|
|
||||||
}, function () {
|
|
||||||
$.ajax({
|
|
||||||
method: 'POST',
|
|
||||||
url: Router.route('server.schedules.trigger', {
|
|
||||||
server: Pterodactyl.server.uuidShort,
|
|
||||||
schedule: self.data('schedule-id'),
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
},
|
|
||||||
}).done(function (data) {
|
|
||||||
swal({
|
|
||||||
type: 'success',
|
|
||||||
title: '',
|
|
||||||
text: 'Schedule has been added to the next-run queue.'
|
|
||||||
});
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
console.error(jqXHR);
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
text: 'An error occurred while attempting to trigger this schedule.'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('[data-action="toggle-schedule"]').click(function (event) {
|
|
||||||
var self = $(this);
|
|
||||||
swal({
|
|
||||||
type: 'info',
|
|
||||||
title: 'Toggle Schedule',
|
|
||||||
text: 'This will toggle the selected schedule.',
|
|
||||||
showCancelButton: true,
|
|
||||||
allowOutsideClick: true,
|
|
||||||
closeOnConfirm: false,
|
|
||||||
confirmButtonText: 'Continue',
|
|
||||||
showLoaderOnConfirm: true
|
|
||||||
}, function () {
|
|
||||||
$.ajax({
|
|
||||||
method: 'POST',
|
|
||||||
url: Router.route('server.schedules.toggle', {
|
|
||||||
server: Pterodactyl.server.uuidShort,
|
|
||||||
schedule: self.data('schedule-id'),
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
|
||||||
}
|
|
||||||
}).done(function (data) {
|
|
||||||
swal({
|
|
||||||
type: 'success',
|
|
||||||
title: '',
|
|
||||||
text: 'Schedule has been toggled.'
|
|
||||||
});
|
|
||||||
if (data.status !== 1) {
|
|
||||||
self.parent().parent().addClass('muted muted-hover');
|
|
||||||
} else {
|
|
||||||
self.parent().parent().removeClass('muted muted-hover');
|
|
||||||
}
|
|
||||||
}).fail(function (jqXHR) {
|
|
||||||
console.error(jqXHR);
|
|
||||||
swal({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Whoops!',
|
|
||||||
text: 'An error occurred while attempting to toggle this schedule.'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,61 +0,0 @@
|
||||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// 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
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
function setupSelect2() {
|
|
||||||
$('select[name="tasks[time_value][]"]').select2();
|
|
||||||
$('select[name="tasks[time_interval][]"]').select2();
|
|
||||||
$('select[name="tasks[action][]"]').select2();
|
|
||||||
}
|
|
||||||
|
|
||||||
setupSelect2();
|
|
||||||
|
|
||||||
$('[data-action="update-field"]').on('change', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
var updateField = $(this).data('field');
|
|
||||||
var selected = $(this).map(function (i, opt) {
|
|
||||||
return $(opt).val();
|
|
||||||
}).toArray();
|
|
||||||
if (selected.length === $(this).find('option').length) {
|
|
||||||
$('input[name=' + updateField + ']').val('*');
|
|
||||||
} else {
|
|
||||||
$('input[name=' + updateField + ']').val(selected.join(','));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('button[data-action="add-new-task"]').on('click', function () {
|
|
||||||
if ($('#containsTaskList').find('.task-list-item').length >= 5) {
|
|
||||||
swal('Task Limit Reached', 'You may only assign a maximum of 5 tasks to one schedule.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var clone = $('div[data-target="task-clone"]').clone();
|
|
||||||
clone.insertBefore('#taskAppendBefore').removeAttr('data-target');
|
|
||||||
clone.find('select:first').attr('selected');
|
|
||||||
clone.find('input').val('');
|
|
||||||
clone.find('span.select2-container').remove();
|
|
||||||
clone.find('div[data-attribute="remove-task-element"]').addClass('input-group').find('div.input-group-btn').removeClass('hidden');
|
|
||||||
clone.find('button[data-action="remove-task"]').on('click', function () {
|
|
||||||
clone.remove();
|
|
||||||
});
|
|
||||||
setupSelect2();
|
|
||||||
$(this).data('element', clone);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -77,7 +77,7 @@
|
||||||
}, function () {
|
}, function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: Router.route('admin.api.delete', { identifier: self.data('attr') }),
|
url: '/admin/api/revoke/' + self.data('attr'),
|
||||||
headers: {
|
headers: {
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@
|
||||||
}, function () {
|
}, function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: Router.route('admin.nodes.view.allocation.removeSingle', { node: Pterodactyl.node.id, allocation: allocation }),
|
url: '/admin/nodes/view/' + Pterodactyl.node.id + '/allocation/remove/' + allocation,
|
||||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
element.parent().parent().addClass('warning').delay(100).fadeOut();
|
element.parent().parent().addClass('warning').delay(100).fadeOut();
|
||||||
|
@ -247,7 +247,7 @@
|
||||||
clearTimeout(fadeTimers[element.data('id')]);
|
clearTimeout(fadeTimers[element.data('id')]);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: Router.route('admin.nodes.view.allocation.setAlias', { id: Pterodactyl.node.id }),
|
url: '/admin/nodes/view/' + Pterodactyl.node.id + '/allocation/alias',
|
||||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||||
data: {
|
data: {
|
||||||
alias: element.val(),
|
alias: element.val(),
|
||||||
|
@ -321,9 +321,7 @@
|
||||||
}, function () {
|
}, function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: Router.route('admin.nodes.view.allocation.removeMultiple', {
|
url: '/admin/nodes/view/' + Pterodactyl.node.id + '/allocations',
|
||||||
node: Pterodactyl.node.id
|
|
||||||
}),
|
|
||||||
headers: {'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')},
|
headers: {'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')},
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
allocations: selectedIds
|
allocations: selectedIds
|
||||||
|
|
|
@ -130,7 +130,7 @@
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: Router.route('admin.packs.new.template'),
|
url: '/admin/packs/new/template',
|
||||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||||
}).fail(function (jqXhr) {
|
}).fail(function (jqXhr) {
|
||||||
console.error(jqXhr);
|
console.error(jqXhr);
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
}, function () {
|
}, function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: Router.route('admin.servers.view.database.delete', { server: '{{ $server->id }}', database: self.data('id') }),
|
url: '/admin/servers/view/{{ $server->id }}/database/' + self.data('id') + '/delete',
|
||||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||||
}).done(function () {
|
}).done(function () {
|
||||||
self.parent().parent().slideUp();
|
self.parent().parent().slideUp();
|
||||||
|
@ -152,7 +152,7 @@
|
||||||
$(this).addClass('disabled').find('i').addClass('fa-spin');
|
$(this).addClass('disabled').find('i').addClass('fa-spin');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'PATCH',
|
type: 'PATCH',
|
||||||
url: Router.route('admin.servers.view.database', { server: '{{ $server->id }}' }),
|
url: '/admin/servers/view/{{ $server->id }}/database',
|
||||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||||
data: { database: $(this).data('id') },
|
data: { database: $(this).data('id') },
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<script>
|
<script>
|
||||||
$('#pUserId').select2({
|
$('#pUserId').select2({
|
||||||
ajax: {
|
ajax: {
|
||||||
url: Router.route('admin.users.json'),
|
url: '/admin/users/accounts.json',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
delay: 250,
|
delay: 250,
|
||||||
data: function (params) {
|
data: function (params) {
|
||||||
|
|
|
@ -112,12 +112,12 @@
|
||||||
|
|
||||||
@section('footer-scripts')
|
@section('footer-scripts')
|
||||||
@parent
|
@parent
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function saveSettings() {
|
function saveSettings() {
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
url: Router.route('admin.settings.mail'),
|
url: '/admin/settings/mail',
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
'mail:host': $('input[name="mail:host"]').val(),
|
'mail:host': $('input[name="mail:host"]').val(),
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
}, function () {
|
}, function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: Router.route('admin.settings.mail.test'),
|
url: '/admin/settings/mail/test',
|
||||||
headers: { 'X-CSRF-Token': $('input[name="_token"]').val() }
|
headers: { 'X-CSRF-Token': $('input[name="_token"]').val() }
|
||||||
}).fail(function (jqXHR) {
|
}).fail(function (jqXHR) {
|
||||||
showErrorDialog(jqXHR, 'test');
|
showErrorDialog(jqXHR, 'test');
|
||||||
|
|
Loading…
Reference in a new issue