Merge branch 'develop' into feature/admin-retheme
# Conflicts: # public/themes/pterodactyl/css/pterodactyl.css
This commit is contained in:
commit
799f2ee6d9
22 changed files with 10923 additions and 528 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,4 +1,14 @@
|
|||
/vendor
|
||||
*.DS_Store*
|
||||
.env
|
||||
.vagrant/*
|
||||
|
||||
composer.lock
|
||||
|
||||
Homestead.yaml
|
||||
Vagrantfile
|
||||
Vagrantfile
|
||||
|
||||
node_modules
|
||||
yarn.lock
|
||||
node_modules
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
// 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.
|
||||
$(window).load(function () {
|
||||
$(document).ready(function () {
|
||||
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({
|
||||
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>.',
|
||||
|
|
|
@ -245,3 +245,24 @@ span[aria-labelledby="select2-pUserId-container"] {
|
|||
.nav-tabs-custom.nav-tabs-floating > .nav-tabs > li:first-child.active > a {
|
||||
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,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
$(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).load(function () {
|
||||
$('#hide_img_load').slideUp(function () {
|
||||
$('#qr_image_insert').attr('src', image.src).slideDown();
|
||||
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).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);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
$('#2fa_token_verify').submit(function (event) {
|
||||
event.preventDefault();
|
||||
$('#submit_action').html('<i class="fa fa-spinner fa-spin"></i> Submit').addClass('disabled');
|
||||
return {
|
||||
init: function () {
|
||||
bindListeners();
|
||||
}
|
||||
}
|
||||
|
||||
$.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,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
var CONSOLE_PUSH_COUNT = 50;
|
||||
var CONSOLE_PUSH_FREQ = 200;
|
||||
|
||||
(function initConsole() {
|
||||
window.TerminalQueue = [];
|
||||
window.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;
|
||||
}
|
||||
});
|
||||
var Console = (function () {
|
||||
var CONSOLE_PUSH_COUNT = 50;
|
||||
var CONSOLE_PUSH_FREQ = 200;
|
||||
|
||||
Socket.on('initial status', function (data) {
|
||||
Terminal.clear();
|
||||
if (data.status === 1 || data.status === 2) {
|
||||
Socket.emit('send server log');
|
||||
}
|
||||
});
|
||||
})();
|
||||
var terminalQueue;
|
||||
var terminal;
|
||||
|
||||
(function pushOutputQueue() {
|
||||
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
|
||||
// console throttled warning show
|
||||
var cpuChart;
|
||||
var cpuData;
|
||||
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) {
|
||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
|
||||
Terminal.echo(TerminalQueue[0]);
|
||||
TerminalQueue.shift();
|
||||
}
|
||||
function initGraphs() {
|
||||
var ctc = $('#chart_cpu');
|
||||
timeLabels = [];
|
||||
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 () {
|
||||
$('[data-attr="power"]').click(function (event) {
|
||||
if (! $(this).hasClass('disabled')) {
|
||||
Socket.emit('set status', $(this).data('action'));
|
||||
terminal.clear();
|
||||
if (data.status === 1 || data.status === 2) {
|
||||
Socket.emit('send server log');
|
||||
}
|
||||
});
|
||||
|
||||
// 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');
|
||||
var timeLabels = [];
|
||||
var cpuData = [];
|
||||
var CPUChart = new Chart(ctc, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timeLabels,
|
||||
datasets: [
|
||||
{
|
||||
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,
|
||||
if (terminalQueue.length > 0) {
|
||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && terminalQueue.length > 0; i++) {
|
||||
terminal.echo(terminalQueue[0]);
|
||||
terminalQueue.shift();
|
||||
}
|
||||
|
||||
// Show
|
||||
if (!terminal.is_bottom()) {
|
||||
$terminalNotify.removeClass('hidden');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ctm = $('#chart_memory');
|
||||
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);
|
||||
});
|
||||
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
||||
}
|
||||
|
||||
function updateServerPowerControls (data) {
|
||||
// Server is On or Starting
|
||||
|
@ -203,4 +233,33 @@ $(document).ready(function () {
|
|||
$('[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;
|
||||
}
|
||||
|
||||
folder() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
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'));
|
||||
|
||||
let inputValue = `${currentPath}${currentName}/`;
|
||||
if ($(this.element).data('type') === 'file') {
|
||||
inputValue = currentPath;
|
||||
if ($(this.element).data('type') === 'file') {
|
||||
inputValue = currentPath;
|
||||
} else {
|
||||
inputValue = `${currentPath}${currentName}/`;
|
||||
}
|
||||
}
|
||||
|
||||
swal({
|
||||
type: 'input',
|
||||
title: 'Create Folder',
|
||||
|
|
|
@ -33,7 +33,7 @@ class ContextMenuClass {
|
|||
$(document).find('#fileOptionMenu').remove();
|
||||
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') {
|
||||
const nameBlock = parent.find('td[data-identifier="name"]');
|
||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
|
|
|
@ -44,6 +44,7 @@ class FileManager {
|
|||
$('#load_files').slideUp(10).html(data).slideDown(10, () => {
|
||||
ContextMenu.run();
|
||||
this.reloadFilesButton();
|
||||
this.addFolderButton();
|
||||
if (_.isFunction(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() {
|
||||
return decodeURIComponent(window.location.hash.substring(1));
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
window.onbeforeunload = function () {
|
||||
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);
|
||||
|
||||
$('#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,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
(function initSocket() {
|
||||
if (typeof $.notifyDefaults !== 'function') {
|
||||
console.error('Notify does not appear to be loaded.');
|
||||
return;
|
||||
|
||||
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 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') {
|
||||
console.error('Socket.io is reqired to use this panel.');
|
||||
return;
|
||||
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:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$.notifyDefaults({
|
||||
placement: {
|
||||
from: 'bottom',
|
||||
align: 'right'
|
||||
return {
|
||||
init: function () {
|
||||
initSocket();
|
||||
},
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Server.init();
|
||||
|
|
|
@ -17,14 +17,16 @@
|
|||
// 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 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) {
|
||||
var element = $(this);
|
||||
var serverShortUUID = $(this).data('server');
|
||||
|
@ -67,16 +69,32 @@ var Status = {
|
|||
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);
|
||||
} 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>');
|
||||
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);
|
||||
} 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,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
(function initTaskFunctions() {
|
||||
$('[data-action="delete-task"]').click(function (event) {
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Delete Task?',
|
||||
text: 'Are you sure you want to delete this task? There is no undo.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Delete Task',
|
||||
confirmButtonColor: '#d9534f',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('server.tasks.delete', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
id: self.data('id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Task has been deleted.'
|
||||
});
|
||||
self.parent().parent().slideUp();
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
text: 'An error occured while attempting to delete this task.'
|
||||
|
||||
var Tasks = (function () {
|
||||
|
||||
function initTaskFunctions() {
|
||||
$('[data-action="delete-task"]').click(function (event) {
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Delete Task?',
|
||||
text: 'Are you sure you want to delete this task? There is no undo.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Delete Task',
|
||||
confirmButtonColor: '#d9534f',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('server.tasks.delete', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
id: self.data('id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Task has been deleted.'
|
||||
});
|
||||
self.parent().parent().slideUp();
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
text: 'An error occured while attempting to delete this task.'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
$('[data-action="toggle-task"]').click(function (event) {
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'info',
|
||||
title: 'Toggle Task',
|
||||
text: 'This will toggle the selected task.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Continue',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: Router.route('server.tasks.toggle', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
id: self.data('id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Task 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 occured while attempting to toggle this task.'
|
||||
$('[data-action="toggle-task"]').click(function (event) {
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'info',
|
||||
title: 'Toggle Task',
|
||||
text: 'This will toggle the selected task.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Continue',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: Router.route('server.tasks.toggle', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
id: self.data('id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Task 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 occured while attempting to toggle this task.'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: function () {
|
||||
initTaskFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
Tasks.init();
|
||||
|
|
10220
public/themes/pterodactyl/vendor/jquery/jquery.js
vendored
Normal file
10220
public/themes/pterodactyl/vendor/jquery/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
4
public/themes/pterodactyl/vendor/jquery/jquery.min.js
vendored
Normal file
4
public/themes/pterodactyl/vendor/jquery/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/themes/pterodactyl/vendor/jquery/jquery.min.map
vendored
Normal file
1
public/themes/pterodactyl/vendor/jquery/jquery.min.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -212,6 +212,7 @@ return [
|
|||
'size' => 'Size',
|
||||
'last_modified' => 'Last Modified',
|
||||
'add_new' => 'Add New File',
|
||||
'add_folder' => 'Add New Folder',
|
||||
'edit' => [
|
||||
'header' => 'Edit File',
|
||||
'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 />
|
||||
</p>
|
||||
</div>
|
||||
{!! Theme::js('js/vendor/jquery/jquery.min.js') !!}
|
||||
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
||||
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
||||
|
||||
@if(config('app.phrase_in_context')) {!! Theme::js('js/phraseapp.js') !!} @endif
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
</div>
|
||||
@section('footer-scripts')
|
||||
{!! 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/slimscroll/jquery.slimscroll.min.js') !!}
|
||||
{!! Theme::js('vendor/adminlte/app.min.js') !!}
|
||||
|
|
|
@ -266,7 +266,7 @@
|
|||
</div>
|
||||
@section('footer-scripts')
|
||||
{!! 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/bootstrap/bootstrap.min.js') !!}
|
||||
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
|
||||
|
|
|
@ -38,8 +38,10 @@
|
|||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<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 class="callout callout-info" style="margin:10px;">@lang('server.files.loading')</div>
|
||||
<div id="load_files">
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<div class="callout callout-info" style="margin:10px;">@lang('server.files.loading')</div>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
|
|
|
@ -17,148 +17,151 @@
|
|||
{{-- 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. --}}
|
||||
<table class="table table-hover" id="file_listing">
|
||||
<thead>
|
||||
<tr>
|
||||
<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>
|
||||
<th style="width:55%">@lang('server.files.file_name')</th>
|
||||
<th style="width:15%">@lang('server.files.size')</th>
|
||||
<th style="width:20%">@lang('server.files.last_modified')</th>
|
||||
<th style="width:8%">
|
||||
<label class="btn btn-primary btn-xs btn-file">
|
||||
Upload <input type="file" id="files_touch_target" style="display: none;"/>
|
||||
</label>
|
||||
</th>
|
||||
</tr>
|
||||
<tr id="headerTableRow" data-currentdir="{{ $directory['header'] }}">
|
||||
<th class="middle"><i class="fa fa-folder-open"></i></th>
|
||||
<th colspan="4" class="middle">
|
||||
<code>/home/container{{ $directory['header'] }}</code>
|
||||
<small>
|
||||
<a href="/server/{{ $server->uuidShort }}/files/add/@if($directory['header'] !== '')?dir={{ $directory['header'] }}@endif" class="text-muted">
|
||||
<i class="fa fa-plus" data-toggle="tooltip" data-placement="top" title="@lang('server.files.add_new')"></i>
|
||||
</a>
|
||||
</small>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<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>
|
||||
|
||||
<div class="box-header">
|
||||
<i class="fa fa-refresh muted muted-hover use-pointer" data-action="reload-files"></i>
|
||||
<code class="box-title">/home/container{{ $directory['header'] }}</code>
|
||||
<a class="text-muted">
|
||||
<i class="fa fa-plus" data-action="add-folder" data-toggle="tooltip" data-placement="top" title="@lang('server.files.add_folder')"></i>
|
||||
</a>
|
||||
<div class="box-tools pull-right">
|
||||
<a class="btn btn-primary btn-sm" href="/server/{{ $server->uuidShort }}/files/add/@if($directory['header'] !== '')?dir={{ $directory['header'] }}@endif">
|
||||
<i class="fa fa-file"></i> Create File
|
||||
</a>
|
||||
<a class="btn btn-primary btn-sm btn-icon btn-file">
|
||||
<i class="fa fa-upload"></i> Upload <input type="file" id="files_touch_target" style="display: none;">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover" id="file_listing" data-current-dir="{{ $directory['header'] }}">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:2%;" class="middle"></th>
|
||||
<th style="width:55%">@lang('server.files.file_name')</th>
|
||||
<th style="width:15%" class="hidden-xs">@lang('server.files.size')</th>
|
||||
<th style="width:20%" class="hidden-xs">@lang('server.files.last_modified')</th>
|
||||
<th style="width:8%"></th>
|
||||
</tr>
|
||||
@endif
|
||||
@if (isset($directory['show']) && $directory['show'] === true)
|
||||
<tr data-type="disabled">
|
||||
<td class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||
<td data-name="{{ rawurlencode($directory['link']) }}">
|
||||
<a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">← {{ $directory['link_show'] }}</a>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
@endif
|
||||
@foreach ($folders as $folder)
|
||||
<tr data-type="folder">
|
||||
<td data-identifier="type" class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||
<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">{{ $folder['entry'] }}</a>
|
||||
</td>
|
||||
<td data-identifier="size">{{ $folder['size'] }}</td>
|
||||
<td data-identifier="modified">
|
||||
<?php $carbon = Carbon::createFromTimestamp($folder['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
||||
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
||||
{{ $carbon->format('m/d/y H:i:s') }}
|
||||
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
||||
<em>@lang('server.files.seconds_ago')</em>
|
||||
@else
|
||||
{{ $carbon->diffForHumans() }}
|
||||
@endif
|
||||
</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>
|
||||
</tr>
|
||||
@endforeach
|
||||
@foreach ($files as $file)
|
||||
<tr data-type="file" data-mime="{{ $file['mime'] }}">
|
||||
<td data-identifier="type" class="middle">
|
||||
{{-- oh boy --}}
|
||||
@if(in_array($file['mime'], [
|
||||
'application/x-7z-compressed',
|
||||
'application/zip',
|
||||
'application/x-compressed-zip',
|
||||
'application/x-tar',
|
||||
'application/x-gzip',
|
||||
'application/x-bzip',
|
||||
'application/x-bzip2',
|
||||
'application/java-archive'
|
||||
]))
|
||||
<i class="fa fa-file-archive-o" style="margin-left: 2px;"></i>
|
||||
@elseif(in_array($file['mime'], [
|
||||
'application/json',
|
||||
'application/javascript',
|
||||
'application/xml',
|
||||
'application/xhtml+xml',
|
||||
'text/xml',
|
||||
'text/css',
|
||||
'text/html',
|
||||
'text/x-perl',
|
||||
'text/x-shellscript'
|
||||
]))
|
||||
<i class="fa fa-file-code-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'image'))
|
||||
<i class="fa fa-file-image-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'video'))
|
||||
<i class="fa fa-file-video-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'video'))
|
||||
<i class="fa fa-file-audio-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'application/vnd.ms-powerpoint'))
|
||||
<i class="fa fa-file-powerpoint-o" style="margin-left: 2px;"></i>
|
||||
@elseif(in_array($file['mime'], [
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'application/msword'
|
||||
]) || starts_with($file['mime'], 'application/vnd.ms-word'))
|
||||
<i class="fa fa-file-word-o" style="margin-left: 2px;"></i>
|
||||
@elseif(in_array($file['mime'], [
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
]) || starts_with($file['mime'], 'application/vnd.ms-excel'))
|
||||
<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>
|
||||
</thead>
|
||||
<tbody id="append_files_to">
|
||||
@if (isset($directory['first']) && $directory['first'] === true)
|
||||
<tr data-type="disabled">
|
||||
<td><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||
<td><a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">←</a></a></td>
|
||||
<td class="hidden-xs"></td>
|
||||
<td class="hidden-xs"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
@endif
|
||||
@if (isset($directory['show']) && $directory['show'] === true)
|
||||
<tr data-type="disabled">
|
||||
<td><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||
<td data-name="{{ rawurlencode($directory['link']) }}">
|
||||
<a href="/server/{{ $server->uuidShort }}/files" data-action="directory-view">← {{ $directory['link_show'] }}</a>
|
||||
</td>
|
||||
<td class="hidden-xs"></td>
|
||||
<td class="hidden-xs"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
@endif
|
||||
@foreach ($folders as $folder)
|
||||
<tr data-type="folder">
|
||||
<td data-identifier="type" class="middle"><i class="fa fa-folder" style="margin-left: 0.859px;"></i></td>
|
||||
<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">{{ $folder['entry'] }}</a>
|
||||
</td>
|
||||
<td data-identifier="size" class="hidden-xs">{{ $folder['size'] }}</td>
|
||||
<td data-identifier="modified" class="hidden-xs">
|
||||
<?php $carbon = Carbon::createFromTimestamp($folder['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
||||
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
||||
{{ $carbon->format('m/d/y H:i:s') }}
|
||||
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
||||
<em>@lang('server.files.seconds_ago')</em>
|
||||
@else
|
||||
{{ $carbon->diffForHumans() }}
|
||||
@endif
|
||||
</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>
|
||||
</tr>
|
||||
@endforeach
|
||||
@foreach ($files as $file)
|
||||
<tr data-type="file" data-mime="{{ $file['mime'] }}">
|
||||
<td data-identifier="type" class="middle">
|
||||
{{-- oh boy --}}
|
||||
@if(in_array($file['mime'], [
|
||||
'application/x-7z-compressed',
|
||||
'application/zip',
|
||||
'application/x-compressed-zip',
|
||||
'application/x-tar',
|
||||
'application/x-gzip',
|
||||
'application/x-bzip',
|
||||
'application/x-bzip2',
|
||||
'application/java-archive'
|
||||
]))
|
||||
<i class="fa fa-file-archive-o" style="margin-left: 2px;"></i>
|
||||
@elseif(in_array($file['mime'], [
|
||||
'application/json',
|
||||
'application/javascript',
|
||||
'application/xml',
|
||||
'application/xhtml+xml',
|
||||
'text/xml',
|
||||
'text/css',
|
||||
'text/html',
|
||||
'text/x-perl',
|
||||
'text/x-shellscript'
|
||||
]))
|
||||
<i class="fa fa-file-code-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'image'))
|
||||
<i class="fa fa-file-image-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'video'))
|
||||
<i class="fa fa-file-video-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'video'))
|
||||
<i class="fa fa-file-audio-o" style="margin-left: 2px;"></i>
|
||||
@elseif(starts_with($file['mime'], 'application/vnd.ms-powerpoint'))
|
||||
<i class="fa fa-file-powerpoint-o" style="margin-left: 2px;"></i>
|
||||
@elseif(in_array($file['mime'], [
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'application/msword'
|
||||
]) || starts_with($file['mime'], 'application/vnd.ms-word'))
|
||||
<i class="fa fa-file-word-o" style="margin-left: 2px;"></i>
|
||||
@elseif(in_array($file['mime'], [
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
]) || starts_with($file['mime'], 'application/vnd.ms-excel'))
|
||||
<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
|
||||
{{ $file['entry'] }}
|
||||
@endcan
|
||||
@else
|
||||
{{ $file['entry'] }}
|
||||
@endif
|
||||
</td>
|
||||
<td data-identifier="size">{{ $file['size'] }}</td>
|
||||
<td data-identifier="modified">
|
||||
<?php $carbon = Carbon::createFromTimestamp($file['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
||||
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
||||
{{ $carbon->format('m/d/y H:i:s') }}
|
||||
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
||||
<em>@lang('server.files.seconds_ago')</em>
|
||||
@else
|
||||
{{ $carbon->diffForHumans() }}
|
||||
@endif
|
||||
</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>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
</td>
|
||||
<td data-identifier="size" class="hidden-xs">{{ $file['size'] }}</td>
|
||||
<td data-identifier="modified" class="hidden-xs">
|
||||
<?php $carbon = Carbon::createFromTimestamp($file['date'])->timezone(env('APP_TIMEZONE', 'America/New_York')); ?>
|
||||
@if($carbon->diffInMinutes(Carbon::now()) > 60)
|
||||
{{ $carbon->format('m/d/y H:i:s') }}
|
||||
@elseif($carbon->diffInSeconds(Carbon::now()) < 5 || $carbon->isFuture())
|
||||
<em>@lang('server.files.seconds_ago')</em>
|
||||
@else
|
||||
{{ $carbon->diffForHumans() }}
|
||||
@endif
|
||||
</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>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -40,8 +40,11 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
<div class="box-body position-relative">
|
||||
<div id="terminal" style="width:100%;"></div>
|
||||
<div id="terminalNotify" class="terminal-notify hidden">
|
||||
<i class="fa fa-bell"></i>
|
||||
</div>
|
||||
</div>
|
||||
<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
|
||||
|
|
Loading…
Reference in a new issue