Changeset - 69ca2b2fc133
[Not reviewed]
default
0 1 1
drewp@bigasterisk.com - 8 months ago 2024-05-17 23:58:26
drewp@bigasterisk.com
overcomplicated attempt at persisting the pane layout in the rdf graph

this was hard because we have to somehow wait for the graph to load before config'ing the panes
2 files changed with 113 insertions and 16 deletions:
0 comments (0 inline, 0 general)
web/TiledHome.ts
Show inline comments
 
@@ -4,12 +4,13 @@ import { LitElement, html } from "lit";
 
import { customElement } from "lit/decorators.js";
 
import * as React from "react";
 
import { createRoot } from "react-dom/client";
 
import { getTopGraph } from "./RdfdbSyncedGraph";
 
import { SyncedGraph } from "./SyncedGraph";
 
import { Patch } from "./patch";
 
import { SimpleLayout, fullLayout, persistedLayout, simpleLayout } from "./tiledLayoutPersistence";
 
import { NamedNode } from "n3";
 
export { RdfdbSyncedGraph } from "./RdfdbSyncedGraph";
 
export { Light9CollectorUi } from "./collector/Light9CollectorUi";
 
export { Light9FadeUi } from "./fade/Light9FadeUi";
 
export { Light9DeviceSettings } from "./live/Light9DeviceSettings";
 
import { showRoot } from "./show_specific";
 
@@ -18,28 +19,13 @@ const log = debug("home");
 

	
 
const config: FlexLayout.IJsonModel = {
 
  global: {
 
    tabEnableRename: false,
 
  },
 
  borders: [],
 
  layout: {
 
    type: "row",
 
    weight: 100,
 
    children: [
 
      {
 
        type: "tabset",
 
        weight: 50,
 
        children: [{ type: "tab", name: "devsettings", component: "light9-device-settings" }],
 
      },
 
      {
 
        type: "tabset",
 
        weight: 50,
 
        children: [{ type: "tab", name: "collector", component: "light9-collector-ui" }],
 
      },
 
    ],
 
  },
 
  layout: fullLayout(persistedLayout) as FlexLayout.IJsonRowNode,
 
};
 

	
 
// see https://github.com/lit/lit/tree/main/packages/labs/react
 

	
 
class Main extends React.Component {
 
  state: { model: FlexLayout.Model };
 
@@ -70,12 +56,44 @@ export class Light9HomeStatus extends Li
 
      <a href="metrics/">metrics</a> `;
 
  }
 
  constructor() {
 
    super();
 
    getTopGraph().then((g) => {
 
      this.graph = g;
 
      runHandlerAfterGraphLoads(this.graph, this.homeLayout.bind(this), "homeLayout");
 
    });
 
  }
 
  homeLayout(patch?: Patch) {
 
    const U = this.graph.U();
 
    const s = U(":homeLayout");
 
    const p = U(":config");
 
    let cfg;
 

	
 
    try {
 
      cfg = this.graph.stringValue(s, p);
 
    } catch (e) {
 
      const ctx = new NamedNode(showRoot + "/homeLayout");
 
      log(`no config in graph- adding one to `, ctx);
 
      cfg = JSON.stringify(persistedLayout);
 
      this.graph.patchObject(s, p, this.graph.Literal(cfg), ctx);
 
    }
 
    const fl = fullLayout(JSON.parse(cfg) as SimpleLayout);
 
    log("got config", fl);
 
  }
 
}
 

	
 
function runHandlerAfterGraphLoads(graph: SyncedGraph, handler: HandlerFunc, label: string) {
 
  let patchesSeen = 0;
 
  const wrapHandler = (patch?: Patch) => {
 
    patchesSeen += 1;
 
    if (patchesSeen == 2) {
 
      handler(patch);
 
    } else {
 
      graph.objects(null, null);
 
    }
 
  };
 

	
 
  graph.runHandler(wrapHandler, label);
 
}
 

	
 
const root = createRoot(document.getElementById("container")!);
 
root.render(React.createElement(Main));
web/tiledLayoutPersistence.ts
Show inline comments
 
new file 100644
 
// for persistence
 
interface SimpleLayoutTab {
 
  type: "tab";
 
  light9Element: string;
 
}
 
export interface SimpleLayout {
 
  type: string;
 
  weight?: number;
 
  children: (SimpleLayout | SimpleLayoutTab)[];
 
}
 
// for FlexLayout
 
interface FullLayoutTab {
 
  type: "tab";
 
  name: string;
 
  component: string;
 
}
 
interface FullLayout {
 
  type: string;
 
  weight?: number;
 
  children: (FullLayout | FullLayoutTab)[];
 
}
 
function tabConfigFromSimpleTabName(name: string): FullLayoutTab {
 
  return { type: "tab", name: name.replace(/^light9-/, ""), component: name };
 
}
 
export function simpleLayout(full: FullLayout | FullLayoutTab): SimpleLayout | SimpleLayoutTab {
 
  if (full.type == "tab") {
 
    return { type: "tab", light9Element: (full as FullLayoutTab).component };
 
  } else {
 
    return { ...(full as FullLayout), children: (full as FullLayout).children.map(simpleLayout) };
 
  }
 
}
 
export function fullLayout(simple: SimpleLayout | SimpleLayoutTab): FullLayout | FullLayoutTab {
 
  if (simple.type == "tab") {
 
    return tabConfigFromSimpleTabName((simple as SimpleLayoutTab).light9Element);
 
  } else {
 
    return { ...(simple as SimpleLayout), children: (simple as SimpleLayout).children.map(fullLayout) };
 
  }
 
}
 
export const persistedLayout: SimpleLayout = {
 
  type: "row",
 
  children: [
 
    // {
 
    //   type: "tabset",
 
    //   weight: 50,
 
    //   children: [
 
    //     {
 
    //       type: "tab",
 
    //       light9Element: "light9-device-settings",
 
    //     },
 
    //   ],
 
    // },
 
    // {
 
    //   type: "row",
 
    //   weight: 50,
 
    //   children: [
 
    //     {
 
    //       type: "tabset",
 
    //       weight: 50,
 
    //       children: [
 
    //         {
 
    //           type: "tab",
 
    //           light9Element: "light9-fade-ui",
 
    //         },
 
    //       ],
 
    //     },
 
    //     {
 
    //       type: "tabset",
 
    //       weight: 50,
 
    //       children: [
 
    //         {
 
    //           type: "tab",
 
    //           light9Element: "light9-collector-ui",
 
    //         },
 
    //       ],
 
    //     },
 
    //   ],
 
    // },
 
  ],
 
};
0 comments (0 inline, 0 general)