aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/linking
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/linking')
-rw-r--r--src/client/views/linking/LinkEditor.tsx346
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx226
2 files changed, 333 insertions, 239 deletions
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index 1414bfdf7..ba301962b 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -1,15 +1,14 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
-import { action, computed, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, NumListCast, StrListCast, Field } from "../../../fields/Doc";
-import { DateCast, StrCast, Cast } from "../../../fields/Types";
-import { LinkManager } from "../../util/LinkManager";
-import { undoBatch } from "../../util/UndoManager";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc, NumListCast, StrListCast, Field } from '../../../fields/Doc';
+import { DateCast, StrCast, Cast } from '../../../fields/Types';
+import { LinkManager } from '../../util/LinkManager';
+import { undoBatch } from '../../util/UndoManager';
import './LinkEditor.scss';
-import { LinkRelationshipSearch } from "./LinkRelationshipSearch";
-import React = require("react");
-
+import { LinkRelationshipSearch } from './LinkRelationshipSearch';
+import React = require('react');
interface LinkEditorProps {
sourceDoc: Doc;
@@ -19,16 +18,20 @@ interface LinkEditorProps {
}
@observer
export class LinkEditor extends React.Component<LinkEditorProps> {
-
@observable description = Field.toString(LinkManager.currentLink?.description as any as Field);
@observable relationship = StrCast(LinkManager.currentLink?.linkRelationship);
@observable zoomFollow = StrCast(this.props.sourceDoc.followLinkZoom);
@observable openDropdown: boolean = false;
@observable showInfo: boolean = false;
- @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; }
- @observable private buttonColor: string = "";
- @observable private relationshipButtonColor: string = "";
- @observable private relationshipSearchVisibility: string = "none";
+ @computed get infoIcon() {
+ if (this.showInfo) {
+ return 'chevron-up';
+ }
+ return 'chevron-down';
+ }
+ @observable private buttonColor: string = '';
+ @observable private relationshipButtonColor: string = '';
+ @observable private relationshipSearchVisibility: string = 'none';
@observable private searchIsActive: boolean = false;
//@observable description = this.props.linkDoc.description ? StrCast(this.props.linkDoc.description) : "DESCRIPTION";
@@ -37,7 +40,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
deleteLink = (): void => {
LinkManager.Instance.deleteLink(this.props.linkDoc);
this.props.showLinks();
- }
+ };
@undoBatch
setRelationshipValue = action((value: string) => {
@@ -49,11 +52,11 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
const linkRelationshipSizes = NumListCast(Doc.UserDoc().linkRelationshipSizes);
const linkColorList = StrListCast(Doc.UserDoc().linkColorList);
- // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color
+ // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color
if (!linkRelationshipList?.includes(value)) {
linkRelationshipList.push(value);
linkRelationshipSizes.push(1);
- const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")";
+ const randColor = 'rgb(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ')';
linkColorList.push(randColor);
// if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes
} else if (linkRelationshipList && value !== prevRelationship) {
@@ -61,20 +64,22 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
//increment size of new relationship size
if (index !== -1 && index < linkRelationshipSizes.length) {
const pvalue = linkRelationshipSizes[index];
- linkRelationshipSizes[index] = (pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue + 1);
+ linkRelationshipSizes[index] = pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue + 1;
}
//decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation)
if (linkRelationshipList.includes(prevRelationship)) {
const pindex = linkRelationshipList.indexOf(prevRelationship);
if (pindex !== -1 && pindex < linkRelationshipSizes.length) {
const pvalue = linkRelationshipSizes[pindex];
- linkRelationshipSizes[pindex] = Math.max(0, (pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue - 1));
+ linkRelationshipSizes[pindex] = Math.max(0, pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue - 1);
}
}
-
}
- this.relationshipButtonColor = "rgb(62, 133, 55)";
- setTimeout(action(() => this.relationshipButtonColor = ""), 750);
+ this.relationshipButtonColor = 'rgb(62, 133, 55)';
+ setTimeout(
+ action(() => (this.relationshipButtonColor = '')),
+ 750
+ );
return true;
}
});
@@ -89,144 +94,143 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
if (linkRelationshipList) {
return linkRelationshipList.filter(rel => rel.includes(query));
}
- }
+ };
/**
* toggles visibility of the relationship search results when the input field is focused on
*/
@action
toggleRelationshipResults = () => {
- this.relationshipSearchVisibility = this.relationshipSearchVisibility === "none" ? "block" : "none";
- }
+ this.relationshipSearchVisibility = this.relationshipSearchVisibility === 'none' ? 'block' : 'none';
+ };
@undoBatch
setDescripValue = action((value: string) => {
if (LinkManager.currentLink) {
Doc.GetProto(LinkManager.currentLink).description = value;
- this.buttonColor = "rgb(62, 133, 55)";
- setTimeout(action(() => this.buttonColor = ""), 750);
+ this.buttonColor = 'rgb(62, 133, 55)';
+ setTimeout(
+ action(() => (this.buttonColor = '')),
+ 750
+ );
return true;
}
});
onDescriptionKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
- if (e.key === "Enter") {
+ if (e.key === 'Enter') {
this.setDescripValue(this.description);
document.getElementById('input')?.blur();
}
e.stopPropagation();
- }
+ };
onRelationshipKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
- if (e.key === "Enter") {
+ if (e.key === 'Enter') {
this.setRelationshipValue(this.relationship);
document.getElementById('input')?.blur();
}
e.stopPropagation();
- }
+ };
onDescriptionDown = () => this.setDescripValue(this.description);
onRelationshipDown = () => this.setRelationshipValue(this.relationship);
onBlur = () => {
- //only hide the search results if the user clicks out of the input AND not on any of the search results
+ //only hide the search results if the user clicks out of the input AND not on any of the search results
// i.e. if search is not active
if (!this.searchIsActive) {
this.toggleRelationshipResults();
}
- }
+ };
onFocus = () => {
this.toggleRelationshipResults();
- }
+ };
toggleSearchIsActive = () => {
this.searchIsActive = !this.searchIsActive;
- }
+ };
@action
- handleDescriptionChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.description = e.target.value; }
+ handleDescriptionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.description = e.target.value;
+ };
@action
- handleRelationshipChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.relationship = e.target.value; }
+ handleRelationshipChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.relationship = e.target.value;
+ };
@action
- handleZoomFollowChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.props.sourceDoc.followLinkZoom = e.target.checked; }
+ handleZoomFollowChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.props.sourceDoc.followLinkZoom = e.target.checked;
+ };
@action
handleRelationshipSearchChange = (result: string) => {
this.setRelationshipValue(result);
this.toggleRelationshipResults();
this.relationship = result;
- }
+ };
@computed
get editRelationship() {
//NOTE: confusingly, the classnames for the following relationship JSX elements are the same as the for the description elements for shared CSS
- return <div className="linkEditor-description">
- <div className="linkEditor-description-label">Link Relationship:</div>
- <div className="linkEditor-description-input">
- <div className="linkEditor-description-editing">
- <input
- style={{ width: "100%" }}
- id="input"
- value={this.relationship}
- autoComplete={"off"}
- placeholder={"Enter link relationship"}
- onKeyDown={this.onRelationshipKey}
- onChange={this.handleRelationshipChange}
- onFocus={this.onFocus}
- onBlur={this.onBlur}
- ></input>
- <LinkRelationshipSearch
- results={this.getRelationshipResults()}
- display={this.relationshipSearchVisibility}
- handleRelationshipSearchChange={this.handleRelationshipSearchChange}
- toggleSearch={this.toggleSearchIsActive}
- />
+ return (
+ <div className="linkEditor-description">
+ <div className="linkEditor-description-label">Link Relationship:</div>
+ <div className="linkEditor-description-input">
+ <div className="linkEditor-description-editing">
+ <input
+ style={{ width: '100%' }}
+ id="input"
+ value={this.relationship}
+ autoComplete={'off'}
+ placeholder={'Enter link relationship'}
+ onKeyDown={this.onRelationshipKey}
+ onChange={this.handleRelationshipChange}
+ onFocus={this.onFocus}
+ onBlur={this.onBlur}></input>
+ <LinkRelationshipSearch results={this.getRelationshipResults()} display={this.relationshipSearchVisibility} handleRelationshipSearchChange={this.handleRelationshipSearchChange} toggleSearch={this.toggleSearchIsActive} />
+ </div>
+ <div className="linkEditor-description-add-button" style={{ background: this.relationshipButtonColor }} onPointerDown={this.onRelationshipDown}>
+ Set
+ </div>
</div>
- <div className="linkEditor-description-add-button"
- style={{ background: this.relationshipButtonColor }}
- onPointerDown={this.onRelationshipDown}>Set</div>
</div>
- </div>;
+ );
}
@computed
get editZoomFollow() {
//NOTE: confusingly, the classnames for the following relationship JSX elements are the same as the for the description elements for shared CSS
- return <div className="linkEditor-zoomFollow">
- <div className="linkEditor-zoomFollow-label">Zoom To Link Target:</div>
- <div className="linkEditor-zoomFollow-input">
- <div className="linkEditor-zoomFollow-editing">
- <input
- style={{ width: "100%" }}
- type="checkbox"
- value={this.zoomFollow}
- onChange={this.handleZoomFollowChange} />
+ return (
+ <div className="linkEditor-zoomFollow">
+ <div className="linkEditor-zoomFollow-label">Zoom To Link Target:</div>
+ <div className="linkEditor-zoomFollow-input">
+ <div className="linkEditor-zoomFollow-editing">
+ <input style={{ width: '100%' }} type="checkbox" value={this.zoomFollow} onChange={this.handleZoomFollowChange} />
+ </div>
</div>
</div>
- </div >;
+ );
}
@computed
get editDescription() {
- return <div className="linkEditor-description">
- <div className="linkEditor-description-label">Link Description:</div>
- <div className="linkEditor-description-input">
- <div className="linkEditor-description-editing">
- <input
- style={{ width: "100%" }}
- autoComplete={"off"}
- id="input"
- value={this.description}
- placeholder={"Enter link description"}
- onKeyDown={this.onDescriptionKey}
- onChange={this.handleDescriptionChange}
- ></input>
+ return (
+ <div className="linkEditor-description">
+ <div className="linkEditor-description-label">Link Description:</div>
+ <div className="linkEditor-description-input">
+ <div className="linkEditor-description-editing">
+ <input style={{ width: '100%' }} autoComplete={'off'} id="input" value={this.description} placeholder={'Enter link description'} onKeyDown={this.onDescriptionKey} onChange={this.handleDescriptionChange}></input>
+ </div>
+ <div className="linkEditor-description-add-button" style={{ background: this.buttonColor }} onPointerDown={this.onDescriptionDown}>
+ Set
+ </div>
</div>
- <div className="linkEditor-description-add-button"
- style={{ background: this.buttonColor }}
- onPointerDown={this.onDescriptionDown}>Set</div>
</div>
- </div>;
+ );
}
@action
- changeDropdown = () => { this.openDropdown = !this.openDropdown; }
+ changeDropdown = () => {
+ this.openDropdown = !this.openDropdown;
+ };
@undoBatch
changeFollowBehavior = action((follow: string) => {
@@ -236,94 +240,114 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
@computed
get followingDropdown() {
- return <div className="linkEditor-followingDropdown">
- <div className="linkEditor-followingDropdown-label">Follow Behavior:</div>
- <div className="linkEditor-followingDropdown-dropdown">
- <div className="linkEditor-followingDropdown-header"
- onPointerDown={this.changeDropdown}>
- {StrCast(this.props.linkDoc.followLinkLocation, "default")}
- <FontAwesomeIcon className="linkEditor-followingDropdown-icon"
- icon={this.openDropdown ? "chevron-up" : "chevron-down"}
- size={"lg"} />
- </div>
- <div className="linkEditor-followingDropdown-optionsList"
- style={{ display: this.openDropdown ? "" : "none" }}>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("default")}>
- Default
+ return (
+ <div className="linkEditor-followingDropdown">
+ <div className="linkEditor-followingDropdown-label">Follow Behavior:</div>
+ <div className="linkEditor-followingDropdown-dropdown">
+ <div className="linkEditor-followingDropdown-header" onPointerDown={this.changeDropdown}>
+ {StrCast(this.props.linkDoc.followLinkLocation, 'default')}
+ <FontAwesomeIcon className="linkEditor-followingDropdown-icon" icon={this.openDropdown ? 'chevron-up' : 'chevron-down'} size={'lg'} />
</div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("add:left")}>
- Always open in new left pane
- </div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("add:right")}>
- Always open in new right pane
- </div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("replace:right")}>
- Always replace right tab
- </div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("replace:left")}>
- Always replace left tab
- </div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("fullScreen")}>
- Always open full screen
- </div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("add")}>
- Always open in a new tab
- </div>
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("replace")}>
- Replace Tab
- </div>
- {this.props.linkDoc.linksToAnnotation ?
- <div className="linkEditor-followingDropdown-option"
- onPointerDown={() => this.changeFollowBehavior("openExternal")}>
- Always open in external page
+ <div className="linkEditor-followingDropdown-optionsList" style={{ display: this.openDropdown ? '' : 'none' }}>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('default')}>
+ Default
+ </div>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('add:left')}>
+ Always open in new left pane
+ </div>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('add:right')}>
+ Always open in new right pane
+ </div>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('replace:right')}>
+ Always replace right tab
+ </div>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('replace:left')}>
+ Always replace left tab
</div>
- : null}
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('fullScreen')}>
+ Always open full screen
+ </div>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('add')}>
+ Always open in a new tab
+ </div>
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('replace')}>
+ Replace Tab
+ </div>
+ {this.props.linkDoc.linksToAnnotation ? (
+ <div className="linkEditor-followingDropdown-option" onPointerDown={() => this.changeFollowBehavior('openExternal')}>
+ Always open in external page
+ </div>
+ ) : null}
+ </div>
</div>
</div>
- </div>;
+ );
}
@action
- changeInfo = () => { this.showInfo = !this.showInfo; }
+ changeInfo = () => {
+ this.showInfo = !this.showInfo;
+ };
render() {
const destination = LinkManager.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
- return !destination ? (null) : (
+ return !destination ? null : (
<div className="linkEditor" tabIndex={0} onKeyDown={e => e.stopPropagation()}>
<div className="linkEditor-info">
- <Tooltip title={<><div className="dash-tooltip">Return to link menu</div></>} placement="top">
- <button className="linkEditor-button-back"
- style={{ display: this.props.hideback ? "none" : "" }}
- onClick={this.props.showLinks}>
- <FontAwesomeIcon icon="arrow-left" size="sm" /> </button>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">Return to link menu</div>
+ </>
+ }
+ placement="top">
+ <button className="linkEditor-button-back" style={{ display: this.props.hideback ? 'none' : '' }} onClick={this.props.showLinks}>
+ <FontAwesomeIcon icon="arrow-left" size="sm" />{' '}
+ </button>
</Tooltip>
- <p className="linkEditor-linkedTo">Editing Link to: <b>{
- destination.proto?.title ?? destination.title ?? "untitled"}</b></p>
- <Tooltip title={<><div className="dash-tooltip">Show more link information</div></>} placement="top">
- <div className="linkEditor-downArrow"><FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} /></div>
+ <p className="linkEditor-linkedTo">
+ Editing Link to: <b>{StrCast(destination.proto?.title, StrCast(destination.title, 'untitled'))}</b>
+ </p>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">Show more link information</div>
+ </>
+ }
+ placement="top">
+ <div className="linkEditor-downArrow">
+ <FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} />
+ </div>
</Tooltip>
</div>
- {this.showInfo ? <div className="linkEditor-moreInfo">
- <div>{this.props.linkDoc.author ? <div> <b>Author:</b> {this.props.linkDoc.author}</div> : null}</div>
- <div>{this.props.linkDoc.creationDate ? <div> <b>Creation Date:</b>
- {DateCast(this.props.linkDoc.creationDate).toString()}</div> : null}</div>
- </div> : null}
+ {this.showInfo ? (
+ <div className="linkEditor-moreInfo">
+ <div>
+ {this.props.linkDoc.author ? (
+ <div>
+ {' '}
+ <b>Author:</b> {StrCast(this.props.linkDoc.author)}
+ </div>
+ ) : null}
+ </div>
+ <div>
+ {this.props.linkDoc.creationDate ? (
+ <div>
+ {' '}
+ <b>Creation Date:</b>
+ {DateCast(this.props.linkDoc.creationDate).toString()}
+ </div>
+ ) : null}
+ </div>
+ </div>
+ ) : null}
{this.editDescription}
{this.editRelationship}
{this.editZoomFollow}
{this.followingDropdown}
</div>
-
);
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index a75e7a0c4..1e7f4f10b 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { action, observable } from 'mobx';
-import { observer } from "mobx-react";
+import { observer } from 'mobx-react';
import { Doc, DocListCast } from '../../../fields/Doc';
import { Cast, StrCast } from '../../../fields/Types';
import { WebField } from '../../../fields/URLField';
@@ -16,8 +16,7 @@ import { undoBatch } from '../../util/UndoManager';
import { DocumentView } from '../nodes/DocumentView';
import { LinkDocPreview } from '../nodes/LinkDocPreview';
import './LinkMenuItem.scss';
-import React = require("react");
-
+import React = require('react');
interface LinkMenuItemProps {
groupType: string;
@@ -50,22 +49,21 @@ export async function StartLinkTargetsDrag(dragEle: HTMLElement, docView: Docume
};
const containingView = docView.props.ContainingCollectionView;
const finishDrag = (e: DragManager.DragCompleteEvent) =>
- e.docDragData && (e.docDragData.droppedDocuments =
- dragData.draggedDocuments.reduce((droppedDocs, d) => {
- const dvs = DocumentManager.Instance.getDocumentViews(d).filter(dv => dv.props.ContainingCollectionView === containingView);
- if (dvs.length) {
- dvs.forEach(dv => droppedDocs.push(dv.props.Document));
- } else {
- droppedDocs.push(Doc.MakeAlias(d));
- }
- return droppedDocs;
- }, [] as Doc[]));
+ e.docDragData &&
+ (e.docDragData.droppedDocuments = dragData.draggedDocuments.reduce((droppedDocs, d) => {
+ const dvs = DocumentManager.Instance.getDocumentViews(d).filter(dv => dv.props.ContainingCollectionView === containingView);
+ if (dvs.length) {
+ dvs.forEach(dv => droppedDocs.push(dv.props.Document));
+ } else {
+ droppedDocs.push(Doc.MakeAlias(d));
+ }
+ return droppedDocs;
+ }, [] as Doc[]));
DragManager.StartDrag([dragEle], dragData, downX, downY, undefined, finishDrag);
}
}
-
@observer
export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
private _drag = React.createRef<HTMLDivElement>();
@@ -74,20 +72,31 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
_buttonRef = React.createRef<HTMLDivElement>();
@observable private _showMore: boolean = false;
- @action toggleShowMore(e: React.PointerEvent) { e.stopPropagation(); this._showMore = !this._showMore; }
+ @action toggleShowMore(e: React.PointerEvent) {
+ e.stopPropagation();
+ this._showMore = !this._showMore;
+ }
onEdit = (e: React.PointerEvent): void => {
LinkManager.currentLink = this.props.linkDoc;
- setupMoveUpEvents(this, e, e => {
- const dragData = new DragManager.DocumentDragData([this.props.linkDoc], "alias");
- dragData.removeDropProperties = ["hidden"];
- DragManager.StartDocumentDrag([this._editRef.current!], dragData, e.x, e.y);
- return true;
- }, emptyFunction, () => this.props.showEditor(this.props.linkDoc));
- }
+ setupMoveUpEvents(
+ this,
+ e,
+ e => {
+ const dragData = new DragManager.DocumentDragData([this.props.linkDoc], 'alias');
+ dragData.removeDropProperties = ['hidden'];
+ DragManager.StartDocumentDrag([this._editRef.current!], dragData, e.x, e.y);
+ return true;
+ },
+ emptyFunction,
+ () => this.props.showEditor(this.props.linkDoc)
+ );
+ };
onLinkButtonDown = (e: React.PointerEvent): void => {
- setupMoveUpEvents(this, e,
+ setupMoveUpEvents(
+ this,
+ e,
e => {
const eleClone: any = this._drag.current!.cloneNode(true);
eleClone.style.transform = `translate(${e.x}px, ${e.y}px)`;
@@ -99,109 +108,170 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
() => {
this.props.clearLinkEditor();
if (this.props.itemHandler) {
-
this.props.itemHandler?.(this.props.linkDoc);
} else {
- const focusDoc = Cast(this.props.linkDoc.anchor1, Doc, null)?.annotationOn === this.props.sourceDoc ? Cast(this.props.linkDoc.anchor1, Doc, null) :
- Cast(this.props.linkDoc.anchor2, Doc, null)?.annotationOn === this.props.sourceDoc ? Cast(this.props.linkDoc.anchor12, Doc, null) : undefined;
+ const focusDoc =
+ Cast(this.props.linkDoc.anchor1, Doc, null)?.annotationOn === this.props.sourceDoc
+ ? Cast(this.props.linkDoc.anchor1, Doc, null)
+ : Cast(this.props.linkDoc.anchor2, Doc, null)?.annotationOn === this.props.sourceDoc
+ ? Cast(this.props.linkDoc.anchor12, Doc, null)
+ : undefined;
if (focusDoc) this.props.docView.ComponentView?.scrollFocus?.(focusDoc, true);
LinkManager.FollowLink(this.props.linkDoc, this.props.sourceDoc, this.props.docView.props, false);
}
- });
- }
+ }
+ );
+ };
deleteLink = (e: React.PointerEvent): void => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => {
- this.props.linkDoc.linksToAnnotation && Hypothesis.deleteLink(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc);
- LinkManager.Instance.deleteLink(this.props.linkDoc);
- })));
- }
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ undoBatch(
+ action(() => {
+ this.props.linkDoc.linksToAnnotation && Hypothesis.deleteLink(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc);
+ LinkManager.Instance.deleteLink(this.props.linkDoc);
+ })
+ )
+ );
+ };
autoMove = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.props.linkDoc.linkAutoMove = !this.props.linkDoc.linkAutoMove)));
- }
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => (this.props.linkDoc.linkAutoMove = !this.props.linkDoc.linkAutoMove))));
+ };
showLink = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.props.linkDoc.linkDisplay = !this.props.linkDoc.linkDisplay)));
- }
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => (this.props.linkDoc.linkDisplay = !this.props.linkDoc.linkDisplay))));
+ };
showAnchor = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.props.linkDoc.hidden = !this.props.linkDoc.hidden)));
- }
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => (this.props.linkDoc.hidden = !this.props.linkDoc.hidden))));
+ };
render() {
const destinationIcon = Doc.toIcon(this.props.destinationDoc) as any as IconProp;
- const title = StrCast(this.props.destinationDoc.title).length > 18 ?
- StrCast(this.props.destinationDoc.title).substr(0, 14) + "..." : this.props.destinationDoc.title;
+ const title = StrCast(this.props.destinationDoc.title).length > 18 ? StrCast(this.props.destinationDoc.title).substr(0, 14) + '...' : this.props.destinationDoc.title;
// ...
// from anika to bob: here's where the text that is specifically linked would show up (linkDoc.storedText)
// ...
- const source = this.props.sourceDoc.type === DocumentType.RTF ? this.props.linkDoc.storedText ?
- StrCast(this.props.linkDoc.storedText).length > 17 ?
- StrCast(this.props.linkDoc.storedText).substr(0, 18)
- : this.props.linkDoc.storedText : undefined : undefined;
+ const source =
+ this.props.sourceDoc.type === DocumentType.RTF
+ ? this.props.linkDoc.storedText
+ ? StrCast(this.props.linkDoc.storedText).length > 17
+ ? StrCast(this.props.linkDoc.storedText).substr(0, 18)
+ : this.props.linkDoc.storedText
+ : undefined
+ : undefined;
return (
<div className="linkMenu-item">
- <div className={"linkMenu-item-content expand-two"}>
-
- <div ref={this._drag} className="linkMenu-name" //title="drag to view target. click to customize."
+ <div className={'linkMenu-item-content expand-two'}>
+ <div
+ ref={this._drag}
+ className="linkMenu-name" //title="drag to view target. click to customize."
onPointerLeave={LinkDocPreview.Clear}
- onPointerEnter={e => this.props.linkDoc && LinkDocPreview.SetLinkInfo({
- docProps: this.props.docView.props,
- linkSrc: this.props.sourceDoc,
- linkDoc: this.props.linkDoc,
- showHeader: false,
- location: [e.clientX, e.clientY + 20]
- })}
+ onPointerEnter={e =>
+ this.props.linkDoc &&
+ LinkDocPreview.SetLinkInfo({
+ docProps: this.props.docView.props,
+ linkSrc: this.props.sourceDoc,
+ linkDoc: this.props.linkDoc,
+ showHeader: false,
+ location: [e.clientX, e.clientY + 20],
+ })
+ }
onPointerDown={this.onLinkButtonDown}>
-
<div className="linkMenu-text">
- {source ? <p className="linkMenu-source-title"> <b>Source: {source}</b></p> : null}
+ {source ? (
+ <p className="linkMenu-source-title">
+ {' '}
+ <b>Source: {StrCast(source)}</b>
+ </p>
+ ) : null}
<div className="linkMenu-title-wrapper">
- <div className="destination-icon-wrapper" >
+ <div className="destination-icon-wrapper">
<FontAwesomeIcon className="destination-icon" icon={destinationIcon} size="sm" />
</div>
<p className="linkMenu-destination-title">
- {this.props.linkDoc.linksToAnnotation && Cast(this.props.destinationDoc.data, WebField)?.url.href === this.props.linkDoc.annotationUri ? "Annotation in" : ""} {title}
+ {this.props.linkDoc.linksToAnnotation && Cast(this.props.destinationDoc.data, WebField)?.url.href === this.props.linkDoc.annotationUri ? 'Annotation in' : ''} {StrCast(title)}
</p>
</div>
- {!this.props.linkDoc.description ? (null) : <p className="linkMenu-description">{StrCast(this.props.linkDoc.description)}</p>}
+ {!this.props.linkDoc.description ? null : <p className="linkMenu-description">{StrCast(this.props.linkDoc.description)}</p>}
</div>
- <div className="linkMenu-item-buttons" ref={this._buttonRef} >
-
- <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.hidden ? "Show Link Anchor" : "Hide Link Anchor"}</div></>}>
- <div className="button" ref={this._editRef} style={{ background: this.props.linkDoc.hidden ? "" : "#4476f7" /* $medium-blue */ }} onPointerDown={this.showAnchor} onClick={e => e.stopPropagation()}>
- <FontAwesomeIcon className="fa-icon" icon={"eye"} size="sm" /></div>
+ <div className="linkMenu-item-buttons" ref={this._buttonRef}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{this.props.linkDoc.hidden ? 'Show Link Anchor' : 'Hide Link Anchor'}</div>
+ </>
+ }>
+ <div className="button" ref={this._editRef} style={{ background: this.props.linkDoc.hidden ? '' : '#4476f7' /* $medium-blue */ }} onPointerDown={this.showAnchor} onClick={e => e.stopPropagation()}>
+ <FontAwesomeIcon className="fa-icon" icon={'eye'} size="sm" />
+ </div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.linkDisplay ? "Hide Link Line" : "Show Link Line"}</div></>}>
- <div className="button" ref={this._editRef} style={{ background: this.props.linkDoc.hidden ? "gray" : this.props.linkDoc.linkDisplay ? "#4476f7"/* $medium-blue */ : "" }} onPointerDown={this.showLink} onClick={e => e.stopPropagation()}>
- <FontAwesomeIcon className="fa-icon" icon={"project-diagram"} size="sm" /></div>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{this.props.linkDoc.linkDisplay ? 'Hide Link Line' : 'Show Link Line'}</div>
+ </>
+ }>
+ <div
+ className="button"
+ ref={this._editRef}
+ style={{ background: this.props.linkDoc.hidden ? 'gray' : this.props.linkDoc.linkDisplay ? '#4476f7' /* $medium-blue */ : '' }}
+ onPointerDown={this.showLink}
+ onClick={e => e.stopPropagation()}>
+ <FontAwesomeIcon className="fa-icon" icon={'project-diagram'} size="sm" />
+ </div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.linkAutoMove ? "Click to freeze link anchor position" : "Click to auto move link anchor"}</div></>}>
- <div className="button" ref={this._editRef} style={{ background: this.props.linkDoc.hidden ? "gray" : !this.props.linkDoc.linkAutoMove ? "" : "#4476f7" /* $medium-blue */ }} onPointerDown={this.autoMove} onClick={e => e.stopPropagation()}>
- <FontAwesomeIcon className="fa-icon" icon={"play"} size="sm" /></div>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">{this.props.linkDoc.linkAutoMove ? 'Click to freeze link anchor position' : 'Click to auto move link anchor'}</div>
+ </>
+ }>
+ <div
+ className="button"
+ ref={this._editRef}
+ style={{ background: this.props.linkDoc.hidden ? 'gray' : !this.props.linkDoc.linkAutoMove ? '' : '#4476f7' /* $medium-blue */ }}
+ onPointerDown={this.autoMove}
+ onClick={e => e.stopPropagation()}>
+ <FontAwesomeIcon className="fa-icon" icon={'play'} size="sm" />
+ </div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">Edit Link</div></>}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">Edit Link</div>
+ </>
+ }>
<div className="button" ref={this._editRef} onPointerDown={this.onEdit} onClick={e => e.stopPropagation()}>
- <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
+ <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" />
+ </div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">Delete Link</div></>}>
+ <Tooltip
+ title={
+ <>
+ <div className="dash-tooltip">Delete Link</div>
+ </>
+ }>
<div className="button" onPointerDown={this.deleteLink} onClick={e => e.stopPropagation()}>
- <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+ <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" />
+ </div>
</Tooltip>
</div>
</div>
</div>
-
- </div >
+ </div>
);
}
-} \ No newline at end of file
+}