1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-01-18 21:17:59 +00:00

Made shell available for hosts and databases (besides collections)

This commit is contained in:
Romein van Buren 2023-06-25 08:49:57 +02:00
parent 48b26c9df5
commit b0d3e31378
Signed by: romein
GPG Key ID: 0EFF8478ADDF6C49
6 changed files with 85 additions and 21 deletions

View File

@ -283,8 +283,18 @@ async function refresh() {
await database.open(); await database.open();
} }
}; };
database.executeShellScript = async function(script) {
const result = await ExecuteShellScript(hostKey, dbKey, '', script);
return result;
};
} }
host.executeShellScript = async function(script) {
const result = await ExecuteShellScript(hostKey, '', '', script);
return result;
};
host.newDatabase = async function() { host.newDatabase = async function() {
const name = await dialogs.enterText('Create a database', 'Enter the database name. Note: databases in MongoDB do not exist until they have a collection and an item. Your new database will not persist on the server; fill it to have it created.', ''); const name = await dialogs.enterText('Create a database', 'Enter the database name. Note: databases in MongoDB do not exist until they have a collection and an item. Your new database will not persist on the server; fill it to have it created.', '');
if (name) { if (name) {

View File

@ -9,7 +9,7 @@
import Indexes from './indexes.svelte'; import Indexes from './indexes.svelte';
import Insert from './insert.svelte'; import Insert from './insert.svelte';
import Remove from './remove.svelte'; import Remove from './remove.svelte';
import Shell from './shell.svelte'; import Shell from '../shell.svelte';
import Stats from './stats.svelte'; import Stats from './stats.svelte';
import Update from './update.svelte'; import Update from './update.svelte';

View File

@ -2,6 +2,8 @@
import BlankState from '$components/blankstate.svelte'; import BlankState from '$components/blankstate.svelte';
import TabBar from '$components/tabbar.svelte'; import TabBar from '$components/tabbar.svelte';
import { EventsOn } from '$wails/runtime/runtime'; import { EventsOn } from '$wails/runtime/runtime';
import Shell from '../shell.svelte';
import Stats from './stats.svelte'; import Stats from './stats.svelte';
export let database; export let database;
@ -25,9 +27,15 @@
<div class="view" class:empty={!database}> <div class="view" class:empty={!database}>
{#if database} {#if database}
{#key database} {#key database}
<TabBar tabs={[ { key: 'stats', icon: 'chart', title: 'Database stats' } ]} bind:selectedKey={tab} /> <TabBar
tabs={[
{ key: 'stats', icon: 'chart', title: 'Database stats' },
{ key: 'shell', icon: 'shell', title: 'Shell' },
]}
bind:selectedKey={tab} />
<div class="container"> <div class="container">
{#if tab === 'stats'} <Stats {database} /> {#if tab === 'stats'} <Stats {database} />
{:else if tab === 'shell'} <Shell {database} />
{/if} {/if}
</div> </div>
{/key} {/key}

View File

@ -2,6 +2,8 @@
import BlankState from '$components/blankstate.svelte'; import BlankState from '$components/blankstate.svelte';
import TabBar from '$components/tabbar.svelte'; import TabBar from '$components/tabbar.svelte';
import { EventsOn } from '$wails/runtime/runtime'; import { EventsOn } from '$wails/runtime/runtime';
import Shell from '../shell.svelte';
import Status from './status.svelte'; import Status from './status.svelte';
import SystemInfo from './systeminfo.svelte'; import SystemInfo from './systeminfo.svelte';
@ -24,15 +26,19 @@
<div class="view" class:empty={!host}> <div class="view" class:empty={!host}>
{#if host} {#if host}
{#key host} {#key host}
<TabBar tabs={[ <TabBar
{ key: 'status', icon: 'chart', title: 'Host status' }, tabs={[
{ key: 'systemInfo', icon: 'server', title: 'System info' }, { key: 'status', icon: 'chart', title: 'Host status' },
]} { key: 'systemInfo', icon: 'server', title: 'System info' },
bind:selectedKey={tab} /> { key: 'shell', icon: 'shell', title: 'Shell' },
]}
bind:selectedKey={tab}
/>
<div class="container"> <div class="container">
{#if tab === 'status'} <Status {host} /> {#if tab === 'status'} <Status {host} />
{:else if tab === 'systemInfo'} <SystemInfo {host} /> {:else if tab === 'systemInfo'} <SystemInfo {host} />
{:else if tab === 'shell'} <Shell {host} />
{/if} {/if}
</div> </div>
{/key} {/key}

View File

@ -3,20 +3,34 @@
import CodeEditor from '$components/codeeditor.svelte'; import CodeEditor from '$components/codeeditor.svelte';
import Icon from '$components/icon.svelte'; import Icon from '$components/icon.svelte';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { onDestroy } from 'svelte'; import { onDestroy, onMount } from 'svelte';
export let collection; export let host = undefined;
export let database = undefined;
export let collection = undefined;
const placeholder = '// Write your script here...';
const extensions = [ javascript() ]; const extensions = [ javascript() ];
let script = ''; let script = '';
let result = {}; let result = {};
let copySucceeded = false; let copySucceeded = false;
let timeout; let timeout;
let busy = false; let busy = false;
let editor;
async function run() { async function run() {
busy = true; busy = true;
result = await collection.executeShellScript(script);
if (collection) {
result = await collection.executeShellScript(script);
}
else if (database) {
result = await database.executeShellScript(script);
}
else if (host) {
result = await host.executeShellScript(script);
}
busy = false; busy = false;
} }
@ -26,6 +40,22 @@
timeout = setTimeout(() => copySucceeded = false, 1500); timeout = setTimeout(() => copySucceeded = false, 1500);
} }
onMount(() => {
editor.dispatch({
changes: {
from: 0,
to: editor.state.doc.length,
insert: placeholder,
},
selection: {
from: 0,
anchor: 0,
to: placeholder.length,
head: placeholder.length,
},
});
editor.focus();
});
onDestroy(() => clearTimeout(timeout)); onDestroy(() => clearTimeout(timeout));
</script> </script>
@ -33,7 +63,7 @@
<div class="overflow"> <div class="overflow">
<!-- svelte-ignore a11y-label-has-associated-control --> <!-- svelte-ignore a11y-label-has-associated-control -->
<label class="field"> <label class="field">
<CodeEditor bind:text={script} {extensions} /> <CodeEditor bind:editor bind:text={script} {extensions} />
</label> </label>
</div> </div>

View File

@ -56,17 +56,27 @@ func (a *App) ExecuteShellScript(hostKey, dbKey, collKey, script string) (result
return return
} }
url, err := url.Parse(host.URI) scriptHeader := fmt.Sprintf("// Namespace: %s.%s\n", dbKey, collKey)
if err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to parse host URI %s: %s", host.URI, err.Error()) if dbKey != "" {
result.ErrorTitle = "Could parse host URI" url, err := url.Parse(host.URI)
result.ErrorDescription = err.Error() if err != nil {
return runtime.LogWarningf(a.ctx, "Shell: failed to parse host URI %s: %s", host.URI, err.Error())
result.ErrorTitle = "Could parse host URI"
result.ErrorDescription = err.Error()
return
}
url.Path = "/" + dbKey
scriptHeader = scriptHeader + fmt.Sprintf("db = connect('%s');\n", url.String())
} }
url.Path = "/" + dbKey if collKey != "" {
connstr := url.String() scriptHeader = scriptHeader + fmt.Sprintf("coll = db.getCollection('%s');\n", collKey)
script = fmt.Sprintf("db = connect('%s');\ncoll = db.getCollection('%s');\n\n%s", connstr, collKey, script) }
scriptHeader = scriptHeader + "\n// Start of user script\n"
script = scriptHeader + script
if err := os.WriteFile(fname, []byte(script), os.ModePerm); err != nil { if err := os.WriteFile(fname, []byte(script), os.ModePerm); err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to write script to %s", err.Error()) runtime.LogWarningf(a.ctx, "Shell: failed to write script to %s", err.Error())
@ -75,7 +85,7 @@ func (a *App) ExecuteShellScript(hostKey, dbKey, collKey, script string) (result
return return
} }
cmd := exec.Command("mongosh", "--file", fname, connstr) cmd := exec.Command("mongosh", "--file", fname, host.URI)
stdout, err := cmd.Output() stdout, err := cmd.Output()
if exiterr, ok := err.(*exec.ExitError); ok { if exiterr, ok := err.(*exec.ExitError); ok {