Files @ 7a5c7721bf6d
Branch filter:

Location: light9/web/ResourceDisplay.ts - annotation

drewp@bigasterisk.com
better collector err handling
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
import { TextField } from "@material/mwc-textfield";
import debug from "debug";
import { css, html, LitElement, PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { NamedNode } from "n3";
import { getTopGraph } from "./RdfdbSyncedGraph";
import { SyncedGraph } from "./SyncedGraph";
export { Button } from "@material/mwc-button";
export { Dialog } from "@material/mwc-dialog";
export { TextField } from "@material/mwc-textfield";

const log = debug("rdisplay");

@customElement("resource-display")
export class ResourceDisplay extends LitElement {
  graph!: SyncedGraph;
  static styles = [
    css`
      :host {
        display: inline-block;
      }

      a.resource {
        color: inherit;
        text-decoration: none;
      }

      .resource {
        border: 1px solid #545454;
        border-radius: 5px;
        padding: 1px;
        margin: 2px;
        background: rgb(49, 49, 49);
        display: inline-block;
        text-shadow: 1px 1px 2px black;
      }
      .resource.minor {
        background: none;
        border: none;
      }
      .resource a {
        color: rgb(150, 150, 255);
        padding: 1px;
        display: inline-block;
      }
      .resource.minor a {
        text-decoration: none;
        color: rgb(155, 155, 193);
        padding: 0;
      }
    `,
  ];

  render() {
    let renameDialog = html``;
    if (this.renameDialogOpen) {
      renameDialog = html` <mwc-dialog id="renameDialog" open @closing=${this.onRenameClosing} @closed=${this.onRenameClosed}>
        <p>
          New label:
          <mwc-textfield id="renameField" dialogInitialFocus .value=${this.renameTo}></mwc-textfield>
        </p>
        <mwc-button dialogAction="cancel" slot="secondaryAction">Cancel</mwc-button>
        <mwc-button dialogAction="ok" slot="primaryAction">OK</mwc-button>
      </mwc-dialog>`;
    }

    return html` <span class="${this.resClasses()}">
        <a href="${this.href()}" id="uri"> <!-- type icon goes here -->${this.label}</a>
        ${this.rename ? html`<button @click=${this.onRename}>Rename</button>` : ""} </span
      >${renameDialog}`;
    //
  }
  @property() uri?: NamedNode;

  @state() label: string = "";
  @state() renameDialogOpen = false;
  @state() renameTo = "";

  @property({ type: Boolean }) rename: boolean = false;
  @property({ type: Boolean }) noclick: boolean = false;
  @property({ type: Boolean }) minor: boolean = false;

  constructor() {
    super();
    getTopGraph().then((g) => {
      this.graph = g;
      this.onUri();
    });
  }

  updated(changedProperties: PropertyValues) {
    if (changedProperties.has("uri")) {
      this.onUri();
    }
  }

  private onUri() {
    if (!this.graph) {
      return; /*too soon, but getTopGraph will call us again*/
    }
    
    if (this.uri === undefined) {
      this.label = "(unset)";
    } else if  (this.uri === null) {
      throw 'use undefined please'
    } else {
      this.graph.runHandler(this.compile.bind(this, this.graph), `label for ${this.uri.id}`);
    }
  }
  private compile(graph: SyncedGraph) {
    if (this.uri === undefined) {
      return;
    } else {
      this.label = this.graph.labelOrTail(this.uri);
    }
  }

  private href(): string {
    if (!this.uri || this.noclick) {
      return "javascript:;";
    }
    return this.uri.value;
  }

  private resClasses() {
    return this.minor ? "resource minor" : "resource";
  }

  private onRename() {
    this.renameTo = this.label;
    this.renameDialogOpen = true;
    setTimeout(() => {
      // I! 👏 know! 👏 the! 👏 element! 👏 I! 👏 want!
      const inputEl = this.shadowRoot!.querySelector("#renameField")!.shadowRoot!.querySelector("input")! as HTMLInputElement;
      inputEl.setSelectionRange(0, -1);
    }, 100);
  }

  // move to SyncedGraph
  private whatCtxHeldTheObj(subj: NamedNode, pred: NamedNode): NamedNode {
    var ctxs = this.graph.contextsWithPattern(subj, pred, null);
    if (ctxs.length != 1) {
      throw new Error(`${ctxs.length} ${pred.id} stmts for ${subj.id}`);
    }
    return ctxs[0];
  }

  private onRenameClosing(ev: CustomEvent) {
    this.renameTo = (this.shadowRoot!.querySelector("#renameField")! as TextField).value;
  }

  private onRenameClosed(ev: CustomEvent) {
    this.renameDialogOpen = false;
    if (ev.detail.action == "ok") {
      var label = this.graph.Uri("rdfs:label");
      if (this.uri === undefined) {
        throw "lost uri";
      }
      const ctx = this.whatCtxHeldTheObj(this.uri, label);
      this.graph.patchObject(this.uri, label, this.graph.Literal(this.renameTo), ctx);
    }
    this.renameTo = "";
  }
}