diff options
Diffstat (limited to 'src/client/views/DocumentButtonBar.tsx')
-rw-r--r-- | src/client/views/DocumentButtonBar.tsx | 159 |
1 files changed, 95 insertions, 64 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 15ce4c15f..487868169 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,37 +1,42 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ import { IconLookup, IconProp } from '@fortawesome/fontawesome-svg-core'; +import { faCalendarDays } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, makeObservable, observable, runInAction } from 'mobx'; +import { Popup } from 'browndash-components'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../Utils'; +import { FaEdit } from 'react-icons/fa'; +import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../ClientUtils'; +import { emptyFunction } from '../../Utils'; import { Doc } from '../../fields/Doc'; import { Cast, DocCast } from '../../fields/Types'; -import { DocUtils } from '../documents/Documents'; +import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils'; import { CalendarManager } from '../util/CalendarManager'; -import { DragManager, dropActionType } from '../util/DragManager'; -import { IsFollowLinkScript } from '../util/LinkFollower'; -import { SelectionManager } from '../util/SelectionManager'; +import { DictationManager } from '../util/DictationManager'; +import { DragManager } from '../util/DragManager'; +import { dropActionType } from '../util/DropActionTypes'; import { SharingManager } from '../util/SharingManager'; import { UndoManager, undoBatch } from '../util/UndoManager'; import './DocumentButtonBar.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; -import { TabDocView } from './collections/TabDocView'; +import { PinProps } from './PinFuncs'; +import { TemplateMenu } from './TemplateMenu'; import { Colors } from './global/globalEnums'; import { LinkPopup } from './linking/LinkPopup'; import { DocumentLinksButton } from './nodes/DocumentLinksButton'; -import { DocumentView, DocumentViewInternal, OpenWhere } from './nodes/DocumentView'; +import { DocumentView } from './nodes/DocumentView'; +import { OpenWhere } from './nodes/OpenWhere'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; -import { PinProps } from './nodes/trails'; -import { faCalendarDays } from '@fortawesome/free-solid-svg-icons'; -import { Popup } from 'browndash-components'; -import { TemplateMenu } from './TemplateMenu'; -import { FaEdit } from 'react-icons/fa'; @observer export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: any }> { private _dragRef = React.createRef<HTMLDivElement>(); - @observable public static Instance: DocumentButtonBar; + // eslint-disable-next-line no-use-before-define + public static Instance: DocumentButtonBar; constructor(props: any) { super(props); @@ -43,7 +48,6 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( return this._props.views()?.[0]; } - @observable subFollow = ''; @computed get followLinkButton() { const targetDoc = this.view0?.Document; @@ -58,8 +62,12 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( key={icon.toString()} size="sm" icon={icon} - onPointerEnter={action(e => (this.subPin = allDocs ? 'All ' : ''))} - onPointerLeave={action(e => (this.subPin = ''))} + onPointerEnter={action(() => { + this.subPin = allDocs ? 'All ' : ''; + })} + onPointerLeave={action(() => { + this.subPin = ''; + })} onClick={e => { this._props.views().forEach(dv => click(dv!.Document)); e.stopPropagation(); @@ -75,12 +83,14 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( <div className="documentButtonBar-icon documentButtonBar-follow" style={{ backgroundColor: followLink ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: followLink ? Colors.BLACK : Colors.WHITE }} - onClick={undoBatch(e => this._props.views().map(view => view?.toggleFollowLink(undefined, false)))}> + onClick={undoBatch(() => this._props.views().map(view => view?.toggleFollowLink(undefined, false)))}> <div className="documentButtonBar-followTypes"> {followBtn( true, - (doc: Doc) => (doc.followAllLinks = !doc.followAllLinks), - (doc?: Doc) => (doc?.followAllLinks ? true : false), + (doc: Doc) => { + doc.followAllLinks = !doc.followAllLinks; + }, + (doc?: Doc) => !!doc?.followAllLinks, 'window-maximize' )} </div> @@ -98,22 +108,22 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( <div className="documentButtonBar-linkTypes"> <Tooltip title={<div>search for target</div>}> <div className="documentButtonBar-button"> - <button style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleLinkSearch}> - <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(1.5)' }} icon={'search'} size="lg" /> - <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(0.5)', transformOrigin: 'center', top: 9, left: 2 }} icon={'link'} size="lg" /> + <button type="button" style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleLinkSearch}> + <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(1.5)' }} icon="search" size="lg" /> + <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(0.5)', transformOrigin: 'center', top: 9, left: 2 }} icon="link" size="lg" /> </button> </div> </Tooltip> <Tooltip title={<div>open linked trail</div>}> <div className="documentButtonBar-button"> - <button style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleTrail}> + <button type="button" style={{ backgroundColor: 'transparent', width: 35, height: 35, display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative' }} onPointerDown={this.toggleTrail}> <FontAwesomeIcon icon="taxi" size="lg" /> </button> </div> </Tooltip> </div> <div style={{ width: 25, height: 25 }}> - <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={true} /> + <DocumentLinksButton View={this.view0} AlwaysOn InMenu StartLink /> </div> </div> ); @@ -132,8 +142,12 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( key={icon.toString()} size="sm" icon={icon} - onPointerEnter={action(e => (this.subEndLink = (pinLayout ? 'Layout' : '') + (pinLayout && pinContent ? ' &' : '') + (pinContent ? ' Content' : '')))} - onPointerLeave={action(e => (this.subEndLink = ''))} + onPointerEnter={action(() => { + this.subEndLink = (pinLayout ? 'Layout' : '') + (pinLayout && pinContent ? ' &' : '') + (pinContent ? ' Content' : ''); + })} + onPointerLeave={action(() => { + this.subEndLink = ''; + })} onClick={e => { this.view0 && DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.view0.Document, true, this.view0, { @@ -155,7 +169,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( {linkBtn(false, true, 'address-card')} {linkBtn(true, true, 'id-card')} </div> - <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} /> + <DocumentLinksButton View={this.view0} AlwaysOn InMenu StartLink={false} /> </div> ); } @@ -175,21 +189,22 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( key={icon.toString()} size="sm" icon={icon} - onPointerEnter={action( - e => - (this.subPin = - (pinLayoutView ? 'Layout' : '') + - (pinLayoutView && pinContentView ? ' &' : '') + - (pinContentView ? ' Content View' : '') + - (pinLayoutView && pinContentView ? '(shift+alt)' : pinLayoutView ? '(shift)' : pinContentView ? '(alt)' : '')) - )} - onPointerLeave={action(e => (this.subPin = ''))} + onPointerEnter={action(() => { + this.subPin = + (pinLayoutView ? 'Layout' : '') + + (pinLayoutView && pinContentView ? ' &' : '') + + (pinContentView ? ' Content View' : '') + + (pinLayoutView && pinContentView ? '(shift+alt)' : pinLayoutView ? '(shift)' : pinContentView ? '(alt)' : ''); + })} + onPointerLeave={action(() => { + this.subPin = ''; + })} onClick={e => { const docs = this._props .views() .filter(v => v) .map(dv => dv!.Document); - TabDocView.PinDoc(docs, { + DocumentView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: pinLayoutView, pinData: { dataview: pinContentView }, @@ -204,7 +219,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( ); }; return !targetDoc ? null : ( - <Tooltip title={<div className="dash-tooltip">{`Pin Document ${SelectionManager.Views.length > 1 ? 'multiple documents' : ''} to Trail`}</div>}> + <Tooltip title={<div className="dash-tooltip">{`Pin Document ${DocumentView.Selected().length > 1 ? 'multiple documents' : ''} to Trail`}</div>}> <div className="documentButtonBar-icon documentButtonBar-pin" onClick={e => { @@ -212,7 +227,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( .views() .filter(v => v) .map(dv => dv!.Document); - TabDocView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) }); + DocumentView.PinDoc(docs, { pinAudioPlay: true, pinDocLayout: e.shiftKey, pinData: { dataview: e.altKey }, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) }); e.stopPropagation(); }}> <div className="documentButtonBar-pinTypes"> @@ -230,8 +245,8 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( get shareButton() { const targetDoc = this.view0?.Document; return !targetDoc ? null : ( - <Tooltip title={<div className="dash-tooltip">{'Open Sharing Manager'}</div>}> - <div className="documentButtonBar-icon" style={{ color: 'white' }} onClick={e => SharingManager.Instance.open(this.view0, targetDoc)}> + <Tooltip title={<div className="dash-tooltip">Open Sharing Manager</div>}> + <div className="documentButtonBar-icon" style={{ color: 'white' }} onClick={() => SharingManager.Instance.open(this.view0, targetDoc)}> <FontAwesomeIcon className="documentdecorations-icon" icon="users" /> </div> </Tooltip> @@ -242,8 +257,8 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( get menuButton() { const targetDoc = this.view0?.Document; return !targetDoc ? null : ( - <Tooltip title={<div className="dash-tooltip">{`Open Context Menu`}</div>}> - <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => this.openContextMenu(e))}> + <Tooltip title={<div className="dash-tooltip">Open Context Menu</div>}> + <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => this.openContextMenu(clickEv))}> <FontAwesomeIcon className="documentdecorations-icon" icon="bars" /> </div> </Tooltip> @@ -258,8 +273,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( <div className="documentButtonBar-icon" style={{ color: 'white' }} - onClick={e => { - console.log('hi: ', CalendarManager.Instance); + onClick={() => { CalendarManager.Instance.open(this.view0, targetDoc); }}> <FontAwesomeIcon className="documentdecorations-icon" icon={faCalendarDays as IconLookup} /> @@ -280,7 +294,18 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( style={{ backgroundColor: this._isRecording ? Colors.ERROR_RED : Colors.DARK_GRAY, color: Colors.WHITE }} onPointerDown={action((e: React.PointerEvent) => { this._isRecording = true; - this._props.views().map(view => view && DocumentViewInternal.recordAudioAnnotation(view.dataDoc, view.LayoutFieldKey, stopFunc => (this._stopFunc = stopFunc), emptyFunction)); + this._props.views().map( + view => + view && + DictationManager.recordAudioAnnotation( + view.dataDoc, + view.LayoutFieldKey, + stopFunc => { + this._stopFunc = stopFunc; + }, + emptyFunction + ) + ); const b = UndoManager.StartBatch('Recording'); setupMoveUpEvents( this, @@ -308,10 +333,10 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( if (this._dragRef.current) { const dragDocView = this.view0!; const dragData = new DragManager.DocumentDragData([dragDocView.Document]); - const [left, top] = dragDocView.screenToContentsTransform().inverse().transformPoint(0, 0); + const origin = dragDocView.screenToContentsTransform().inverse().transformPoint(0, 0); dragData.defaultDropAction = dropActionType.embed; dragData.canEmbed = true; - DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { hideSource: false }); + DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, origin[0], origin[1], { hideSource: false }); return true; } return false; @@ -334,8 +359,19 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( @computed get templateButton() { return !this.view0 ? null : ( - <Tooltip title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom"> - <div className="documentButtonBar-linkFlyout" ref={this._dragRef} onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}> + <Tooltip + title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>} + open={this._tooltipOpen} + onClose={action(() => { + this._tooltipOpen = false; + })} + placement="bottom"> + <div + className="documentButtonBar-linkFlyout" + ref={this._dragRef} + onPointerEnter={action(() => { + !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true); + })}> <Popup icon={<FaEdit />} popup={this.templateMenu} popupContainsPt={returnTrue} /> </div> </Tooltip> @@ -343,7 +379,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( } openContextMenu = (e: PointerEvent) => { - let child = SelectionManager.Views[0].ContentDiv!.children[0]; + let child = DocumentView.Selected()[0].ContentDiv!.children[0]; while (child.children.length) { const next = Array.from(child.children).find(c => c.className?.toString().includes('SVGAnimatedString') || typeof c.className === 'string'); if (next?.className?.toString().includes(DocumentView.ROOT_DIV)) break; @@ -363,17 +399,17 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( @observable _captureEndLinkLayout = false; @action - captureEndLinkLayout = (e: React.PointerEvent) => { + captureEndLinkLayout = () => { this._captureEndLinkLayout = !this._captureEndLinkLayout; }; @observable _captureEndLinkContent = false; @action - captureEndLinkContent = (e: React.PointerEvent) => { + captureEndLinkContent = () => { this._captureEndLinkContent = !this._captureEndLinkContent; }; @action - captureEndLinkState = (e: React.PointerEvent) => { + captureEndLinkState = () => { this._captureEndLinkContent = this._captureEndLinkLayout = !this._captureEndLinkLayout; }; @@ -400,16 +436,11 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( return ( <div className="documentButtonBar"> <div className="documentButtonBar-button"> - <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} ShowCount={true} /> + <DocumentLinksButton View={this.view0} AlwaysOn InMenu ShowCount /> </div> {this._showLinkPopup ? ( <div style={{ position: 'absolute', zIndex: 1000 }}> - <LinkPopup - key="popup" - linkCreated={link => (link.link_displayLine = !IsFollowLinkScript(this._props.views().lastElement()?.Document.onClick))} - linkCreateAnchor={() => this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)} - linkFrom={() => this._props.views().lastElement()?.Document} - /> + <LinkPopup key="popup" linkCreated={emptyFunction} linkCreateAnchor={() => this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)} linkFrom={() => this._props.views().lastElement()?.Document} /> </div> ) : ( <div className="documentButtonBar-button">{this.linkButton}</div> @@ -417,11 +448,11 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== doc ? <div className="documentButtonBar-button">{this.endLinkButton} </div> : null} <div className="documentButtonBar-button">{this.templateButton}</div> - {!SelectionManager.Views?.some(v => v.allLinks.length) ? null : <div className="documentButtonBar-button">{this.followLinkButton}</div>} + {!DocumentView.Selected().some(v => v.allLinks.length) ? null : <div className="documentButtonBar-button">{this.followLinkButton}</div>} <div className="documentButtonBar-button">{this.pinButton}</div> <div className="documentButtonBar-button">{this.recordButton}</div> <div className="documentButtonBar-button">{this.calendarButton}</div> - {!Doc.UserDoc()['documentLinksButton-fullMenu'] ? null : <div className="documentButtonBar-button">{this.shareButton}</div>} + {!Doc.UserDoc().documentLinksButton_fullMenu ? null : <div className="documentButtonBar-button">{this.shareButton}</div>} <div className="documentButtonBar-button">{this.menuButton}</div> </div> ); |