vito/resources/views/components/console.blade.php
2024-10-06 21:46:03 +02:00

104 lines
3.6 KiB
PHP

<div
x-data="{
user: '{{ $server->ssh_user }}',
running: false,
command: '',
output: '',
runUrl: '{{ route("servers.console.run", ["server" => $server]) }}',
async run() {
if (! this.command) return
this.running = true
this.output = this.command + '\n'
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}',
},
body: JSON.stringify({
user: this.user,
command: this.command,
}),
}
this.command = ''
const response = await fetch(this.runUrl, fetchOptions)
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
while (true) {
if (! this.running) {
reader.cancel()
this.output += '\nStopped!'
break
}
const { value, done } = await reader.read()
if (done) break
const textChunk = decoder.decode(value, { stream: true })
this.output += textChunk
document.getElementById('console-output').scrollTop =
document.getElementById('console-output').scrollHeight
}
this.output += '\nDone!'
this.running = false
},
stop() {
this.running = false
},
}"
>
<div>
<x-console-view id="console-output">
<div class="w-full" x-text="output"></div>
</x-console-view>
<form onsubmit="return false" id="console-form" class="mt-5 flex items-center justify-between">
<div class="grid w-full grid-cols-8 gap-2">
<x-filament::input.wrapper class="col-span-1 w-full">
<x-filament::input.select
id="user"
name="user"
x-model="user"
class="w-full"
x-bind:disabled="running"
>
<option value="root">root</option>
<option value="{{ $server->ssh_user }}">{{ $server->ssh_user }}</option>
</x-filament::input.select>
</x-filament::input.wrapper>
<x-filament::input.wrapper class="col-span-6 w-full">
<x-filament::input
id="command"
name="command"
x-model="command"
type="text"
placeholder="Type your command here..."
class="mx-1 flex-grow"
autocomplete="off"
/>
</x-filament::input.wrapper>
<x-filament::button
color="gray"
icon="heroicon-o-play"
type="submit"
id="btn-run"
x-on:click="run"
class="col-span-1"
x-show="!running"
/>
<x-filament::button
color="gray"
type="button"
id="btn-stop"
x-on:click="stop"
class="col-span-1"
x-show="running"
icon="heroicon-o-stop"
/>
</div>
</form>
</div>
</div>