Skip to content

Commit

Permalink
Created a basic admin component
Browse files Browse the repository at this point in the history
  • Loading branch information
davenquinn committed Sep 17, 2024
1 parent 960b1c2 commit 0f254ee
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 38 deletions.
2 changes: 2 additions & 0 deletions packages/settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const macrostratInstance = getRuntimeConfig("MACROSTRAT_INSTANCE");

export const elevationLayerURL = getRuntimeConfig("ELEVATION_LAYER_URL");

export const enableAdmin = getRuntimeConfig("ENABLE_ADMIN", true);

/** Legacy settings object */
export const SETTINGS = {
cdrPrefix,
Expand Down
11 changes: 10 additions & 1 deletion pages/+Layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import { ReactNode } from "react";

import { AuthProvider } from "~/_providers/auth";
import { usePageContext } from "vike-react/usePageContext";
import { enableAdmin } from "@macrostrat-web/settings";

import "~/styles/blueprint-core";
import "~/styles/_theme.styl";
import "~/styles/core.sass";
import "~/styles/padding.css";
//
import h from "./layout.module.sass";
import { onDemand } from "~/_utils";

import { PageAdminConsole } from "~/components";

export default function Layout({ children }: { children: ReactNode }) {
const pageContext = usePageContext();
Expand All @@ -23,7 +27,12 @@ export default function Layout({ children }: { children: ReactNode }) {
h(
supportsDarkMode ? DarkModeProvider : NoOpDarkModeProvider,
{ followSystem: true },
h("div.app-shell", { className: pageStyle + "-page" }, children)
h("div.app-shell", { className: pageStyle + "-page" }, [
children,
h.if(enableAdmin)(PageAdminConsole, {
className: "page-admin-container",
}),
])
)
);
}
Expand Down
10 changes: 9 additions & 1 deletion pages/layout.module.sass
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@
:global(.in-page-transition)
height: 100vh
overflow: hidden
position: relative
position: relative

// An admin console for the page
.page-admin-container
position: fixed
top: 0
right: 0
margin: 1em
z-index: 5000
5 changes: 4 additions & 1 deletion pages/map/map-interface/map-page/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Suspense, useCallback, useEffect, useRef } from "react";
import { Spinner } from "@blueprintjs/core";
import loadable from "@loadable/component";
import { mapPagePrefix } from "@macrostrat-web/settings";
import { MapAreaContainer } from "@macrostrat/map-interface";
import { MapAreaContainer, MapBottomControls } from "@macrostrat/map-interface";
import classNames from "classnames";
import { useSelector } from "react-redux";
import { Route, Routes } from "react-router-dom";
Expand All @@ -18,6 +18,8 @@ import Searchbar from "../components/navbar";
import MapContainer from "./map-view";
import { MenuPage } from "./menu";
import h from "./main.module.styl";
import { PageAdminButton, PageAdminConsole } from "~/components";
import MapControls from "../../../../packages/sift/src/js/components/MapControls";

