From 074b4b2a3246ae86fda334629d40540dd2bbf633 Mon Sep 17 00:00:00 2001 From: Fawn Date: Tue, 11 Jun 2019 15:27:02 -0400 Subject: links can choose group type from preexisting group types --- src/client/util/LinkManager.ts | 2 +- src/client/views/nodes/LinkEditor.scss | 26 +++ src/client/views/nodes/LinkEditor.tsx | 370 ++++++++++++++++++--------------- src/client/views/nodes/LinkMenu.tsx | 43 ++-- 4 files changed, 252 insertions(+), 189 deletions(-) (limited to 'src') diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 5e8e0475b..99fb4c6c0 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -57,7 +57,7 @@ export class LinkManager { } @observable public allLinks: Array = []; - @observable public allGroups: Map = new Map(); + @observable public allGroups: Map> = new Map(); public findAllRelatedLinks(anchor: Doc): Array { return LinkManager.Instance.allLinks.filter( diff --git a/src/client/views/nodes/LinkEditor.scss b/src/client/views/nodes/LinkEditor.scss index 52ed26442..d3ac8cf19 100644 --- a/src/client/views/nodes/LinkEditor.scss +++ b/src/client/views/nodes/LinkEditor.scss @@ -80,5 +80,31 @@ } .linkEditor-metadata-row { display: flex; + justify-content: space-between; + input { + width: calc(50% - 2px); + } + } +} + +.linkEditor-dropdown { + width: 100%; + position: relative; + .linkEditor-options-wrapper { + width: 100%; + position: absolute; + top: 19px; + left: 0; + display: flex; + flex-direction: column; + } + .linkEditor-option { + background-color: red; + border: 1px solid $intermediate-color; + border-top: 0; + cursor: pointer; + &:hover { + background-color: $light-color-secondary; + } } } \ No newline at end of file diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx index 14fdd26df..481d3bf37 100644 --- a/src/client/views/nodes/LinkEditor.tsx +++ b/src/client/views/nodes/LinkEditor.tsx @@ -21,85 +21,119 @@ import { string } from "prop-types"; library.add(faArrowLeft); library.add(faEllipsisV); +// this dropdown could be generalizeds +@observer +class LinkGroupsDropdown extends React.Component<{ groupId: string, groupType: string, setGroup: (groupId: string, group: string) => void }> { + @observable private _searchTerm: string = ""; + @observable private _groupType: string = this.props.groupType; + + @action + setSearchTerm(value: string) { + this._searchTerm = value; + } + + @action + setGroupType(value: string) { + this._groupType = value; + } + + createGroup(value: string) { + LinkManager.Instance.allGroups.set(value, []); + this.props.setGroup(this.props.groupId, value); + } + + renderOptions = (): JSX.Element[] => { + let allGroups: string[], searchTerm: string, results: string[], exactFound: boolean; + if (this._searchTerm !== "") { + allGroups = Array.from(LinkManager.Instance.allGroups.keys()); + searchTerm = this._searchTerm.toUpperCase(); + results = allGroups.filter(group => group.toUpperCase().indexOf(searchTerm) > -1); + exactFound = results.findIndex(group => group.toUpperCase() === searchTerm) > -1; + } else { + results = []; + exactFound = false; + } + + let options = []; + results.forEach(result => { + options.push(
{ this.props.setGroup(this.props.groupId, result); this.setGroupType(result); this.setSearchTerm("") }}>{result}
) + }); + + if (!exactFound && this._searchTerm !== "") { + options.push(
{ this.createGroup(this._searchTerm); this.setGroupType(this._searchTerm); this.setSearchTerm("") }}>Create new "{this._searchTerm}" group
) + } + + return options; + } + + render() { + return ( +
+ { this.setSearchTerm(e.target.value); this.setGroupType(e.target.value) }}> +
+ {this.renderOptions()} +
+
+ ) + } +} + + interface LinkEditorProps { sourceDoc: Doc; linkDoc: Doc; - groups: Map; - metadata: Map>; + // groups: Map; + // metadata: Map>; showLinks: () => void; } @observer export class LinkEditor extends React.Component { - // @observable private _groups: Map = new Map(); - // @observable private _metadata: Map> = new Map(); - - // // componentDidMount() { - - // // } - // constructor(props: LinkEditorProps) { - // super(props); - - // let groups = new Map(); - // let metadata: Map> = new Map(); - // let groupList = (Doc.AreProtosEqual(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(); - // 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); - // } - // }) - // } - - // @observable private _title: string = StrCast(this.props.linkDoc.title); - // @observable private _description: string = StrCast(this.props.linkDoc.linkDescription); - // @observable private _tags: Array = Cast(this.props.linkDoc.linkTags, List); - - // @action - // onTitleChanged = (e: React.ChangeEvent) => { - // this._title = e.target.value; - // } + @observable private _groups: Map = new Map(); + @observable private _metadata: Map> = new Map(); + + constructor(props: LinkEditorProps) { + super(props); + + let groups = new Map(); + let metadata: Map> = 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(); + 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 - // onDescriptionChanged = (e: React.ChangeEvent) => { - // this._description = e.target.value; - // } - - // renderTags() { - // return this._tags.map(tag => { - // if (tag === "") { - // return ; - // } else { - // return ; - // } - // }) - // } - - // addTag = (): void => { - // this._tags.push(""); + // 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 - editGroup(groupId: string, value: string) { - let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc; - let groupDoc = this.props.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 @@ -107,149 +141,150 @@ export class LinkEditor extends React.Component { groupDoc.proto!.title = ""; groupDoc.proto!.metadata = new List([]); - this.props.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())); + } + @action + setGroup = (groupId: string, group: string): void => { let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc; - LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this.props.groups.values())); + let groupDoc = this._groups.get(groupId); + if (groupDoc) { + groupDoc.proto!.type = group; + LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, [groupDoc]); + } } renderGroup(groupId: string, groupDoc: Doc) { - // let metadata = this.props.metadata.get(groupId); - // if (!metadata) { - // metadata = new Map(); - // } + console.log("testing", groupDoc["strawberry"], groupDoc["type"]); return ( - //
-
-

type:

- this.editGroup(groupId, e.target.value)}> +
+
+

