diff options
Diffstat (limited to 'src/client/views')
21 files changed, 354 insertions, 394 deletions
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 1fffb3dbc..8412a9aae 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -192,11 +192,11 @@ export class ContextMenu extends React.Component { } return this.filteredItems.map((value, index) => Array.isArray(value) ? ( - <div className="contextMenu-group" + <div + className="contextMenu-group" style={{ - background: StrCast(Doc.UserDoc().userVariantColor) - }} - > + background: StrCast(Doc.UserDoc().userVariantColor), + }}> <div className="contextMenu-description">{value.join(' -> ')}</div> </div> ) : ( @@ -219,17 +219,18 @@ export class ContextMenu extends React.Component { this._height = Number(getComputedStyle(r).height.replace('px', '')); } })} - style={{ - left: this.pageX, ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }), + style={{ + left: this.pageX, + ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }), background: StrCast(Doc.UserDoc().userBackgroundColor), - color: StrCast(Doc.UserDoc().userColor) + color: StrCast(Doc.UserDoc().userColor), }}> {!this.itemsNeedSearch ? null : ( <span className={'search-icon'}> <span className="icon-background"> <FontAwesomeIcon icon="search" size="lg" /> </span> - <input className="contextMenu-item contextMenu-description search" type="text" placeholder="Filter Menu..." value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} autoFocus /> + <input style={{ color: 'black' }} className="contextMenu-item contextMenu-description search" type="text" placeholder="Filter Menu..." value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} autoFocus /> </span> )} {this.menuItems} diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 1a5781df0..ae55c8ebf 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -199,7 +199,7 @@ export class DashboardView extends React.Component { <div className="dashboard-container" key={dashboard[Id]} - style={{ background: this.isUnviewedSharedDashboard(dashboard) && this.selectedDashboardGroup === DashboardGroup.SharedDashboards ? 'green' : shared ? 'blue' : '' }} + style={{ background: this.isUnviewedSharedDashboard(dashboard) && this.selectedDashboardGroup === DashboardGroup.SharedDashboards ? '#6CB982' : shared ? variant : '' }} onContextMenu={e => this.onContextMenu(dashboard, e)} onClick={e => this.clickDashboard(e, dashboard)}> <img diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index a41fc8ded..8fe5c2e01 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -145,7 +145,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>() const toRemove = value.filter(v => docs.includes(v)); if (toRemove.length !== 0) { - const recent = Doc.MyRecentlyClosed; + const recent = this.rootDoc !== Doc.MyRecentlyClosed ? Doc.MyRecentlyClosed : undefined; toRemove.forEach(doc => { leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey); Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3522830e5..956dac555 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -831,7 +831,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P {shareSymbolIcon + ' ' + shareMode} - {!Doc.noviceMode ? ( + {/* {!Doc.noviceMode ? ( <div className="checkbox"> <div className="checkbox-box"> <input type="checkbox" checked={this.showLayoutAcl} onChange={action(() => (this.showLayoutAcl = !this.showLayoutAcl))} /> @@ -839,7 +839,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P <div className="checkbox-text"> Layout </div> </div> ) : null} - + */} </div> </div> ) : ( @@ -911,7 +911,13 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P width: bounds.r - bounds.x + this._resizeBorderWidth + 'px', height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px', }}> - <div className="documentDecorations-topbar" style={{ display: hideDeleteButton && hideTitle && hideOpenButton ? 'none' : undefined }} onPointerDown={this.onContainerDown}> + <div + className="documentDecorations-topbar" + style={{ + color: 'black', + display: hideDeleteButton && hideTitle && hideOpenButton ? 'none' : undefined, + }} + onPointerDown={this.onContainerDown}> {hideDeleteButton ? null : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')} {hideResizers || hideDeleteButton ? null : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')} {titleArea} diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 0c377730e..b3faff442 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -47,6 +47,10 @@ h1, align-items: center; justify-content: space-between; gap: 10px; + background: rgb(0, 0, 0); + border-radius: 8px; + padding-left: 5px; + padding-right: 5px; } .mainView-snapLines { @@ -190,10 +194,10 @@ h1, left: 0; position: absolute; z-index: 2; - background-color: linen;//$light-gray; + background-color: linen; //$light-gray; .editable-title { - background-color: linen;//$light-gray; + background-color: linen; //$light-gray; } } } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 5ab8a2f55..dc85fdfae 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -215,7 +215,7 @@ export class MainView extends React.Component { window.removeEventListener('keydown', KeyManager.Instance.handle); window.removeEventListener('pointerdown', this.globalPointerDown, true); window.removeEventListener('pointermove', this.globalPointerMove, true); - window.removeEventListener('mouseclick', this.globalPointerClick, true); + window.removeEventListener('pointerup', this.globalPointerClick, true); window.removeEventListener('paste', KeyManager.Instance.paste as any); document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener); } @@ -534,7 +534,7 @@ export class MainView extends React.Component { // document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined)); document.addEventListener('pointerdown', this.globalPointerDown, true); document.addEventListener('pointermove', this.globalPointerMove, true); - document.addEventListener('mouseclick', this.globalPointerClick, true); + document.addEventListener('pointerup', this.globalPointerClick, true); document.addEventListener( 'click', (e: MouseEvent) => { @@ -749,8 +749,7 @@ export class MainView extends React.Component { @computed get leftMenuPanel() { return ( - <div key="menu" className="mainView-leftMenuPanel" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), - display: LightboxView.LightboxDoc ? 'none' : undefined }}> + <div key="menu" className="mainView-leftMenuPanel" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), display: LightboxView.LightboxDoc ? 'none' : undefined }}> <DocumentView Document={Doc.MyLeftSidebarMenu} DataDoc={undefined} @@ -805,14 +804,17 @@ export class MainView extends React.Component { {this._hideUI ? null : this.leftMenuPanel} <div key="inner" className={`mainView-innerContent${this.colorScheme}`}> {this.flyout} - <div className="mainView-libraryHandle" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} onPointerDown={this.onFlyoutPointerDown}> + <div + className="mainView-libraryHandle" + style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} + onPointerDown={this.onFlyoutPointerDown}> <FontAwesomeIcon icon="chevron-left" color={StrCast(Doc.UserDoc().userColor)} style={{ opacity: '50%' }} size="sm" /> </div> <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}> {this.dockingContent} {this._hideUI ? null : ( - <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1, background : 'linen' }}> + <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1, background: 'linen' }}> <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? 'chevron-left' : 'chevron-right'} color={this.colorScheme === ColorScheme.Dark ? Colors.WHITE : Colors.BLACK} size="sm" /> </div> )} @@ -879,7 +881,7 @@ export class MainView extends React.Component { @computed get docButtons() { return !Doc.MyDockedBtns ? null : ( - <div className="mainView-docButtons" ref={this._docBtnRef}> + <div className="mainView-docButtons" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), color: StrCast(Doc.UserDoc().userColor) }} ref={this._docBtnRef}> <CollectionLinearView Document={Doc.MyDockedBtns} DataDoc={undefined} diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 6105cc1b5..2e3668268 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -56,24 +56,25 @@ export class PropertiesButtons extends React.Component<{}, {}> { propertyToggleBtn = (label: (on?: any) => string, property: string, tooltip: (on?: any) => string, icon: (on?: any) => any, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => { const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedDoc; const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => ((dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? false : true); - return !targetDoc ? null : <Toggle - toggleStatus={BoolCast(targetDoc[property])} - text={label(targetDoc?.[property])} - color={StrCast(Doc.UserDoc().userColor)} - icon={icon(targetDoc?.[property] as any)} - iconPlacement={'left'} - align={'flex-start'} - fillWidth={true} - toggleType={ToggleType.BUTTON} - onClick={undoable(() => { - if (SelectionManager.Views().length > 1) { - SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property)); - } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property); - }, property)} - /> + return !targetDoc ? null : ( + <Toggle + toggleStatus={BoolCast(targetDoc[property])} + text={label(targetDoc?.[property])} + color={StrCast(Doc.UserDoc().userColor)} + icon={icon(targetDoc?.[property] as any)} + iconPlacement={'left'} + align={'flex-start'} + fillWidth={true} + toggleType={ToggleType.BUTTON} + onClick={undoable(() => { + if (SelectionManager.Views().length > 1) { + SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property)); + } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property); + }, property)} + /> + ); }; - // this implments a container pattern by marking the targetDoc (collection) as a lightbox // that always fits its contents to its container and that hides all other documents when // a link is followed that targets a 'lightbox' destination @@ -110,7 +111,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { (dv, doc) => { const tdoc = dv?.rootDoc || doc; const newtitle = !tdoc._layout_showTitle ? 'title' : tdoc._layout_showTitle === 'title' ? 'title:hover' : ''; - tdoc._layout_showTitle = newtitle; + tdoc._layout_showTitle = newtitle ? newtitle : undefined; } ); } @@ -148,7 +149,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get clustersButton() { return this.propertyToggleBtn( - on => (on ?'DISABLE CLUSTERS' : 'HIGHLIGHT CLUSTERS'), + on => (on ? 'DISABLE CLUSTERS' : 'HIGHLIGHT CLUSTERS'), '_freeform_useClusters', on => `${on ? 'Hide' : 'Show'} clusters`, on => <FaBraille /> @@ -163,12 +164,13 @@ export class PropertiesButtons extends React.Component<{}, {}> { ); } - @computed get forceActiveButton() { //select text + @computed get forceActiveButton() { + //select text return this.propertyToggleBtn( - on => on ? 'INACTIVE INTERACTION' : 'ACTIVE INTERACTION', + on => (on ? 'INACTIVE INTERACTION' : 'ACTIVE INTERACTION'), '_forceActive', on => `${on ? 'Select to activate' : 'Contents always active'} `, - on => <MdTouchApp/> // 'eye' + on => <MdTouchApp /> // 'eye' ); } @@ -218,7 +220,8 @@ export class PropertiesButtons extends React.Component<{}, {}> { } @computed get captionButton() { - return this.propertyToggleBtn( //DEVELOPER + return this.propertyToggleBtn( + //DEVELOPER on => (on ? 'HIDE CAPTION' : 'SHOW CAPTION'), //'Caption', '_layout_showCaption', on => `${on ? 'Hide' : 'Show'} caption footer`, @@ -227,17 +230,19 @@ export class PropertiesButtons extends React.Component<{}, {}> { ); } - @computed get chromeButton() { // developer -- removing UI decoration + @computed get chromeButton() { + // developer -- removing UI decoration return this.propertyToggleBtn( - on => on ? 'ENABLE UI CONTROLS' : 'DISABLE UI CONTROLS', + on => (on ? 'ENABLE UI CONTROLS' : 'DISABLE UI CONTROLS'), '_chromeHidden', on => `${on ? 'Show' : 'Hide'} editing UI`, - on => on? <TbEditCircle/> : <TbEditCircleOff/> , // 'edit', + on => (on ? <TbEditCircle /> : <TbEditCircleOff />), // 'edit', (dv, doc) => ((dv?.rootDoc || doc)._chromeHidden = !(dv?.rootDoc || doc)._chromeHidden) ); } - @computed get layout_autoHeightButton() { // store previous dimensions to store old values + @computed get layout_autoHeightButton() { + // store previous dimensions to store old values return this.propertyToggleBtn( on => 'Auto\xA0Size', '_layout_autoHeight', @@ -251,7 +256,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { on => (on ? 'HIDE GRID' : 'DISPLAY GRID'), '_freeform_backgroundGrid', on => `Display background grid in collection`, - on => (on ? <MdGridOff /> :<MdGridOn /> ) //'border-all' + on => (on ? <MdGridOff /> : <MdGridOn />) //'border-all' ); } @@ -288,13 +293,14 @@ export class PropertiesButtons extends React.Component<{}, {}> { // } // ); // } - @computed get snapButton() { // THESE ARE NOT COMING + @computed get snapButton() { + // THESE ARE NOT COMING return this.propertyToggleBtn( on => (on ? 'HIDE SNAP LINES' : 'SHOW SNAP LINES'), 'freeform_snapLines', on => `Display snapping lines when objects are dragged`, on => <TfiBarChart />, //'th', - undefined, + undefined ); } @@ -346,11 +352,11 @@ export class PropertiesButtons extends React.Component<{}, {}> { const followLoc = this.selectedDoc._followLinkLocation; const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox); - if (followLoc === OpenWhere.lightbox && !linkedToLightboxView()) return 'linkInPlace' - else if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight' - else if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal' - else if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail' - else return 'nothing' + if (followLoc === OpenWhere.lightbox && !linkedToLightboxView()) return 'linkInPlace'; + else if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight'; + else if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal'; + else if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail'; + else return 'nothing'; } @computed @@ -362,22 +368,20 @@ export class PropertiesButtons extends React.Component<{}, {}> { ['linkInPlace', 'Open Link in Lightbox'], ['linkOnRight', 'Open Link on Right'], ]; - + const items: IListItemProps[] = buttonList.map(value => { - return ( - { - text: value[1], - val: value[1], - } - ); + return { + text: value[1], + val: value[1], + }; }); - console.log("click val: ", this.onClickVal) + console.log('click val: ', this.onClickVal); return !this.selectedDoc ? null : ( <Dropdown - tooltip={'Choose onClick behavior'} + tooltip={'Choose onClick behavior'} items={items} selectedVal={this.onClickVal} - setSelectedVal={(val) => this.handleOptionChange(val as string)} + setSelectedVal={val => this.handleOptionChange(val as string)} title={'Choose onClick behaviour'} color={StrCast(Doc.UserDoc().userColor)} dropdownType={DropdownType.SELECT} diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 060b506e3..b79486167 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -42,16 +42,6 @@ padding: 0; margin-top: -5; } - - .propertiesView-acls-checkbox { - margin-top: -15px; - margin-bottom: -10px; - - .propertiesView-acls-checkbox-text { - display: inline; - font-size: 9px; - } - } } .change-buttons { @@ -68,14 +58,19 @@ } } + .propertiesView-acls-checkbox { + float: right; + margin-left: 50px; + } + .propertiesView-shareDropDown{ margin-right: 10px; min-width: 65px; & .propertiesView-shareDropDownNone{ - height: 16px; padding: 0px; padding-left: 3px; + padding-right: 3px; background: grey; color: rgb(71, 71, 71); border-radius: 6px; @@ -83,18 +78,18 @@ } & .propertiesView-shareDropDownEdit, .propertiesView-shareDropDownAdmin{ - height: 16px; padding: 0px; padding-left: 3px; + padding-right: 3px; background: rgb(254, 254, 199); color: rgb(75, 75, 5); border-radius: 6px; border: 1px solid rgb(75, 75, 5); } & .propertiesView-shareDropDownAugment{ - height: 16px; padding: 0px; padding-left: 3px; + padding-right: 3px; background: rgb(208, 255, 208); color:rgb(19, 80, 19); border-radius: 6px; @@ -102,18 +97,18 @@ } & .propertiesView-shareDropDownView{ - height: 16px; padding: 0px; padding-left: 3px; + padding-right: 3px; background: rgb(213, 213, 255); color: rgb(25, 25, 101); border-radius: 6px; border: 1px solid rgb(25, 25, 101); } & .propertiesView-shareDropDownNot-Shared{ - height: 16px; padding: 0px; padding-left: 3px; + padding-right: 3px; background: rgb(255, 207, 207); color: rgb(138, 47, 47); border-radius: 6px; @@ -177,19 +172,7 @@ } .expansion-button { - margin-left: -15px; - margin-right: 20px; - - .expansion-button-icon { - width: 11px; - height: 11px; - color: black; - - &:hover { - color: rgb(131, 131, 131); - cursor: pointer; - } - } + margin-right: 10px; } .propertiesView-sharingTable { @@ -238,6 +221,11 @@ } } + .propertiesView-permissions-select { + background: inherit; + border: none; + } + .propertiesView-field { display: flex; font-size: 7px; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index a6a99b3cc..27b9c3c7a 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -3,7 +3,7 @@ import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@material-ui/core'; -import { Button, Colors, EditableText, NumberInput, Size, Slider, Type } from 'browndash-components'; +import { Button, Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; import { concat } from 'lodash'; import { Lambda, action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; @@ -367,17 +367,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { */ @computed get expansionIcon() { return ( - <Tooltip title={<div className="dash-tooltip">Show more permissions</div>}> - <div - className="expansion-button" - onPointerDown={() => { + <div className="expansion-button" > + <IconButton + icon={<FontAwesomeIcon icon={'ellipsis-h'} />} + size={Size.XSMALL} + color={StrCast(Doc.UserDoc().userColor)} + onClick={action(() => { if (this.selectedDocumentView || this.selectedDoc) { SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined, this.selectedDoc); } - }}> - <FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" /> - </div> - </Tooltip> + })} + /> + </div> ); } @@ -417,7 +418,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div> <div className={'propertiesView-shareDropDown'}> <div className={`propertiesView-shareDropDown${permission}`}> - <div className="propertiesView-shareDropDown">{admin && permission !== 'Owner' ? this.getPermissionsSelect(name, permission, showGuestOptions) : concat(shareImage, ' ', permission)}</div> + <div >{admin && permission !== 'Owner' ? this.getPermissionsSelect(name, permission, showGuestOptions) : concat(shareImage, ' ', permission)}</div> </div> </div> </div> @@ -449,6 +450,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { const target = docs[0]; const showAdmin = GetEffectiveAcl(target) == AclAdmin; + console.log(GetEffectiveAcl(target), Doc.GetProto(target)[`acl-${normalizeEmail(Doc.CurrentUserEmail)}`]) const individualTableEntries = []; const usersAdded: string[] = []; // all shared users being added - organized by denormalized email @@ -512,28 +514,29 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } }); - // public permission - const publicPermission = StrCast((this.layoutDocAcls ? target : Doc.GetProto(target))['acl-Guest']); + // guest permission + const guestPermission = StrCast((this.layoutDocAcls ? target : Doc.GetProto(target))['acl-Guest']); return ( <div> - <br /> - <div className="propertiesView-sharingTable">{<div> {individualTableEntries}</div>}</div> + <div> + <br></br> Individuals with Access to this Document + </div> + <div className="propertiesView-sharingTable" style={{background: StrCast(Doc.UserDoc().userBackgroundColor), color: StrCast(Doc.UserDoc().userColor)}}> + {<div> {individualTableEntries}</div>} + </div> {groupTableEntries.length > 0 ? ( <div> <div> - {' '} - <br></br> Groups with Access to this Document{' '} + <br></br> Groups with Access to this Document + </div> + <div className="propertiesView-sharingTable" style={{background: StrCast(Doc.UserDoc().userBackgroundColor), color: StrCast(Doc.UserDoc().userColor)}}> + {<div> {groupTableEntries}</div>} </div> - <div className="propertiesView-sharingTable">{<div> {groupTableEntries}</div>}</div> </div> ) : null} - Guest - <div>{this.colorACLDropDown('Guest', true, publicPermission!, true)}</div> - <div> - {' '} - <br></br> Individual Users with Access to this Document{' '} - </div> + <br></br> Guest + <div>{this.colorACLDropDown('Guest', showAdmin, guestPermission!, true)}</div> </div> ); } @@ -1145,26 +1148,17 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return <PropertiesSection title="Sharing & Permissions" content={<> - <div className="propertiesView-buttonContainer"> - {!Doc.noviceMode ? ( - <div className="propertiesView-buttonContainer"> - <div className="propertiesView-acls-checkbox"> - <div className="propertiesView-acls-checkbox-text"> Show / Contol Layout Permissions </div> - <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> - </div> - {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}> - <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}> - <FontAwesomeIcon icon="redo-alt" color="white" size="1x" /> - </button> - </Tooltip> */} - </div> - ) : null} + {/* <div className="propertiesView-buttonContainer"> */} + <div className="propertiesView-acls-checkbox"> + Layout Permissions + <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> + </div> {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}> <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}> <FontAwesomeIcon icon="redo-alt" size="1x" /> </button> </Tooltip> */} - </div> + {/* </div> */} {this.sharingTable} </>} isOpen={this.openSharing} diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 6f88f6727..22beb19de 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -8,7 +8,7 @@ import { Id } from '../../../fields/FieldSymbols'; import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { ScriptField } from '../../../fields/ScriptField'; import { NumCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, numberRange, returnEmptyString, setupMoveUpEvents } from '../../../Utils'; +import { emptyFunction, numberRange, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { CompileScript } from '../../util/Scripting'; @@ -252,10 +252,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr return ( <div className="collectionStackingView-optionPicker"> <div className="optionOptions"> - <div className={'optionPicker' + (selected === true ? ' active' : '')} onClick={this.toggleEmbedding}> - Create Embedding - </div> - <div className={'optionPicker' + (selected === true ? ' active' : '')} onClick={this.deleteRow}> + <div className={'optionPicker' + (selected === true ? ' active' : '')} onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.deleteRow)}> Delete </div> </div> @@ -273,13 +270,16 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr const stackPad = showChrome ? `0px ${this.props.parent.xMargin}px` : `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px 0px ${this.props.parent.xMargin}px `; return this.collapsed ? null : ( <div style={{ position: 'relative' }}> + {this.props.showHandle && this.props.parent.props.isContentActive() ? this.props.parent.columnDragger : null} {showChrome ? ( <div className="collectionStackingView-addDocumentButton" - style={{ - //width: style.columnWidth / style.numGroupColumns, - padding: `${NumCast(this.props.parent.layoutDoc._yPadding, this.props.parent.yMargin)}px 0px 0px 0px`, - }}> + style={ + { + //width: style.columnWidth / style.numGroupColumns, + //padding: `${NumCast(this.props.parent.layoutDoc._yPadding, this.props.parent.yMargin)}px 0px 0px 0px`, + } + }> <EditableView GetValue={returnEmptyString} SetValue={this.addDocument} textCallback={this.textCallback} contents={'+ NEW'} /> </div> ) : null} @@ -288,12 +288,12 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr ref={this._contRef} style={{ padding: stackPad, + minHeight: this.props.showHandle && this.props.parent.props.isContentActive() ? '10px' : undefined, width: this.props.parent.NodeWidth, gridGap: this.props.parent.gridGap, gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ''), }}> {this.props.parent.children(this.props.docList)} - {this.props.showHandle && this.props.parent.props.isContentActive() ? this.props.parent.columnDragger : null} </div> </div> ); @@ -313,23 +313,33 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr onPointerDown={this.headerDown} title={evContents === `NO ${key.toUpperCase()} VALUE` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''} style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this.color : 'lightgrey' }}> - {noChrome ? evContents : editableHeaderView} + {noChrome ? evContents : <div>{editableHeaderView}</div>} {noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : ( <div className="collectionStackingView-sectionColor"> - <button className="collectionStackingView-sectionColorButton" onClick={action(e => (this._paletteOn = !this._paletteOn))}> + <button + className="collectionStackingView-sectionColorButton" + onPointerDown={e => + setupMoveUpEvents( + this, + e, + returnFalse, + emptyFunction, + action(e => (this._paletteOn = !this._paletteOn)) + ) + }> <FontAwesomeIcon icon="palette" size="lg" /> </button> {this._paletteOn ? this.renderColorPicker() : null} </div> )} {noChrome ? null : ( - <button className="collectionStackingView-sectionDelete" onClick={noChrome ? undefined : this.collapseSection}> + <button className="collectionStackingView-sectionDelete" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, noChrome ? emptyFunction : this.collapseSection)}> <FontAwesomeIcon icon={this.collapsed ? 'chevron-down' : 'chevron-up'} size="lg" /> </button> )} {noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : ( - <div className="collectionStackingView-sectionOptions"> - <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderMenu()}> + <div className="collectionStackingView-sectionOptions" onPointerDown={e => e.stopPropagation()}> + <Flyout anchorPoint={anchorPoints.RIGHT_TOP} content={this.renderMenu()}> <button className="collectionStackingView-sectionOptionButton"> <FontAwesomeIcon icon="ellipsis-v" size="lg" /> </button> diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 9eb716763..5135cfb57 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -33,7 +33,7 @@ import { LightboxView } from '../LightboxView'; import { MainView } from '../MainView'; import { DefaultStyleProvider } from '../StyleProvider'; import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView'; -import { DocumentView, OpenWhereMod } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewInternal, OpenWhereMod } from '../nodes/DocumentView'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { CollectionDockingView } from './CollectionDockingView'; import './CollectionMenu.scss'; @@ -129,7 +129,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { docViewPath={returnEmptyDoclist} moveDocument={returnFalse} addDocument={returnFalse} - addDocTab={returnFalse} + addDocTab={DocumentViewInternal.addDocTabFunc} pinToPres={emptyFunction} removeDocument={returnFalse} ScreenToLocalTransform={this.buttonBarXf} @@ -154,21 +154,21 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { const hardCodedButtons = ( <div className={`hardCodedButtons`}> - <Toggle - toggleType={ToggleType.BUTTON} - type={Type.PRIM} - color={StrCast(Doc.UserDoc().userColor)} - onClick={this.toggleTopBar} - toggleStatus={SettingsManager.headerBarHeight > 0} + <Toggle + toggleType={ToggleType.BUTTON} + type={Type.PRIM} + color={StrCast(Doc.UserDoc().userColor)} + onClick={this.toggleTopBar} + toggleStatus={SettingsManager.headerBarHeight > 0} icon={<FontAwesomeIcon icon={headerIcon} size="lg" />} tooltip={headerTitle} /> - <Toggle - toggleType={ToggleType.BUTTON} + <Toggle + toggleType={ToggleType.BUTTON} type={Type.PRIM} - color={StrCast(Doc.UserDoc().userColor)} - onClick={this.toggleProperties} - toggleStatus={SettingsManager.propertiesWidth > 0} + color={StrCast(Doc.UserDoc().userColor)} + onClick={this.toggleProperties} + toggleStatus={SettingsManager.propertiesWidth > 0} icon={<FontAwesomeIcon icon={propIcon} size="lg" />} tooltip={propTitle} /> @@ -178,11 +178,12 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { // NEW BUTTONS //dash col linear view buttons const contMenuButtons = ( - <div className="collectionMenu-container" - style={{ - background: StrCast(Doc.UserDoc().userBackgroundColor), - // borderColor: StrCast(Doc.UserDoc().userColor) - }} > + <div + className="collectionMenu-container" + style={{ + background: StrCast(Doc.UserDoc().userBackgroundColor), + // borderColor: StrCast(Doc.UserDoc().userColor) + }}> {this.contMenuButtons} {hardCodedButtons} </div> diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 99a68e94b..255bc3889 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -128,6 +128,7 @@ height: 15; position: absolute; margin-left: -5; + z-index: 10; } // Documents in stacking view diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 805002452..a5c276125 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -1,7 +1,7 @@ import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { CursorProperty } from 'csstype'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, Opt } from '../../../fields/Doc'; import { DocData, Height, Width } from '../../../fields/DocSymbols'; @@ -11,7 +11,7 @@ import { listSpec } from '../../../fields/Schema'; import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils'; +import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnNone, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType } from '../../documents/DocumentTypes'; import { DragManager, dropActionType } from '../../util/DragManager'; @@ -31,7 +31,6 @@ import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow'; import './CollectionStackingView.scss'; import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn'; import { CollectionSubView } from './CollectionSubView'; -import { Colors } from '../global/globalEnums'; const _global = (window /* browser */ || global) /* node */ as any; export type collectionStackingViewProps = { @@ -59,7 +58,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection // map of node headers to their heights. Used in Masonry @observable _heightMap = new Map<string, number>(); // Assuming that this is the current css cursor style - @observable _cursor: CursorProperty = 'grab'; + @observable _cursor: CursorProperty = 'ew-resize'; // gets reset whenever we scroll. Not sure what it is @observable _scroll = 0; // used to force the document decoration to update when scrolling // does this mean whether the browser is hidden? Or is chrome something else entirely? @@ -308,19 +307,18 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection ? false : undefined; isChildButtonContentActive = () => (this.props.childDocumentsActive?.() === false || this.rootDoc.childDocumentsActive === false ? false : undefined); + @observable docRefs = new ObservableMap<Doc, DocumentView>(); // this is what renders the document that you see on the screen // called in Children: this actually adds a document to our children list getDisplayDoc(doc: Doc, width: () => number, count: number) { const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.DataDoc; const height = () => this.getDocHeight(doc); - let dref: Opt<DocumentView>; - const stackedDocTransform = () => this.getDocTransform(doc, dref); + const stackedDocTransform = () => this.getDocTransform(doc); this._docXfs.push({ stackedDocTransform, width, height }); - //DocumentView is how the node will be rendered return count > this._renderCount ? null : ( <DocumentView - ref={r => (dref = r || undefined)} + ref={action((r: DocumentView) => r?.ContentDiv && this.docRefs.set(doc, r))} Document={doc} DataDoc={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)} renderDepth={this.props.renderDepth + 1} @@ -368,9 +366,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection ); } - getDocTransform(doc: Doc, dref?: DocumentView) { - const y = this._scroll; // required for document decorations to update when the text box container is scrolled - const { scale, translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined); + getDocTransform(doc: Doc) { + const dref = this.docRefs.get(doc); + this._scroll; // must be referenced for document decorations to update when the text box container is scrolled + const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv); // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale); } @@ -409,7 +408,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection e, this.onDividerMove, action(() => { - this._cursor = 'grab'; + this._cursor = 'ew-resize'; batch.end(); }), emptyFunction @@ -423,7 +422,11 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection @computed get columnDragger() { return ( - <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }}> + <div + className="collectionStackingView-columnDragger" + onPointerDown={this.columnDividerDown} + ref={this._draggerRef} + style={{ cursor: this._cursor, color: StrCast(Doc.UserDoc().userColor), left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }}> <FontAwesomeIcon icon={'arrows-alt-h'} /> </div> ); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index d904749b1..1098b56c2 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -222,10 +222,8 @@ export class TreeView extends React.Component<TreeViewProps> { this.treeViewOpen = !this.treeViewOpen; } else { // choose an appropriate embedding or make one. --- choose the first embedding that (1) user owns, (2) has no context field ... otherwise make a new embedding - const bestEmbedding = docView.rootDoc.author === Doc.CurrentUserEmail && !Doc.IsDataProto(docView.props.Document) - ? docView.rootDoc - : Doc.BestEmbedding(docView.rootDoc); - this.props.addDocTab(bestEmbedding, OpenWhere.lightbox); + const bestEmbedding = docView.rootDoc.author === Doc.CurrentUserEmail && !Doc.IsDataProto(docView.props.Document) ? docView.rootDoc : Doc.BestEmbedding(docView.rootDoc); + this.props.addDocTab(bestEmbedding, OpenWhere.lightbox); } }; @@ -344,7 +342,6 @@ export class TreeView extends React.Component<TreeViewProps> { TreeView._editTitleOnLoad = { id: folder[Id], parent: this.props.parentTreeView }; return this.props.addDocument(folder); }; - deleteItem = () => this.props.removeDoc?.(this.doc); preTreeDrop = (e: Event, de: DragManager.DropEvent) => { const dragData = de.complete.docDragData; @@ -540,8 +537,8 @@ export class TreeView extends React.Component<TreeViewProps> { TraceMobx(); const expandKey = this.treeViewExpandedView; const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string; icon: JSX.Element | string } }) ?? {}; - const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color) - console.log("tree view", color, this.doc.title, Doc.IsSystem(this.doc)) + const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color); + console.log('tree view', color, this.doc.title, Doc.IsSystem(this.doc)); if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) { const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None); const sortKeys = Object.keys(sortings); @@ -581,9 +578,10 @@ export class TreeView extends React.Component<TreeViewProps> { ); } return ( - <div style={{ - color: color - }}> + <div + style={{ + color: color, + }}> {!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : ( <div className={'treeView-sorting'}> <IconButton @@ -725,26 +723,19 @@ export class TreeView extends React.Component<TreeViewProps> { }> {this.props.treeView.outlineMode ? ( !(this.doc.text as RichTextField)?.Text ? null : ( - <IconButton - color={color} - icon={<FontAwesomeIcon - icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />} - size={Size.XSMALL} - /> + <IconButton color={color} icon={<FontAwesomeIcon icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />} size={Size.XSMALL} /> ) ) : ( <div className="treeView-bulletIcons" style={{ color: Doc.IsSystem(DocCast(this.doc.proto)) ? 'red' : undefined }}> - {this.onCheckedClick ? <IconButton - color={color} - icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />} - size={Size.XSMALL} - /> : + {this.onCheckedClick ? ( <IconButton - color={color} - icon={<FontAwesomeIcon icon={iconType as IconProp} />} + color={color} + icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />} size={Size.XSMALL} /> - } + ) : ( + <IconButton color={color} icon={<FontAwesomeIcon icon={iconType as IconProp} />} size={Size.XSMALL} /> + )} </div> )} </div> @@ -776,17 +767,15 @@ export class TreeView extends React.Component<TreeViewProps> { return this.props.treeViewHideHeaderFields() || this.doc.treeViewHideHeaderFields ? null : ( <> {customHeaderButtons} {/* e.g.,. hide button is set by dashboardStyleProvider */} - {this.doc._layout_hideContextMenu ? null : ( - <IconButton - color={color} - icon={<FontAwesomeIcon icon="bars" />} - size={Size.XSMALL} - onClick={e => { - this.showContextMenu(e); - e.stopPropagation(); - }} - /> - )} + <IconButton + color={color} + icon={<FontAwesomeIcon icon="bars" />} + size={Size.XSMALL} + onClick={e => { + this.showContextMenu(e); + e.stopPropagation(); + }} + /> {Doc.noviceMode ? null : this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? null : ( <span className="collectionTreeView-keyHeader" title="type of expanded data" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}> {this.treeViewExpandedView} @@ -803,10 +792,10 @@ export class TreeView extends React.Component<TreeViewProps> { }; contextMenuItems = () => { const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: 'any' })!, icon: 'folder-plus', label: 'New Folder' }; - const deleteItem = { script: ScriptField.MakeFunction(`scriptContext.deleteItem()`, { scriptContext: 'any' })!, icon: 'folder-plus', label: 'Delete' }; const folderOp = this.childDocs?.length ? [makeFolder] : []; const openEmbedding = { script: ScriptField.MakeFunction(`openDoc(getEmbedding(self), "${OpenWhere.addRight}")`)!, icon: 'copy', label: 'Open New Embedding' }; const focusDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, icon: 'eye', label: 'Focus or Open' }; + const reopenDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, icon: 'eye', label: 'Reopen' }; return [ ...(this.props.contextMenuItems ?? []).filter(mi => (!mi.filter ? true : mi.filter.script.run({ doc: this.doc })?.result)), ...(this.doc.isFolder @@ -817,7 +806,9 @@ export class TreeView extends React.Component<TreeViewProps> { ? [openEmbedding, makeFolder] : this.doc._type_collection === CollectionViewType.Docking ? [] - : [deleteItem, openEmbedding, focusDoc]), + : this.props.treeView.rootDoc === Doc.MyRecentlyClosed + ? [reopenDoc] + : [openEmbedding, focusDoc]), ]; }; childContextMenuItems = () => { @@ -1014,12 +1005,13 @@ export class TreeView extends React.Component<TreeViewProps> { onPointerDown={this.ignoreEvent} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> - {contents} - <div className={`treeView-background`} + <div + className="treeView-background" style={{ - background: StrCast(Doc.UserDoc().userColor) + background: StrCast(Doc.UserDoc().userColor), }} /> + {contents} </div> {this.renderBorder} </> diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 7e8eef0a5..2d8663c9c 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -18,7 +18,6 @@ import { SearchBox } from '../search/SearchBox'; import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo'; import { YoutubeBox } from './../../apis/youtube/YoutubeBox'; import { AudioBox } from './AudioBox'; -import { FontIconBox } from './FontIconBox/FontIconBox'; import { ColorBox } from './ColorBox'; import { ComparisonBox } from './ComparisonBox'; import { DataVizBox } from './DataVizBox/DataVizBox'; @@ -26,9 +25,11 @@ import { DocumentViewProps } from './DocumentView'; import './DocumentView.scss'; import { EquationBox } from './EquationBox'; import { FieldView, FieldViewProps } from './FieldView'; +import { FontIconBox } from './FontIconBox/FontIconBox'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { FunctionPlotBox } from './FunctionPlotBox'; import { ImageBox } from './ImageBox'; +import { ImportElementBox } from './importBox/ImportElementBox'; import { KeyValueBox } from './KeyValueBox'; import { LabelBox } from './LabelBox'; import { LinkAnchorBox } from './LinkAnchorBox'; @@ -269,6 +270,7 @@ export class DocumentContentsView extends React.Component< LoadingBox, PhysicsSimulationBox, SchemaRowBox, + ImportElementBox, }} bindings={bindings} jsx={layoutFrame} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 38922cb24..2990e2159 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -332,8 +332,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps return ( DocumentView.LongPress || onScriptDisable === 'always' || - (onScriptDisable !== 'never' && (this.rootSelected() || this.props.isSelected())) || - this._componentView?.isAnyChildContentActive?.() + (onScriptDisable !== 'never' && (this.rootSelected() || this._componentView?.isAnyChildContentActive?.())) ); } @computed get onClickHandler() { @@ -800,7 +799,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps } const constantItems: ContextMenuProps[] = []; if (!Doc.IsSystem(this.rootDoc)) { - constantItems.push({ description: 'Export as Zip file', icon: 'download', event: async () => Doc.Zip(this.props.Document) }); + constantItems.push({ description: 'Zip Export', icon: 'download', event: async () => Doc.Zip(this.props.Document) }); (this.rootDoc._type_collection !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this.props.DocumentView()), icon: 'users' }); if (this.props.removeDocument && Doc.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions) @@ -875,13 +874,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps // undefined - it is not active, but it should be responsive to actions that might active it or its contents (eg clicking) return this.props.isContentActive() === false || this.props.pointerEvents?.() === 'none' || (this.rootDoc.pointerEvents === 'none' && !StrCast(this.props.LayoutTemplateString).includes(KeyValueBox.name)) ? false - : Doc.ActiveTool !== InkTool.None || - SnappingManager.GetIsDragging() || - this.rootSelected() || - this.rootDoc.forceActive || - this.props.isSelected(outsideReaction) || - this._componentView?.isAnyChildContentActive?.() || - this.props.isContentActive() + : Doc.ActiveTool !== InkTool.None || SnappingManager.GetIsDragging() || this.rootSelected() || this.rootDoc.forceActive || this._componentView?.isAnyChildContentActive?.() || this.props.isContentActive() ? true : undefined; }; @@ -903,8 +896,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps }; childFilters = () => [...this.props.childFilters(), ...StrListCast(this.layoutDoc.childFilters)]; - /// disable pointer events on content when there's an enabled onClick script (but not the browse script), or if contents are marked inactive - contentPointerEvents = () => ((!this.disableClickScriptFunc && this.onClickHandler && !this.props.onBrowseClick?.()) || this.isContentActive() === false ? 'none' : this.pointerEvents); + /// disable pointer events on content when there's an enabled onClick script (but not the browse script) and the contents aren't forced active, or if contents are marked inactive + contentPointerEvents = () => ((!this.disableClickScriptFunc && this.onClickHandler && !this.props.onBrowseClick?.() && this.isContentActive() !== true) || this.isContentActive() === false ? 'none' : this.pointerEvents); @computed get contents() { TraceMobx(); @@ -1236,7 +1229,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps const renderDoc = this.renderDoc({ borderRadius: this.borderRounding, outline: highlighting && !this.borderRounding && !highlighting.highlightStroke ? `${highlighting.highlightColor} ${highlighting.highlightStyle} ${highlighting.highlightIndex}px` : 'solid 0px', - border: highlighting && this.borderRounding && highlighting.highlightStyle === 'dashed' ? `${highlighting.highlightStyle} ${highlighting.highlightColor} ${highlighting.highlightIndex}px` : undefined, + border: highlighting && this.borderRounding && highlighting.highlightStyle === 'dashed' ? `${highlighting.highlightStyle} ${highlighting.highlightColor} ${highlighting.highlightIndex}px` : undefined, boxShadow, clipPath: borderPath?.clipPath, }); diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 3ec53beac..da1b89200 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -86,10 +86,10 @@ export class FontIconBox extends DocComponent<ButtonProps>() { } Icon = (color: string, iconFalse?: boolean) => { let icon; - if (iconFalse ) { + if (iconFalse) { icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any; - if (icon) return <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} /> - else return null + if (icon) return <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />; + else return null; } icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any; const trailsIcon = () => <img src={`/assets/${'presTrails.png'}`} style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? '0%' : '100%'})` }} />; @@ -124,36 +124,38 @@ export class FontIconBox extends DocComponent<ButtonProps>() { */ @computed get numberDropdown() { let type: NumberDropdownType; - switch(this.type) { - case ButtonType.NumberDropdownButton: - type = 'dropdown' + switch (this.type) { + case ButtonType.NumberDropdownButton: + type = 'dropdown'; break; case ButtonType.NumberInlineButton: - type = 'input' + type = 'input'; break; case ButtonType.NumberSliderButton: default: - type = 'slider' + type = 'slider'; break; } - const numScript = (value?: number) => ScriptCast(this.rootDoc.script).script.run({ self: this.rootDoc, value, _readOnly_: value === undefined }); + const numScript = (value?: number) => ScriptCast(this.rootDoc.script).script.run({ this: this.layoutDoc, self: this.rootDoc, value, _readOnly_: value === undefined }); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); // Script for checking the outcome of the toggle const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3))); const label = !FontIconBox.GetShowLabels() ? null : <div className="fontIconBox-label">{this.label}</div>; - return <NumberDropdown - color={color} - numberDropdownType={type} - showPlusMinus={false} - tooltip={this.label} - type={Type.PRIM} - min={NumCast(this.rootDoc.numBtnMin, 0)} - max={NumCast(this.rootDoc.numBtnMax, 100)} - number={checkResult} - setNumber={undoable(value => numScript(value), `${this.rootDoc.title} button set from list`)} - fillWidth - /> + return ( + <NumberDropdown + color={color} + numberDropdownType={type} + showPlusMinus={false} + tooltip={this.label} + type={Type.PRIM} + min={NumCast(this.rootDoc.numBtnMin, 0)} + max={NumCast(this.rootDoc.numBtnMax, 100)} + number={checkResult} + setNumber={undoable(value => numScript(value), `${this.rootDoc.title} button set from list`)} + fillWidth + /> + ); } /** @@ -202,84 +204,69 @@ export class FontIconBox extends DocComponent<ButtonProps>() { let dropdown = true; let getStyle: (val: string) => any = () => {}; let icon: IconProp = 'caret-down'; - let isViewDropdown: boolean = script?.script.originalScript.startsWith('setView') + let isViewDropdown: boolean = script?.script.originalScript.startsWith('setView'); try { if (isViewDropdown) { const selectedDocs: Doc[] = SelectionManager.Docs(); const selected = SelectionManager.Docs().lastElement(); - console.log('selected') + console.log('selected'); if (selected) { if (StrCast(selected.type) === DocumentType.COL) { text = StrCast(selected._type_collection); - console.log("collection selected", text) + console.log('collection selected', text); } else { - console.log("doc selected", selected.title); + console.log('doc selected', selected.title); dropdown = false; if (selectedDocs.length > 1) { - text = selectedDocs.length + " selected" + text = selectedDocs.length + ' selected'; } else { text = Utils.cleanDocumentType(StrCast(selected.type) as DocumentType); icon = Doc.toIcon(selected); } - return <Popup - icon={<FontAwesomeIcon size={'1x'} icon={icon} />} - text={text} - type={Type.TERT} - color={color} - popup={<SelectedDocView selectedDocs={selectedDocs}/>} - fillWidth - /> + return <Popup icon={<FontAwesomeIcon size={'1x'} icon={icon} />} text={text} type={Type.TERT} color={color} popup={<SelectedDocView selectedDocs={selectedDocs} />} fillWidth />; } } else { dropdown = false; - return <Button - text={`None Selected`} - type={Type.TERT} - color={color} - fillWidth - inactive - /> + return <Button text={`None Selected`} type={Type.TERT} color={color} fillWidth inactive />; } noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking]; - } else { + } else { text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily); - getStyle = (val: string) => { return { fontFamily: val } } + getStyle = (val: string) => { + return { fontFamily: val }; + }; } } catch (e) { console.log(e); } - console.log("current item: ", text); + console.log('current item: ', text); // Get items to place into the list const list: IListItemProps[] = this.buttonList .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value)) - .map(value => ( - { - text: value.charAt(0).toUpperCase() + value.slice(1), - val: value, - style: getStyle(value), - onClick: undoable(() => script.script.run({ self: this.rootDoc, value }), value) - // shortcut: '#', - } - )); - + .map(value => ({ + text: value.charAt(0).toUpperCase() + value.slice(1), + val: value, + style: getStyle(value), + onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value), + // shortcut: '#', + })); return ( - <Dropdown + <Dropdown selectedVal={text} - setSelectedVal={undoable((val) => script.script.run({ self: this.rootDoc, val }), `dropdown select ${this.label}`)} - color={color} - type={isViewDropdown ? Type.TERT : Type.PRIM} - dropdownType={DropdownType.SELECT} + setSelectedVal={undoable(val => script.script.run({ this: this.layoutDoc, self: this.rootDoc, val }), `dropdown select ${this.label}`)} + color={color} + type={isViewDropdown ? Type.TERT : Type.PRIM} + dropdownType={DropdownType.SELECT} items={list} tooltip={this.label} fillWidth /> - ) + ); } - @computed get colorScript() { return ScriptCast(this.rootDoc.script); } @@ -290,14 +277,14 @@ export class FontIconBox extends DocComponent<ButtonProps>() { @computed get colorButton() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); - const curColor = this.colorScript?.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent'; + const curColor = this.colorScript?.script.run({ this: this.layoutDoc, self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent'; const tooltip: string = StrCast(this.rootDoc.toolTip); return ( - <ColorPicker - setSelectedColor={(value) => { + <ColorPicker + setSelectedColor={value => { const s = this.colorScript; - s && undoable(() => s.script.run({ self: this.rootDoc, value: value, _readOnly_: false }).result, `Set ${tooltip} to ${value}`)(); + s && undoable(() => s.script.run({ this: this.layoutDoc, self: this.rootDoc, value: value, _readOnly_: false }).result, `Set ${tooltip} to ${value}`)(); }} selectedColor={curColor} type={Type.PRIM} @@ -306,7 +293,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { tooltip={tooltip} label={this.label} /> - ) + ); } @computed get toggleButton() { @@ -315,25 +302,24 @@ export class FontIconBox extends DocComponent<ButtonProps>() { const tooltip: string = StrCast(this.rootDoc.toolTip); const script = ScriptCast(this.rootDoc.onClick); - const toggleStatus = script ? script.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result : false; + const toggleStatus = script ? script.script.run({ this: this.layoutDoc, self: this.rootDoc, value: undefined, _readOnly_: true }).result : false; // Colors const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); - console.log(tooltip, toggleStatus); return ( - <Toggle - tooltip={`Toggle ${tooltip}`} - toggleType={ToggleType.BUTTON} - type={Type.PRIM} - toggleStatus={toggleStatus} - text={buttonText} - color={color} - icon={this.Icon(color)!} + <Toggle + tooltip={`Toggle ${tooltip}`} + toggleType={ToggleType.BUTTON} + type={Type.PRIM} + toggleStatus={toggleStatus} + text={buttonText} + color={color} + icon={this.Icon(color)!} label={this.label} - onPointerDown={() => script.script.run({ self: this.rootDoc, value: !toggleStatus, _readOnly_: false })} + onPointerDown={() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value: !toggleStatus, _readOnly_: false })} /> - ) + ); } /** @@ -344,28 +330,24 @@ export class FontIconBox extends DocComponent<ButtonProps>() { const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const tooltip: string = StrCast(this.rootDoc.toolTip); - return ( - <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label}/> - ) + return <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label} />; } @computed get editableText() { // Script for running the toggle const script = ScriptCast(this.rootDoc.script); // Function to run the script - const checkResult = script?.script.run({ value: '', _readOnly_: true }).result; + const checkResult = script?.script.run({ this: this.layoutDoc, self: this.rootDoc, value: '', _readOnly_: true }).result; + + const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ this: this.layoutDoc, self: this.rootDoc, value, _readOnly_: false }).result; + + return <EditableText editing={false} setEditing={(editing: boolean) => {}} />; - const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result; - - return <EditableText - editing={false} setEditing={(editing: boolean) => {}} - /> - return ( <div className="menuButton editableText"> <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'lock'} /> <div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}> - <EditableView GetValue={() => script?.script.run({ value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} /> + <EditableView GetValue={() => script?.script.run({ this: this.layoutDoc, self: this.rootDoc, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} /> </div> </div> ); @@ -403,7 +385,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() { case ButtonType.ClickButton: case ButtonType.ToolButton: button = ( - <IconButton tooltip={tooltip} onPointerDown={() => onClickScript?.script.run({ _readOnly_: false })} color={color} icon={this.Icon(color)!} label={this.label}/> + <IconButton tooltip={tooltip} + color={color} icon={this.Icon(color)!} label={this.label}/> ); break; case ButtonType.TextButton: @@ -412,7 +395,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { ); break; case ButtonType.MenuButton: button = ( - <IconButton tooltip={tooltip} onPointerDown={() => onClickScript?.script.run({ self: this.rootDoc, _readOnly_: false })} tooltipPlacement='right' size={Size.LARGE} color={color} icon={this.Icon(color)!} label={this.label}/> + <IconButton tooltip={tooltip} onPointerDown={() => onClickScript?.script.run({ this: this.layoutDoc, self: this.rootDoc, _readOnly_: false })} tooltipPlacement='right' size={Size.LARGE} color={color} icon={this.Icon(color)!} label={this.label}/> ); break; } diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index b4fb7a44e..d5ad128fe 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -17,6 +17,7 @@ import { OpenWhere } from '../DocumentView'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; import React = require('react'); +import { Transform } from '../../../util/Transform'; export class DashFieldView { dom: HTMLDivElement; // container for label and value @@ -113,6 +114,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna componentWillUnmount() { this._reactionDisposer?.(); } + return100 = () => 100; // set the display of the field's value (checkbox for booleans, span of text for strings) @computed get fieldValueContent() { @@ -123,7 +125,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna col={0} deselectCell={emptyFunction} selectCell={emptyFunction} - maxWidth={this.props.hideKey ? undefined : () => 100} + maxWidth={this.props.hideKey ? undefined : this.return100} columnWidth={this.props.hideKey ? () => this.props.tbox.props.PanelWidth() - 20 : returnZero} selectedCell={() => [this._dashDoc!, 0]} fieldKey={this._fieldKey} @@ -135,6 +137,8 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna allowCRs={true} oneLine={!this._expanded} finishEdit={action(() => (this._expanded = false))} + transform={Transform.Identity} + menuTarget={null} /> </div> ); diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx index a5d21cc8e..58f0b29e4 100644 --- a/src/client/views/nodes/importBox/ImportElementBox.tsx +++ b/src/client/views/nodes/importBox/ImportElementBox.tsx @@ -1,13 +1,13 @@ -import { observer } from "mobx-react"; -import { ViewBoxBaseComponent } from "../../DocComponent"; -import { FieldView, FieldViewProps } from "../FieldView"; -import { computed } from "mobx"; -import { Id } from "../../../../fields/FieldSymbols"; -import React from "react"; -import { EditableView } from "../../EditableView"; -import { DocListCast } from "../../../../fields/Doc"; -import { StrCast } from "../../../../fields/Types"; - +import { computed } from 'mobx'; +import { observer } from 'mobx-react'; +import { Doc } from '../../../../fields/Doc'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue } from '../../../../Utils'; +import { Transform } from '../../../util/Transform'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { DefaultStyleProvider } from '../../StyleProvider'; +import { DocumentView, DocumentViewInternal } from '../DocumentView'; +import { FieldView, FieldViewProps } from '../FieldView'; +import React = require('react'); @observer export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() { @@ -15,56 +15,24 @@ export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() { return FieldView.LayoutString(ImportElementBox, fieldKey); } - private _itemRef: React.RefObject<HTMLDivElement> = React.createRef(); - private _dragRef: React.RefObject<HTMLDivElement> = React.createRef(); - private _titleRef: React.RefObject<EditableView> = React.createRef(); - - @computed importBoxVoew() { - return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as PresBox; - } - - @computed get indexInPres() { - return DocListCast(this.presBox?.[StrCast(this.presBox.presFieldKey, 'data')]).indexOf(this.rootDoc); + screenToLocalXf = () => this.props.ScreenToLocalTransform().scale(1 * (this.props.NativeDimScaling?.() || 1)); + @computed get mainItem() { + return ( + <div style={{ backgroundColor: 'pink' }}> + <DocumentView + {...this.props} // + LayoutTemplateString={undefined} + Document={this.rootDoc} + isContentActive={returnFalse} + DataDoc={undefined} + addDocument={returnFalse} + ScreenToLocalTransform={this.screenToLocalXf} + hideResizeHandles={true} + /> + </div> + ); } - - @computed get presBox() { - return this.props.DocumentView?.().props.docViewPath().lastElement()?.rootDoc; + render() { + return !(this.rootDoc instanceof Doc) ? null : this.mainItem; } - - // @computed get selectedArray() { - // return this.presBoxView?.selectedArray; - // } - -@computed get mainItem() { - const isCurrent: boolean = this.presBox?._itemIndex === this.indexInPres; - //const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false; - // const activeItem: Doc = this.rootDoc; - - return( - <div - className = {`presItem-container`} - // key={this.props.Document[Id] + this.indexInPres} - style = {{backgroundColor: 'pink'}} - - > - <div - ref = {this._dragRef} - className = {`presItem-slide ${isCurrent ? 'active' : ''}`} - style = {{ - backgroundColor: 'green' - }}> - <div - className="presItem-number" - title = "select without navigation" - - > - {/* <EditableView ref={this._titleRef} oneLine={true} editing={!isSelected ? false : undefined} contents={activeItem.title} overflow={'ellipsis'} GetValue={() => StrCast(activeItem.title)} SetValue={this.onSetValue} /> */} - - </div> - </div> - - </div> - ) } - -}
\ No newline at end of file diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 0fd93868a..1319a236d 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -26,6 +26,7 @@ import { Annotation } from './Annotation'; import './PDFViewer.scss'; import React = require('react'); import { GPTPopup } from './GPTPopup/GPTPopup'; +import { InkingStroke } from '../InkingStroke'; const PDFJSViewer = require('pdfjs-dist/web/pdf_viewer'); const pdfjsLib = require('pdfjs-dist'); const _global = (window /* browser */ || global) /* node */ as any; @@ -519,7 +520,8 @@ export class PDFViewer extends React.Component<IViewerProps> { childStyleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string): any => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc) || this.props.isContentActive() === false) return 'none'; - return 'all'; + const isInk = doc && StrCast(Doc.Layout(doc).layout).includes(InkingStroke.name) && !props?.LayoutTemplateString; + return isInk ? 'visiblePainted' : 'all'; } return this.props.styleProvider?.(doc, props, property); }; @@ -537,7 +539,7 @@ export class PDFViewer extends React.Component<IViewerProps> { NativeWidth={returnZero} NativeHeight={returnZero} setContentView={emptyFunction} // override setContentView to do nothing - pointerEvents={SnappingManager.GetIsDragging() && this.props.isContentActive() ? returnAll : returnNone} // freeform view doesn't get events unless something is being dragged onto it. + pointerEvents={this.props.isContentActive() && (SnappingManager.GetIsDragging() || Doc.ActiveTool !== InkTool.None) ? returnAll : returnNone} // freeform view doesn't get events unless something is being dragged onto it. childPointerEvents={this.props.isContentActive() !== false ? 'all' : 'none'} // but freeform children need to get events to allow text editing, etc renderDepth={this.props.renderDepth + 1} isAnnotationOverlay={true} diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index 79f41fe9d..ec4252eb8 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -134,14 +134,16 @@ export class TopBar extends React.Component { @computed get topbarRight() { return ( <div className="topbar-right"> - <Button - text={GetEffectiveAcl(Doc.ActiveDashboard) === AclAdmin ? 'Share' : 'View Original'} - type={Type.TERT} - color={this.variantColor} - onClick={() => { - SharingManager.Instance.open(undefined, Doc.ActiveDashboard); - }} - /> + {Doc.ActiveDashboard ? + <Button + text={GetEffectiveAcl(Doc.ActiveDashboard) === AclAdmin ? 'Share' : 'View Original'} + type={Type.TERT} + color={this.variantColor} + onClick={() => { + SharingManager.Instance.open(undefined, Doc.ActiveDashboard); + }} + /> + : null } <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} /> <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} /> <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} /> |
