aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/LinkEditor.tsx
diff options
context:
space:
mode:
authorMohammad Amoush <mohammad_amoush@brown.edu>2019-07-16 12:38:37 -0400
committerMohammad Amoush <mohammad_amoush@brown.edu>2019-07-16 12:38:37 -0400
commit52ea2cbd66bd223730bb370470e706bc05f88fa8 (patch)
treec7a025c9e47e217c94e2fffac6ea354967ad7187 /src/client/views/nodes/LinkEditor.tsx
parent3593c1c4a67e8fb398e5a456ad4d758305294625 (diff)
parent03deba08d6af54bfc4235ed7c5ac26b8f673607a (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into presentation-reordering-mohammad
Diffstat (limited to 'src/client/views/nodes/LinkEditor.tsx')
-rw-r--r--src/client/views/nodes/LinkEditor.tsx132
1 files changed, 93 insertions, 39 deletions
diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx
index 22da732cf..afde85b69 100644
--- a/src/client/views/nodes/LinkEditor.tsx
+++ b/src/client/views/nodes/LinkEditor.tsx
@@ -22,11 +22,9 @@ interface GroupTypesDropdownProps {
// this dropdown could be generalized
@observer
class GroupTypesDropdown extends React.Component<GroupTypesDropdownProps> {
- @observable private _searchTerm: string = "";
+ @observable private _searchTerm: string = this.props.groupType;
@observable private _groupType: string = this.props.groupType;
-
- @action setSearchTerm = (value: string): void => { this._searchTerm = value; };
- @action setGroupType = (value: string): void => { this._groupType = value; };
+ @observable private _isEditing: boolean = false;
@action
createGroup = (groupType: string): void => {
@@ -34,9 +32,52 @@ class GroupTypesDropdown extends React.Component<GroupTypesDropdownProps> {
LinkManager.Instance.addGroupType(groupType);
}
+ @action
onChange = (val: string): void => {
- this.setSearchTerm(val);
- this.setGroupType(val);
+ this._searchTerm = val;
+ this._groupType = val;
+ this._isEditing = true;
+ }
+
+ @action
+ onKeyDown = (e: React.KeyboardEvent): void => {
+ if (e.key === "Enter") {
+ let allGroupTypes = Array.from(LinkManager.Instance.getAllGroupTypes());
+ let groupOptions = allGroupTypes.filter(groupType => groupType.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+ let exactFound = groupOptions.findIndex(groupType => groupType.toUpperCase() === this._searchTerm.toUpperCase());
+
+ if (exactFound > -1) {
+ let groupType = groupOptions[exactFound];
+ this.props.setGroupType(groupType);
+ this._groupType = groupType;
+ } else {
+ this.createGroup(this._searchTerm);
+ this._groupType = this._searchTerm;
+ }
+
+ this._searchTerm = this._groupType;
+ this._isEditing = false;
+ }
+ }
+
+ @action
+ onOptionClick = (value: string, createNew: boolean): void => {
+ if (createNew) {
+ this.createGroup(this._searchTerm);
+ this._groupType = this._searchTerm;
+
+ } else {
+ this.props.setGroupType(value);
+ this._groupType = value;
+
+ }
+ this._searchTerm = this._groupType;
+ this._isEditing = false;
+ }
+
+ @action
+ onButtonPointerDown = (): void => {
+ this._isEditing = true;
}
renderOptions = (): JSX.Element[] | JSX.Element => {
@@ -47,29 +88,35 @@ class GroupTypesDropdown extends React.Component<GroupTypesDropdownProps> {
let exactFound = groupOptions.findIndex(groupType => groupType.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
let options = groupOptions.map(groupType => {
- return <div key={groupType} className="linkEditor-option"
- onClick={() => { this.props.setGroupType(groupType); this.setGroupType(groupType); this.setSearchTerm(""); }}>{groupType}</div>;
+ let ref = React.createRef<HTMLDivElement>();
+ return <div key={groupType} ref={ref} className="linkEditor-option"
+ onClick={() => this.onOptionClick(groupType, false)}>{groupType}</div>;
});
// if search term does not already exist as a group type, give option to create new group type
if (!exactFound && this._searchTerm !== "") {
- options.push(<div key={""} className="linkEditor-option"
- onClick={() => { this.createGroup(this._searchTerm); this.setGroupType(this._searchTerm); this.setSearchTerm(""); }}>Define new "{this._searchTerm}" relationship</div>);
+ let ref = React.createRef<HTMLDivElement>();
+ options.push(<div key={""} ref={ref} className="linkEditor-option"
+ onClick={() => this.onOptionClick(this._searchTerm, true)}>Define new "{this._searchTerm}" relationship</div>);
}
return options;
}
render() {
- return (
- <div className="linkEditor-dropdown">
- <input type="text" value={this._groupType} placeholder="Search for or create a new group"
- onChange={e => this.onChange(e.target.value)}></input>
- <div className="linkEditor-options-wrapper">
- {this.renderOptions()}
- </div>
- </div >
- );
+ if (this._isEditing || this._groupType === "") {
+ return (
+ <div className="linkEditor-dropdown">
+ <input type="text" value={this._groupType} placeholder="Search for or create a new group"
+ onChange={e => this.onChange(e.target.value)} onKeyDown={this.onKeyDown} autoFocus></input>
+ <div className="linkEditor-options-wrapper">
+ {this.renderOptions()}
+ </div>
+ </div >
+ );
+ } else {
+ return <button className="linkEditor-typeButton" onClick={() => this.onButtonPointerDown()}>{this._groupType}</button>;
+ }
}
}
@@ -177,9 +224,10 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
LinkManager.Instance.deleteGroupType(groupType);
}
- copyGroup = (groupType: string): void => {
+ copyGroup = async (groupType: string): Promise<void> => {
let sourceGroupDoc = this.props.groupDoc;
- let sourceMdDoc = Cast(sourceGroupDoc.metadata, Doc, new Doc);
+ const sourceMdDoc = await Cast(sourceGroupDoc.metadata, Doc);
+ if (!sourceMdDoc) return;
let destDoc = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
// let destGroupList = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, destDoc);
@@ -199,7 +247,9 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
destGroupDoc.type = groupType;
destGroupDoc.metadata = destMdDoc;
- LinkManager.Instance.addGroupToAnchor(this.props.linkDoc, destDoc, destGroupDoc, true);
+ if (destDoc) {
+ LinkManager.Instance.addGroupToAnchor(this.props.linkDoc, destDoc, destGroupDoc, true);
+ }
}
@action
@@ -241,7 +291,7 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
if (index > -1) keys.splice(index, 1);
let cols = ["anchor1", "anchor2", ...[...keys]];
let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
- let createTable = action(() => Docs.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
+ let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
let ref = React.createRef<HTMLDivElement>();
return <div ref={ref}><button className="linkEditor-button" onPointerDown={SetupDrag(ref, createTable)} title="Drag to view relationship table"><FontAwesomeIcon icon="table" size="sm" /></button></div>;
}
@@ -271,10 +321,9 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
</>
);
}
- trace();
return (
<div className="linkEditor-group">
- <div className="linkEditor-group-row">
+ <div className="linkEditor-group-row ">
<p className="linkEditor-group-row-label">type:</p>
<GroupTypesDropdown groupType={groupType} setGroupType={this.setGroupType} />
</div>
@@ -308,7 +357,10 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
// create new metadata document for group
let mdDoc = new Doc();
mdDoc.anchor1 = this.props.sourceDoc.title;
- mdDoc.anchor2 = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc).title;
+ let opp = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
+ if (opp) {
+ mdDoc.anchor2 = opp.title;
+ }
// create new group document
let groupDoc = new Doc();
@@ -326,20 +378,22 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
return <LinkGroupEditor key={"gred-" + StrCast(groupDoc.type)} linkDoc={this.props.linkDoc} sourceDoc={this.props.sourceDoc} groupDoc={groupDoc} />;
});
- return (
- <div className="linkEditor">
- <button className="linkEditor-back" onPointerDown={() => this.props.showLinks()}><FontAwesomeIcon icon="arrow-left" size="sm" /></button>
- <div className="linkEditor-info">
- <p className="linkEditor-linkedTo">editing link to: <b>{destination.proto!.title}</b></p>
- <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link"><FontAwesomeIcon icon="trash" size="sm" /></button>
+ if (destination) {
+ return (
+ <div className="linkEditor">
+ <button className="linkEditor-back" onPointerDown={() => this.props.showLinks()}><FontAwesomeIcon icon="arrow-left" size="sm" /></button>
+ <div className="linkEditor-info">
+ <p className="linkEditor-linkedTo">editing link to: <b>{destination.proto!.title}</b></p>
+ <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link"><FontAwesomeIcon icon="trash" size="sm" /></button>
+ </div>
+ <div className="linkEditor-groupsLabel">
+ <b>Relationships:</b>
+ <button className="linkEditor-button" onClick={() => this.addGroup()} title=" Add Group"><FontAwesomeIcon icon="plus" size="sm" /></button>
+ </div>
+ {groups.length > 0 ? groups : <div className="linkEditor-group">There are currently no relationships associated with this link.</div>}
</div>
- <div className="linkEditor-groupsLabel">
- <b>Relationships:</b>
- <button className="linkEditor-button" onClick={() => this.addGroup()} title=" Add Group"><FontAwesomeIcon icon="plus" size="sm" /></button>
- </div>
- {groups.length > 0 ? groups : <div className="linkEditor-group">There are currently no relationships associated with this link.</div>}
- </div>
- );
+ );
+ }
}
} \ No newline at end of file