diff options
author | Fawn <fangrui_tong@brown.edu> | 2019-06-12 16:20:46 -0400 |
---|---|---|
committer | Fawn <fangrui_tong@brown.edu> | 2019-06-12 16:20:46 -0400 |
commit | e1fd270f1806ffd51174c835b335ceb4ebb2fe56 (patch) | |
tree | b1882eca27303e7160a31c66e3752bed3710f85d /src | |
parent | 2c3b54d6e07c37a4f5fd52a49d6d60e7a8e5d2d2 (diff) |
created remove handlers for link metadata and groups
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 14 | ||||
-rw-r--r-- | src/client/util/LinkManager.ts | 110 | ||||
-rw-r--r-- | src/client/views/nodes/LinkBox.tsx | 38 | ||||
-rw-r--r-- | src/client/views/nodes/LinkEditor.scss | 32 | ||||
-rw-r--r-- | src/client/views/nodes/LinkEditor.tsx | 250 | ||||
-rw-r--r-- | src/client/views/nodes/LinkMenu.scss | 2 | ||||
-rw-r--r-- | src/client/views/nodes/LinkMenu.tsx | 33 |
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> ); |