Instance UI refactor

This commit is contained in:
Ben Allfree 2023-12-12 05:25:40 -08:00
parent dcf0138dde
commit 59cf4e4956
21 changed files with 274 additions and 197 deletions

View File

@ -1,6 +1,8 @@
<script>
import { page } from '$app/stores'
import AlertBar from '$components/AlertBar.svelte'
import { assert } from '$shared'
import { INSTANCE_ADMIN_URL } from '$src/env'
import { globalInstancesStore } from '$util/stores'
import { instance } from './store'
@ -14,9 +16,77 @@
}
isReady = !!_instance
}
console.log($page.url)
$: ({ status, version, id } = $instance || {})
</script>
{#if isReady}
<div
class="flex md:flex-row flex-col items-center justify-between mb-6 gap-4"
>
<div>
<h2
class="text-4xl md:text-left text-center text-base-content font-bold capitalize mb-3 break-words"
>
{$instance.subdomain}
</h2>
<div class="flex flex-wrap md:justify-start justify-center gap-2">
<div class="badge badge-accent badge-outline">
Status: &nbsp;<span class="capitalize">{status}</span>
</div>
<div class="badge badge-accent badge-outline">Version: {version}</div>
</div>
</div>
<a
href={INSTANCE_ADMIN_URL($instance.subdomain)}
rel="noreferrer"
target="_blank"
class="btn btn-primary"
>
<img
src="/images/pocketbase-logo.svg"
alt="PocketBase Logo"
class="w-6"
/>
Admin
</a>
</div>
{#if $instance.maintenance}
<AlertBar
message="This instance is in Maintenance Mode and will not respond to requests"
type="warning"
/>
{/if}
<div role="tablist" class="tabs tabs-boxed">
<a
role="tab"
class="tab {$page.url.pathname.endsWith(id) ? `tab-active` : ``}"
href="/app/instances/{id}">Overview</a
>
<a
role="tab"
class="tab {$page.url.pathname.endsWith(`logs`) ? `tab-active` : ``}"
href="/app/instances/{id}/logs">Logs</a
>
<a
role="tab"
class="tab {$page.url.pathname.endsWith(`secrets`) ? `tab-active` : ``}"
href="/app/instances/{id}/secrets">Secrets</a
>
<a
role="tab"
class="tab {$page.url.pathname.endsWith(`settings`) ? `tab-active` : ``}"
href="/app/instances/{id}/settings">Settings</a
>
</div>
<slot />
{:else}
<div>Instance not found</div>

View File

@ -1,85 +1,20 @@
<script lang="ts">
import { assertExists } from '$shared'
import { INSTANCE_ADMIN_URL } from '$src/env'
import Code from './Code.svelte'
import AdminSync from './Danger/AdminSync.svelte'
import DangerZoneTitle from './Danger/DangerZoneTitle.svelte'
import DeleteInstance from './Danger/DeleteInstance.svelte'
import Maintenance from './Danger/Maintenance.svelte'
import RenameInstance from './Danger/RenameInstance.svelte'
import VersionChange from './Danger/VersionChange/VersionChange.svelte'
import Ftp from './Ftpx.svelte'
import Logging from './Logging.svelte'
import Secrets from './Secrets/Secrets.svelte'
import { instance } from './store'
import AlertBar from '$components/AlertBar.svelte'
$: ({ status, version } = $instance)
$: ({ status, version, id } = $instance)
assertExists($instance, `Expected instance here`)
const { subdomain } = $instance
</script>
<svelte:head>
<title>{subdomain} details - PocketHost</title>
<title>{subdomain} overview - PocketHost</title>
</svelte:head>
<div class="flex md:flex-row flex-col items-center justify-between mb-6 gap-4">
<div>
<h2
class="text-4xl md:text-left text-center text-base-content font-bold capitalize mb-3 break-words"
>
{$instance.subdomain}
</h2>
<div class="flex flex-wrap md:justify-start justify-center gap-2">
<div class="badge badge-accent badge-outline">
Status: &nbsp;<span class="capitalize">{status}</span>
</div>
<div class="badge badge-accent badge-outline">Version: {version}</div>
</div>
</div>
<a
href={INSTANCE_ADMIN_URL($instance.subdomain)}
rel="noreferrer"
target="_blank"
class="btn btn-primary"
>
<img src="/images/pocketbase-logo.svg" alt="PocketBase Logo" class="w-6" />
Admin
</a>
</div>
{#if $instance.maintenance}
<AlertBar
message="This instance is in Maintenance Mode and will not respond to requests"
type="warning"
/>
{/if}
<div class="grid lg:grid-cols-2 grid-cols-1 gap-4 mb-4">
<Code />
<Logging />
</div>
<div class="grid lg:grid-cols-2 grid-cols-1 gap-4 mb-16">
<Ftp />
<Secrets />
</div>
<DangerZoneTitle />
<div class="grid lg:grid-cols-3 gap-4 mb-4">
<RenameInstance />
<Maintenance />
<VersionChange />
<AdminSync />
<DeleteInstance />
</div>

View File

@ -1,82 +0,0 @@
<script lang="ts">
import CodeSample from '$components/CodeSample.svelte'
import Card from '$components/cards/Card.svelte'
import CardHeader from '$components/cards/CardHeader.svelte'
import { forEach } from '@s-libs/micro-dash'
import { instance } from '../store'
import Form from './Form.svelte'
import List from './List.svelte'
import { items } from './stores'
// TODO: Hot Reload is causing an infinite loop in the network tab for some reason. Wasn't able to figure out why
$: {
const { id, secrets } = $instance
items.clear()
forEach(secrets || {}, (value, name) => {
items.upsert({ name, value })
})
}
// Keep track of which tab the user has selected
let activeTab = 0
// Toggle between the tabs on click
const handleTabChange = (id: number) => {
activeTab = id
}
</script>
<Card>
<CardHeader>Secrets</CardHeader>
<p class="mb-4">
These secrets are passed into your <code>pocketbase</code> executable and
can be accessed from <code>pb_hooks</code> JS hooks.
</p>
<!-- If the user has any secrets, render them in a code block -->
{#if $items.length > 0}
<div class="mb-8">
<CodeSample code={`const YOUR_KEY = process.env.YOUR_KEY`} />
</div>
{/if}
{#if $items.length === 0}
<div class="alert border-2 border-neutral mb-8">
<i class="fa-regular fa-shield-keyhole"></i>
<span>No Environment Variables Found</span>
</div>
{/if}
<div class="tabs mb-4 border-b-[1px] border-neutral">
<button
on:click={() => handleTabChange(0)}
type="button"
class="tab border-b-2 {activeTab === 0
? 'tab-active font-bold border-base-content'
: 'border-neutral'}"
><i class="fa-regular fa-plus mr-2"></i> Add New</button
>
<button
on:click={() => handleTabChange(1)}
type="button"
class="tab border-b-2 {activeTab === 1
? 'tab-active font-bold border-base-content'
: 'border-neutral'}"
><i class="fa-regular fa-list mr-2"></i> Current List</button
>
</div>
<div>
{#if activeTab === 0}
<Form />
{/if}
{#if activeTab === 1}
<List />
{/if}
</div>
</Card>

View File

@ -0,0 +1,16 @@
<script lang="ts">
import { assertExists } from '$shared'
import { instance } from '../store'
import LoggingInner from './LoggingInner.svelte'
$: ({ status, version, id } = $instance)
assertExists($instance, `Expected instance here`)
const { subdomain } = $instance
</script>
<svelte:head>
<title>{subdomain} logging - PocketHost</title>
</svelte:head>
<LoggingInner />

View File

@ -0,0 +1,11 @@
<script lang="ts">
import Card from '$components/cards/Card.svelte'
import CardHeader from '$components/cards/CardHeader.svelte'
import LoggingInner from './LoggingInner.svelte'
</script>
<Card>
<CardHeader>Instance Logging</CardHeader>
<LoggingInner /></Card
>

View File

@ -1,12 +1,10 @@
<script lang="ts">
import Card from '$components/cards/Card.svelte'
import CardHeader from '$components/cards/CardHeader.svelte'
import { StreamNames, Unsubscribe, type InstanceLogFields } from '$shared'
import { client } from '$src/pocketbase-client'
import { mkCleanup } from '$util/componentCleanup'
import { onMount } from 'svelte'
import { derived, writable } from 'svelte/store'
import { instance } from './store'
import { instance } from '../store'
$: ({ id } = $instance)
@ -57,9 +55,6 @@
})
</script>
<Card>
<CardHeader>Instance Logging</CardHeader>
<p class="mb-4">
Instance logs appear here in realtime, including <code>console.log</code> from
JavaScript hooks.
@ -104,10 +99,7 @@
>
<div class="h-[450px] flex flex-col overflow-y-scroll gap-3">
{#each $logs as log}
<div
class="px-4 text-[11px] font-mono flex align-center"
data-prefix=">"
>
<div class="px-4 text-[11px] font-mono flex align-center" data-prefix=">">
<span class="mr-2"
><i class="fa-regular fa-angle-right text-accent"></i></span
>
@ -123,4 +115,3 @@
{/each}
</div>
</div>
</Card>

View File

@ -0,0 +1,16 @@
<script lang="ts">
import { assertExists } from '$shared'
import { instance } from '../store'
import SecretsInner from './SecretsInner.svelte'
$: ({ status, version, id } = $instance)
assertExists($instance, `Expected instance here`)
const { subdomain } = $instance
</script>
<svelte:head>
<title>{subdomain} secrets - PocketHost</title>
</svelte:head>
<SecretsInner />

View File

@ -0,0 +1,11 @@
<script lang="ts">
import Card from '$components/cards/Card.svelte'
import CardHeader from '$components/cards/CardHeader.svelte'
import SecretsInner from './SecretsInner.svelte'
</script>
<Card>
<CardHeader>Secrets</CardHeader>
<SecretsInner />
</Card>

View File

@ -0,0 +1,76 @@
<script lang="ts">
import CodeSample from '$components/CodeSample.svelte'
import { forEach } from '@s-libs/micro-dash'
import { instance } from '../store'
import Form from './Form.svelte'
import List from './List.svelte'
import { items } from './stores'
// TODO: Hot Reload is causing an infinite loop in the network tab for some reason. Wasn't able to figure out why
$: {
const { id, secrets } = $instance
items.clear()
forEach(secrets || {}, (value, name) => {
items.upsert({ name, value })
})
}
// Keep track of which tab the user has selected
let activeTab = 0
// Toggle between the tabs on click
const handleTabChange = (id: number) => {
activeTab = id
}
</script>
<p class="mb-4">
These secrets are passed into your <code>pocketbase</code> executable and can
be accessed from <code>pb_hooks</code> JS hooks.
</p>
<!-- If the user has any secrets, render them in a code block -->
{#if $items.length > 0}
<div class="mb-8">
<CodeSample code={`const YOUR_KEY = process.env.YOUR_KEY`} />
</div>
{/if}
{#if $items.length === 0}
<div class="alert border-2 border-neutral mb-8">
<i class="fa-regular fa-shield-keyhole"></i>
<span>No Environment Variables Found</span>
</div>
{/if}
<div class="tabs mb-4 border-b-[1px] border-neutral">
<button
on:click={() => handleTabChange(0)}
type="button"
class="tab border-b-2 {activeTab === 0
? 'tab-active font-bold border-base-content'
: 'border-neutral'}"
><i class="fa-regular fa-plus mr-2"></i> Add New</button
>
<button
on:click={() => handleTabChange(1)}
type="button"
class="tab border-b-2 {activeTab === 1
? 'tab-active font-bold border-base-content'
: 'border-neutral'}"
><i class="fa-regular fa-list mr-2"></i> Current List</button
>
</div>
<div>
{#if activeTab === 0}
<Form />
{/if}
{#if activeTab === 1}
<List />
{/if}
</div>

View File

@ -0,0 +1,33 @@
<script lang="ts">
import { assertExists } from '$shared'
import { instance } from '../store'
import AdminSync from './AdminSync.svelte'
import DangerZoneTitle from './DangerZoneTitle.svelte'
import DeleteInstance from './DeleteInstance.svelte'
import Maintenance from './Maintenance.svelte'
import RenameInstance from './RenameInstance.svelte'
import VersionChange from './VersionChange/VersionChange.svelte'
$: ({ status, version, id } = $instance)
assertExists($instance, `Expected instance here`)
const { subdomain } = $instance
</script>
<svelte:head>
<title>{subdomain} overview - PocketHost</title>
</svelte:head>
<DangerZoneTitle />
<div class="grid lg:grid-cols-3 gap-4 mb-4">
<RenameInstance />
<Maintenance />
<VersionChange />
<AdminSync />
<DeleteInstance />
</div>