diff options
Diffstat (limited to 'src/client/views/nodes/LinkBox.tsx')
-rw-r--r-- | src/client/views/nodes/LinkBox.tsx | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 68b692aad..09df1eac5 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -1,86 +1,107 @@ import { library } from '@fortawesome/fontawesome-svg-core'; -import { faEdit, faEye, faTimes } from '@fortawesome/free-solid-svg-icons'; +import { faEdit, faEye, faTimes, faArrowRight, faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { observer } from "mobx-react"; import { DocumentManager } from "../../util/DocumentManager"; import { undoBatch } from "../../util/UndoManager"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; import './LinkBox.scss'; import React = require("react"); import { Doc } from '../../../new_fields/Doc'; -import { Cast, NumCast } from '../../../new_fields/Types'; -import { listSpec } from '../../../new_fields/Schema'; -import { action } from 'mobx'; +import { StrCast, Cast } from '../../../new_fields/Types'; +import { observable, action } from 'mobx'; +import { LinkManager } from '../../util/LinkManager'; +import { DragLinksAsDocuments } from '../../util/DragManager'; +import { SelectionManager } from '../../util/SelectionManager'; +library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp); -library.add(faEye); -library.add(faEdit); -library.add(faTimes); - interface Props { + groupType: string; linkDoc: Doc; - linkName: String; - pairedDoc: Doc; - type: String; + sourceDoc: Doc; + destinationDoc: Doc; showEditor: () => void; } @observer export class LinkBox extends React.Component<Props> { + private _drag = React.createRef<HTMLDivElement>(); + @observable private _showMore: boolean = false; + @action toggleShowMore() { this._showMore = !this._showMore; } @undoBatch - onViewButtonPressed = async (e: React.PointerEvent): Promise<void> => { + onFollowLink = async (e: React.PointerEvent): Promise<void> => { e.stopPropagation(); - DocumentManager.Instance.jumpToDocument(this.props.pairedDoc, e.altKey); + DocumentManager.Instance.jumpToDocument(this.props.destinationDoc, e.altKey); } - onEditButtonPressed = (e: React.PointerEvent): void => { + onEdit = (e: React.PointerEvent): void => { e.stopPropagation(); - 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); - } + renderMetadata = (): JSX.Element => { + let groups = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, this.props.sourceDoc); + let index = groups.findIndex(groupDoc => StrCast(groupDoc.type).toUpperCase() === this.props.groupType.toUpperCase()); + let groupDoc = index > -1 ? groups[index] : undefined; + + let mdRows: Array<JSX.Element> = []; + if (groupDoc) { + let mdDoc = Cast(groupDoc.metadata, Doc, new Doc); + let keys = LinkManager.Instance.groupMetadataKeys.get(this.props.groupType); + mdRows = keys!.map(key => { + return (<div key={key} className="link-metadata-row"><b>{key}</b>: {StrCast(mdDoc[key])}</div>); + }); } - if (linkedTo) { - const linkedFromDocs = Cast(linkedTo.linkedFromDocs, listSpec(Doc)); - if (linkedFromDocs) { - linkedFromDocs.splice(linkedFromDocs.indexOf(this.props.linkDoc), 1); - } + + return (<div className="link-metadata">{mdRows}</div>); + } + + 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) => { + if (this._drag.current !== null && (e.movementX > 1 || e.movementY > 1)) { + document.removeEventListener("pointermove", this.onLinkButtonMoved); + document.removeEventListener("pointerup", this.onLinkButtonUp); + + DragLinksAsDocuments(this._drag.current, e.x, e.y, SelectionManager.SelectedDocuments()[0].props.Document); } + e.stopPropagation(); } render() { + let keys = LinkManager.Instance.groupMetadataKeys.get(this.props.groupType); + let canExpand = keys ? keys.length > 0 : false; + return ( - //<LinkEditor linkBox={this} linkDoc={this.props.linkDoc} /> - <div className="link-container"> - <div className="info-container" onPointerDown={this.onViewButtonPressed}> + <div className="linkMenu-item"> + <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}> <div className="link-name"> - <p>{this.props.linkName}</p> - </div> - <div className="doc-name"> - <p>{this.props.type}{this.props.pairedDoc.Title}</p> + <p>{StrCast(this.props.destinationDoc.title)}</p> + <div className="linkMenu-item-buttons"> + {canExpand ? <div title="Show more" className="button" onPointerDown={() => this.toggleShowMore()}> + <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>} + <div title="Edit link" className="button" onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div> + <div title="Follow link" className="button" ref={this._drag} onPointerDown={this.onLinkButtonDown} onPointerUp={this.onFollowLink}><FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /></div> + </div> </div> + {this._showMore ? this.renderMetadata() : <></>} </div> - <div className="button-container"> - {/* <div title="Follow Link" className="button" onPointerDown={this.onViewButtonPressed}> - <FontAwesomeIcon className="fa-icon-view" icon="eye" size="sm" /></div> */} - <div title="Edit Link" className="button" onPointerDown={this.onEditButtonPressed}> - <FontAwesomeIcon className="fa-icon-edit" icon="edit" size="sm" /></div> - <div title="Delete Link" className="button" onPointerDown={this.onDeleteButtonPressed}> - <FontAwesomeIcon className="fa-icon-delete" icon="times" size="sm" /></div> - </div> - </div> + </div > ); } }
\ No newline at end of file |