File adding support, editor enhancements, JS improved.
This commit is contained in:
parent
50b377d08c
commit
81dc74a175
4 changed files with 83 additions and 41 deletions
|
@ -136,7 +136,7 @@ class FileRepository
|
|||
*
|
||||
* @param string $file
|
||||
* @param string $content
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function saveFileContents($file, $content)
|
||||
{
|
||||
|
@ -149,23 +149,6 @@ class FileRepository
|
|||
|
||||
$file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
|
||||
|
||||
$res = $this->client->request('GET', '/server/files/stat/' . rawurlencode($file->dirname.$file->basename) , [
|
||||
'headers' => $this->headers
|
||||
]);
|
||||
|
||||
$stat = json_decode($res->getBody());
|
||||
if($res->getStatusCode() !== 200 || !isset($stat->size)) {
|
||||
throw new DisplayException('The daemon provided a non-200 error code on stat lookup: HTTP\\' . $res->getStatusCode());
|
||||
}
|
||||
|
||||
if (!in_array($stat->mime, HelperRepository::editableFiles())) {
|
||||
throw new DisplayException('You cannot edit that type of file (' . $stat->mime . ') through the panel.');
|
||||
}
|
||||
|
||||
if ($stat->size > 5000000) {
|
||||
throw new DisplayException('That file is too large to save in the browser, consider using a SFTP client.');
|
||||
}
|
||||
|
||||
$res = $this->client->request('POST', '/server/file/' . rawurlencode($file->dirname.$file->basename), [
|
||||
'headers' => $this->headers,
|
||||
'json' => [
|
||||
|
|
|
@ -40,15 +40,45 @@
|
|||
<form method="post" id="new_file">
|
||||
<h4>/home/container/{{ $directory }} <input type="text" id="file_name" class="filename" value="newfile.txt" /></h4>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<textarea name="file_contents" id="fileContents" style="border: 1px solid #dddddd;" class="form-control console"></textarea>
|
||||
</div>
|
||||
<div id="fileContents" style="height:500px;"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<button class="btn btn-primary btn-sm" id="create_file">{{ trans('strings.save') }}</button>
|
||||
<button class="btn btn-default btn-sm" onclick="window.location='/server/{{ $server->uuidShort }}/files?dir=/{{ $directory }}';return false;">{{ trans('server.files.back') }}</button>
|
||||
</div>
|
||||
<div class="col-md-4 pull-right">
|
||||
<select name="aceMode" id="aceMode" class="form-control">
|
||||
<option value="assembly_x86">Assembly x86</option>
|
||||
<option value="c_cpp">C/C++</option>
|
||||
<option value="coffee">CoffeeScript</option>
|
||||
<option value="csharp">C#</option>
|
||||
<option value="css">CSS</option>
|
||||
<option value="golang">Go</option>
|
||||
<option value="haml">HAML</option>
|
||||
<option value="html">HTML</option>
|
||||
<option value="ini">INI</option>
|
||||
<option value="java">Java</option>
|
||||
<option value="javascript">JavaScript</option>
|
||||
<option value="json">JSON</option>
|
||||
<option value="lua">Lua</option>
|
||||
<option value="markdown">Markdown</option>
|
||||
<option value="mysql">MySQL</option>
|
||||
<option value="objectivec">Objective-C</option>
|
||||
<option value="perl">Perl</option>
|
||||
<option value="php">PHP</option>
|
||||
<option value="properties">Properties</option>
|
||||
<option value="python">Python</option>
|
||||
<option value="ruby">Ruby</option>
|
||||
<option value="rust">Rust</option>
|
||||
<option value="smarty">Smarty</option>
|
||||
<option value="textile" selected="selected">Plain Text</option>
|
||||
<option value="xml">XML</option>
|
||||
<option value="yaml">YAML</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -66,6 +96,8 @@
|
|||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
{!! Theme::js('js/vendor/ace/ace.js') !!}
|
||||
{!! Theme::js('js/vendor/ace/ext-modelist.js') !!}
|
||||
<script>
|
||||
$(window).load(function () {
|
||||
|
||||
|
@ -170,35 +202,54 @@ $(window).load(function () {
|
|||
}
|
||||
@endcan
|
||||
|
||||
$('textarea').keydown(function (e) {
|
||||
if (e.keyCode === 9) {
|
||||
var start = this.selectionStart;
|
||||
var end = this.selectionEnd;
|
||||
var value = $(this).val();
|
||||
$(this).val(value.substring(0, start) + '\t' + value.substring(end));
|
||||
this.selectionStart = this.selectionEnd = start + 1;
|
||||
e.preventDefault();
|
||||
}
|
||||
const Editor = ace.edit('fileContents');
|
||||
|
||||
Editor.setTheme('ace/theme/chrome');
|
||||
Editor.getSession().setUseWrapMode(true);
|
||||
Editor.setShowPrintMargin(false);
|
||||
|
||||
$('#aceMode').on('change', event => {
|
||||
Editor.getSession().setMode(`ace/mode/${$('#aceMode').val()}`);
|
||||
});
|
||||
|
||||
$("#create_file").click(function(e) {
|
||||
Editor.commands.addCommand({
|
||||
name: 'save',
|
||||
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
||||
exec: function(editor) {
|
||||
save();
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
|
||||
$('#create_file').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$("#create_file").append(' <i class="fa fa-spinner fa fa-spin"></i>').addClass("disabled");
|
||||
save();
|
||||
});
|
||||
|
||||
function save() {
|
||||
var fileName = $('input[name="file"]').val();
|
||||
$('#create_file').append(' <i class="fa fa-spinner fa fa-spin"></i>').addClass('disabled');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '{{ route('server.files.save', $server->uuidShort) }}',
|
||||
headers: { 'X-CSRF-Token': '{{ csrf_token() }}' },
|
||||
data: {
|
||||
file: '{{ $directory }}' + $('#file_name').val(),
|
||||
contents: $('#fileContents').val()
|
||||
contents: Editor.getValue()
|
||||
}
|
||||
}).done(function (data) {
|
||||
window.location.replace('/server/{{ $server->uuidShort }}/files/edit/{{ $directory }}' + $('#file_name').val());
|
||||
}).fail(function (jqXHR) {
|
||||
$('#write_status').html('<div class="alert alert-danger">' + jqXHR.responseText + '</div>').show();
|
||||
$('#create_file').html('{{ trans('strings.save') }}').removeClass('disabled');
|
||||
$.notify({
|
||||
message: jqXHR.responseText
|
||||
}, {
|
||||
type: 'danger'
|
||||
});
|
||||
}).always(function () {
|
||||
$('#save_file').html('{{ trans('strings.save') }}').removeClass('disabled');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -50,7 +50,7 @@ $(document).ready(function () {
|
|||
const Editor = ace.edit('editor');
|
||||
const Modelist = ace.require('ace/ext/modelist')
|
||||
|
||||
Editor.setTheme('ace/theme/github');
|
||||
Editor.setTheme('ace/theme/chrome');
|
||||
Editor.getSession().setMode(Modelist.getModeForPath('{{ $stat->name }}').mode);
|
||||
Editor.getSession().setUseWrapMode(true);
|
||||
Editor.setShowPrintMargin(false);
|
||||
|
|
|
@ -99,7 +99,11 @@ class ActionsClass {
|
|||
inputField.focus();
|
||||
inputField.on('blur keypress', e => {
|
||||
// Save Field
|
||||
if (e.type === 'blur' || (e.type === 'keypress' && e.which === 27) || currentName === inputField.val()) {
|
||||
if (
|
||||
(e.type === 'keypress' && e.which === 27)
|
||||
|| e.type === 'blur'
|
||||
|| (e.type === 'keypress' && e.which === 13 && currentName === inputField.val())
|
||||
) {
|
||||
if (!_.isEmpty(currentLink)) {
|
||||
nameBlock.html(currentLink);
|
||||
} else {
|
||||
|
@ -110,6 +114,10 @@ class ActionsClass {
|
|||
return;
|
||||
}
|
||||
|
||||
if (e.type === 'keypress' && e.which !== 13) return;
|
||||
|
||||
console.log('did not');
|
||||
|
||||
inputLoader.show();
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
||||
|
|
Loading…
Reference in a new issue