const ElevationChart = loadable(() => import("../components/elevation-chart"));
const InfoDrawer = loadable(() => import("../components/info-drawer"));
Expand Down Expand Up @@ -79,6 +81,7 @@ function MapPage({
detailPanel: h(InfoDrawerHolder),
detailPanelStyle: "floating",
bottomPanel: h(ElevationChart, null),
mapControls: h(MapBottomControls, [h(PageAdminButton)]),
contextPanelOpen: contextPanelOpen || inputFocus,
detailPanelOpen: infoDrawerOpen,
className: classNames(
Expand Down
24 changes: 24 additions & 0 deletions src/components/admin/_inner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Dialog } from "@blueprintjs/core";
import { JSONView } from "@macrostrat/ui-components";
import { usePageContext } from "vike-react/usePageContext";
import h from "./page-admin.module.sass";

export function PageAdminInner({ isOpen, setIsOpen }) {
return h([
h(
Dialog,
{
isOpen,
onClose: () => setIsOpen(false),
title: "Page info",
className: "page-admin",
},
h("div.dialog-content.bp5-dialog-content", [h(PageContextViewer)])
),
h("span.__render_alarm__"),
]);
}

function PageContextViewer() {
return h(JSONView, { data: usePageContext(), hideRoot: true });
}
97 changes: 65 additions & 32 deletions src/components/admin/index.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,102 @@
import { Dialog, Button } from "@blueprintjs/core";
import { useEffect, useState } from "react";
import { JSONView } from "@macrostrat/ui-components";
import { usePageContext } from "vike-react/usePageContext";
import { Button } from "@blueprintjs/core";
import { useEffect } from "react";
import h from "./page-admin.module.sass";
import loadable from "@loadable/component";
import { create } from "zustand";

const useStore: any = create((set) => {
return {
isOpen: false,
isButtonShown: false,
setIsOpen(isOpen) {
set({ isOpen });
},
toggle() {
set((state) => ({ isOpen: !state.isOpen }));
},
toggleButton() {
set((state) => {
let isOpen = state.isButtonShown ? false : state.isOpen;
return { isButtonShown: !state.isButtonShown, isOpen };
});
},
buttonRef: null,
setButtonRef(ref) {
console.log("Setting button ref");
set({ buttonRef: ref });
},
};
});

function PageAdmin({ isOpen, setIsOpen }) {
if (!isOpen) return null;

const Window = loadable(() =>
import("./_inner").then((mod) => mod.PageAdminInner)
);

return h(Window, { isOpen, setIsOpen });
}

export function PageAdminConsole({ className }) {
const [isOpen, setIsOpen] = usePageAdminIsOpen();
const [isAdminButtonShown, _] = usePageAdminButtonIsShown();
const buttonRef = useStore((state) => state.buttonRef);
usePageAdminButtonEffect();

return h("div", { className }, [
h.if(isAdminButtonShown)(Button, {
onClick: () => setIsOpen(true),
minimal: true,
icon: "cog",
}),
h(
Dialog,
{
isOpen,
onClose: () => setIsOpen(false),
title: "Page info",
className: "page-admin",
},
h("div.dialog-content.bp5-dialog-content", [h(PageContextViewer)])
),
h("span.__render_alarm__"),
h(PageAdmin, { isOpen, setIsOpen }),
h.if(buttonRef == null)(PageAdminButton, { setRef: false }),
]);
}

function PageContextViewer() {
return h(JSONView, { data: usePageContext(), hideRoot: true });
export function PageAdminButton({ setRef = true }) {
const onClick = useStore((state) => state.toggle);
const _setRef = useStore((state) => state.setButtonRef);
const isShown = useStore((state) => state.isButtonShown);
const ref = (el) => {
if (setRef) _setRef(el);
};

return h.if(isShown)(Button, {
onClick,
className: "page-admin-button",
ref,
minimal: true,
small: true,
icon: "cog",
});
}

function usePageAdminButtonIsShown() {
function usePageAdminButtonEffect() {
// Show the page admin console only if the appropriate query parameter is set
// OR if the user presses shift+alt+I
const [isAdminShown, setIsAdminShown] = usePageAdminIsOpen();
const [isAdminButtonShown, setIsAdminButtonShown] = useState(false);
const toggleButton = useStore((s) => s.toggleButton);

useEffect(() => {
function handleKeyDown(event: KeyboardEvent) {
if (event.key === "I" && event.shiftKey) {
setIsAdminButtonShown((d) => {
return !d;
});
toggleButton();
}
}
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, []);

return [isAdminButtonShown || isAdminShown, setIsAdminButtonShown];
}

function usePageAdminIsOpen(): [boolean, (isOpen: boolean) => void] {
const [isOpen, _setIsOpen] = useState(false);
const isOpen = useStore((state) => state.isOpen);
const _setIsOpen = useStore((state) => state.setIsOpen);

// Check if the appropriate query parameter is set
useEffect(() => {
if (window == null) return;
const params = new URLSearchParams(window.location.search);
const isOpen = params.get("show") == "admin";
_setIsOpen(isOpen);
}, []);

function setIsOpen(isOpen: boolean) {
if (window == null) return;
const params = new URLSearchParams(window.location.search);
if (isOpen) {
params.set("show", "admin");
Expand Down
4 changes: 4 additions & 0 deletions src/components/admin/page-admin.module.sass
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@

.page-admin
max-height: 80vh

.page-admin-button
width: 16px
height: 16px
5 changes: 2 additions & 3 deletions src/layouts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styles from "./main.module.sass";
import { Spinner } from "@blueprintjs/core";
import { usePageTransitionStore } from "~/renderer/usePageTransitionStore";
import classNames from "classnames";
import { PageAdminConsole, PageBreadcrumbs } from "~/components";
import { PageBreadcrumbs } from "~/components";
import { useTransition } from "transition-hook";

const h = hyper.styled(styles);
Expand All @@ -22,8 +22,7 @@ export function BasePage({ children, className, fitViewport = false }) {
},
[
children,
// A global admin console that can be opened with shift+I
h(PageAdminConsole, { className: "page-admin-container" }),
// A global admin console that can be opened with shift+alt+I
h.if(loadingTransition.shouldMount)(
"div.page-transition",
{ className: `page-transition-${loadingTransition.stage}` },
Expand Down

0 comments on commit 0f254ee

Please sign in to comment.