pod-os / PodOS

Personal Online Data Operating System
MIT License
13 stars 1 forks source link

Load SolidOS panes #48

Open josephguillaume opened 1 week ago

josephguillaume commented 1 week ago

In creating a dashboard, I want to be able to use UI components created for use in SolidOS.

Partial proof of concept, assuming the server has mashlib available and the required SolidOS pane only needs access to the rdflib.js store.

          <script src="/mashlib.min.js"></script>
          <style src="/mash.css"></style>
          <script>
            function usePodOS(el) {
              return new Promise((resolve) => {
                el.dispatchEvent(
                  new CustomEvent("pod-os:init", {
                    bubbles: true,
                    composed: true,
                    cancelable: true,
                    detail: (os) => {
                      resolve(os);
                    },
                  }),
                );
              });
            }
            class SolidOsPane extends HTMLElement {
              connectedCallback() {
                let subject = this.getAttribute("uri");
                let pane = this.getAttribute("pane");
                usePodOS(this).then((os) =>
                  this.appendChild(
                    panes.byName(pane).render(os.store.graph.sym(subject), {
                      dom: document,
                      session: {
                        store: os.store.graph,
                      },
                    }),
                  ),
                );
              }
            }
            customElements.define("solidos-pane", SolidOsPane);
          </script>
          <solidos-pane
            style="display:block;width:100%;overflow-x:auto"
            pane="source"
            uri="https://angelo.veltens.org/profile/card"
          ></solidos-pane>
josephguillaume commented 1 day ago

In principle, panes can be automatically selected for a subject using code like:

relevantPanes = panes.list.filter(
      pane => pane.label(subject, context) && !pane.global
    )

From https://github.com/SolidOS/solid-panes/blob/b1bb05b37ddd3a9d21671be1f0a03a19639694fa/src/outline/manager.js#L543

Unfortunately it turns out that in practice many panes access the store not through the context but through the solid-logic global singleton. https://github.com/SolidOS/solid-logic/blob/efa1982bb7c91373121c723952b8d7b1fc915e4e/src/logic/solidLogicSingleton.ts A short term workaround is for the browser to use two rdflib stores, one for PodOS and one for solid-logic. However, panes also check the user authentication status, and this shouldn't be duplicated between PodOS and solid-logic.

Edit: next proof of concept overriding session and authenticated fetch (https://github.com/SolidOS/solidos/blob/5d44e80256bfcdf644cd5b46b2b1d8c39493e524/documentation/SolidOS_fetcher.md). I still have CSS issues on mobile that go away in desktop mode. Edit: Support panes using outliner too

<script>
            class SolidOsPane extends HTMLElement {
              connectedCallback() {
                let subject = this.getAttribute("uri");
                let paneName = this.getAttribute("pane");
                usePodOS(this).then(async (os) => {
                  let kb = os.store.graph;
                  panes.UI.store.fetcher._fetch =
                    os.session._authenticatedFetch;
                  UI.authn.session = os.session.session;
                  let pane;
                  if (paneName == null) {                 
                    await UI.store.fetcher.load(kb.sym(subject));
                    let relevantPanes = panes.list
                      .filter(
                        (pane) =>
                          pane.label(kb.sym(subject), {
                            dom: document,
                            getOutliner: (dom) => dom.outlineManager,
                            session: {
                              store: UI.store,
                              paneRegistry: panes
                            },
                          }) && !pane.global,
                      )
                    console.log(relevantPanes);
                    pane = relevantPanes[0];
                    console.log(pane.name);
                  } else {
                    pane = panes.byName(paneName);
                  }
                  if (pane) {
                    this.appendChild(
                      pane.render(kb.sym(subject), {
                        dom: document,
                        session: {
                          store: UI.store,
                        },
                      }),
                    );
                  }
                });
              }
            }
            customElements.define("solidos-pane", SolidOsPane);
          </script>
          <solidos-pane
            style="display:block;width:100%;overflow-x:auto"
      uri="https://solidos.solidcommunity.net/public/Roadmap/Tasks/state.ttl#Iss1595502698406"

          ></solidos-pane>