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`
New label:
Cancel
OK
`;
}
return html`
${this.label}
${this.rename ? html`` : ""} ${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 = "";
}
}