1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-01-10 00:43:36 +02:00
pocketbase/ui/src/App.svelte
2023-03-21 18:52:13 +02:00

160 lines
5.1 KiB
Svelte

<script>
import "./scss/main.scss";
import Router, { replace, link } from "svelte-spa-router";
import active from "svelte-spa-router/active";
import routes from "./routes";
import ApiClient from "@/utils/ApiClient";
import CommonHelper from "@/utils/CommonHelper";
import tooltip from "@/actions/tooltip";
import Toasts from "@/components/base/Toasts.svelte";
import Toggler from "@/components/base/Toggler.svelte";
import Confirmation from "@/components/base/Confirmation.svelte";
import { pageTitle, appName, hideControls } from "@/stores/app";
import { admin } from "@/stores/admin";
import { setErrors } from "@/stores/errors";
import { resetConfirmation } from "@/stores/confirmation";
import TinyMCE from "@tinymce/tinymce-svelte";
let oldLocation = undefined;
let showAppSidebar = false;
let isTinyMCEPreloaded = false;
$: if ($admin?.id) {
loadSettings();
}
function handleRouteLoading(e) {
if (e?.detail?.location === oldLocation) {
return; // not an actual change
}
showAppSidebar = !!e?.detail?.userData?.showAppSidebar;
oldLocation = e?.detail?.location;
// resets
$pageTitle = "";
setErrors({});
resetConfirmation();
}
function handleRouteFailure() {
replace("/");
}
async function loadSettings() {
if (!$admin?.id) {
return;
}
try {
const settings = await ApiClient.settings.getAll({
$cancelKey: "initialAppSettings",
});
$appName = settings?.meta?.appName || "";
$hideControls = !!settings?.meta?.hideControls;
} catch (err) {
if (!err?.isAbort) {
console.warn("Failed to load app settings.", err);
}
}
}
function logout() {
ApiClient.logout();
}
</script>
<svelte:head>
<title>{CommonHelper.joinNonEmpty([$pageTitle, $appName, "PocketBase"], " - ")}</title>
</svelte:head>
<div class="app-layout">
{#if $admin?.id && showAppSidebar}
<aside class="app-sidebar">
<a href="/" class="logo logo-sm" use:link>
<img
src="{import.meta.env.BASE_URL}images/logo.svg"
alt="PocketBase logo"
width="40"
height="40"
/>
</a>
<nav class="main-menu">
<a
href="/collections"
class="menu-item"
aria-label="Collections"
use:link
use:active={{ path: "/collections/?.*", className: "current-route" }}
use:tooltip={{ text: "Collections", position: "right" }}
>
<i class="ri-database-2-line" />
</a>
<a
href="/logs"
class="menu-item"
aria-label="Logs"
use:link
use:active={{ path: "/logs/?.*", className: "current-route" }}
use:tooltip={{ text: "Logs", position: "right" }}
>
<i class="ri-line-chart-line" />
</a>
<a
href="/settings"
class="menu-item"
aria-label="Settings"
use:link
use:active={{ path: "/settings/?.*", className: "current-route" }}
use:tooltip={{ text: "Settings", position: "right" }}
>
<i class="ri-tools-line" />
</a>
</nav>
<figure class="thumb thumb-circle link-hint closable">
<img
src="{import.meta.env.BASE_URL}images/avatars/avatar{$admin?.avatar || 0}.svg"
alt="Avatar"
/>
<Toggler class="dropdown dropdown-nowrap dropdown-upside dropdown-left">
<a href="/settings/admins" class="dropdown-item closable" use:link>
<i class="ri-shield-user-line" />
<span class="txt">Manage admins</span>
</a>
<hr />
<button type="button" class="dropdown-item closable" on:click={logout}>
<i class="ri-logout-circle-line" />
<span class="txt">Logout</span>
</button>
</Toggler>
</figure>
</aside>
{/if}
<div class="app-body">
<Router {routes} on:routeLoading={handleRouteLoading} on:conditionsFailed={handleRouteFailure} />
<Toasts />
</div>
</div>
<Confirmation />
{#if showAppSidebar && !isTinyMCEPreloaded}
<div class="tinymce-preloader hidden">
<TinyMCE
scriptSrc="{import.meta.env.BASE_URL}libs/tinymce/tinymce.min.js"
conf={CommonHelper.defaultEditorOptions()}
on:init={() => {
isTinyMCEPreloaded = true;
}}
/>
</div>
{/if}