diff options
Diffstat (limited to 'src/client/views/linking')
-rw-r--r-- | src/client/views/linking/LinkEditor.scss | 88 | ||||
-rw-r--r-- | src/client/views/linking/LinkEditor.tsx | 69 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenu.scss | 75 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenu.tsx | 26 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuGroup.tsx | 2 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuItem.scss | 69 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuItem.tsx | 40 |
7 files changed, 283 insertions, 86 deletions
diff --git a/src/client/views/linking/LinkEditor.scss b/src/client/views/linking/LinkEditor.scss index 406a38c26..87afc99eb 100644 --- a/src/client/views/linking/LinkEditor.scss +++ b/src/client/views/linking/LinkEditor.scss @@ -3,12 +3,12 @@ .linkEditor { width: 100%; height: auto; - font-size: 12px; // TODO + font-size: 13px; // TODO user-select: none; } .linkEditor-button-back { - margin-bottom: 6px; + //margin-bottom: 6px; border-radius: 10px; width: 18px; height: 18px; @@ -17,12 +17,13 @@ .linkEditor-info { //border-bottom: 0.5px solid $light-color-secondary; - padding-bottom: 4px; + //padding-bottom: 1px; padding-top: 5px; padding-left: 5px; //margin-bottom: 6px; display: flex; justify-content: space-between; + color: black; .linkEditor-linkedTo { width: calc(100% - 26px); @@ -31,30 +32,69 @@ } } +.linkEditor-moreInfo { + margin-left: 12px; + padding-left: 13px; + padding-right: 6.5px; + padding-bottom: 4px; + font-size: 9px; + //font-style: italic; + text-decoration-color: grey; + + .button { + color: black; + } +} + .linkEditor-description { padding-left: 6.5px; padding-right: 6.5px; padding-bottom: 3.5px; - .linkEditor-description-text { - text-decoration-color: grey; + .linkEditor-description-label { + text-decoration-color: black; + color: black; } .linkEditor-description-input { - border: 1px solid grey; - border-radius: 4px; - background-color: rgb(236, 236, 236); - padding-left: 2px; - padding-right: 2px; - color: grey; - text-decoration-color: grey; + display: flex; + + .linkEditor-description-editing { + min-width: 85%; + //border: 1px solid grey; + //border-radius: 4px; + padding-left: 2px; + padding-right: 2px; + //margin-right: 4px; + color: black; + text-decoration-color: grey; + } + + .linkEditor-description-add-button { + display: inline; + /* float: right; */ + border-radius: 7px; + font-size: 9px; + background-color: black; + /* padding: 3px; */ + padding-top: 4px; + padding-left: 7px; + padding-bottom: 4px; + padding-right: 8px; + height: 80%; + color: white; + } } } .linkEditor-followingDropdown { padding-left: 6.5px; padding-right: 6.5px; - padding-bottom: 3.5px; + padding-bottom: 6px; + + .linkEditor-followingDropdown-label { + color: black; + } .linkEditor-followingDropdown-dropdown { @@ -62,14 +102,15 @@ border: 1px solid grey; border-radius: 4px; - background-color: rgb(236, 236, 236); + //background-color: rgb(236, 236, 236); padding-left: 2px; padding-right: 2px; - color: grey; - text-decoration-color: grey; + text-decoration-color: black; + color: rgb(94, 94, 94); .linkEditor-followingDropdown-icon { float: right; + color: black; } } @@ -77,17 +118,22 @@ padding-left: 3px; padding-right: 3px; + &:last-child { + border-bottom: none; + } + .linkEditor-followingDropdown-option { - border: 0.25px dotted grey; - background-color: rgb(236, 236, 236); + border: 0.25px solid grey; + //background-color: rgb(236, 236, 236); padding-left: 2px; padding-right: 2px; color: grey; text-decoration-color: grey; font-size: 9px; + border-top: none; &:hover { - background-color: rgb(211, 210, 210); + background-color: rgb(187, 220, 231); } } @@ -98,6 +144,10 @@ } + + + + .linkEditor-button, .linkEditor-addbutton { width: 18px; diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 014d57ed0..a26685318 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -1,10 +1,10 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faArrowLeft, faCog, faEllipsisV, faExchangeAlt, faPlus, faTable, faTimes, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, observable, computed } from "mobx"; +import { action, observable, computed, toJS } from "mobx"; import { observer } from "mobx-react"; import { Doc, Opt } from "../../../fields/Doc"; -import { StrCast } from "../../../fields/Types"; +import { StrCast, DateCast } from "../../../fields/Types"; import { Utils } from "../../../Utils"; import { LinkManager } from "../../util/LinkManager"; import './LinkEditor.scss'; @@ -291,6 +291,10 @@ export class LinkEditor extends React.Component<LinkEditorProps> { @observable followBehavior = this.props.linkDoc.follow ? this.props.linkDoc.follow : "Default"; + @observable showInfo: boolean = false; + + @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; } + //@observable description = this.props.linkDoc.description ? StrCast(this.props.linkDoc.description) : "DESCRIPTION"; @@ -308,19 +312,45 @@ export class LinkEditor extends React.Component<LinkEditorProps> { } } + @action + onKey = (e: React.KeyboardEvent<HTMLInputElement>) => { + if (e.key === "Enter") { + this.setDescripValue(this.description); + document.getElementById('input')?.blur(); + } + } + + @action + onDown = () => { + this.setDescripValue(this.description); + } + + @action + handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { + this.description = e.target.value; + } + + @computed get editDescription() { return <div className="linkEditor-description"> <div className="linkEditor-description-label"> - Link Description:</div> + Link Label:</div> <div className="linkEditor-description-input"> - <EditableView - GetValue={() => StrCast(LinkManager.currentLink?.description)} - SetValue={value => { this.setDescripValue(value); return false; }} - contents={LinkManager.currentLink?.description} - placeholder={"(optional) enter link description"} - color={"rgb(88, 88, 88)"} - ></EditableView></div></div>; + <div className="linkEditor-description-editing"> + <input + style={{ width: "100%" }} + id="input" + value={this.description} + placeholder={"enter link label"} + // color={"rgb(88, 88, 88)"} + onKeyDown={this.onKey} + onChange={this.handleChange} + ></input> + </div> + <div className="linkEditor-description-add-button" + onPointerDown={this.onDown}>Add</div> + </div></div>; } @action @@ -346,7 +376,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> { {this.followBehavior} <FontAwesomeIcon className="linkEditor-followingDropdown-icon" icon={this.openDropdown ? "chevron-up" : "chevron-down"} - size={"lg"} onPointerDown={this.changeDropdown} /> + size={"lg"} /> </div> <div className="linkEditor-followingDropdown-optionsList" style={{ display: this.openDropdown ? "" : "none" }}> @@ -367,6 +397,11 @@ export class LinkEditor extends React.Component<LinkEditorProps> { </div>; } + @action + changeInfo = () => { + this.showInfo = !this.showInfo; + } + render() { const destination = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc); @@ -382,11 +417,17 @@ export class LinkEditor extends React.Component<LinkEditorProps> { style={{ display: this.props.hideback ? "none" : "" }} onClick={this.props.showLinks}> <FontAwesomeIcon icon="arrow-left" size="sm" /> </button> - <p className="linkEditor-linkedTo">editing link to: <b>{ + <p className="linkEditor-linkedTo">Editing Link to: <b>{ destination.proto?.title ?? destination.title ?? "untitled"}</b></p> - <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link"> - <FontAwesomeIcon icon="trash" size="sm" /></button> + {/* <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link"> + <FontAwesomeIcon icon="trash" size="sm" /></button> */} + <FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} /> </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} <div>{this.editDescription}</div> <div>{this.followingDropdown}</div> diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss index 4b1a3f425..4f7ac3275 100644 --- a/src/client/views/linking/LinkMenu.scss +++ b/src/client/views/linking/LinkMenu.scss @@ -1,33 +1,64 @@ @import "../globalCssVariables"; .linkMenu { - width: 100%; + width: auto; height: auto; - //border: 1px solid black; - &:hover { - width: calc(auto + 26px); + + .linkMenu-list { + + display: inline-block; + + border: 1px solid black; + + box-shadow: 3px 3px 1.5px grey; + + max-height: 170px; + overflow-y: scroll; + position: relative; + z-index: 10; + background: white; + min-width: 170px; + //border-radius: 5px; + //padding-top: 6.5px; + //padding-bottom: 6.5px; + //padding-left: 6.5px; + //padding-right: 2px; + //width: calc(auto + 50px); + + white-space: nowrap; + + overflow-x: hidden; + + &:last-child { + border-bottom: none; + } + + &:hover { + padding-right: 65px; + display: inline-block; + } } -} -.linkMenu-list { - border: 1px solid black; - max-height: 200px; - overflow-y: scroll; - position: absolute; - z-index: 10; - background: white; - min-width: 150px; - border-radius: 5px; - padding-top: 6.5px; - padding-bottom: 6.5px; - padding-left: 6.5px; - padding-right: 2px; - //width: calc(auto + 50px); + .linkMenu-listEditor { + + display: inline-block; + + border: 1px solid black; + + box-shadow: 3px 3px 1.5px grey; + + max-height: 170px; + overflow-y: scroll; + position: relative; + z-index: 10; + background: white; + min-width: 170px; + } } .linkMenu-group { - //border-bottom: 0.5px solid lightgray; + border-bottom: 0.5px solid lightgray; //@extend: 5px 0; @@ -46,7 +77,7 @@ } p.expand-one { - width: calc(100% + 26px); + width: calc(100% + 20px); } .linkEditor-tableButton { @@ -56,7 +87,7 @@ p { width: 100%; - padding: 4px 6px; + //padding: 4px 6px; line-height: 12px; border-radius: 5px; font-weight: bold; diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 8a7b12f48..234cd5e07 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -1,4 +1,4 @@ -import { action, observable } from "mobx"; +import { action, observable, computed } from "mobx"; import { observer } from "mobx-react"; import { DocumentView } from "../nodes/DocumentView"; import { LinkEditor } from "./LinkEditor"; @@ -29,6 +29,15 @@ export class LinkMenu extends React.Component<Props> { @observable private _linkMenuRef = React.createRef<HTMLDivElement>(); private _editorRef = React.createRef<HTMLDivElement>(); + //@observable private _numLinks: number = 0; + + // @computed get overflow() { + // if (this._numLinks) { + // return "scroll"; + // } + // return "auto"; + // } + @action onClick = (e: PointerEvent) => { @@ -81,13 +90,16 @@ export class LinkMenu extends React.Component<Props> { const sourceDoc = this.props.docView.props.Document; const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc); return <div className="linkMenu" ref={this._linkMenuRef} > - <div className="linkMenu-list" - style={{ left: this.props.location[0], top: this.props.location[1] }}> - {!this._editingLink ? - this.renderAllGroups(groups) : + {!this._editingLink ? <div className="linkMenu-list" style={{ + left: this.props.location[0], top: this.props.location[1] }}> + {this.renderAllGroups(groups)} + </div> : <div className="linkMenu-listEditor" style={{ + left: this.props.location[0], top: this.props.location[1]}}> <LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)} /> - } - </div> </div>; + </div> + } + + </div>; } }
\ No newline at end of file diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index ec17776e3..2f6b75437 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -82,11 +82,13 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> { return ( <div className="linkMenu-group" ref={this._menuRef}> + {/* <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> diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss index 67bf71fb9..e444b832b 100644 --- a/src/client/views/linking/LinkMenuItem.scss +++ b/src/client/views/linking/LinkMenuItem.scss @@ -4,6 +4,13 @@ // border-top: 0.5px solid $main-accent; position: relative; display: flex; + border-bottom: 0.5px solid black; + + padding-left: 6.5px; + padding-right: 2px; + + padding-top: 6.5px; + padding-bottom: 6.5px; .linkMenu-name { @@ -14,11 +21,35 @@ padding: 4px 2px; //display: inline; - .linkMenu-destination-title { + .linkMenu-source-title { text-decoration: none; - color: rgb(85, 120, 196); - font-size: 14px; - padding-bottom: 2px; + color: rgb(43, 43, 43); + font-size: 7px; + padding-bottom: 0.75px; + } + + + .linkMenu-title-wrapper { + + display: flex; + + .destination-icon { + float: left; + width: 12px; + height: 12px; + padding-right: 3px; + margin-right: 3px; + } + + .linkMenu-destination-title { + text-decoration: none; + color: rgb(85, 120, 196); + font-size: 14px; + padding-bottom: 2px; + padding-right: 4px; + margin-right: 4px; + float: right; + } } .linkMenu-description { @@ -29,12 +60,16 @@ } p { - //padding: 4px 2px; + padding-right: 4px; line-height: 12px; border-radius: 5px; - overflow-wrap: break-word; + //overflow-wrap: break-word; user-select: none; } + + &:hover { + padding-right: 8px; + } } } @@ -53,6 +88,7 @@ &:hover { + width: calc(100% + 58px); .linkMenu-item-buttons { display: flex; @@ -67,19 +103,13 @@ text-overflow: break; } - &.expand-two p { - width: calc(100% - 52px); - //text-decoration: underline; - //color: rgb(15, 57, 148); - //background-color: lightgray; - } + // &.expand-two p { + // width: calc(100% - 63px); + // } - &.expand-three p { - width: calc(100% - 84px); - //text-decoration: underline; - //color: rgb(15, 57, 148); - //background-color: lightgray; - } + // &.expand-three p { + // width: calc(100% - 93px); + // } } } } @@ -96,7 +126,8 @@ width: 20px; height: 20px; margin: 0; - margin-right: 6px; + margin-right: 4px; + padding-right: 6px; border-radius: 50%; pointer-events: auto; background-color: $dark-color; diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 6af474513..d2363c7d3 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -1,5 +1,5 @@ import { library } from '@fortawesome/fontawesome-svg-core'; -import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt } from '@fortawesome/free-solid-svg-icons'; +import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt, faEyeSlash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from "mobx-react"; @@ -15,7 +15,7 @@ import { setupMoveUpEvents, emptyFunction } from '../../../Utils'; import { DocumentView } from '../nodes/DocumentView'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; -library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt); +library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash); interface LinkMenuItemProps { @@ -78,7 +78,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { @action toggleShowMore(e: React.PointerEvent) { e.stopPropagation(); this._showMore = !this._showMore; } onEdit = (e: React.PointerEvent): void => { + + console.log("Edit"); LinkManager.currentLink = this.props.linkDoc; + console.log(this.props.linkDoc); setupMoveUpEvents(this, e, this.editMoved, emptyFunction, () => this.props.showEditor(this.props.linkDoc)); } @@ -176,9 +179,28 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType); const canExpand = keys ? keys.length > 0 : false; + const eyeIcon = this.props.linkDoc.shown ? "eye-slash" : "eye"; + + const destinationIcon = this.props.destinationDoc.type === "image" ? "image" : + this.props.destinationDoc.type === "comparison" ? "columns" : + this.props.destinationDoc.type === "rtf" ? "font" : + this.props.destinationDoc.type === "collection" ? "folder" : + this.props.destinationDoc.type === "web" ? "globe-asia" : + this.props.destinationDoc.type === "screenshot" ? "photo-video" : + this.props.destinationDoc.type === "webcam" ? "video" : + this.props.destinationDoc.type === "audio" ? "microphone" : + this.props.destinationDoc.type === "button" ? "lightning" : + this.props.destinationDoc.type === "presentation" ? "tv" : + this.props.destinationDoc.type === "query" ? "search" : + this.props.destinationDoc.type === "script" ? "terminal" : + this.props.destinationDoc.type === "import" ? "cloud-upload-alt" : + this.props.destinationDoc.type === "docholder" ? "expand" : "question"; + + return ( <div className="linkMenu-item"> <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}> + <div ref={this._drag} className="linkMenu-name" //title="drag to view target. click to customize." onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)} onPointerEnter={action(e => this.props.linkDoc && (LinkDocPreview.LinkInfo = { @@ -190,9 +212,14 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { onPointerDown={this.onLinkButtonDown}> <div className="linkMenu-text"> - <p className="linkMenu-destination-title" - onPointerDown={this.followDefault}> - {StrCast(this.props.destinationDoc.title)}</p> + {this.props.linkDoc.linkedText ? <p className="linkMenu-source-title"> + Source: <b>{StrCast(this.props.linkDoc.linkedText)}</b></p> : null} + <div className="linkMenu-title-wrapper"> + <FontAwesomeIcon className="destination-icon" icon={destinationIcon} size="sm" /> + <p className="linkMenu-destination-title" + onPointerDown={this.followDefault}> + {StrCast(this.props.destinationDoc.title)}</p> + </div> {this.props.linkDoc.description !== "" ? <p className="linkMenu-description"> {StrCast(this.props.linkDoc.description)}</p> : null} </div> @@ -200,6 +227,9 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { {canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}> <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>} + <div title="Show link" className="button" ref={this._editRef} onPointerDown={emptyFunction}> + <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div> + <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}> <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div> <div title="Delete link" className="button" onPointerDown={this.deleteLink}> |