UNPKG

astro-integration-pocketbase

Version:

An Astro integration to support developers working with astro-loader-pocketbase.

254 lines (237 loc) 7.1 kB
import { defineToolbarApp } from "astro/toolbar"; import { closeOnOutsideClick, createWindowElement, synchronizePlacementOnUpdate } from "astro/runtime/client/dev-toolbar/apps/utils/window.js"; //#region src/toolbar/dom/create-entity.ts /** * Creates cards for the entities. */ function createEntities(data, baseUrl) { const groupedData = Object.groupBy(data, (data) => data.collectionName); return ` <style> .collectionName { text-transform: capitalize; } .entity { position: relative; pre { margin: 0; overflow: auto; } astro-dev-toolbar-button { position: absolute; top: 0; right: 0; } } </style> ${Object.keys(groupedData).map((collection) => ` <b class=".collectionName">${collection}</b> ${groupedData[collection]?.map((entity) => createEntity(entity, baseUrl)).join("")} `).join("")} `; } /** * Creates a card for a single entity */ function createEntity(data, baseUrl) { return ` <astro-dev-toolbar-card> <div class="entity"> <pre>${JSON.stringify(data, void 0, 2).replaceAll("<", "&lt;")}</pre> ${baseUrl ? ` <astro-dev-toolbar-button size="small" button-style="purple" title="View in PocketBase" onclick="window.open('${baseUrl}/_/#/collections?collection=${data.collectionId}&record=${data.id}', '_blank')" > View in PocketBase </astro-dev-toolbar-button> ` : ""} </div> </astro-dev-toolbar-card> `; } //#endregion //#region package.json var version = "4.0.0"; //#endregion //#region src/toolbar/dom/create-header.ts /** * Creates the header for the PocketBase toolbar. */ function createHeader(windowElement, server, { hasContentLoader, realtime }) { const header = windowElement.querySelector("header"); if (!header) throw new Error("The header element is missing"); header.innerHTML = ` <style> header { display: grid; grid-template-columns: auto auto 1fr; gap: 0.5rem; } h1 { display: flex; align-items: center; gap: 8px; font-weight: 600; color: #fff; margin: 0; font-size: 22px; } .actions { display: flex; align-items: start; justify-content: flex-end; gap: 0.25rem; .toggle-container { display: flex; align-items: center; label { font-size: 0.8rem; } } } </style> <h1>PocketBase</h1> <astro-dev-toolbar-badge badge-style="yellow"> ${version} </astro-dev-toolbar-badge> <div class="actions"> ${realtime ? ` <div class="toggle-container"> <label for="real-time" title="Enable or disable real-time updates temporarily" > Real-time updates </label> <!-- real-time-toggle --> </div> ` : ""} ${hasContentLoader ? ` <astro-dev-toolbar-button id="refresh-content" size="small" button-style="green" title="Right click to force refresh every collection" > Refresh content </astro-dev-toolbar-button> ` : ""} </div> `; if (realtime) { const realTimeToggle = document.createElement("astro-dev-toolbar-toggle"); realTimeToggle.input.id = "real-time-toggle"; realTimeToggle.input.title = "Enable or disable real-time updates temporarily"; realTimeToggle.input.checked = !(localStorage.getItem("astro-integration-pocketbase:real-time") === "false"); realTimeToggle.input.addEventListener("change", () => { localStorage.setItem("astro-integration-pocketbase:real-time", realTimeToggle.input.checked.toString()); server.send("astro-integration-pocketbase:real-time", realTimeToggle.input.checked); }); server.send("astro-integration-pocketbase:real-time", realTimeToggle.input.checked); windowElement.querySelector(".toggle-container")?.append(realTimeToggle); } if (hasContentLoader) { const refresh = windowElement.querySelector("#refresh-content"); if (!refresh) throw new Error("The refresh button is missing"); refresh.addEventListener("click", () => { server.send("astro-integration-pocketbase:refresh", { force: false }); }); refresh.addEventListener("contextmenu", (event) => { event.preventDefault(); server.send("astro-integration-pocketbase:refresh", { force: true }); }); server.on("astro-integration-pocketbase:refresh", ({ loading }) => { if (loading) { refresh.textContent = "Refreshing content..."; refresh.buttonStyle = "gray"; refresh.style.pointerEvents = "none"; } else { refresh.textContent = "Refresh content"; refresh.buttonStyle = "green"; refresh.style.pointerEvents = "unset"; } }); } } //#endregion //#region src/toolbar/dom/create-placeholder.ts /** * Creates a placeholder card. */ function createPlaceholder() { return ` <style> #placeholder div { display: flex; align-items: center; justify-content: center; } </style> <astro-dev-toolbar-card id="placeholder"> <div> <span> Here you will see the raw content of an entity </span> </div> </astro-dev-toolbar-card> `; } //#endregion //#region src/toolbar/init-toolbar.ts /** * Initializes the PocketBase toolbar. */ function initToolbar(canvas, app, server) { let options = { realtime: false, hasContentLoader: false, baseUrl: "" }; server.on("astro-integration-pocketbase:settings", (updatedOptions) => { options = updatedOptions; createPocketBaseWindow(); }); createPocketBaseWindow(); document.addEventListener("astro:after-swap", createPocketBaseWindow); closeOnOutsideClick(app); synchronizePlacementOnUpdate(app, canvas); function createPocketBaseWindow() { canvas.innerHTML = ""; const entities = window.__astro_entities__ || []; const windowElement = createWindowElement(` <style> :host astro-dev-toolbar-window { max-height: 480px; } main { display: flex; flex-direction: column; gap: 1rem; overflow-y: auto; } </style> <header></header> <hr /> <main> ${entities.length > 0 ? createEntities(entities, options.baseUrl) : createPlaceholder()} </main> `); createHeader(windowElement, server, options); canvas.append(windowElement); if (entities.length > 0) app.toggleNotification({ state: true, level: "info" }); else { app.toggleNotification({ state: false }); app.toggleState({ state: false }); } } } //#endregion //#region src/toolbar/index.ts var toolbar_default = defineToolbarApp({ init: initToolbar }); //#endregion export { toolbar_default as default }; //# sourceMappingURL=toolbar.mjs.map