2023-02-07 20:29:19 +00:00
|
|
|
<!doctype html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Direktil Local Server</title>
|
|
|
|
<style>
|
|
|
|
@import url('./style.css');
|
|
|
|
@import url('./app.css');
|
|
|
|
</style>
|
|
|
|
<script src="js/jsonpatch.min.js" crossorigin="anonymous"></script>
|
|
|
|
<script src="js/app.js" type="module" defer></script>
|
|
|
|
<body>
|
|
|
|
|
|
|
|
<div id="app">
|
|
|
|
<header>
|
|
|
|
<div id="logo">
|
|
|
|
<img src="/favicon.ico" />
|
|
|
|
<span>Direktil Local Server</span>
|
|
|
|
</div>
|
|
|
|
<div class="utils">
|
|
|
|
<span id="login-hdr" v-if="session.token">
|
|
|
|
Logged in
|
|
|
|
<button class="link" @click="copyText(session.token)">🗐</button>
|
|
|
|
</span>
|
|
|
|
|
2023-11-04 12:53:00 +00:00
|
|
|
<span>server <code>{{ serverVersion || '-----' }}</code></span>
|
|
|
|
<span>ui <code>{{ uiHash || '-----' }}</code></span>
|
2023-02-07 20:29:19 +00:00
|
|
|
|
2023-04-11 13:13:53 +00:00
|
|
|
<span :class="publicState ? 'green' : 'red'">🗲</span>
|
2023-02-07 20:29:19 +00:00
|
|
|
</div>
|
|
|
|
</header>
|
|
|
|
|
|
|
|
<div class="error" v-if="error">
|
|
|
|
<button class="btn-close" @click="error=null">×</button>
|
|
|
|
<div class="code" v-if="error.code">{{ error.code }}</div>
|
|
|
|
<div class="message">{{ error.message }}</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<template v-if="!publicState">
|
|
|
|
<p>Not connected.</p>
|
|
|
|
</template>
|
|
|
|
<template v-else-if="publicState.Store.New">
|
|
|
|
<p>Store is new.</p>
|
2023-08-19 19:17:23 +00:00
|
|
|
<p>Option 1: initialize a new store</p>
|
|
|
|
<form @submit="unlockStore">
|
2023-09-10 14:47:54 +00:00
|
|
|
<input type="text" v-model="forms.store.name" name="name" placeholder="Name" /><br/>
|
|
|
|
<input type="password" v-model="forms.store.pass1" name="passphrase" required placeholder="Passphrase" />
|
|
|
|
<input type="password" v-model="forms.store.pass2" required placeholder="Passphrase confirmation" />
|
2023-02-07 20:29:19 +00:00
|
|
|
<input type="submit" value="initialize" :disabled="!forms.store.pass1 || forms.store.pass1 != forms.store.pass2" />
|
|
|
|
</form>
|
2023-08-19 19:17:23 +00:00
|
|
|
<p>Option 2: upload a previously downloaded store</p>
|
|
|
|
<form @submit="uploadStore">
|
|
|
|
<input type="file" ref="storeUpload" />
|
|
|
|
<input type="submit" value="upload" />
|
|
|
|
</form>
|
2023-02-07 20:29:19 +00:00
|
|
|
</template>
|
|
|
|
<template v-else-if="!publicState.Store.Open">
|
|
|
|
<p>Store is not open.</p>
|
2023-08-19 19:17:23 +00:00
|
|
|
<form @submit="unlockStore">
|
2023-09-10 14:47:54 +00:00
|
|
|
<input type="password" name="passphrase" v-model="forms.store.pass1" required placeholder="Passphrase" />
|
2023-02-07 20:29:19 +00:00
|
|
|
<input type="submit" value="unlock" :disabled="!forms.store.pass1" />
|
|
|
|
</form>
|
|
|
|
</template>
|
|
|
|
<template v-else-if="!state">
|
|
|
|
<p v-if="!session.token">Not logged in.</p>
|
|
|
|
<p v-else>Invalid token</p>
|
|
|
|
|
2024-02-26 10:21:29 +00:00
|
|
|
<form @submit="unlockStore">
|
|
|
|
<input type="password" v-model="forms.store.pass1" required placeholder="Passphrase" />
|
|
|
|
<input type="submit" value="log in"/>
|
2023-02-07 20:29:19 +00:00
|
|
|
</form>
|
|
|
|
</template>
|
|
|
|
<template v-else>
|
|
|
|
<div v-if="state.Clusters" id="clusters">
|
|
|
|
<h2>Clusters</h2>
|
|
|
|
|
|
|
|
<div class="sheets">
|
|
|
|
<Cluster v-for="c in state.Clusters" :cluster="c" :token="session.token" :state="state" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="state.Hosts" id="hosts">
|
|
|
|
<h2>Hosts</h2>
|
|
|
|
|
|
|
|
<div class="sheets">
|
|
|
|
<Host v-for="h in state.Hosts" :host="h" :token="session.token" :state="state" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2023-09-10 14:47:54 +00:00
|
|
|
<h2>Admin actions</h2>
|
2024-04-15 14:35:53 +00:00
|
|
|
|
2023-09-10 14:47:54 +00:00
|
|
|
<h3>Config</h3>
|
|
|
|
<form @submit="uploadConfig">
|
|
|
|
<input type="file" ref="configUpload" required />
|
|
|
|
<input type="submit" value="upload config" />
|
|
|
|
</form>
|
2024-04-15 14:35:53 +00:00
|
|
|
|
2023-09-10 14:47:54 +00:00
|
|
|
<h3>Store</h3>
|
|
|
|
<p><a :href="'/public/store.tar?token='+state.Store.DownloadToken" target="_blank">Download</a></p>
|
|
|
|
<form @submit="storeAddKey" action="/store/add-key">
|
|
|
|
<p>Add an unlock phrase:</p>
|
|
|
|
<input type="text" v-model="forms.store.name" name="name" required placeholder="Name" /><br/>
|
|
|
|
<input type="password" v-model="forms.store.pass1" name="passphrase" autocomplete="new-password" required placeholder="Phrase" />
|
|
|
|
<input type="password" v-model="forms.store.pass2" autocomplete="new-password" required placeholder="Phrase confirmation" />
|
|
|
|
<input type="submit" value="add unlock phrase" :disabled="!forms.store.pass1 || forms.store.pass1 != forms.store.pass2" />
|
|
|
|
</form>
|
|
|
|
<form @submit="storeDelKey" action="/store/delete-key">
|
|
|
|
<p>Remove an unlock phrase:</p>
|
|
|
|
<input type="text" v-model="forms.delKey.name" name="name" required placeholder="Name" />
|
|
|
|
<input type="submit" value="remove unlock phrase" />
|
|
|
|
|
|
|
|
<p v-if="state.Store.KeyNames">Available names:
|
|
|
|
<template v-for="k,i in state.Store.KeyNames">{{i?", ":""}}<code @click="forms.delKey.name=k">{{k}}</code></template>.</p>
|
|
|
|
</form>
|
2024-04-15 14:35:53 +00:00
|
|
|
|
2024-04-19 13:16:31 +00:00
|
|
|
<template v-if="state.HostTemplates && state.HostTemplates.length">
|
2024-04-15 14:35:53 +00:00
|
|
|
<h3>Hosts from template</h3>
|
|
|
|
<form @submit="hostFromTemplateAdd" action="">
|
|
|
|
<p>Add a host from template instance:</p>
|
|
|
|
<input type="text" v-model="forms.hostFromTemplate.name" required placeholder="Name" />
|
|
|
|
<select v-model="forms.hostFromTemplate.Template" required>
|
|
|
|
<option v-for="name in state.HostTemplates" :value="name">{{name}}</option>
|
|
|
|
</select>
|
|
|
|
<input type="text" v-model="forms.hostFromTemplate.IP" required placeholder="IP" />
|
|
|
|
<input type="submit" value="add instance" />
|
|
|
|
</form>
|
|
|
|
<form @submit="hostFromTemplateDel" action="">
|
|
|
|
<p>Remove a host from template instance:</p>
|
|
|
|
<select v-model="forms.hostFromTemplateDel" required>
|
|
|
|
<option v-for="h in hostsFromTemplate" :value="h.Name">{{h.Name}}</option>
|
|
|
|
</select>
|
|
|
|
<input type="submit" value="delete instance" :disabled="!forms.hostFromTemplateDel" />
|
|
|
|
</form>
|
|
|
|
</template>
|
|
|
|
|
2023-02-07 20:29:19 +00:00
|
|
|
</template>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|