diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/documents/DocumentTypes.ts | 2 | ||||
| -rw-r--r-- | src/client/documents/Documents.ts | 31 | ||||
| -rw-r--r-- | src/client/util/CaptureManager.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/MainView.scss | 4 | ||||
| -rw-r--r-- | src/client/views/MainView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/PropertiesButtons.scss | 104 | ||||
| -rw-r--r-- | src/client/views/PropertiesButtons.tsx | 363 | ||||
| -rw-r--r-- | src/client/views/PropertiesDocContextSelector.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/PropertiesView.scss | 69 | ||||
| -rw-r--r-- | src/client/views/PropertiesView.tsx | 333 |
10 files changed, 663 insertions, 249 deletions
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index cdc8c275c..bd71281fa 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -2,7 +2,7 @@ export enum DocumentType { NONE = 'none', // core data types - RTF = 'rtf', + RTF = 'rich text', IMG = 'image', WEB = 'web', COL = 'collection', diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 00864c6fd..1db83b838 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -437,6 +437,7 @@ export namespace Docs { nativeHeightUnfrozen: true, layout_forceReflow: true, defaultDoubleClick: 'ignore', + systemIcon: 'BsFileEarmarkTextFill', }, }, ], @@ -458,21 +459,21 @@ export namespace Docs { DocumentType.IMG, { layout: { view: ImageBox, dataField: defaultDataKey }, - options: { freeform: '' }, + options: { freeform: '', systemIcon: 'BsFileEarmarkImageFill' }, }, ], [ DocumentType.WEB, { layout: { view: WebBox, dataField: defaultDataKey }, - options: { _height: 300, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, waitForDoubleClickToClick: 'always' }, + options: { _height: 300, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' }, }, ], [ DocumentType.COL, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { _layout_fitWidth: true, freeform: '', _freeform_panX: 0, _freeform_panY: 0, _freeform_scale: 1 }, + options: { _layout_fitWidth: true, freeform: '', _freeform_panX: 0, _freeform_panY: 0, _freeform_scale: 1, systemIcon: 'BsFillCollectionFill' }, }, ], [ @@ -486,35 +487,35 @@ export namespace Docs { DocumentType.VID, { layout: { view: VideoBox, dataField: defaultDataKey }, - options: { _layout_currentTimecode: 0 }, + options: { _layout_currentTimecode: 0, systemIcon: 'BsFileEarmarkPlayFill' }, }, ], [ DocumentType.AUDIO, { layout: { view: AudioBox, dataField: defaultDataKey }, - options: { _height: 100, layout_fitWidth: true, layout_forceReflow: true, nativeDimModifiable: true }, + options: { _height: 100, layout_fitWidth: true, layout_forceReflow: true, nativeDimModifiable: true, systemIcon: 'BsFillVolumeUpFill' }, }, ], [ DocumentType.REC, { layout: { view: VideoBox, dataField: defaultDataKey }, - options: { _height: 100, backgroundColor: 'pink' }, + options: { _height: 100, backgroundColor: 'pink', systemIcon: 'BsFillMicFill' }, }, ], [ DocumentType.PDF, { layout: { view: PDFBox, dataField: defaultDataKey }, - options: { _layout_curPage: 1, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true }, + options: { _layout_curPage: 1, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsFileEarmarkPdfFill' }, }, ], [ DocumentType.MAP, { layout: { view: MapBox, dataField: defaultDataKey }, - options: { _height: 600, _width: 800, nativeDimModifiable: true }, + options: { _height: 600, _width: 800, nativeDimModifiable: true, systemIcon: 'BsFillPinMapFill' }, }, ], [ @@ -561,7 +562,7 @@ export namespace Docs { DocumentType.SCRIPTING, { layout: { view: ScriptingBox, dataField: defaultDataKey }, - options: {}, + options: { systemIcon: 'BsFileEarmarkCodeFill' }, }, ], [ @@ -581,7 +582,7 @@ export namespace Docs { DocumentType.EQUATION, { layout: { view: EquationBox, dataField: 'text' }, - options: { nativeDimModifiable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true }, + options: { nativeDimModifiable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, ///systemIcon: 'BsSuperscript' + BsSubscript }, ], [ @@ -623,7 +624,7 @@ export namespace Docs { DocumentType.WEBCAM, { layout: { view: RecordingBox, dataField: defaultDataKey }, - options: {}, + options: { systemIcon: 'BsFillCameraVideoFill' }, }, ], [ @@ -645,14 +646,14 @@ export namespace Docs { { // NOTE: this is unused!! ink fields are filled in directly within the InkDocument() method layout: { view: InkingStroke, dataField: 'stroke' }, - options: {}, + options: { systemIcon: 'BsFillPencilFill' }, }, ], [ DocumentType.SCREENSHOT, { layout: { view: ScreenshotBox, dataField: defaultDataKey }, - options: { nativeDimModifiable: true, nativeHeightUnfrozen: true }, + options: { nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsCameraFill' }, }, ], [ @@ -660,7 +661,7 @@ export namespace Docs { { data: '', layout: { view: ComparisonBox, dataField: defaultDataKey }, - options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always' }, + options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always', systemIcon: 'BsLayoutSplit' }, }, ], [ @@ -697,7 +698,7 @@ export namespace Docs { { data: '', layout: { view: PhysicsSimulationBox, dataField: defaultDataKey, _width: 1000, _height: 800 }, - options: { _height: 100, layout_forceReflow: true, nativeHeightUnfrozen: true, mass1: '', mass2: '', nativeDimModifiable: true, position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: '' }, + options: { _height: 100, layout_forceReflow: true, nativeHeightUnfrozen: true, mass1: '', mass2: '', nativeDimModifiable: true, position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: '', systemIcon: 'BsShareFill' }, }, ], ]); diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index d68761ba7..f42336ee7 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -58,7 +58,6 @@ export class CaptureManager extends React.Component<{}> { ) ); } - return ( <div className="capture-block"> <div className="capture-block-title">Links</div> diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index b95ce0e99..eee9066b5 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -198,10 +198,10 @@ h1, left: 0; position: absolute; z-index: 2; - background-color: $light-gray; + background-color: linen;//$light-gray; .editable-title { - background-color: $light-gray; + background-color: linen;//$light-gray; } } } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ab2e0f7c5..79c308221 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -815,7 +815,7 @@ export class MainView extends React.Component { {this.dockingContent} {this._hideUI ? null : ( - <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}> + <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> )} diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss index 36b2df73e..dd4f67106 100644 --- a/src/client/views/PropertiesButtons.scss +++ b/src/client/views/PropertiesButtons.scss @@ -20,22 +20,31 @@ $linkGap : 3px; .propertiesButtons-linkButton-empty, .propertiesButtons-linkButton-nonempty { - height: 25px; - width: 29px; - border-radius: 6px; - pointer-events: auto; - background-color: $dark-gray; - color: #fcfbf7; - text-transform: uppercase; - letter-spacing: 2px; - font-size: 75%; - transition: transform 0.2s; - text-align: center; + // margin-right: 7px; + // margin-left: 8px; + height: 28px; + // width: 226px;//29px; display: flex; - justify-content: center; align-items: center; - margin-right: 10px; - margin-left: 4px; + // height: 25px; + // width: 230px;//29px; + // display: flex; + // align-items: center; + // border-radius: 6px; + pointer-events: auto; + // background-color: $dark-gray; + // color: #fcfbf7; + // text-transform: uppercase; + // letter-spacing: 2px; + // font-size: 75%; + transition: transform 0.2s; + // text-align: center; + + + // justify-content: center; + + // margin-right: 10px; + // margin-left: 4px; &:hover { background: $medium-gray; @@ -46,25 +55,34 @@ $linkGap : 3px; .propertiesButtons-linkButton-empty.toggle-on { background-color: $medium-blue; color: $white; + width:100% } .propertiesButtons-linkButton-empty.toggle-hover { background-color: $light-blue; color: $black; + width:100% } .propertiesButtons-linkButton-empty.toggle-off { - background-color: $dark-gray; - color: white; + background-color: white;//$dark-gray; + color: black; //white; + width:100% +} + +.propertiesButtons-icon { + margin-left:8px; } .propertiesButtons { - margin-top: 3px; - grid-column: 1/4; + position:relative; width: 100%; - height: auto; - display: flex; - flex-direction: row; - flex-wrap: wrap; - padding-bottom: 5.5px; + // margin-top: 3px; +// // grid-column: 1/4; +// width: 100%; +// height: auto; +// display: flex; +// // flex-direction: row; +// // flex-wrap: wrap; +// padding-bottom: 5.5px; } .onClickFlyout-editScript { @@ -80,8 +98,8 @@ $linkGap : 3px; .propertiesButtons-button { pointer-events: auto; - padding-right: 5px; - width: 25px; + padding-right: 8px;//5px; + width: 100%;//width: 25px; border-radius: 5px; margin-right: 20px; margin-bottom: 8px; @@ -110,18 +128,32 @@ $linkGap : 3px; } } -.propertiesButtons-title { - background: $dark-gray; - color: $white; - font-size: 6px; - width: 37px; - padding: 3px; - height: 12px; - border-radius: 7px; +// .propertiesButtons-iconAndText{ +// height: 28px; +// width: 220px;//29px; +// display: flex; +// align-items: center; +// background-color: white; +// } + +.propertiesButtons-label { text-transform: uppercase; - text-align: center; - margin-top: -4px; -} + margin-left: 8px; + // margin-right: 50 px; +} + +// .propertiesButtons-title { +// background: pink; //$dark-gray; +// color: $white; +// font-size: 6px; +// width: 37px; +// padding: 3px; +// height: 12px; +// border-radius: 7px; +// text-transform: uppercase; +// text-align: center; +// margin-top: -4px; +// } .propertiesButtons-linker { height: 25px; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 74dd1c2f7..387397e9d 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Icon, Tooltip } from '@material-ui/core'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; @@ -21,6 +21,16 @@ import { DocumentView, OpenWhere } from './nodes/DocumentView'; import { pasteImageBitmap } from './nodes/WebBoxRenderer'; import './PropertiesButtons.scss'; import React = require('react'); +import { JsxElement } from 'typescript'; +import { FaBraille, FaHighlighter, FaLock, FaLockOpen, FaThumbtack } from 'react-icons/fa'; +import { AiOutlineApple, AiOutlineColumnWidth, AiOutlinePicture } from 'react-icons/ai'; +import { MdClosedCaption, MdClosedCaptionDisabled, MdGridOff, MdGridOn, MdSubtitles, MdSubtitlesOff, MdTouchApp } from 'react-icons/md'; +import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb'; +import { BiHide, BiShow } from 'react-icons/bi'; +import { BsGrid3X3GapFill } from 'react-icons/bs'; +import { TfiBarChart } from 'react-icons/tfi'; +import { CiGrid31 } from 'react-icons/ci'; +import { RxWidth } from 'react-icons/rx'; const higflyout = require('@hig/flyout'); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -30,6 +40,7 @@ enum UtilityButtonState { OpenRight, OpenExternally, } + @observer export class PropertiesButtons extends React.Component<{}, {}> { @observable public static Instance: PropertiesButtons; @@ -41,12 +52,15 @@ export class PropertiesButtons extends React.Component<{}, {}> { return !SelectionManager.SelectedSchemaDoc() && SelectionManager.Views().lastElement()?.topMost; } - propertyToggleBtn = (label: string, property: string, tooltip: (on?: any) => string, icon: (on: boolean) => string, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => { + 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); + + // console.log('current icon ' + icon(targetDoc?.[property])); + return !targetDoc ? null : ( <Tooltip title={<div className={`dash-tooltip`}>{tooltip(targetDoc?.[property])} </div>} placement="top"> - <div> + <div className="propertiesButtons-iconAndText"> <div className={`propertiesButtons-linkButton-empty toggle-${StrCast(targetDoc[property]).includes(':hover') ? 'hover' : targetDoc[property] ? 'on' : 'off'}`} onPointerDown={e => e.stopPropagation()} @@ -55,229 +69,246 @@ export class PropertiesButtons extends React.Component<{}, {}> { SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property)); } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property); }, property)}> - <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon={icon(BoolCast(targetDoc?.[property])) as any} /> + <div className="propertiesButtons-icon"> {icon(targetDoc?.[property] as any)} </div> + + <div className="propertiesButtons-label"> {label(targetDoc?.[property])}</div> + {/* <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon={icon(BoolCast(targetDoc?.[property])) as any} /> */} </div> - <div className="propertiesButtons-title">{label}</div> </div> </Tooltip> ); }; + @computed get titleButton() { + return this.propertyToggleBtn( + on => (!on ? 'SHOW TITLE' : this.selectedDoc?.['_layout_showTitle'] === 'title:hover' ? 'HIDE TITLE' : 'HOVER TITLE'), + '_layout_showTitle', + on => 'Switch between title styles', + on => (on ? <MdSubtitlesOff /> : <MdSubtitles />), // {currentIcon}, //(on ? <MdSubtitles/> :) , //,'text-width', on ? <MdSubtitles/> : <MdSubtitlesOff/>, + (dv, doc) => { + const tdoc = dv?.rootDoc || doc; + const newtitle = !tdoc._layout_showTitle ? 'title' : tdoc._layout_showTitle === 'title' ? 'title:hover' : ''; + tdoc._layout_showTitle = newtitle; + } + ); + } + @computed get lockButton() { return this.propertyToggleBtn( - 'No\xA0Drag', + on => (on ? 'UNLOCK' : 'LOCK'), // 'No\xA0Drag', '_lockedPosition', on => `${on ? 'Unlock' : 'Lock'} position to prevent dragging`, - on => 'thumbtack' + on => (on ? <FaLockOpen /> : <FaLock />) + // on => 'thumbtack' ); } + @computed get maskButton() { + //highlight text while going down and reading through return this.propertyToggleBtn( - 'Mask', + on => (on ? 'PLAIN INK' : 'HIGHLIGHTER MASK'), 'stroke_isInkMask', on => (on ? 'Make plain ink' : 'Make highlight mask'), - on => 'paint-brush', + on => (on ? <TbHighlightOff /> : <TbHighlight />), // <FaHighlighter/>,// 'paint-brush', (dv, doc) => InkingStroke.toggleMask(dv?.layoutDoc || doc) ); } + @computed get hideImageButton() { + // put in developer -- can trace on top of object and drawing is still there return this.propertyToggleBtn( - 'Background', + on => (on ? 'SHOW BACKGROUND IMAGE' : 'HIDE BACKGROUND IMAGE'), //'Background', '_hideImage', on => (on ? 'Show Image' : 'Show Background'), - on => 'portrait' + on => (on ? <BiShow /> : <BiHide />) //'portrait' ); } + @computed get clustersButton() { return this.propertyToggleBtn( - 'Clusters', + on => (on ?'DISABLE CLUSTERS' : 'HIGHLIGHT CLUSTERS'), '_freeform_useClusters', on => `${on ? 'Hide' : 'Show'} clusters`, - on => 'braille' + on => <FaBraille /> ); } @computed get panButton() { return this.propertyToggleBtn( - 'Lock\xA0View', + on => (on ? 'ENABLE PANNING' : 'DISABLE PANNING'), //'Lock\xA0View', '_lockedTransform', on => `${on ? 'Unlock' : 'Lock'} panning of view`, - on => 'lock' + on => (on ? <TbHandStop /> : <TbHandOff />) //'lock' ); } - @computed get forceActiveButton() { + + @computed get forceActiveButton() { //select text return this.propertyToggleBtn( - 'Active', + on => on ? 'INACTIVE INTERACTION' : 'ACTIVE INTERACTION', '_forceActive', on => `${on ? 'Select to activate' : 'Contents always active'} `, - on => 'eye' + on => <MdTouchApp/> // 'eye' ); } + @computed get fitContentButton() { return this.propertyToggleBtn( - 'View All', + on => (on ? 'PREVIOUS VIEW' : 'VIEW ALL'), //'View All', '_freeform_fitContentsToBox', on => `${on ? "Don't" : 'Do'} fit content to container visible area`, - on => 'object-group' - ); - } - // 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 - @computed get isLightboxButton() { - return this.propertyToggleBtn( - 'Lightbox', - 'isLightbox', - on => `${on ? 'Set' : 'Remove'} lightbox flag`, - on => 'window-restore', - onClick => { - SelectionManager.Views().forEach(dv => { - const containerDoc = dv.rootDoc; - //containerDoc.followAllLinks = - // containerDoc.noShadow = - // containerDoc.layout_disableBrushing = - // containerDoc._forceActive = - //containerDoc._freeform_fitContentsToBox = - containerDoc._isLightbox = !containerDoc._isLightbox; - //containerDoc._xPadding = containerDoc._yPadding = containerDoc._isLightbox ? 10 : undefined; - const containerContents = DocListCast(dv.dataDoc[dv.props.fieldKey ?? Doc.LayoutFieldKey(containerDoc)]); - //dv.rootDoc.onClick = ScriptField.MakeScript('{self.data = undefined; documentView.select(false)}', { documentView: 'any' }); - containerContents.forEach(doc => LinkManager.Links(doc).forEach(link => (link.link_displayLine = false))); - }); - } + on => (on ? <CiGrid31 /> : <BsGrid3X3GapFill />) //'object-group' ); } + + // // 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 + // @computed get isLightboxButton() { // developer + // return this.propertyToggleBtn( + // on => 'Lightbox', + // 'isLightbox', + // on => `${on ? 'Set' : 'Remove'} lightbox flag`, + // on => 'window-restore', + // onClick => { + // SelectionManager.Views().forEach(dv => { + // const containerDoc = dv.rootDoc; + // //containerDoc.followAllLinks = + // // containerDoc.noShadow = + // // containerDoc.disableDocBrushing = + // // containerDoc._forceActive = + // //containerDoc._freeform_fitContentsToBox = + // containerDoc._isLightbox = !containerDoc._isLightbox; + // //containerDoc._xPadding = containerDoc._yPadding = containerDoc._isLightbox ? 10 : undefined; + // const containerContents = DocListCast(dv.dataDoc[dv.props.fieldKey ?? Doc.LayoutFieldKey(containerDoc)]); + // //dv.rootDoc.onClick = ScriptField.MakeScript('{self.data = undefined; documentView.select(false)}', { documentView: 'any' }); + // containerContents.forEach(doc => LinkManager.Links(doc).forEach(link => (link.layout_linkDisplay = false))); + // }); + // } + // ); + // } + @computed get layout_fitWidthButton() { return this.propertyToggleBtn( - 'Fit\xA0Width', + on => (on ? 'RESTRICT WIDTH' : 'FIT WIDTH'), //'Fit\xA0Width', '_layout_fitWidth', on => `${on ? "Don't" : 'Do'} fit content to width of container`, - on => 'arrows-alt-h' + on => (on ? <AiOutlineColumnWidth /> : <RxWidth />) // 'arrows-alt-h' ); } + @computed get captionButton() { - return this.propertyToggleBtn( - 'Caption', + return this.propertyToggleBtn( //DEVELOPER + on => (on ? 'HIDE CAPTION' : 'SHOW CAPTION'), //'Caption', '_layout_showCaption', on => `${on ? 'Hide' : 'Show'} caption footer`, - on => 'closed-captioning', + on => (on ? <MdClosedCaptionDisabled /> : <MdClosedCaption />), //'closed-captioning', (dv, doc) => ((dv?.rootDoc || doc)._layout_showCaption = (dv?.rootDoc || doc)._layout_showCaption === undefined ? 'caption' : undefined) ); } - @computed get chromeButton() { + + @computed get chromeButton() { // developer -- removing UI decoration return this.propertyToggleBtn( - 'Controls', + on => on ? 'ENABLE UI CONTROLS' : 'DISABLE UI CONTROLS', '_chromeHidden', on => `${on ? 'Show' : 'Hide'} editing UI`, - on => 'edit', + on => on? <TbEditCircle/> : <TbEditCircleOff/> , // 'edit', (dv, doc) => ((dv?.rootDoc || doc)._chromeHidden = !(dv?.rootDoc || doc)._chromeHidden) ); } - @computed get titleButton() { - return this.propertyToggleBtn( - 'Title', - '_layout_showTitle', - on => 'Switch between title styles', - on => 'text-width', - (dv, doc) => { - const tdoc = dv?.rootDoc || doc; - const newtitle = !tdoc._layout_showTitle ? 'title' : tdoc._layout_showTitle === 'title' ? 'title:hover' : ''; - tdoc._layout_showTitle = newtitle; - } - ); - } - @computed get layout_autoHeightButton() { + + @computed get layout_autoHeightButton() { // store previous dimensions to store old values return this.propertyToggleBtn( - 'Auto\xA0Size', + on => 'Auto\xA0Size', '_layout_autoHeight', on => `Automatical vertical sizing to show all content`, on => 'arrows-alt-v' ); } + @computed get gridButton() { return this.propertyToggleBtn( - 'Grid', + on => (on ? 'HIDE GRID' : 'DISPLAY GRID'), '_freeform_backgroundGrid', on => `Display background grid in collection`, - on => 'border-all' - ); - } - @computed get groupButton() { - return this.propertyToggleBtn( - 'Group', - 'isGroup', - on => `Display collection as a Group`, - on => 'object-group', - (dv, doc) => { - doc.isGroup = !doc.isGroup; - doc.forceActive = doc.isGroup; - doc.dragWhenActive = doc.isGroup; - } - ); - } - @computed get freezeThumb() { - return this.propertyToggleBtn( - 'FreezeThumb', - '_thumb-frozen', - on => `${on ? 'Freeze' : 'Unfreeze'} thumbnail`, - on => 'snowflake', - (dv, doc) => { - if (doc['thumb-frozen']) doc['thumb-frozen'] = undefined; - else { - document.body.focus(); // so that we can access the clipboard without an error - setTimeout(() => - pasteImageBitmap((data_url: any, error: any) => { - error && console.log(error); - data_url && Utils.convertDataUri(data_url, doc[Id] + '-thumb-frozen', true).then(returnedfilename => (doc['thumb-frozen'] = new ImageField(returnedfilename))); - }) - ); - } - } + on => (on ? <MdGridOff /> :<MdGridOn /> ) //'border-all' ); } - @computed get snapButton() { + + // @computed get groupButton() { //developer + // return this.propertyToggleBtn( + // on => 'Group', + // 'isGroup', + // on => `Display collection as a Group`, + // on => 'object-group', + // (dv, doc) => { + // doc.isGroup = !doc.isGroup; + // doc.forceActive = doc.isGroup; + // } + // ); + // } + + // @computed get freezeThumb() { + // return this.propertyToggleBtn( + // 'FreezeThumb', + // '_thumb-frozen', + // on => `${on ? 'Freeze' : 'Unfreeze'} thumbnail`, + // on => 'snowflake', + // (dv, doc) => { + // if (doc['thumb-frozen']) doc['thumb-frozen'] = undefined; + // else { + // document.body.focus(); // so that we can access the clipboard without an error + // setTimeout(() => + // pasteImageBitmap((data_url: any, error: any) => { + // error && console.log(error); + // data_url && Utils.convertDataUri(data_url, doc[Id] + '-thumb-frozen', true).then(returnedfilename => (doc['thumb-frozen'] = new ImageField(returnedfilename))); + // }) + // ); + // } + // } + // ); + // } + @computed get snapButton() { // THESE ARE NOT COMING return this.propertyToggleBtn( - 'Snap\xA0Lines', + on => (on ? 'HIDE SNAP LINES' : 'SHOW SNAP LINES'), 'freeform_snapLines', on => `Display snapping lines when objects are dragged`, - on => 'th', + on => <TfiBarChart />, //'th', undefined, - true ); } - @computed - get onClickButton() { - return !this.selectedDoc ? null : ( - <Tooltip title={<div className="dash-tooltip">Choose onClick behavior</div>} placement="top"> - <div> - <div className="propertiesButtons-linkFlyout"> - <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onClickFlyout}> - <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}> - <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" /> - </div> - </Flyout> - </div> - <div className="propertiesButtons-title"> onclick </div> - </div> - </Tooltip> - ); - } - @computed - get perspectiveButton() { - return !this.selectedDoc ? null : ( - <Tooltip title={<div className="dash-tooltip">Choose view perspective</div>} placement="top"> - <div> - <div className="propertiesButtons-linkFlyout"> - <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onPerspectiveFlyout}> - <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}> - <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" /> - </div> - </Flyout> - </div> - <div className="propertiesButtons-title"> Perspective </div> - </div> - </Tooltip> - ); - } + // @computed + // get onClickButton() { + // return !this.selectedDoc ? null : ( + // <Tooltip title={<div className="dash-tooltip">Choose onClick behavior</div>} placement="top"> + // <div> + // <div className="propertiesButtons-linkFlyout"> + // <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onClickFlyout}> + // <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}> + // <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" /> + // </div> + // </Flyout> + // </div> + // <div className="propertiesButtons-title"> onclick </div> + // </div> + // </Tooltip> + // ); + // } + // @computed + // get perspectiveButton() { // gone + // return !this.selectedDoc ? null : ( + // <Tooltip title={<div className="dash-tooltip">Choose view perspective</div>} placement="top"> + // <div> + // <div className="propertiesButtons-linkFlyout"> + // <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onPerspectiveFlyout}> + // <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}> + // <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" /> + // </div> + // </Flyout> + // </div> + // <div className="propertiesButtons-title"> Perspective </div> + // </div> + // </Tooltip> + // ); + // } @undoBatch handlePerspectiveChange = (e: any) => { @@ -366,26 +397,26 @@ export class PropertiesButtons extends React.Component<{}, {}> { </div> ); } - @computed - get onPerspectiveFlyout() { - const excludedViewTypes = [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear]; + // @computed WHERE IS THIS + // get onPerspectiveFlyout() { + // const excludedViewTypes = [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear]; - const makeLabel = (value: string, label: string) => ( - <div className="radio" key={label}> - <label> - <input type="radio" value={value} checked={(this.selectedDoc?._type_collection ?? 'invalid') === value} onChange={this.handlePerspectiveChange} /> - {label} - </label> - </div> - ); - return ( - <form> - {Object.values(CollectionViewType) - .filter(type => !excludedViewTypes.includes(type)) - .map(type => makeLabel(type, type))} - </form> - ); - } + // const makeLabel = (value: string, label: string) => ( + // <div className="radio" key={label}> + // <label> + // <input type="radio" value={value} checked={(this.selectedDoc?._type_collection ?? 'invalid') === value} onChange={this.handlePerspectiveChange} /> + // {label} + // </label> + // </div> + // ); + // return ( + // <form> + // {Object.values(CollectionViewType) + // .filter(type => !excludedViewTypes.includes(type)) + // .map(type => makeLabel(type, type))} + // </form> + // ); + // } render() { const layoutField = this.selectedDoc?.[Doc.LayoutFieldKey(this.selectedDoc)]; @@ -411,22 +442,22 @@ export class PropertiesButtons extends React.Component<{}, {}> { {toggle(this.titleButton)} {toggle(this.captionButton)} {toggle(this.lockButton)} - {toggle(this.onClickButton)} + {/* {toggle(this.onClickButton)} */} {toggle(this.layout_fitWidthButton)} - {toggle(this.freezeThumb)} + {/* {toggle(this.freezeThumb)} */} {toggle(this.forceActiveButton)} {toggle(this.fitContentButton, { display: !isFreeForm && !isMap ? 'none' : '' })} - {toggle(this.isLightboxButton, { display: !isFreeForm && !isMap ? 'none' : '' })} + {/* {toggle(this.isLightboxButton, { display: !isFreeForm && !isMap ? 'none' : '' })} */} {toggle(this.layout_autoHeightButton, { display: !isText && !isStacking && !isTree ? 'none' : '' })} {toggle(this.maskButton, { display: !isInk ? 'none' : '' })} {toggle(this.hideImageButton, { display: !isImage ? 'none' : '' })} {toggle(this.chromeButton, { display: !isCollection || isNovice ? 'none' : '' })} {toggle(this.gridButton, { display: !isCollection ? 'none' : '' })} - {toggle(this.groupButton, { display: isTabView || !isCollection ? 'none' : '' })} + {/* {toggle(this.groupButton, { display: isTabView || !isCollection ? 'none' : '' })} */} {toggle(this.snapButton, { display: !isCollection ? 'none' : '' })} {toggle(this.clustersButton, { display: !isFreeForm ? 'none' : '' })} {toggle(this.panButton, { display: !isFreeForm ? 'none' : '' })} - {toggle(this.perspectiveButton, { display: !isCollection || isNovice ? 'none' : '' })} + {/* {toggle(this.perspectiveButton, { display: !isCollection || isNovice ? 'none' : '' })} */} </div> ); } diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx index e1279c9a7..ea3bb434b 100644 --- a/src/client/views/PropertiesDocContextSelector.tsx +++ b/src/client/views/PropertiesDocContextSelector.tsx @@ -19,6 +19,7 @@ type PropertiesDocContextSelectorProps = { @observer export class PropertiesDocContextSelector extends React.Component<PropertiesDocContextSelectorProps> { + @computed get _docs() { if (!this.props.DocView) return []; const target = this.props.DocView.props.Document; @@ -39,6 +40,8 @@ export class PropertiesDocContextSelector extends React.Component<PropertiesDocC }, new Set<Doc>()) .keys() ); + console.log("embeddings " + embeddings.length); + return doclayouts .filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance?.props.Document)) .filter(doc => !Doc.IsSystem(doc)) diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 897be9a32..023e08e6a 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -14,14 +14,19 @@ overflow-x: hidden; overflow-y: auto; + .propertiesView-propAndInfoGrouping{ + display: flex; + } + .propertiesView-title { - text-align: center; + text-align: left; padding-top: 12px; - padding-bottom: 12px; + // padding-bottom: 12px; + padding-left: 10px; display: flex; - font-size: 18px; + font-size: 25px; font-weight: bold; - justify-content: center; + // justify-content: center; .propertiesView-title-icon { width: 20px; @@ -39,8 +44,15 @@ } } + .propertiesView-info{ + margin-top: 20; + margin-right: 10; + float: right; + font-size: 20; + } + .propertiesView-name { - border-bottom: 1px solid black; + // border-bottom: 1px solid black; padding: 8.5px; font-size: 12.5px; @@ -49,6 +61,11 @@ } } + .propertiesView-type{ + padding: 8.5px; + font-size: 12.5px; + } + .propertiesView-settings { //border-bottom: 1px solid black; //padding: 8.5px; @@ -426,12 +443,20 @@ .propertiesView-fields-checkbox { float: right; height: 20px; - margin-top: -9px; + margin-top: -4px; + //margin-top: -9px; + display: flex; + flex-direction: column; + align-items: center; + color:black; + // justify-content: center; .propertiesView-fields-checkbox-text { font-size: 7px; - margin-top: -10px; - margin-left: 6px; + text-align: center; + margin-right: 6px; + margin-top: -10px; + // margin-left: 6px; } } @@ -830,8 +855,16 @@ } } +.propertiesView-wordTitle{ + color:darkslategray; + font-weight:200; +} + .editable-title { border: solid 1px #323232; + padding-left: 5px; + padding-top: 4px; + border-radius: 4px; height: fit-content; &:hover { @@ -839,6 +872,26 @@ } } +.propertiesView-wordType{ + color:darkslategray; + font-weight:200; +} + +.currentType{ + text-decoration: underline; + display: flex; + align-items:center; + // border: solid 1px #323232; + // padding-left: 5px; + // padding-top: 4px; + // border-radius: 4px; + // height: fit-content; +} + +.currentType-icon{ + margin-right:5px; +} + .properties-flyout { grid-column: 2/4; } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 09aac053a..9f6c86502 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1,13 +1,13 @@ import React = require('react'); import { IconLookup } from '@fortawesome/fontawesome-svg-core'; -import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; +import { faAnchor, faArrowRight, faListNumeric, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Checkbox, Tooltip } from '@material-ui/core'; +import { Checkbox, Icon, Tooltip } from '@material-ui/core'; import { intersection } from 'lodash'; import { action, computed, Lambda, observable } from 'mobx'; import { observer } from 'mobx-react'; import { ColorState, SketchPicker } from 'react-color'; -import { Doc, Field, FieldResult, HierarchyMapping, NumListCast, Opt, StrListCast } from '../../fields/Doc'; +import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, StrListCast } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData, Height, Width } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { InkField } from '../../fields/InkField'; @@ -35,6 +35,17 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector import { PropertiesDocContextSelector } from './PropertiesDocContextSelector'; import './PropertiesView.scss'; import { DefaultStyleProvider } from './StyleProvider'; +import { RichTextField } from '../../fields/RichTextField'; +import { AiFillFileText } from "react-icons/ai" //* as Icons from "react-icons/ai" // +import * as Icons from "react-icons/bs" //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" +import { GrCircleInformation } from 'react-icons/gr' +import { CgBrowser} from "react-icons/cg" +import { ImageField, VideoField, WebField } from '../../fields/URLField'; +import { FaFileVideo } from 'react-icons/fa'; //* as Icons from "react-icons/fa"; // +import { IconButton } from 'browndash-components'; +import { IconBase } from 'react-icons'; +import { MdOutlineAddShoppingCart, MdOutlineMedicalServices } from 'react-icons/md'; +import { createPromiseCapability } from 'pdfjs-dist'; const higflyout = require('@hig/flyout'); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -47,6 +58,7 @@ interface PropertiesViewProps { addDocTab: (doc: Doc, where: OpenWhere) => boolean; } + @observer export class PropertiesView extends React.Component<PropertiesViewProps> { private _widthUndo?: UndoManager.Batch; @@ -186,7 +198,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { }); rows.push( - <div className="propertiesView-field" key="newKeyValue" style={{ marginTop: '3px' }}> + <div className="propertiesView-field" key="newKeyValue" style={{ marginTop: '3px', backgroundColor: "white", textAlign: "center" }}> <EditableView key="editableView" oneLine contents={'add key:value or #tags'} height={13} fontSize={10} GetValue={() => ''} SetValue={this.setKeyValue} /> </div> ); @@ -244,11 +256,34 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return !this.selectedDoc ? null : <PropertiesDocContextSelector DocView={this.selectedDocumentView} hideTitle={true} addDocTab={this.props.addDocTab} />; } + @computed get contextCount(){ + console.log("in context count"); + if (this.selectedDocumentView){ + const target = (this.selectedDocumentView.props.Document) + const embeddings = DocListCast(target.proto_embeddings) + console.log(embeddings.length -1 ); + return (embeddings.length - 1) + } else{ + return 0; + } + } + @computed get links() { const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.currentLinkAnchor ?? this.selectedDoc; return !selAnchor ? null : <PropertiesDocBacklinksSelector Document={selAnchor} hideTitle={true} addDocTab={this.props.addDocTab} />; } + @computed get linkCount(){ + const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.currentLinkAnchor ?? this.selectedDoc; + var counter = 0; + + LinkManager.Links(selAnchor).forEach((l, i) => + counter ++ + ); + + return counter; + } + @computed get layoutPreview() { if (SelectionManager.Views().length > 1) { return '-- multiple selected --'; @@ -429,6 +464,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get fieldsCheckbox() { + // color= "primary" return <Checkbox color="primary" onChange={this.toggleCheckbox} checked={this.layoutFields} />; } @@ -436,16 +472,63 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { toggleCheckbox = () => (this.layoutFields = !this.layoutFields); @computed get editableTitle() { + const titles = new Set<string>(); SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title))); const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title); return ( - <div className="editable-title"> - <EditableView key="editableView" contents={title} height={25} fontSize={14} GetValue={() => title} SetValue={this.setTitle} /> + <div> + <div className="propertiesView-wordTitle">Title</div> + <div className="editable-title"> + <EditableView key="editableView" contents={title} height={25} fontSize={14} GetValue={() => title} SetValue={this.setTitle} /> + </div> </div> + ); } + @computed get currentComponent() { + + var iconName = StrCast(this.selectedDoc?.systemIcon) + + // if (this.selectedDoc?.type === DocumentType.COL){ + // console.log("i did it!") + // } + + + if (iconName){ + const Icon = Icons[iconName as keyof typeof Icons]; + return <Icon />; + } else{ + return <Icons.BsFillCollectionFill/> + + } + } + + @computed get currentType() { + // console.log("current type " + this.selectedDoc?.type) + + const documentType = StrCast(this.selectedDoc?.type) + var currentType: string = documentType; + var capitalizedDocType = currentType.charAt(0).toUpperCase() + currentType.slice(1) + + return ( + <div> + <div className = "propertiesView-wordType">Type</div> + <div className= "currentType"> + <div className='currentType-icon'> + {this.currentComponent} + </div> + + {capitalizedDocType} + + </div> + + </div> + + ) + } + @undoBatch @action setTitle = (value: string) => { @@ -891,9 +974,34 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get optionsSubMenu() { + let isDouble = false; + return ( <div className="propertiesView-settings" onPointerEnter={action(() => (this.inOptions = true))} onPointerLeave={action(() => (this.inOptions = false))}> - <div className="propertiesView-settings-title" onPointerDown={action(() => (this.openOptions = !this.openOptions))} style={{ backgroundColor: this.openOptions ? 'black' : '' }}> + <div className="propertiesView-settings-title" onClick ={action(() => { + if (!isDouble){ + this.openOptions = !this.openOptions + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = false; + this.openLinks = false; + this.openOptions = true; + this.openTransform = false; + this.openFields = false; + this.openSharing = false; + this.openLayout = false; + this.openFilters = false; + + + setTimeout(() => { + isDouble = false; + }, 300) + } + + )} + style={{ backgroundColor: this.openOptions ? 'black' : '' }}> Options <div className="propertiesView-settings-title-icon"> <FontAwesomeIcon icon={this.openOptions ? 'caret-down' : 'caret-right'} size="lg" color="white" /> @@ -909,9 +1017,32 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get sharingSubMenu() { + let isDouble:boolean = false; + return ( <div className="propertiesView-sharing"> - <div className="propertiesView-sharing-title" onPointerDown={action(() => (this.openSharing = !this.openSharing))} style={{ backgroundColor: this.openSharing ? 'black' : '' }}> + <div className="propertiesView-sharing-title" onClick ={action(() => { + if (!isDouble){ + this.openSharing = !this.openSharing + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = false; + this.openLinks = false; + this.openOptions = false; + this.openTransform = false; + this.openFields = false; + this.openSharing = true; + this.openLayout = false; + this.openFilters = false; + + + setTimeout(() => { + isDouble = false; + }, 300) + })} + style={{ backgroundColor: this.openSharing ? 'black' : '' }}> Sharing {'&'} Permissions <div className="propertiesView-sharing-title-icon"> <FontAwesomeIcon icon={this.openSharing ? 'caret-down' : 'caret-right'} size="lg" color="white" /> @@ -964,9 +1095,34 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { }; @computed get filtersSubMenu() { + let isDouble: boolean = false; + return ( <div className="propertiesView-filters"> - <div className="propertiesView-filters-title" onPointerDown={action(() => (this.openFilters = !this.openFilters))} style={{ backgroundColor: this.openFilters ? 'black' : '' }}> + <div className="propertiesView-filters-title" onClick ={action(() => { + if (!isDouble){ + this.openFilters = !this.openFilters + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = false; + this.openLinks = false; + this.openOptions = false; + this.openTransform = false; + this.openFields = false; + this.openSharing = false; + this.openLayout = false; + this.openFilters = true; + + + setTimeout(() => { + isDouble = false; + }, 300) + } + + )} + style={{ backgroundColor: this.openFilters ? 'black' : '' }}> Filters <div className="propertiesView-filters-title-icon"> <FontAwesomeIcon icon={this.openFilters ? 'caret-down' : 'caret-right'} size="lg" color="white" /> @@ -982,6 +1138,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get inkSubMenu() { + let isDouble = false; + return ( <> {!this.isInk ? null : ( @@ -997,7 +1155,28 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { )} <div className="propertiesView-transform"> - <div className="propertiesView-transform-title" onPointerDown={action(() => (this.openTransform = !this.openTransform))} style={{ backgroundColor: this.openTransform ? 'black' : '' }}> + <div className="propertiesView-transform-title" onClick ={action(() => { + if (!isDouble){ + this.openTransform = !this.openTransform + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = false; + this.openLinks = false; + this.openOptions = false; + this.openTransform = true; + this.openFields = false; + this.openSharing = false; + this.openLayout = false; + this.openFilters = false; + + + setTimeout(() => { + isDouble = false; + }, 300) + })} + style={{ backgroundColor: this.openTransform ? 'black' : '' }}> Transform <div className="propertiesView-transform-title-icon"> <FontAwesomeIcon icon={this.openTransform ? 'caret-down' : 'caret-right'} size="lg" color="white" /> @@ -1010,9 +1189,34 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get fieldsSubMenu() { + let isDouble: boolean = false; + return ( <div className="propertiesView-fields"> - <div className="propertiesView-fields-title" onPointerDown={action(() => (this.openFields = !this.openFields))} style={{ backgroundColor: this.openFields ? 'black' : '' }}> + <div className="propertiesView-fields-title" onClick ={action(() => { + if (!isDouble){ + this.openFields = !this.openFields + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = false; + this.openLinks = false; + this.openOptions = false; + this.openTransform = false; + this.openFields = true; + this.openSharing = false; + this.openLayout = false; + this.openFilters = false; + + + setTimeout(() => { + isDouble = false; + }, 300) + } + + )} + style={{ backgroundColor: this.openFields ? 'black' : '' }}> Fields {'&'} Tags <div className="propertiesView-fields-title-icon"> <FontAwesomeIcon icon={this.openFields ? 'caret-down' : 'caret-right'} size="lg" color="white" /> @@ -1021,7 +1225,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { {!Doc.noviceMode && this.openFields ? ( <div className="propertiesView-fields-checkbox"> {this.fieldsCheckbox} - <div className="propertiesView-fields-checkbox-text">Layout</div> + <div className="propertiesView-fields-checkbox-text">Embedding</div> </div> ) : null} {!this.openFields ? null : <div className="propertiesView-fields-content">{Doc.noviceMode ? this.noviceFields : this.expandedField}</div>} @@ -1030,37 +1234,117 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get contextsSubMenu() { + let isDouble = false; return ( <div className="propertiesView-contexts"> - <div className="propertiesView-contexts-title" onPointerDown={action(() => (this.openContexts = !this.openContexts))} style={{ backgroundColor: this.openContexts ? 'black' : '' }}> + <div className="propertiesView-contexts-title" onClick ={action(() => { + if (!isDouble){ + this.openContexts = !this.openContexts + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = true; + this.openLinks = false; + this.openOptions = false; + this.openTransform = false; + this.openFields = false; + this.openSharing = false; + this.openLayout = false; + this.openFilters = false; + + + setTimeout(() => { + isDouble = false; + }, 300) + } + + )} + style={{ backgroundColor: this.openContexts ? 'black' : '' }}> Other Contexts <div className="propertiesView-contexts-title-icon"> <FontAwesomeIcon icon={this.openContexts ? 'caret-down' : 'caret-right'} size="lg" color="white" /> </div> </div> - {this.openContexts ? <div className="propertiesView-contexts-content">{this.contexts}</div> : null} + {!this.openContexts ? null : this.contextCount > 0 ? <div className="propertiesView-contexts-content">{this.contexts}</div> : <div className="propertiesView-contexts-content">There are no other contexts.</div>} </div> ); } + + @computed get linksSubMenu() { +//onClick={action(() => (this.openLinks = !this.openLinks))} onDoubleClick={action(() => (this.openContexts = false, this.openOptions = false, this.openTransform = false, +//this.openFields = false, this.openSharing = false, this.openLayout = false, this.openFilters = false, this.openLinks = false ))} + + let isDouble = false; + return ( <div className="propertiesView-contexts"> - <div className="propertiesView-contexts-title" onPointerDown={action(() => (this.openLinks = !this.openLinks))} style={{ backgroundColor: this.openLinks ? 'black' : '' }}> + + <div className="propertiesView-contexts-title" onClick = {action(() => { + if (!isDouble){ + this.openLinks = !this.openLinks + } } )} + + onDoubleClick = {action(() => { + isDouble = true; + + this.openContexts = false; + this.openOptions = false; + this.openTransform = false; + this.openFields = false; + this.openSharing = false; + this.openLayout = false; + this.openFilters = false; + this.openLinks = true; + + setTimeout(() => { + isDouble = false; + }, 300) + } + + )} + style={{ backgroundColor: this.openLinks ? 'black' : '' }}> Linked To <div className="propertiesView-contexts-title-icon"> <FontAwesomeIcon icon={this.openLinks ? 'caret-down' : 'caret-right'} size="lg" color="white" /> </div> </div> - {this.openLinks ? <div className="propertiesView-contexts-content">{this.links}</div> : null} + {!this.openLinks ? null : this.linkCount > 0 ? <div className="propertiesView-contexts-content">{this.links}</div> : <div className="propertiesView-contexts-content">There are no current links.</div>} </div> ); } @computed get layoutSubMenu() { + let isDouble: boolean = false; + return ( <div className="propertiesView-layout"> - <div className="propertiesView-layout-title" onPointerDown={action(() => (this.openLayout = !this.openLayout))} style={{ backgroundColor: this.openLayout ? 'black' : '' }}> + <div className="propertiesView-layout-title" onClick ={action(() => { + if (!isDouble){ + this.openLayout = !this.openLayout + } } )} + onDoubleClick={action(() => { + isDouble = true; + + this.openContexts = false; + this.openLinks = false; + this.openOptions = false; + this.openTransform = false; + this.openFields = false; + this.openSharing = false; + this.openLayout = true; + this.openFilters = false; + + + setTimeout(() => { + isDouble = false; + }, 300) + } + + )} + style={{ backgroundColor: this.openLayout ? 'black' : '' }}> Layout <div className="propertiesView-layout-title-icon"> <FontAwesomeIcon icon={this.openLayout ? 'caret-down' : 'caret-right'} size="lg" color="white" /> @@ -1305,11 +1589,21 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { minWidth: this.props.width, //overflowY: this.scrolling ? "scroll" : "visible" }}> - <div className="propertiesView-title" style={{ width: this.props.width }}> - Properties + <div className = "propertiesView-propAndInfoGrouping"> + <div className="propertiesView-title" style={{ width: this.props.width }}> + Properties + </div> + <div className = "propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/')}> + <GrCircleInformation/> </div> + </div> + + <div className="propertiesView-name">{this.editableTitle}</div> + <div className = "propertiesView-type"> {this.currentType} </div> + + {this.contextsSubMenu} {this.linksSubMenu} @@ -1553,6 +1847,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { Presentation </div> <div className="propertiesView-name" style={{ borderBottom: 0 }}> + {this.editableTitle} <div className="propertiesView-presSelected"> <div className="propertiesView-selectedCount">{PresBox.Instance.selectedArray.size} selected</div> |
