Files
codeocean/app/assets/javascripts/shell.js
Sebastian Serth 944b455194 Introduce Dark Mode
This commit mainly changes the color definitions. Mostly, those changes are semantically equally, but there are a few changes that occurred to align the color scheme within the app.
2023-07-31 11:48:42 +02:00

185 lines
6.0 KiB
JavaScript

$(document).on('turbolinks:load', function () {
const ENTER_KEY_CODE = 13;
const clearOutput = function () {
log.html('');
};
const executeCommand = function (command) {
$.ajax({
data: {
command: command,
sudo: sudo.is(':checked')
},
method: 'POST',
url: Routes.execute_command_execution_environment_path(id)
}).done(handleResponse);
};
const handleKeyPress = function (event) {
if (event.which === ENTER_KEY_CODE) {
const command = $(this).val();
if (command === 'clear') {
clearOutput();
} else {
printCommand(command);
executeCommand(command);
}
$(this).val('');
}
};
const handleResponse = function (response) {
// Always print stdout and stderr
printOutput(response);
// If an error occurred, print it too
if (response.status === 'timeout') {
printTimeout(response);
} else if (response.status === 'out_of_memory') {
printOutOfMemory(response);
}
};
const printCommand = function (command) {
const em = $('<em>');
em.text(command);
const p = $('<p>');
p.append(em)
log.append(p);
};
const printOutput = function (output) {
if (output) {
if (output.stdout) {
const element = $('<p>');
element.addClass('text-success');
element.text(output.stdout);
log.append(element);
}
if (output.stderr) {
const element = $('<p>');
element.addClass('text-warning');
element.text(output.stderr);
log.append(element);
}
if (!output.stdout && !output.stderr) {
const element = $('<p>');
element.addClass('text-body-secondary');
element.text(log.data('message-no-output'));
log.append(element);
}
}
};
const printTimeout = function (output) {
const element = $('<p>');
element.addClass('text-danger');
element.text($('#shell').data('message-timeout'));
log.append(element);
};
const printOutOfMemory = function (output) {
const element = $('<p>');
element.addClass('text-danger');
element.text($('#shell').data('message-out-of-memory'));
log.append(element);
};
const retrieveFiles = function () {
let fileTree = $('#download-file-tree');
// Get current instance of the jstree if available and refresh the existing one.
// Otherwise, initialize a new one.
if (fileTree.jstree(true)) {
return fileTree.jstree('refresh');
} else {
fileTree.removeClass('my-3 justify-content-center');
fileTree.jstree({
'core': {
'themes': {
'name': window.getCurrentTheme() === "dark" ? "default-dark" : "default"
},
'data': {
'url': function (node) {
const params = {sudo: sudo.is(':checked')};
return Routes.list_files_in_execution_environment_path(id, params);
},
'data': function (node) {
return {'path': getPath(fileTree.jstree(true), node)|| '/'};
}
}
}
});
fileTree.on('select_node.jstree', function (node, selected, _event) {
// We never want a node to be selected permanently, so we deselect it immediately.
selected.instance.deselect_all();
const path = getPath(selected.instance, selected.node)
const params = {sudo: sudo.is(':checked')};
const downloadPath = Routes.download_file_from_execution_environment_path(id, path, params);
// Now we download the file if allowed.
if (selected.node.original.icon.split(" ").some(function (icon) {
return ['fa-lock', 'fa-folder'].includes(icon);
})) {
$.flash.danger({
icon: ['fa-solid', 'fa-shield-halved'],
text: I18n.t('execution_environments.shell.file_tree.permission_denied')
});
} else {
window.location = downloadPath;
}
}.bind(this));
$(document).on('theme:change', function(event) {
const newColorScheme = event.detail.currentTheme;
// Update the JStree theme
fileTree.jstree(true).set_theme(newColorScheme === "dark" ? "default-dark" : "default");
});
}
}
const getPath = function (jstree, node) {
if (node.id === '#') {
// Root node
return '/'
}
// We build the path to the file by concatenating the paths of all parent nodes.
let file_path = node.parents.reverse().map(function (id) {
return jstree.get_text(id);
}).filter(function (text) {
return text !== false;
}).join('/');
return `${node.parent !== '#' ? '/' : ''}${file_path}${node.original.path}`;
}
const shell = $('#shell');
if (!shell.isPresent()) {
return;
}
const command = $('#command')
command.focus();
command.on('keypress', handleKeyPress);
const id = shell.data('id');
const log = $('#output');
const sudo = $('#sudo');
sudo.on('change', function () {
sudo.parent().toggleClass('text-body-secondary')
command.focus();
});
$('#reload-files').on('click', function () {
new bootstrap.Collapse('#collapse_files', 'show');
retrieveFiles();
});
$('#reload-now-link').on('click', retrieveFiles);
})
;