<!doctype html>
<html>
<head>
<title>Direktil Local Server</title>
<base href="/ui/" />

<link rel="icon" href="favicon.ico" />



<style>@import url('/ui/style.css');@import url('/ui/app.css');</style>
<script src="/ui/jsonpatch.min-942279a1c4209cc2.js" integrity="sha384-GcPrkRS12jtrElEkbJcrZ8asvvb9s3mc+CUq9UW/8bL4L0bpkmh9M+oFnWN6qLq2"></script>
<script src="/ui/app-4f0c6935250753e9.js" defer integrity="sha384-SrAfGs5pnGcgL5E78t2MszNYmdkGME9yPgtPsDg61Rljw+dfiP+rabjPnrMkWDUH" type="module"></script>
<script src="/ui/Downloads-3c8cba0572aebfae.js" integrity="sha384-Pof/sPwhdqKGp7NUmYkDc0pSSyACabwLjkRRylZKHxRmiHBV3SGomPUMAWG9y7Ix"></script>
<script src="/ui/GetCopy-2e04b7b63750e25a.js" integrity="sha384-sNvTYXhjog3BkYL20RzrUWIG9VGyHNO8oEiP5oxL5f2WKmLj/03fdR79FgHfzlj+"></script>
<script src="/ui/ClusterAccess-f38a8132c1c029e.js" integrity="sha384-jDiukS9Hz3HCNpLEoV9jdljj5UmvzS95TCY6U+cjSl07JzhgKRvwYwBi8jNoxFBH"></script>
<script src="/ui/ClusterCAs-4f0a381bfb0c1b88.js" integrity="sha384-QcSHKzEHNSCqyjFELXfYFAdfmIZZwJHDzPqI2prH47jHrkeomJD60rcEMLkVAO3o"></script>
<script src="/ui/Cluster-34a012ee0910827c.js" integrity="sha384-Q0sXP0WFJu4gHOI/8NMOGwpJvvFDNBR3T/vDCYxCWL2szAu4+sQuwHm81Jcad/ve"></script>
<script src="/ui/Host-61916516a854adff.js" integrity="sha384-/wh3KrC0sb4MT7ekO2U84rswxI42WSH/0jB4dbDaaGaGhX60xTEZHFsdQAf7UgTG"></script>
<body>

<div id="app">
<header>
    <span id="logo"><img src="favicon.ico" /> Direktil Local Server</span>
    <span class="utils">
        <span id="login-hdr" v-if="session.token">
            Logged in
            <button class="link" @click="copyText(session.token)">&#x1F5D0;</button>
        </span>
        <span>server <code>{{ serverVersion || '-----' }}</code></span>
        <span>ui     <code>{{ uiHash || '-----' }}</code></span>
        <span :class="publicState ? 'green' : 'red'">&#x1F5F2;</span>
    </span>
</header>

<div class="error" v-if="error">
    <button class="btn-close" @click="error=null">&times;</button>
    <div class="code" v-if="error.code">{{ error.code }}</div>
    <div class="message">{{ error.message }}</div>
</div>

<div class="toasts"><div v-for="t in toasts" :class="'toast '+t.kind" @click="dismissToast(t.id)">{{ t.message }}</div></div>

<main class="content" v-if="!publicState">
    <p>Not connected.</p>
</main>

<main class="content" v-else-if="publicState.Store.New">
    <p>Store is new.</p>
    <p>Option 1: initialize a new store</p>
    <form @submit="unlockStore">
        <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" />
        <input type="submit" value="initialize" :disabled="!forms.store.pass1 || forms.store.pass1 != forms.store.pass2" />
    </form>
    <p>Option 2: upload a previously downloaded store</p>
    <form @submit="uploadStore">
        <input type="file" ref="storeUpload" />
        <input type="submit" value="upload" />
    </form>
</main>

<main class="content" v-else-if="!publicState.Store.Open">
    <p>Store is not open.</p>
    <form @submit="unlockStore">
        <input type="password" name="passphrase" v-model="forms.store.pass1" required placeholder="Passphrase" />
        <input type="submit" value="unlock" :disabled="!forms.store.pass1" />
    </form>
</main>

<main class="content" v-else-if="!state">
    <p v-if="!session.token">Not logged in.</p>
    <p v-else>Invalid token</p>

    <form @submit="unlockStore">
        <input type="password" v-model="forms.store.pass1" required placeholder="Passphrase" />
        <input type="submit" value="log in"/>
    </form>
</main>

<template v-else>
  <nav class="sidebar">
    <input type="search" placeholder="Filter" v-model="viewFilter"/>
    <p class="nav-section">Admin</p>
    <p class="view-links"><button type="button" v-for="v in adminViews" @click="view = v" :class="{selected: isActive(v)}">{{v.title}}</button></p>
    <p class="nav-section" v-if="clusterViews.length">Clusters</p>
    <p class="view-links" v-if="clusterViews.length"><button type="button" v-for="v in clusterViews" @click="view = v" :class="{selected: isActive(v)}">{{v.title}}</button></p>
    <p class="nav-section" v-if="hostViews.length">Hosts</p>
    <p class="view-links" v-if="hostViews.length"><button type="button" v-for="v in hostViews" @click="view = v" :class="{selected: isActive(v)}">{{v.title}}</button></p>
  </nav>
  <main class="content">
  <h2 v-if="view">{{ view.type == 'cluster' ? 'Cluster ' : view.type == 'host' ? 'Host ' : '' }}{{view.title}}</h2>

  <div v-if="view.type == 'cluster'" id="clusters">
    <Cluster :cluster="viewObj" :token="session.token" :state="state" />
  </div>

  <div v-if="view.type == 'host'" id="hosts">
    <Host :host="viewObj" :token="session.token" :state="state" />
  </div>

  <div v-if="view.type == 'actions' && view.name == 'admin'">
  <h3>Config</h3>
  <form @submit="uploadConfig">
      <input type="file" ref="configUpload" required />
      <input type="submit" value="upload config" />
  </form>

  <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/>
      <label><input type="checkbox" v-model="forms.store.byHash"> {{ forms.store.byHash ? "hash (base64)" : "passphrase"}}</label>
      <div v-if="forms.store.byHash">
      <input type="hash"     v-model="forms.store.hash"  name="passphrase" required placeholder="Hash" />
        {{" "}}generate with <code>dls hash '{{state.Store.Salt}}'</code>
      </div><div v-else>
      <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" />
      </div>
      <input type="submit" value="add unlock phrase" :disabled="!((forms.store.pass1 && forms.store.pass1 == forms.store.pass2) || forms.store.hash)" />
  </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>

<template v-if="any(state.HostTemplates) || any(hostsFromTemplate)">
  <h3>Hosts from template</h3>
  <form @submit="hostFromTemplateAdd" action="" v-if="any(state.HostTemplates)">
      <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="" v-if="any(hostsFromTemplate)">
      <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>
  </div>
  </main>
</template>
</div>
</body>
</html>
