mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-02 14:36:17 +00:00
add directory state to console (#416)
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
<div
|
||||
{{ $attributes->merge(["class" => "font-mono whitespace-pre relative h-[500px] w-full overflow-auto whitespace-pre-line rounded-xl border border-gray-200 bg-black p-5 text-gray-50 dark:border-gray-800"]) }}
|
||||
{{ $attributes->merge(["class" => "font-mono relative h-[500px] w-full overflow-auto whitespace-pre-line rounded-xl border border-gray-200 bg-black p-5 text-gray-50 dark:border-gray-800"]) }}
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
|
@ -2,13 +2,48 @@
|
||||
x-data="{
|
||||
user: '{{ $server->ssh_user }}',
|
||||
running: false,
|
||||
dir: '{{ cache()->get("console.$server->id.dir", "~") }}',
|
||||
command: '',
|
||||
output: '',
|
||||
serverName: '{{ $server->name }}',
|
||||
shellPrefix: '',
|
||||
clearAfterCommand: false,
|
||||
runUrl: '{{ route("servers.console.run", ["server" => $server]) }}',
|
||||
init() {
|
||||
this.setShellPrefix()
|
||||
$watch('user', async (value) => {
|
||||
await this.getWorkingDir()
|
||||
})
|
||||
const consoleOutput = document.getElementById('console-output')
|
||||
consoleOutput.addEventListener('mouseup', (event) => {
|
||||
if (window.getSelection()?.toString()) {
|
||||
return
|
||||
}
|
||||
this.focusCommand()
|
||||
})
|
||||
this.focusCommand()
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.ctrlKey && event.key === 'l') {
|
||||
event.preventDefault()
|
||||
if (this.running) return
|
||||
this.output = ''
|
||||
}
|
||||
})
|
||||
},
|
||||
async run() {
|
||||
if (! this.command) return
|
||||
this.running = true
|
||||
this.output = this.command + '\n'
|
||||
let output = this.shellPrefix + ' ' + this.command + '\n'
|
||||
if (this.clearAfterCommand) {
|
||||
this.output = output
|
||||
} else {
|
||||
this.output += output
|
||||
}
|
||||
setTimeout(() => {
|
||||
document.getElementById('console-output').scrollTop =
|
||||
document.getElementById('console-output').scrollHeight
|
||||
}, 100)
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -25,6 +60,7 @@
|
||||
const response = await fetch(this.runUrl, fetchOptions)
|
||||
const reader = response.body.getReader()
|
||||
const decoder = new TextDecoder('utf-8')
|
||||
this.setShellPrefix()
|
||||
|
||||
while (true) {
|
||||
if (! this.running) {
|
||||
@ -39,65 +75,91 @@
|
||||
|
||||
this.output += textChunk
|
||||
|
||||
document.getElementById('console-output').scrollTop =
|
||||
document.getElementById('console-output').scrollHeight
|
||||
setTimeout(() => {
|
||||
document.getElementById('console-output').scrollTop =
|
||||
document.getElementById('console-output').scrollHeight
|
||||
}, 100)
|
||||
}
|
||||
this.output += '\nDone!'
|
||||
this.output += '\n'
|
||||
await this.getWorkingDir()
|
||||
this.running = false
|
||||
setTimeout(() => {
|
||||
document.getElementById('command').focus()
|
||||
}, 100)
|
||||
},
|
||||
stop() {
|
||||
this.running = false
|
||||
},
|
||||
setShellPrefix() {
|
||||
this.shellPrefix = `${this.user}@${this.serverName}:${this.dir}$`
|
||||
},
|
||||
focusCommand() {
|
||||
document.getElementById('command').focus()
|
||||
},
|
||||
async getWorkingDir() {
|
||||
const response = await fetch(
|
||||
'{{ route("servers.console.working-dir", ["server" => $server]) }}',
|
||||
)
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
this.dir = data.dir
|
||||
this.setShellPrefix()
|
||||
}
|
||||
},
|
||||
}"
|
||||
>
|
||||
<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>
|
||||
<div class="relative">
|
||||
<form class="flex items-center justify-between">
|
||||
<x-filament::input.wrapper>
|
||||
<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>
|
||||
<div class="flex items-center">
|
||||
<x-filament::button
|
||||
color="gray"
|
||||
icon="heroicon-o-play"
|
||||
type="submit"
|
||||
id="btn-run"
|
||||
x-on:click="run"
|
||||
class="col-span-1"
|
||||
type="button"
|
||||
x-on:click="output = ''"
|
||||
icon="heroicon-o-trash"
|
||||
tooltip="Clear"
|
||||
x-show="!running"
|
||||
/>
|
||||
>
|
||||
Clear
|
||||
</x-filament::button>
|
||||
<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"
|
||||
/>
|
||||
tooltip="Stop"
|
||||
class="ml-2"
|
||||
>
|
||||
Stop
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</form>
|
||||
<x-console-view id="console-output" class="mt-5">
|
||||
<div class="w-full" x-text="output"></div>
|
||||
</x-console-view>
|
||||
<div
|
||||
class="relative -mt-5 flex h-[50px] w-full items-center rounded-b-xl border-b border-l border-r border-gray-200 bg-black px-5 font-mono text-gray-50 dark:border-gray-800"
|
||||
>
|
||||
<form class="flex w-full items-center" x-show="!running" onsubmit="return false" id="console-form">
|
||||
<div x-text="shellPrefix"></div>
|
||||
<input
|
||||
type="text"
|
||||
class="h-5 flex-grow border-0 bg-transparent p-0 px-1 outline-none ring-0 focus:outline-none focus:ring-0"
|
||||
autofocus
|
||||
id="command"
|
||||
name="command"
|
||||
x-model="command"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<button type="submit" id="btn-run" x-on:click="run" class="hidden"></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user