type:

+ + {/* this.editGroup(groupId, e.target.value)}> */} + {/* this.editGroup(groupId, e.target.value)}> */} +
+ {this.renderMetadata(groupId)} +
- // {/* {this.renderMetadata(groupId)} */ } - // {/* */ } - // //
) } @action - addMetadata = (groupId: string): void => { - // create new metadata doc - let mdDoc = Docs.TextDocument(); - mdDoc.proto!.title = ""; - mdDoc.proto!.value = ""; - - // append to map - let mdMap = this.props.metadata.get(groupId); - if (mdMap) { - mdMap.set(Utils.GenerateGuid(), mdDoc); + addMetadata = (groupType: string): void => { + let mdKeys = LinkManager.Instance.allGroups.get(groupType); + if (mdKeys) { + if (mdKeys.indexOf("new key") > -1) { + mdKeys.push("new key"); + } } else { - mdMap = new Map(); - mdMap.set(Utils.GenerateGuid(), mdDoc); + mdKeys = ["new key"]; } + LinkManager.Instance.allGroups.set(groupType, mdKeys); + console.log("md added", groupType, LinkManager.Instance.allGroups.get(groupType), LinkManager.Instance.allGroups); + + // // 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.props.metadata.set(groupId, mdMap); - - // add to internatal representation of group - let groupDoc = this.props.groups.get(groupId); - if (groupDoc) { - groupDoc.proto!.metadata = new List(Array.from(mdMap.values())); - this.props.groups.set(groupId, groupDoc); - } + // // add to internal representation of metadata + // this._metadata.set(groupId, mdMap); - // 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.props.groups.values())); + // // add to internatal representation of group + // let groupDoc = this._groups.get(groupId); + // if (groupDoc) { + // groupDoc.proto!.metadata = new List(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 - // addMetadata = (groupId: string): void => { - // let groupDoc = this.props.groups.get(groupId); - // if (groupDoc) { - // // create new document for metadata row - // let metadata = Cast(groupDoc.metadata, listSpec(Doc), []); - // let metadataDoc = Docs.TextDocument(); - // metadataDoc.proto!.title = ""; - // metadataDoc.proto!.value = ""; - // let metadataMap = new Map([metadataDoc]); // TODO: append to metadata - // } - // } - - // @action - // editMetadataTitle = (groupId: string, mdId: string, value: string) => { - // let group = this.props.metadata.get(groupId); - // if (group) { - // let mdDoc = group.get(mdId); + // 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 group = this.props.metadata.get(groupId); - // if (group) { - // let mdDoc = group.get(mdId); + // 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 - editMetadataTitle(groupId: string, mdId: string, value: string) { - - } - - @action - editMetadataValue(groupId: string, mdId: string, value: string) { - - } - renderMetadata(groupId: string) { let metadata: Array = []; - let metadataMap = this.props.metadata.get(groupId); - if (metadataMap) { - metadataMap.forEach((mdDoc, mdId) => { - metadata.push( -
- this.editMetadataTitle(groupId, mdId, e.target.value)}> - : - this.editMetadataValue(groupId, mdId, e.target.value)}> -
- ) - }) + let groupDoc = this._groups.get(groupId); + if (groupDoc) { + let mdDoc = Cast(groupDoc.proto!.metadata, Doc, new Doc); + let groupType = StrCast(groupDoc.proto!.type); + let groupMdKeys = LinkManager.Instance.allGroups.get(groupType); + console.log("rendering md", groupType, groupMdKeys, LinkManager.Instance.allGroups); + if (groupMdKeys) { + groupMdKeys.forEach(key => { + metadata.push( +
+ + : + +
+ ) + }) + } } - return metadata; - // let metadataList: Array = []; - // metadata.forEach((mdDoc, mdId) => { - // metadataList.push( - //
- // this.editMetadataTitle(groupId, mdId, e.target.value)}>: - // this.editMetadataValue(groupId, mdId, e.target.value)}> - //
- // ) - // }) - } + // let metadataMap = this._metadata.get(groupId); + // if (metadataMap) { + // metadataMap.forEach((mdDoc, mdId) => { + // metadata.push( + //
+ // this.editMetadataTitle(groupId, mdId, e.target.value)}> + // : + // this.editMetadataValue(groupId, mdId, e.target.value)}> + //
+ // ) + // }) + // } - renderGroups() { - let groups: Array = []; - this.props.groups.forEach((groupDoc, groupId) => { - groups.push(this.renderGroup(groupId, groupDoc)) - }); - return groups; + return metadata; } render() { let destination = LinkUtils.findOppositeAnchor(this.props.linkDoc, this.props.sourceDoc); + let groups: Array = []; + this._groups.forEach((groupDoc, groupId) => { + groups.push(this.renderGroup(groupId, groupDoc)) + }); + return (
@@ -258,8 +293,7 @@ export class LinkEditor extends React.Component { Groups:
- {this.renderGroups()} - + {groups}
); diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx index ab478feae..e378ee1cb 100644 --- a/src/client/views/nodes/LinkMenu.tsx +++ b/src/client/views/nodes/LinkMenu.tsx @@ -48,7 +48,6 @@ export class LinkMenu extends React.Component { let linkItems: Array = []; links.forEach((links, group) => { - console.log("category is ", group); linkItems.push(

{group}:

@@ -59,6 +58,10 @@ export class LinkMenu extends React.Component { ) }); + if (linkItems.length === 0) { + linkItems.push(

no links have been created yet

); + } + return linkItems; } @@ -79,28 +82,28 @@ export class LinkMenu extends React.Component {
); } else { - let groups = new Map(); - let metadata: Map> = 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 groups = new Map(); + // let metadata: Map> = 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(); - 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); - } - }) + // let metadataMap = new Map(); + // 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 ( - this._editingLink = undefined)}> + this._editingLink = undefined)}> ); } -- cgit v1.2.3-70-g09d2