| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import { Dynamic } from "solid-js/web";
- import { WidgetRenderer } from "./WidgetRenderer";
- import { getGrid } from "../grids/registry";
- import type { DashboardGridConfig } from "../types/grid";
- import { createMemo, createSignal, onMount, Show, For } from "solid-js";
- import type { WidgetConfig } from "../types/widget";
- export function Preview() {
- const [widgets, setWidgets] = createSignal<WidgetConfig[]>([]);
- const [gridConfig, setGridConfig] = createSignal<DashboardGridConfig>({
- templateId: null,
- widgetPlacements: [],
- });
- const [error, setError] = createSignal<string>("");
- // Calculate scale to fit grid inside viewport
- const scale = createMemo(() => {
- const grid = gridConfig().templateId
- ? getGrid(gridConfig().templateId!)
- : null;
- if (!grid) return 1;
- const gridWidth = grid.template?.width || 800;
- const gridHeight = grid.template?.height || 600;
- const viewportWidth = window.innerWidth - 40; // Add margin for safety
- const viewportHeight = window.innerHeight - 40; // Add margin for safety
- const scaleX = viewportWidth / gridWidth;
- const scaleY = viewportHeight / gridHeight;
- // Use slightly smaller scale to ensure nothing clips
- return Math.min(scaleX, scaleY) * 0.98; // 98% to add buffer
- });
- onMount(() => {
- try {
- const urlParams = new URLSearchParams(window.location.search);
- const configParam = urlParams.get("config");
- if (configParam) {
- const decoded = decodeURIComponent(configParam);
- const config = JSON.parse(decoded);
- // Support both old format (array) and new format (object with widgets and grid)
- if (Array.isArray(config)) {
- setWidgets(config);
- } else {
- if (config.widgets) {
- setWidgets(config.widgets);
- }
- if (config.grid) {
- setGridConfig(config.grid);
- }
- }
- } else {
- setError("No configuration found in URL");
- }
- } catch (err) {
- console.error("Error loading config:", err);
- setError("Failed to load dashboard configuration");
- }
- });
- return (
- <div
- onClick={() => window.location.reload()}
- style={{
- width: "100vw",
- height: "100vh",
- position: "fixed",
- top: "0",
- left: "0",
- background: "var(--bg, #fff)",
- overflow: "hidden",
- display: "flex",
- "align-items": "center",
- "justify-content": "center",
- padding: "20px",
- "box-sizing": "border-box",
- }}
- >
- <Show when={error()}>
- <div
- style={{
- padding: "2rem",
- "text-align": "center",
- color: "var(--gray)",
- }}
- >
- <h2>Error</h2>
- <p>{error()}</p>
- </div>
- </Show>
- <Show when={!error() && widgets().length > 0}>
- <div
- data-grid-container
- style={{
- width: gridConfig().templateId
- ? `${getGrid(gridConfig().templateId!)?.template.width || 800}px`
- : "100%",
- height: gridConfig().templateId
- ? `${getGrid(gridConfig().templateId!)?.template.height || 600}px`
- : "100%",
- position: "relative",
- transform: `scale(${scale()})`,
- "transform-origin": "center center",
- "flex-shrink": "0",
- }}
- >
- {/* Render grid template if selected */}
- <Show when={gridConfig().templateId}>
- {/* @ts-ignore */}
- {() => {
- const grid = getGrid(gridConfig().templateId!);
- return grid ? <Dynamic component={grid.Component} /> : null;
- }}
- </Show>
- {/* Render widgets */}
- <For each={widgets()}>
- {(widget) => <WidgetRenderer config={widget} locked={true} />}
- </For>
- </div>
- </Show>
- <Show when={!error() && widgets().length === 0}>
- <div
- style={{
- padding: "2rem",
- "text-align": "center",
- color: "var(--gray)",
- }}
- >
- <p>No widgets to display</p>
- </div>
- </Show>
- </div>
- );
- }
|