aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFawn <fangrui_tong@brown.edu>2019-06-12 16:20:46 -0400
committerFawn <fangrui_tong@brown.edu>2019-06-12 16:20:46 -0400
commite1fd270f1806ffd51174c835b335ceb4ebb2fe56 (patch)
treeb1882eca27303e7160a31c66e3752bed3710f85d
parent2c3b54d6e07c37a4f5fd52a49d6d60e7a8e5d2d2 (diff)
created remove handlers for link metadata and groups
-rw-r--r--src/client/documents/Documents.ts14
-rw-r--r--src/client/util/LinkManager.ts110
-rw-r--r--src/client/views/nodes/LinkBox.tsx38
-rw-r--r--src/client/views/nodes/LinkEditor.scss32
-rw-r--r--src/client/views/nodes/LinkEditor.tsx250
-rw-r--r--src/client/views/nodes/LinkMenu.scss2
-rw-r--r--src/client/views/nodes/LinkMenu.tsx33
7 files changed, 251 insertions, 228 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 9f1501265..9517cbbda 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -89,9 +89,13 @@ export namespace DocUtils {
// let protoSrc = source.proto ? source.proto : source;
// let protoTarg = target.proto ? target.proto : target;
UndoManager.RunInBatch(() => {
- let groupDoc = Docs.TextDocument();
- groupDoc.proto!.type = "*";
- groupDoc.proto!.metadata = Docs.TextDocument();
+ // let groupDoc1 = Docs.TextDocument();
+ // groupDoc1.proto!.type = "*";
+ // groupDoc1.proto!.metadata = Docs.TextDocument();
+
+ // let groupDoc2 = Docs.TextDocument();
+ // groupDoc2.proto!.type = "*";
+ // groupDoc2.proto!.metadata = Docs.TextDocument();
let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 });
//let linkDoc = new Doc;
@@ -99,11 +103,11 @@ export namespace DocUtils {
// linkDoc.proto!.linkDescription = "";
linkDoc.proto!.anchor1 = source;
linkDoc.proto!.anchor1Page = source.curPage;
- linkDoc.proto!.anchor1Groups = new List<Doc>([groupDoc]);
+ linkDoc.proto!.anchor1Groups = new List<Doc>([]);
linkDoc.proto!.anchor2 = target;
linkDoc.proto!.anchor2Page = target.curPage;
- linkDoc.proto!.anchor2Groups = new List<Doc>([groupDoc]);
+ linkDoc.proto!.anchor2Groups = new List<Doc>([]);
// linkDoc.proto!.linkedTo = target;
// linkDoc.proto!.linkedToPage = target.curPage;
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 99fb4c6c0..cc8617052 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -9,6 +9,7 @@ import { StrCast, Cast } from "../../new_fields/Types";
import { Doc } from "../../new_fields/Doc";
import { listSpec } from "../../new_fields/Schema";
import { List } from "../../new_fields/List";
+import { string } from "prop-types";
export namespace LinkUtils {
export function findOppositeAnchor(link: Doc, anchor: Doc): Doc {
@@ -40,14 +41,48 @@ export namespace LinkUtils {
// }
export function setAnchorGroups(link: Doc, anchor: Doc, groups: Doc[]) {
+ // console.log("setting groups for anchor", anchor["title"]);
if (Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, new Doc))) {
link.anchor1Groups = new List<Doc>(groups);
} else {
link.anchor2Groups = new List<Doc>(groups);
}
}
+
+ export function removeGroupFromAnchor(link: Doc, anchor: Doc, groupType: string) {
+ let groups = [];
+ if (Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, new Doc))) {
+ groups = Cast(link["anchor1Groups"], listSpec(Doc), []);
+ } else {
+ groups = Cast(link["anchor2Groups"], listSpec(Doc), []);
+ }
+
+ let newGroups: Doc[] = [];
+ groups.forEach(groupDoc => {
+ if (groupDoc instanceof Doc && StrCast(groupDoc["type"]) !== groupType) {
+ newGroups.push(groupDoc);
+ }
+ })
+ LinkUtils.setAnchorGroups(link, anchor, newGroups);
+ }
}
+/*
+ * link doc:
+ * - anchor1: doc
+ * - anchor1page: number
+ * - anchor1groups: list of group docs representing the groups anchor1 categorizes this link/anchor2 in
+ * - anchor2: doc
+ * - anchor2page: number
+ * - anchor2groups: list of group docs representing the groups anchor2 categorizes this link/anchor1 in
+ *
+ * group doc:
+ * - type: string representing the group type/name/category
+ * - metadata: doc representing the metadata kvps
+ *
+ * metadata doc:
+ * - user defined kvps
+ */
export class LinkManager {
private static _instance: LinkManager;
public static get Instance(): LinkManager {
@@ -56,60 +91,57 @@ export class LinkManager {
private constructor() {
}
- @observable public allLinks: Array<Doc> = [];
- @observable public allGroups: Map<string, Array<string>> = new Map();
+ @observable public allLinks: Array<Doc> = []; // list of link docs
+ @observable public allGroups: Map<string, Array<string>> = new Map(); // map of group type to list of its metadata keys
public findAllRelatedLinks(anchor: Doc): Array<Doc> {
return LinkManager.Instance.allLinks.filter(
link => Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, new Doc)) || Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, new Doc)));
}
+ // returns map of group type to anchor's links in that group type
public findRelatedGroupedLinks(anchor: Doc): Map<string, Array<Doc>> {
let related = this.findAllRelatedLinks(anchor);
- let anchorGroups = new Map();
+ let anchorGroups = new Map<string, Array<Doc>>();
related.forEach(link => {
- // get groups of given doc
- let oppGroups = (Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, new Doc))) ? Cast(link.anchor1Groups, listSpec(Doc), []) : Cast(link.anchor2Groups, listSpec(Doc), []);
- if (oppGroups) {
- if (oppGroups.length > 0) {
- oppGroups.forEach(groupDoc => {
- if (groupDoc instanceof Doc) {
- let groupType = StrCast(groupDoc.proto!.type);
- let group = anchorGroups.get(groupType); // TODO: clean this up lol
- if (group) group.push(link);
- else group = [link];
- anchorGroups.set(groupType, group);
- } else {
- // promise doc
- }
-
- })
- }
- else {
- // if link is in no groups then put it in default group
- let group = anchorGroups.get("*");
- if (group) group.push(link);
- else group = [link];
- anchorGroups.set("*", group);
- }
- }
+ // get groups of given anchor categorizes this link/opposite anchor in
+ let groups = (Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, new Doc))) ? Cast(link.anchor1Groups, listSpec(Doc), []) : Cast(link.anchor2Groups, listSpec(Doc), []);
+ if (groups.length > 0) {
+ groups.forEach(groupDoc => {
+ if (groupDoc instanceof Doc) {
+ let groupType = StrCast(groupDoc["type"]);
+ let group = anchorGroups.get(groupType); // TODO: clean this up lol
+ if (group) group.push(link);
+ else group = [link];
+ anchorGroups.set(groupType, group);
+ } else {
+ // promise doc
+ }
+
+ })
+ }
+ else {
+ // if link is in no groups then put it in default group
+ let group = anchorGroups.get("*");
+ if (group) group.push(link);
+ else group = [link];
+ anchorGroups.set("*", group);
+ }
- // let anchor = this.findOppositeAnchor(link, source);
- // let group = categories.get(link.linkTags);
- // if (group) group.push(link);
- // else group = [link];
- // categories.set(link.linkTags, group);
})
return anchorGroups;
}
-
-
-
- // public findAnchorTags(link: Doc, source: Doc): Doc[] {
- // if (source)
- // }
+ public deleteGroup(groupType: string) {
+ let deleted = LinkManager.Instance.allGroups.delete(groupType);
+ if (deleted) {
+ LinkManager.Instance.allLinks.forEach(linkDoc => {
+ LinkUtils.removeGroupFromAnchor(linkDoc, Cast(linkDoc["anchor1"], Doc, new Doc), groupType);
+ LinkUtils.removeGroupFromAnchor(linkDoc, Cast(linkDoc["anchor2"], Doc, new Doc), groupType);
+ })
+ }
+ }
} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index ebca1dc69..5597bb1aa 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -41,23 +41,23 @@ export class LinkBox extends React.Component<Props> {
this.props.showEditor();
}
- @action
- onDeleteButtonPressed = async (e: React.PointerEvent): Promise<void> => {
- e.stopPropagation();
- const [linkedFrom, linkedTo] = await Promise.all([Cast(this.props.linkDoc.linkedFrom, Doc), Cast(this.props.linkDoc.linkedTo, Doc)]);
- if (linkedFrom) {
- const linkedToDocs = Cast(linkedFrom.linkedToDocs, listSpec(Doc));
- if (linkedToDocs) {
- linkedToDocs.splice(linkedToDocs.indexOf(this.props.linkDoc), 1);
- }
- }
- if (linkedTo) {
- const linkedFromDocs = Cast(linkedTo.linkedFromDocs, listSpec(Doc));
- if (linkedFromDocs) {
- linkedFromDocs.splice(linkedFromDocs.indexOf(this.props.linkDoc), 1);
- }
- }
- }
+ // @action
+ // onDeleteButtonPressed = async (e: React.PointerEvent): Promise<void> => {
+ // e.stopPropagation();
+ // const [linkedFrom, linkedTo] = await Promise.all([Cast(this.props.linkDoc.linkedFrom, Doc), Cast(this.props.linkDoc.linkedTo, Doc)]);
+ // if (linkedFrom) {
+ // const linkedToDocs = Cast(linkedFrom.linkedToDocs, listSpec(Doc));
+ // if (linkedToDocs) {
+ // linkedToDocs.splice(linkedToDocs.indexOf(this.props.linkDoc), 1);
+ // }
+ // }
+ // if (linkedTo) {
+ // const linkedFromDocs = Cast(linkedTo.linkedFromDocs, listSpec(Doc));
+ // if (linkedFromDocs) {
+ // linkedFromDocs.splice(linkedFromDocs.indexOf(this.props.linkDoc), 1);
+ // }
+ // }
+ // }
render() {
@@ -80,8 +80,8 @@ export class LinkBox extends React.Component<Props> {
<FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /></div>
<div title="Edit Link" className="button" onPointerDown={this.onEditButtonPressed}>
<FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
- <div title="Delete Link" className="button" onPointerDown={this.onDeleteButtonPressed}>
- <FontAwesomeIcon className="fa-icon" icon="times" size="sm" /></div>
+ {/* <div title="Delete Link" className="button" onPointerDown={this.onDeleteButtonPressed}>
+ <FontAwesomeIcon className="fa-icon" icon="times" size="sm" /></div> */}
</div>
</div>
);
diff --git a/src/client/views/nodes/LinkEditor.scss b/src/client/views/nodes/LinkEditor.scss
index d3ac8cf19..b56f3046a 100644
--- a/src/client/views/nodes/LinkEditor.scss
+++ b/src/client/views/nodes/LinkEditor.scss
@@ -74,6 +74,7 @@
}
.linkEditor-group-row {
display: flex;
+ margin-bottom: 6px;
.linkEditor-group-row-label {
margin-right: 6px;
}
@@ -81,8 +82,17 @@
.linkEditor-metadata-row {
display: flex;
justify-content: space-between;
+ margin-bottom: 6px;
input {
- width: calc(50% - 2px);
+ width: calc(50% - 18px);
+ height: 20px;
+ }
+ button {
+ width: 20px;
+ height: 20px;
+ margin-left: 6px;
+ padding: 0;
+ font-size: 14px;
}
}
}
@@ -90,6 +100,7 @@
.linkEditor-dropdown {
width: 100%;
position: relative;
+ z-index: 999;
.linkEditor-options-wrapper {
width: 100%;
position: absolute;
@@ -107,4 +118,23 @@
background-color: $light-color-secondary;
}
}
+}
+
+.linkEditor-group-buttons {
+ height: 20px;
+ display: flex;
+ justify-content: space-between;
+ button {
+ width: 31%;
+ height: 20px;
+ margin-left: 6px;
+ padding: 0;
+ font-size: 10px;
+ &:first-child { // delete
+ font-size: 14px;
+ }
+ &:disabled { // delete
+ background-color: gray;
+ }
+ }
} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx
index 8d12bc30f..05e05c2ee 100644
--- a/src/client/views/nodes/LinkEditor.tsx
+++ b/src/client/views/nodes/LinkEditor.tsx
@@ -1,11 +1,7 @@
import { observable, computed, action } from "mobx";
import React = require("react");
-import { SelectionManager } from "../../util/SelectionManager";
import { observer } from "mobx-react";
import './LinkEditor.scss';
-import { props } from "bluebird";
-import { DocumentView } from "./DocumentView";
-import { link } from "fs";
import { StrCast, Cast } from "../../../new_fields/Types";
import { Doc } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
@@ -21,7 +17,7 @@ import { string } from "prop-types";
library.add(faArrowLeft);
library.add(faEllipsisV);
-// this dropdown could be generalizeds
+// this dropdown could be generalized
@observer
class LinkGroupsDropdown extends React.Component<{ groupId: string, groupType: string, setGroup: (groupId: string, group: string) => void }> {
@observable private _searchTerm: string = "";
@@ -63,7 +59,7 @@ class LinkGroupsDropdown extends React.Component<{ groupId: string, groupType: s
if (!exactFound && this._searchTerm !== "") {
options.push(<div key={""} className="linkEditor-option"
- onClick={() => { this.createGroup(this._searchTerm); this.setGroupType(this._searchTerm); this.setSearchTerm("") }}>Create new "{this._searchTerm}" group</div>)
+ onClick={() => { this.createGroup(this._searchTerm); this.setGroupType(this._searchTerm); this.setSearchTerm("") }}>Define new "{this._searchTerm}" relationship</div>)
}
return options;
@@ -82,6 +78,8 @@ class LinkGroupsDropdown extends React.Component<{ groupId: string, groupType: s
}
}
+
+
@observer
class LinkMetadataEditor extends React.Component<{ groupType: string, mdDoc: Doc, mdKey: string, mdValue: string }> {
@observable private _key: string = this.props.mdKey;
@@ -111,11 +109,28 @@ class LinkMetadataEditor extends React.Component<{ groupType: string, mdDoc: Doc
this._value = value;
}
+ @action
+ removeMetadata = (): void => {
+ let groupMdKeys = new Array(...LinkManager.Instance.allGroups.get(this.props.groupType)!);
+ if (groupMdKeys) {
+ let index = groupMdKeys.indexOf(this._key);
+ if (index > -1) {
+ groupMdKeys.splice(index, 1);
+ }
+ else {
+ console.log("OLD KEY WAS NOT FOUND", ...groupMdKeys)
+ }
+ }
+ this._key = "";
+ LinkManager.Instance.allGroups.set(this.props.groupType, groupMdKeys);
+ }
+
render() {
return (
<div className="linkEditor-metadata-row">
<input type="text" value={this._key} placeholder="key" onChange={e => this.editMetadataKey(e.target.value)}></input>:
<input type="text" value={this._value} placeholder="value" onChange={e => this.editMetadataValue(e.target.value)}></input>
+ <button onClick={() => this.removeMetadata()}>X</button>
</div>
)
}
@@ -131,85 +146,129 @@ interface LinkEditorProps {
@observer
export class LinkEditor extends React.Component<LinkEditorProps> {
- @observable private _groups: Map<string, Doc> = new Map();
- @observable private _metadata: Map<string, Map<string, Doc>> = new Map();
+ @observable private _groups: Map<string, Doc> = new Map(); // map of temp group id to the corresponding group doc
constructor(props: LinkEditorProps) {
super(props);
let groups = new Map<string, Doc>();
- let metadata: Map<string, Map<string, Doc>> = new Map();
let groupList = (Doc.AreProtosEqual(props.sourceDoc, Cast(props.linkDoc.anchor1, Doc, new Doc))) ?
Cast(props.linkDoc.anchor1Groups, listSpec(Doc), []) : Cast(props.linkDoc.anchor2Groups, listSpec(Doc), []);
groupList.forEach(groupDoc => {
if (groupDoc instanceof Doc) {
let id = Utils.GenerateGuid();
groups.set(id, groupDoc);
-
- let metadataMap = new Map<string, Doc>();
- let metadataDocs = Cast(groupDoc.proto!.metadata, listSpec(Doc), []);
- metadataDocs.forEach(mdDoc => {
- if (mdDoc && mdDoc instanceof Doc) { // TODO: handle promise doc
- metadataMap.set(Utils.GenerateGuid(), mdDoc);
- }
- })
- metadata.set(id, metadataMap);
} else {
// promise doc
}
})
this._groups = groups;
- this._metadata = metadata;
}
- // @action
- // editGroup(groupId: string, value: string) {
- // let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
- // let groupDoc = this._groups.get(groupId);
- // if (groupDoc) {
- // groupDoc.proto!.type = value;
- // LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, [groupDoc]);
- // }
- // }
-
@action
- addGroup = (e: React.MouseEvent): void => {
- // create new document for group
- let groupDoc = Docs.TextDocument();
- groupDoc.proto!.title = "";
- groupDoc.proto!.metadata = new List<Doc>([]);
+ addGroup = (): void => {
+ console.log("before adding", ...Array.from(this._groups.keys()));
+
+ let index = Array.from(this._groups.values()).findIndex(groupDoc => {
+ return groupDoc["type"] === "New Group";
+ })
+ if (index === -1) {
+ // create new document for group
+ let groupDoc = Docs.TextDocument();
+ groupDoc.proto!.type = "New Group";
+ groupDoc.proto!.metadata = Docs.TextDocument();
- this._groups.set(Utils.GenerateGuid(), groupDoc);
+ this._groups.set(Utils.GenerateGuid(), groupDoc);
- let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
- LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
+ let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
+ LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
+ }
+
+
+ // console.log("set anchor groups for", this.props.sourceDoc["title"]);
+ console.log("after adding", ...Array.from(this._groups.keys()));
}
@action
- setGroup = (groupId: string, group: string): void => {
+ setGroupType = (groupId: string, groupType: string): void => {
+ console.log("setting for ", groupId);
let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
let groupDoc = this._groups.get(groupId);
if (groupDoc) {
- groupDoc.proto!.type = group;
- LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, [groupDoc]);
+ console.log("found group doc");
+ groupDoc.proto!.type = groupType;
+
+ this._groups.set(groupId, groupDoc);
+
+ let gd = this._groups.get(groupId);
+ if (gd)
+ console.log("just created", StrCast(gd["type"]));
+
+ LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
+ console.log("set", Array.from(this._groups.values()).length)
+ }
+
+ let anchor1groups: string[] = [];
+ Cast(this.props.linkDoc.anchor1Groups, listSpec(Doc), []).forEach(doc => {
+ if (doc instanceof Doc) {
+ anchor1groups.push(StrCast(doc.proto!.type));
+ } else {
+ console.log("promise");
+ }
+ })
+ let anchor2groups: string[] = [];
+ Cast(this.props.linkDoc.anchor2Groups, listSpec(Doc), []).forEach(doc => {
+ if (doc instanceof Doc) {
+ anchor2groups.push(StrCast(doc.proto!.type));
+ } else {
+ console.log("promise");
+ }
+ })
+ console.log("groups for anchors; anchor1: [", ...anchor1groups, "] ; anchor2: [", ...anchor2groups, "]")
+ }
+
+ removeGroupFromLink = (groupId: string, groupType: string) => {
+ // this._groups.delete(groupId);
+ let groupDoc = this._groups.get(groupId);
+ if (groupDoc) {
+ LinkUtils.removeGroupFromAnchor(this.props.linkDoc, this.props.sourceDoc, groupType);
+ this._groups.delete(groupId);
+ }
+ // LinkUtils.setAnchorGroups(this.props.linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
+ console.log("\nremoved", groupId, "remaining", ...Array.from(this._groups.keys()), "\n");
+ }
+
+ deleteGroup = (groupId: string, groupType: string) => {
+ let groupDoc = this._groups.get(groupId);
+ if (groupDoc) {
+ LinkManager.Instance.deleteGroup(groupType);
+ this._groups.delete(groupId);
}
}
renderGroup(groupId: string, groupDoc: Doc) {
- return (
- <div key={groupId} className="linkEditor-group">
- <div className="linkEditor-group-row">
- <p className="linkEditor-group-row-label">type:</p>
- <LinkGroupsDropdown groupId={groupId} groupType={StrCast(groupDoc.proto!.type)} setGroup={this.setGroup} />
- {/* <input key={groupId + "-type"} type="text" value={StrCast(groupDoc.proto!.type)} onChange={e => this.editGroup(groupId, e.target.value)}></input> */}
- {/* <input key={groupId + "-type"} type="text" value={StrCast(groupDoc.proto!.type)} onChange={e => this.editGroup(groupId, e.target.value)}></input> */}
+ let type = StrCast(groupDoc["type"]);
+ if ((type && LinkManager.Instance.allGroups.get(type)) || type === "New Group") {
+ return (
+ <div key={groupId} className="linkEditor-group">
+ <div className="linkEditor-group-row">
+ <p className="linkEditor-group-row-label">type:</p>
+ <LinkGroupsDropdown groupId={groupId} groupType={StrCast(groupDoc.proto!.type)} setGroup={this.setGroupType} />
+ </div>
+ {this.renderMetadata(groupId)}
+ <div className="linkEditor-group-buttons">
+ {groupDoc["type"] === "New Group" ? <button disabled={true} title="Add KVP">+</button> :
+ <button onClick={() => this.addMetadata(StrCast(groupDoc.proto!.type))} title="Add KVP">+</button>}
+ {/* <button onClick={this.viewGroupAsTable}>view group as table</button> */}
+ <button onClick={() => this.copyGroup(groupId, type)} title="Copy group to opposite anchor">↔</button>
+ <button onClick={() => this.removeGroupFromLink(groupId, type)} title="Remove group from link">x</button>
+ <button onClick={() => this.deleteGroup(groupId, type)} title="Delete group">xx</button>
+ </div>
</div>
- {this.renderMetadata(groupId)}
- {groupDoc["type"] === "*" ? <></> : <button onClick={() => this.addMetadata(StrCast(groupDoc.proto!.type))}>add kvp</button>}
- <button onClick={this.viewGroupAsTable}>view group as table</button>
- {/* <button onClick={() => this.addMetadata(StrCast(groupDoc.proto!.type))}>+</button> */}
- </div>
- )
+ )
+ } else {
+ return <></>
+ }
}
viewGroupAsTable = (): void => {
@@ -228,65 +287,6 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
}
LinkManager.Instance.allGroups.set(groupType, mdKeys);
- // // create new metadata doc
- // let mdDoc = Docs.TextDocument();
- // mdDoc.proto!.title = "";
- // mdDoc.proto!.value = "";
-
- // // append to map
- // let mdMap = this._metadata.get(groupId);
- // if (mdMap) {
- // mdMap.set(Utils.GenerateGuid(), mdDoc);
- // } else {
- // mdMap = new Map();
- // mdMap.set(Utils.GenerateGuid(), mdDoc);
- // }
-
- // // add to internal representation of metadata
- // this._metadata.set(groupId, mdMap);
-
- // // add to internatal representation of group
- // let groupDoc = this._groups.get(groupId);
- // if (groupDoc) {
- // groupDoc.proto!.metadata = new List<Doc>(Array.from(mdMap.values()));
- // this._groups.set(groupId, groupDoc);
- // }
-
- // // add to link doc
- // let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
- // LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
- }
-
- // @action
- // editMetadataTitle(groupId: string, mdId: string, value: string) {
- // let groupMd = this._metadata.get(groupId);
- // if (groupMd) {
- // let mdDoc = groupMd.get(mdId);
- // if (mdDoc) {
- // mdDoc.proto!.title = value;
- // }
- // }
- // // set group and link?
- // }
-
- // @action
- // editMetadataValue(groupId: string, mdId: string, value: string) {
- // let groupMd = this._metadata.get(groupId);
- // if (groupMd) {
- // let mdDoc = groupMd.get(mdId);
- // if (mdDoc) {
- // mdDoc.proto!.value = value;
- // }
- // }
- // // set group and link?
- // }
-
- @action
- editMetadataKey(groupId: string, value: string) {
- let groupDoc = this._groups.get(groupId);
- if (groupDoc) {
-
- }
}
renderMetadata(groupId: string) {
@@ -300,30 +300,10 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
groupMdKeys.forEach((key, index) => {
metadata.push(
<LinkMetadataEditor key={"mded-" + index} groupType={groupType} mdDoc={mdDoc} mdKey={key} mdValue={(mdDoc[key] === undefined) ? "" : StrCast(mdDoc[key])} />
- // <div key={key} className="linkEditor-metadata-row">
- // <input type="text" value={key} placeholder="key"></input>
- // :
- // <input type="text" value={(mdDoc[key] === undefined) ? "" : StrCast(mdDoc[key])} placeholder="value"></input>
- // </div>
)
})
}
}
-
-
- // let metadataMap = this._metadata.get(groupId);
- // if (metadataMap) {
- // metadataMap.forEach((mdDoc, mdId) => {
- // metadata.push(
- // <div key={mdId} className="linkEditor-metadata-row">
- // <input type="text" value={StrCast(mdDoc.proto!.title)} placeholder="key" onChange={e => this.editMetadataTitle(groupId, mdId, e.target.value)}></input>
- // :
- // <input type="text" value={StrCast(mdDoc.proto!.value)} placeholder="value" onChange={e => this.editMetadataValue(groupId, mdId, e.target.value)}></input>
- // </div>
- // )
- // })
- // }
-
return metadata;
}
@@ -340,10 +320,10 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
<button className="linkEditor-back" onPointerDown={() => this.props.showLinks()}><FontAwesomeIcon icon="arrow-left" size="sm" /></button>
<p className="linkEditor-linkedTo">editing link to: <b>{destination.proto!.title}</b></p>
<div className="linkEditor-groupsLabel">
- <b>Groups:</b>
- <button onClick={this.addGroup} title="Add Group">+</button>
+ <b>Relationships:</b>
+ <button onClick={() => this.addGroup()} title="Add Group">+</button>
</div>
- {groups}
+ {groups.length > 0 ? groups : <div className="linkEditor-group">There are currently no relationships associated with this link.</div>}
</div>
);
diff --git a/src/client/views/nodes/LinkMenu.scss b/src/client/views/nodes/LinkMenu.scss
index 860f31d8a..7e031b897 100644
--- a/src/client/views/nodes/LinkMenu.scss
+++ b/src/client/views/nodes/LinkMenu.scss
@@ -40,7 +40,7 @@
display: flex;
}
&:hover .link-menu-item-content {
- width: calc(100% - 72px);
+ width: calc(100% - 42px);
}
}
.link-menu-item-buttons {
diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx
index 21b5807ae..47bd6c3eb 100644
--- a/src/client/views/nodes/LinkMenu.tsx
+++ b/src/client/views/nodes/LinkMenu.tsx
@@ -32,7 +32,7 @@ export class LinkMenu extends React.Component<Props> {
// });
// }
- renderLinkGroupItems(links: Doc[]) {
+ renderGroup(links: Doc[]) {
let source = this.props.docView.Document;
return links.map(link => {
let destination = LinkUtils.findOppositeAnchor(link, source);
@@ -43,7 +43,7 @@ export class LinkMenu extends React.Component<Props> {
});
}
- renderLinkItems = (links: Map<string, Array<Doc>>): Array<JSX.Element> => {
+ renderLinks = (links: Map<string, Array<Doc>>): Array<JSX.Element> => {
let linkItems: Array<JSX.Element> = [];
links.forEach((links, group) => {
@@ -51,7 +51,7 @@ export class LinkMenu extends React.Component<Props> {
<div key={group} className="link-menu-group">
<p className="link-menu-group-name">{group}:</p>
<div className="link-menu-group-wrapper">
- {this.renderLinkGroupItems(links)}
+ {this.renderGroup(links)}
</div>
</div>
)
@@ -65,10 +65,7 @@ export class LinkMenu extends React.Component<Props> {
}
render() {
- //get list of links from document
- // let linkFrom = DocListCast(this.props.docView.props.Document.linkedFromDocs);
- // let linkTo = DocListCast(this.props.docView.props.Document.linkedToDocs);
- let related = LinkManager.Instance.findRelatedGroupedLinks(this.props.docView.props.Document);
+ let related: Map<string, Doc[]> = LinkManager.Instance.findRelatedGroupedLinks(this.props.docView.props.Document);
if (this._editingLink === undefined) {
return (
<div id="linkMenu-container">
@@ -76,31 +73,11 @@ export class LinkMenu extends React.Component<Props> {
<div id="linkMenu-list">
{/* {this.renderLinkItems(linkTo, "linkedTo", "Destination: ")}
{this.renderLinkItems(linkFrom, "linkedFrom", "Source: ")} */}
- {this.renderLinkItems(related)}
+ {this.renderLinks(related)}
</div>
</div>
);
} else {
- // let groups = new Map<string, Doc>();
- // let metadata: Map<string, Map<string, Doc>> = new Map();
- // let groupList = (Doc.AreProtosEqual(this.props.docView.props.Document, Cast(this._editingLink.anchor1, Doc, new Doc))) ?
- // Cast(this._editingLink.anchor1Groups, listSpec(Doc), []) : Cast(this._editingLink.anchor2Groups, listSpec(Doc), []);
- // groupList.forEach(groupDoc => {
- // if (groupDoc instanceof Doc) {
- // let id = Utils.GenerateGuid();
- // groups.set(id, groupDoc);
-
- // let metadataMap = new Map<string, Doc>();
- // let metadataDocs = Cast(groupDoc.proto!.metadata, listSpec(Doc), []);
- // metadataDocs.forEach(mdDoc => {
- // if (mdDoc && mdDoc instanceof Doc) { // TODO: handle promise doc
- // metadataMap.set(Utils.GenerateGuid(), mdDoc);
- // }
- // })
- // metadata.set(id, metadataMap);
- // }
- // })
-
return (
<LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)}></LinkEditor>
);