diff options
author | bob <bcz@cs.brown.edu> | 2019-09-03 16:47:52 -0400 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-09-03 16:47:52 -0400 |
commit | 25e8cc61f67bed3063dc81997d31f29e451b5610 (patch) | |
tree | 3381aa45ceddd72068385d260473403f30fb693f /src/client/views/linking/LinkMenuGroup.tsx | |
parent | 7e87aa4b7e0125482c87ab61f4a0de14e774558d (diff) | |
parent | a4d36f835b5c43351d1761034b61513b000445ba (diff) |
merged with master
Diffstat (limited to 'src/client/views/linking/LinkMenuGroup.tsx')
-rw-r--r-- | src/client/views/linking/LinkMenuGroup.tsx | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx new file mode 100644 index 000000000..b6a24b0c8 --- /dev/null +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -0,0 +1,111 @@ +import { action, observable } from "mobx"; +import { observer } from "mobx-react"; +import { DocumentView } from "../nodes/DocumentView"; +import { LinkMenuItem } from "./LinkMenuItem"; +import { LinkEditor } from "./LinkEditor"; +import './LinkMenu.scss'; +import React = require("react"); +import { Doc, DocListCast } from "../../../new_fields/Doc"; +import { Id } from "../../../new_fields/FieldSymbols"; +import { LinkManager } from "../../util/LinkManager"; +import { DragLinksAsDocuments, DragManager, SetupDrag } from "../../util/DragManager"; +import { emptyFunction } from "../../../Utils"; +import { Docs } from "../../documents/Documents"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { UndoManager } from "../../util/UndoManager"; +import { StrCast } from "../../../new_fields/Types"; +import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; + +interface LinkMenuGroupProps { + sourceDoc: Doc; + group: Doc[]; + groupType: string; + showEditor: (linkDoc: Doc) => void; + addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; + docView: DocumentView; + +} + +@observer +export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> { + + private _drag = React.createRef<HTMLDivElement>(); + private _table = React.createRef<HTMLDivElement>(); + + onLinkButtonDown = (e: React.PointerEvent): void => { + e.stopPropagation(); + document.removeEventListener("pointermove", this.onLinkButtonMoved); + document.addEventListener("pointermove", this.onLinkButtonMoved); + document.removeEventListener("pointerup", this.onLinkButtonUp); + document.addEventListener("pointerup", this.onLinkButtonUp); + } + + onLinkButtonUp = (e: PointerEvent): void => { + document.removeEventListener("pointermove", this.onLinkButtonMoved); + document.removeEventListener("pointerup", this.onLinkButtonUp); + e.stopPropagation(); + } + + + onLinkButtonMoved = async (e: PointerEvent) => { + UndoManager.RunInBatch(() => { + if (this._drag.current !== null && (e.movementX > 1 || e.movementY > 1)) { + document.removeEventListener("pointermove", this.onLinkButtonMoved); + document.removeEventListener("pointerup", this.onLinkButtonUp); + + let draggedDocs = this.props.group.map(linkDoc => { + let opp = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc); + if (opp) return opp; + }) as Doc[]; + let dragData = new DragManager.DocumentDragData(draggedDocs, draggedDocs.map(d => undefined)); + + DragManager.StartLinkedDocumentDrag([this._drag.current], dragData, e.x, e.y, { + handlers: { + dragComplete: action(emptyFunction), + }, + hideSource: false + }); + } + }, "drag links"); + e.stopPropagation(); + } + + viewGroupAsTable = (groupType: string): JSX.Element => { + let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType); + let index = keys.indexOf(""); + if (index > -1) keys.splice(index, 1); + let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb")); + let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType); + 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 linkEditor-tableButton" onPointerDown={SetupDrag(ref, createTable)} title="Drag to view relationship table"><FontAwesomeIcon icon="table" size="sm" /></button></div>; + } + + render() { + let groupItems = this.props.group.map(linkDoc => { + let destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc); + if (destination && this.props.sourceDoc) { + return <LinkMenuItem key={destination[Id] + this.props.sourceDoc[Id]} + groupType={this.props.groupType} + addDocTab={this.props.addDocTab} + linkDoc={linkDoc} + sourceDoc={this.props.sourceDoc} + destinationDoc={destination} + showEditor={this.props.showEditor} />; + } + }); + + return ( + <div className="linkMenu-group"> + <div className="linkMenu-group-name"> + <p ref={this._drag} onPointerDown={this.onLinkButtonDown} + className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"} > {this.props.groupType}:</p> + {this.props.groupType === "*" || this.props.groupType === "" ? <></> : this.viewGroupAsTable(this.props.groupType)} + </div> + <div className="linkMenu-group-wrapper"> + {groupItems} + </div> + </div > + ); + } +}
\ No newline at end of file |