mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-17 21:06:04 +00:00
moved flash message, removed theme from admin controller
This commit is contained in:
@@ -5,6 +5,7 @@ import { config, isDebug } from "core";
|
|||||||
import { addFlashMessage } from "core/server/flash";
|
import { addFlashMessage } from "core/server/flash";
|
||||||
import { html } from "hono/html";
|
import { html } from "hono/html";
|
||||||
import { Fragment } from "hono/jsx";
|
import { Fragment } from "hono/jsx";
|
||||||
|
import { css, Style } from "hono/css";
|
||||||
import { Controller } from "modules/Controller";
|
import { Controller } from "modules/Controller";
|
||||||
import * as SystemPermissions from "modules/permissions";
|
import * as SystemPermissions from "modules/permissions";
|
||||||
import type { AppTheme } from "modules/server/AppServer";
|
import type { AppTheme } from "modules/server/AppServer";
|
||||||
@@ -23,7 +24,7 @@ export type AdminControllerOptions = {
|
|||||||
export class AdminController extends Controller {
|
export class AdminController extends Controller {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly app: App,
|
private readonly app: App,
|
||||||
private _options: AdminControllerOptions = {}
|
private _options: AdminControllerOptions = {},
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -36,7 +37,7 @@ export class AdminController extends Controller {
|
|||||||
return {
|
return {
|
||||||
...this._options,
|
...this._options,
|
||||||
basepath: this._options.basepath ?? "/",
|
basepath: this._options.basepath ?? "/",
|
||||||
assets_path: this._options.assets_path ?? config.server.assets_path
|
assets_path: this._options.assets_path ?? config.server.assets_path,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ export class AdminController extends Controller {
|
|||||||
const hono = this.create().use(
|
const hono = this.create().use(
|
||||||
authMiddleware({
|
authMiddleware({
|
||||||
//skip: [/favicon\.ico$/]
|
//skip: [/favicon\.ico$/]
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const auth = this.app.module.auth;
|
const auth = this.app.module.auth;
|
||||||
@@ -66,14 +67,14 @@ export class AdminController extends Controller {
|
|||||||
success: configs.auth.cookie.pathSuccess ?? "/",
|
success: configs.auth.cookie.pathSuccess ?? "/",
|
||||||
loggedOut: configs.auth.cookie.pathLoggedOut ?? "/",
|
loggedOut: configs.auth.cookie.pathLoggedOut ?? "/",
|
||||||
login: "/auth/login",
|
login: "/auth/login",
|
||||||
logout: "/auth/logout"
|
logout: "/auth/logout",
|
||||||
};
|
};
|
||||||
|
|
||||||
hono.use("*", async (c, next) => {
|
hono.use("*", async (c, next) => {
|
||||||
const obj = {
|
const obj = {
|
||||||
user: c.get("auth")?.user,
|
user: c.get("auth")?.user,
|
||||||
logout_route: this.withBasePath(authRoutes.logout),
|
logout_route: this.withBasePath(authRoutes.logout),
|
||||||
color_scheme: configs.server.admin.color_scheme
|
color_scheme: configs.server.admin.color_scheme,
|
||||||
};
|
};
|
||||||
const html = await this.getHtml(obj);
|
const html = await this.getHtml(obj);
|
||||||
if (!html) {
|
if (!html) {
|
||||||
@@ -97,11 +98,11 @@ export class AdminController extends Controller {
|
|||||||
console.log("redirecting to success");
|
console.log("redirecting to success");
|
||||||
return c.redirect(authRoutes.success);
|
return c.redirect(authRoutes.success);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
return c.html(c.get("html")!);
|
return c.html(c.get("html")!);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
hono.get(authRoutes.logout, async (c) => {
|
hono.get(authRoutes.logout, async (c) => {
|
||||||
@@ -119,16 +120,16 @@ export class AdminController extends Controller {
|
|||||||
|
|
||||||
console.log("redirecting");
|
console.log("redirecting");
|
||||||
return c.redirect(authRoutes.login);
|
return c.redirect(authRoutes.login);
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
permission(SystemPermissions.schemaRead, {
|
permission(SystemPermissions.schemaRead, {
|
||||||
onDenied: async (c) => {
|
onDenied: async (c) => {
|
||||||
addFlashMessage(c, "You not allowed to read the schema", "warning");
|
addFlashMessage(c, "You not allowed to read the schema", "warning");
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
return c.html(c.get("html")!);
|
return c.html(c.get("html")!);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return hono;
|
return hono;
|
||||||
@@ -141,12 +142,12 @@ export class AdminController extends Controller {
|
|||||||
if (this.options.html.includes(htmlBkndContextReplace)) {
|
if (this.options.html.includes(htmlBkndContextReplace)) {
|
||||||
return this.options.html.replace(
|
return this.options.html.replace(
|
||||||
htmlBkndContextReplace,
|
htmlBkndContextReplace,
|
||||||
"<script>" + bknd_context + "</script>"
|
"<script>" + bknd_context + "</script>",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn(
|
console.warn(
|
||||||
`Custom HTML needs to include '${htmlBkndContextReplace}' to inject BKND context`
|
`Custom HTML needs to include '${htmlBkndContextReplace}' to inject BKND context`,
|
||||||
);
|
);
|
||||||
return this.options.html as string;
|
return this.options.html as string;
|
||||||
}
|
}
|
||||||
@@ -160,27 +161,36 @@ export class AdminController extends Controller {
|
|||||||
|
|
||||||
const assets = {
|
const assets = {
|
||||||
js: "main.js",
|
js: "main.js",
|
||||||
css: "styles.css"
|
css: "styles.css",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isProd) {
|
if (isProd) {
|
||||||
|
let manifest: any;
|
||||||
|
if (this.options.assets_path.startsWith("http")) {
|
||||||
|
manifest = await fetch(this.options.assets_path + "manifest.json", {
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
}).then((res) => res.json());
|
||||||
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const manifest = await import("bknd/dist/manifest.json", {
|
manifest = await import("bknd/dist/manifest.json", {
|
||||||
assert: { type: "json" }
|
assert: { type: "json" },
|
||||||
});
|
}).then((res) => res.default);
|
||||||
// @todo: load all marked as entry (incl. css)
|
}
|
||||||
assets.js = manifest.default["src/ui/main.tsx"].file;
|
|
||||||
assets.css = manifest.default["src/ui/main.tsx"].css[0] as any;
|
// @todo: load all marked as entry (incl. css)
|
||||||
|
assets.js = manifest["src/ui/main.tsx"].file;
|
||||||
|
assets.css = manifest["src/ui/main.tsx"].css[0] as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const theme = configs.server.admin.color_scheme ?? "light";
|
|
||||||
const favicon = isProd ? this.options.assets_path + "favicon.ico" : "/favicon.ico";
|
const favicon = isProd ? this.options.assets_path + "favicon.ico" : "/favicon.ico";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{/* dnd complains otherwise */}
|
{/* dnd complains otherwise */}
|
||||||
{html`<!DOCTYPE html>`}
|
{html`<!DOCTYPE html>`}
|
||||||
<html lang="en" class={theme}>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta
|
<meta
|
||||||
@@ -197,16 +207,8 @@ export class AdminController extends Controller {
|
|||||||
)}
|
)}
|
||||||
{isProd ? (
|
{isProd ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<script
|
<script type="module" src={this.options.assets_path + assets?.js} />
|
||||||
type="module"
|
<link rel="stylesheet" href={this.options.assets_path + assets?.css} />
|
||||||
CrossOrigin
|
|
||||||
src={this.options.assets_path + assets?.js}
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
crossOrigin
|
|
||||||
href={this.options.assets_path + assets?.css}
|
|
||||||
/>
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) : (
|
) : (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@@ -217,7 +219,7 @@ export class AdminController extends Controller {
|
|||||||
RefreshRuntime.injectIntoGlobalHook(window)
|
RefreshRuntime.injectIntoGlobalHook(window)
|
||||||
window.$RefreshReg$ = () => {}
|
window.$RefreshReg$ = () => {}
|
||||||
window.$RefreshSig$ = () => (type) => type
|
window.$RefreshSig$ = () => (type) => type
|
||||||
window.__vite_plugin_react_preamble_installed__ = true`
|
window.__vite_plugin_react_preamble_installed__ = true`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<script type="module" src={"/@vite/client"} />
|
<script type="module" src={"/@vite/client"} />
|
||||||
@@ -227,15 +229,14 @@ export class AdminController extends Controller {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root">
|
<div id="root">
|
||||||
<div id="loading" style={style(theme)}>
|
<Style />
|
||||||
<span style={{ opacity: 0.3, fontSize: 14, fontFamily: "monospace" }}>
|
<div id="loading" className={wrapperStyle}>
|
||||||
Initializing...
|
<span className={loaderStyle}>Initializing...</span>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script
|
<script
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: bknd_context
|
__html: bknd_context,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{!isProd && <script type="module" src={mainPath} />}
|
{!isProd && <script type="module" src={mainPath} />}
|
||||||
@@ -246,31 +247,27 @@ export class AdminController extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = (theme: AppTheme) => {
|
const wrapperStyle = css`
|
||||||
const base = {
|
margin: 0;
|
||||||
margin: 0,
|
padding: 0;
|
||||||
padding: 0,
|
height: 100vh;
|
||||||
height: "100vh",
|
width: 100vw;
|
||||||
width: "100vw",
|
display: flex;
|
||||||
display: "flex",
|
justify-content: center;
|
||||||
justifyContent: "center",
|
align-items: center;
|
||||||
alignItems: "center",
|
-webkit-font-smoothing: antialiased;
|
||||||
"-webkit-font-smoothing": "antialiased",
|
-moz-osx-font-smoothing: grayscale;
|
||||||
"-moz-osx-font-smoothing": "grayscale"
|
color: rgb(9,9,11);
|
||||||
};
|
background-color: rgb(250,250,250);
|
||||||
const styles = {
|
|
||||||
light: {
|
|
||||||
color: "rgb(9,9,11)",
|
|
||||||
backgroundColor: "rgb(250,250,250)"
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
color: "rgb(250,250,250)",
|
|
||||||
backgroundColor: "rgb(30,31,34)"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
@media (prefers-color-scheme: dark) {
|
||||||
...base,
|
color: rgb(250,250,250);
|
||||||
...styles[theme === "light" ? "light" : "dark"]
|
background-color: rgb(30,31,34);
|
||||||
};
|
}
|
||||||
};
|
`;
|
||||||
|
|
||||||
|
const loaderStyle = css`
|
||||||
|
opacity: 0.3;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: monospace;
|
||||||
|
`;
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ import { MantineProvider } from "@mantine/core";
|
|||||||
import { Notifications } from "@mantine/notifications";
|
import { Notifications } from "@mantine/notifications";
|
||||||
import type { ModuleConfigs } from "modules";
|
import type { ModuleConfigs } from "modules";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { BkndProvider, useBknd } from "ui/client/bknd";
|
import { BkndProvider } from "ui/client/bknd";
|
||||||
import { useTheme } from "ui/client/use-theme";
|
import { useTheme } from "ui/client/use-theme";
|
||||||
import { Logo } from "ui/components/display/Logo";
|
import { Logo } from "ui/components/display/Logo";
|
||||||
import * as AppShell from "ui/layouts/AppShell/AppShell";
|
import * as AppShell from "ui/layouts/AppShell/AppShell";
|
||||||
import { FlashMessage } from "ui/modules/server/FlashMessage";
|
|
||||||
import { ClientProvider, type ClientProviderProps } from "./client";
|
import { ClientProvider, type ClientProviderProps } from "./client";
|
||||||
import { createMantineTheme } from "./lib/mantine/theme";
|
import { createMantineTheme } from "./lib/mantine/theme";
|
||||||
import { BkndModalsProvider } from "./modals";
|
import { BkndModalsProvider } from "./modals";
|
||||||
@@ -21,7 +20,7 @@ export type BkndAdminProps = {
|
|||||||
export default function Admin({
|
export default function Admin({
|
||||||
baseUrl: baseUrlOverride,
|
baseUrl: baseUrlOverride,
|
||||||
withProvider = false,
|
withProvider = false,
|
||||||
config
|
config,
|
||||||
}: BkndAdminProps) {
|
}: BkndAdminProps) {
|
||||||
const Component = (
|
const Component = (
|
||||||
<BkndProvider adminOverride={config} fallback={<Skeleton theme={config?.color_scheme} />}>
|
<BkndProvider adminOverride={config} fallback={<Skeleton theme={config?.color_scheme} />}>
|
||||||
@@ -45,8 +44,7 @@ function AdminInternal() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MantineProvider {...createMantineTheme(theme as any)}>
|
<MantineProvider {...createMantineTheme(theme as any)}>
|
||||||
<Notifications />
|
<Notifications position="top-right" />
|
||||||
<FlashMessage />
|
|
||||||
<BkndModalsProvider>
|
<BkndModalsProvider>
|
||||||
<Routes />
|
<Routes />
|
||||||
</BkndModalsProvider>
|
</BkndModalsProvider>
|
||||||
@@ -54,9 +52,9 @@ function AdminInternal() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Skeleton = ({ theme }: { theme?: string }) => {
|
const Skeleton = ({ theme }: { theme?: any }) => {
|
||||||
const actualTheme =
|
const t = useTheme();
|
||||||
(theme ?? document.querySelector("html")?.classList.contains("light")) ? "light" : "dark";
|
const actualTheme = theme ?? t.theme;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="bknd-admin" className={actualTheme + " antialiased"}>
|
<div id="bknd-admin" className={actualTheme + " antialiased"}>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Alert } from "ui/components/display/Alert";
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export function FlashMessage() {
|
export function FlashMessage() {
|
||||||
const [flash, setFlash] = useState<any>();
|
const [flash, setFlash] = useState<ReturnType<typeof getFlashMessage>>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!flash) {
|
if (!flash) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Suspense, lazy } from "react";
|
import React, { Suspense, lazy } from "react";
|
||||||
import { useBknd } from "ui/client/bknd";
|
import { useBknd } from "ui/client/bknd";
|
||||||
import { useTheme } from "ui/client/use-theme";
|
import { useTheme } from "ui/client/use-theme";
|
||||||
import { Route, Router, Switch } from "wouter";
|
import { Route, Router, Switch } from "wouter";
|
||||||
@@ -9,6 +9,7 @@ import FlowRoutes from "./flows";
|
|||||||
import MediaRoutes from "./media";
|
import MediaRoutes from "./media";
|
||||||
import { Root, RootEmpty } from "./root";
|
import { Root, RootEmpty } from "./root";
|
||||||
import SettingsRoutes from "./settings";
|
import SettingsRoutes from "./settings";
|
||||||
|
import { FlashMessage } from "ui/modules/server/FlashMessage";
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const TestRoutes = lazy(() => import("./test"));
|
const TestRoutes = lazy(() => import("./test"));
|
||||||
@@ -20,6 +21,7 @@ export function Routes() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="bknd-admin" className={theme + " antialiased"}>
|
<div id="bknd-admin" className={theme + " antialiased"}>
|
||||||
|
<FlashMessage />
|
||||||
<Router base={basepath}>
|
<Router base={basepath}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/auth/login" component={AuthLogin} />
|
<Route path="/auth/login" component={AuthLogin} />
|
||||||
|
|||||||
Reference in New Issue
Block a user