diff options
-rw-r--r-- | src/client/views/DashboardView.scss | 39 | ||||
-rw-r--r-- | src/client/views/DashboardView.tsx | 50 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 1 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 20 | ||||
-rw-r--r-- | src/client/views/global/globalCssVariables.scss | 2 | ||||
-rw-r--r-- | src/client/views/topbar/TopBar.scss | 366 | ||||
-rw-r--r-- | src/client/views/topbar/TopBar.tsx | 85 |
7 files changed, 341 insertions, 222 deletions
diff --git a/src/client/views/DashboardView.scss b/src/client/views/DashboardView.scss new file mode 100644 index 000000000..1896d7bfb --- /dev/null +++ b/src/client/views/DashboardView.scss @@ -0,0 +1,39 @@ +.dashboard-view { + padding: 50px; + display: flex; + flex-direction: row; + + .left-menu { + display: flex; + flex-direction: column; + width: 300px; + } + + .all-dashboards { + display: flex; + flex-direction: row; + flex-wrap: wrap; + overflow-y: scroll; + } +} + + + +.dashboard-container { + border-radius: 10px; + width: 250px; + border: solid .5px grey; + display: flex; + flex-direction: column; + margin: 0 30px 30px 30px; + overflow: hidden; + + &:hover { + border: solid 1.5px grey; + } + + .title { + margin: 10px; + font-weight: 500; + } +}
\ No newline at end of file diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx new file mode 100644 index 000000000..5fd9b550d --- /dev/null +++ b/src/client/views/DashboardView.tsx @@ -0,0 +1,50 @@ +import { observable } from "mobx"; +import { observer } from "mobx-react"; +import * as React from 'react'; +import { Doc, DocListCast } from "../../fields/Doc"; +import { Id } from "../../fields/FieldSymbols"; +import { Cast, ImageCast, StrCast } from "../../fields/Types"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; +import { UndoManager } from "../util/UndoManager"; +import "./DashboardView.scss" + +@observer +export class DashboardView extends React.Component { + + //TODO: delete dashboard, share dashboard, etc. + + newDashboard = async () => { + const batch = UndoManager.StartBatch("new dash"); + await CurrentUserUtils.createNewDashboard(Doc.UserDoc()); + batch.end(); + } + + clickDashboard = async (e: React.MouseEvent, dashboard: Doc) => { + if (e.detail === 2) { + Doc.UserDoc().activeDashboard = dashboard + } + } + + render() { + const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data); + return <div className="dashboard-view"> + <div className="left-menu"> + <div onClick={this.newDashboard}>New</div> + <div>All Dashboards</div> + </div> + <div className="all-dashboards"> + {myDashboards.map((dashboard) => + <div className="dashboard-container" key={dashboard[Id]} onClick={(e) => { this.clickDashboard(e, dashboard) }}> + <img src="https://media.istockphoto.com/photos/hot-air-balloons-flying-over-the-botan-canyon-in-turkey-picture-id1297349747?b=1&k=20&m=1297349747&s=170667a&w=0&h=oH31fJty_4xWl_JQ4OIQWZKP8C6ji9Mz7L4XmEnbqRU="></img> + <div className="title"> {StrCast(dashboard.title)} </div> + </div> + + )} + {myDashboards.map((dashboard) => { + console.log(dashboard.thumb) + })} + + </div> + </div> + } +} diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 517fe097c..49c2dcf34 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -10,6 +10,7 @@ import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { LinkManager } from "../util/LinkManager"; import { RecordingApi } from "../util/RecordingApi"; import { CollectionView } from "./collections/CollectionView"; +import { DashboardView } from './DashboardView'; import { MainView } from "./MainView"; AssignAllExtensions(); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 15e1dbe18..cdf341c3b 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -37,6 +37,7 @@ import { CollectionView, CollectionViewType } from './collections/CollectionView import "./collections/TreeView.scss"; import { ComponentDecorations } from './ComponentDecorations'; import { ContextMenu } from './ContextMenu'; +import { DashboardView } from './DashboardView'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; import { GestureOverlay } from './GestureOverlay'; @@ -659,12 +660,19 @@ export class MainView extends React.Component { {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null} {DocumentLinksButton.LinkEditorDocView ? <LinkMenu clearLinkEditor={action(() => DocumentLinksButton.LinkEditorDocView = undefined)} docView={DocumentLinksButton.LinkEditorDocView} /> : (null)} {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)} - <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 1999 }} > - <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} /> - </div> - <GestureOverlay > - {this.mainDashboardArea} - </GestureOverlay> + + {Doc.UserDoc().activeDashboard ? + <> + <div style={{ position: "relative", display: LightboxView.LightboxDoc ? "none" : undefined, zIndex: 1999 }} > + <CollectionMenu panelWidth={this.topMenuWidth} panelHeight={this.topMenuHeight} /> + </div> + <GestureOverlay > + {this.mainDashboardArea} + </GestureOverlay> + </> : + <DashboardView/> + } + <PreviewCursor /> <TaskCompletionBox /> <ContextMenu /> diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss index a14634bdc..d41f9e06a 100644 --- a/src/client/views/global/globalCssVariables.scss +++ b/src/client/views/global/globalCssVariables.scss @@ -38,7 +38,7 @@ $small-text: 9px; // misc values $border-radius: 0.3em; $search-thumnail-size: 130; -$topbar-height: 32px; +$topbar-height: 50px; $antimodemenu-height: 36px; // dragged items diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss index 923f1892e..9a8e7c2e5 100644 --- a/src/client/views/topbar/TopBar.scss +++ b/src/client/views/topbar/TopBar.scss @@ -1,29 +1,30 @@ @import "../global/globalCssVariables"; .topbar-container { - display: flex; - flex-direction: column; - width: 100%; - position: relative; - font-size: 10px; - line-height: 1; - overflow-y: auto; - overflow-x: visible; - background: $dark-gray; - overflow: visible; - z-index: 1000; - - .topbar-bar { - height: $topbar-height; - display: grid; - grid-auto-columns: 33.3% 33.3% 33.3%; - align-items: center; - background-color: $dark-gray; - - .topBar-icon { + display: flex; + flex-direction: column; + width: 100%; + position: relative; + font-size: 10px; + line-height: 1; + overflow-y: auto; + overflow-x: visible; + background: $dark-gray; + overflow: visible; + z-index: 1000; + + .topbar-button-text { + color: $white; + padding: 10px; + size: 15; + + &:hover { + font-weight: 500; + } + } + + .topbar-button-icon { cursor: pointer; - font-size: 12.5px; - font-family: 'Roboto'; width: fit-content; display: flex; justify-content: center; @@ -31,190 +32,179 @@ align-items: center; justify-self: center; align-self: center; - border-radius: $standard-border-radius; padding: 5px; transition: linear 0.2s; - color: $black; - background-color: $light-gray; + color: $white; &:hover { - background-color: darken($color: $light-gray, $amount: 20); + background-color: darken($color: $light-gray, $amount: 20); } - } - - - - - .topbar-center { - grid-column: 2; - display: inline-flex; - justify-content: center; + } + + .topbar-title { + color: $white; + font-size: 17; + font-weight: 500; + } + + .topbar-bar { + height: $topbar-height; + display: grid; + grid-auto-columns: 33.3% 33.3% 33.3%; align-items: center; - gap: 5px; - - .topbar-dashboards { - display: flex; - flex-direction: row; - gap: 5px; + background-color: $dark-gray; + + .topbar-center { + grid-column: 2; + display: inline-flex; + justify-content: center; + align-items: center; + gap: 5px; + + .topbar-dashboards { + display: flex; + flex-direction: row; + gap: 5px; + } } - .topbar-lozenge-dashboard { - display: flex; - - - - .topbar-dashSelect { - border: none; - background-color: $dark-gray; - color: $white; - font-family: 'Roboto'; - font-size: 17; - font-weight: 500; - - &:hover { - cursor: pointer; - } - } - } - } - - - .topbar-right { - grid-column: 3; - position: relative; - display: flex; - justify-content: flex-end; - gap: 5px; - margin-right: 5px; - } - - .topbar-left { - grid-column: 1; - color: black; - font-family: 'Roboto'; - position: relative; - display: flex; - width: fit-content; - gap: 5px; - .topBar-icon:hover { - background-color: $close-red; + .topbar-right { + grid-column: 3; + position: relative; + display: flex; + justify-content: flex-end; + gap: 5px; + margin-right: 5px; } - .topbar-lozenge-user, - .topbar-lozenge { - height: 23; - font-size: 12; - color: white; - font-family: 'Roboto'; - font-weight: 400; - padding: 4px; - align-self: center; - margin-left: 7px; - display: flex; - align-items: center; - - .topbar-dashSelect { - border: none; - background-color: transparent; - color: black; - font-family: 'Roboto'; - font-size: 17; - font-weight: 500; - - &:hover { + .topbar-left { + grid-column: 1; + color: black; + font-family: 'Roboto'; + position: relative; + display: flex; + width: fit-content; + gap: 5px; + + .topBar-icon:hover { + background-color: $close-red; + } + + .topbar-lozenge-user, + .topbar-lozenge { + height: 23; + font-size: 12; + color: white; + font-family: 'Roboto'; + font-weight: 400; + padding: 4px; + align-self: center; + margin-left: 7px; + display: flex; + align-items: center; + + .topbar-dashSelect { + border: none; + background-color: transparent; + color: black; + font-family: 'Roboto'; + font-size: 17; + font-weight: 500; + + &:hover { + cursor: pointer; + } + } + } + + .topbar-logoff { + border-radius: 3px; + background: olivedrab; + color: white; + display: none; + margin-left: 5px; + padding: 1px 2px 1px 2px; cursor: pointer; - } - } - } - - .topbar-logoff { - border-radius: 3px; - background: olivedrab; - color: white; - display: none; - margin-left: 5px; - padding: 1px 2px 1px 2px; - cursor: pointer; - } - - .topbar-logoff { - background: red; - } - - .topbar-lozenge-user:hover { - .topbar-logoff { - display: inline-block; - } - } - } - - .topbar-barChild { + } - &.topbar-collection { - flex: 0 1 auto; - margin-left: 2px; - margin-right: 2px - } - - &.topbar-input { - margin: 5px; - border-radius: 20px; - border: $dark-gray; - display: block; - width: 130px; - -webkit-transition: width 0.4s; - transition: width 0.4s; - /* align-self: stretch; */ - outline: none; - - &:focus { - width: 500px; - outline: none; - } - } - - &.topbar-filter { - align-self: stretch; - - button { - transform: none; - - &:hover { - transform: none; - } - } - } + .topbar-logoff { + background: red; + } - &.topbar-submit { - margin-left: 2px; - margin-right: 2px + .topbar-lozenge-user:hover { + .topbar-logoff { + display: inline-block; + } + } } - &.topbar-close { - color: $white; - max-height: $topbar-height; + .topbar-barChild { + + &.topbar-collection { + flex: 0 1 auto; + margin-left: 2px; + margin-right: 2px + } + + &.topbar-input { + margin: 5px; + border-radius: 20px; + border: $dark-gray; + display: block; + width: 130px; + -webkit-transition: width 0.4s; + transition: width 0.4s; + /* align-self: stretch; */ + outline: none; + + &:focus { + width: 500px; + outline: none; + } + } + + &.topbar-filter { + align-self: stretch; + + button { + transform: none; + + &:hover { + transform: none; + } + } + } + + &.topbar-submit { + margin-left: 2px; + margin-right: 2px + } + + &.topbar-close { + color: $white; + max-height: $topbar-height; + } } - } - } + } } .topbar-results { - display: flex; - flex-direction: column; - top: 300px; - display: flex; - flex-direction: column; - height: 100%; - overflow: visible; - - .no-result { - width: 500px; - background: $light-gray; - padding: 10px; - height: 50px; - text-transform: uppercase; - text-align: left; - font-weight: bold; - } + display: flex; + flex-direction: column; + top: 300px; + display: flex; + flex-direction: column; + height: 100%; + overflow: visible; + + .no-result { + width: 500px; + background: $light-gray; + padding: 10px; + height: 50px; + text-transform: uppercase; + text-align: left; + font-weight: bold; + } }
\ No newline at end of file diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index e486bcb52..1a11925dc 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -5,7 +5,7 @@ import { observer } from "mobx-react"; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; -import { StrCast } from '../../../fields/Types'; +import { Cast, StrCast } from '../../../fields/Types'; import { Utils } from '../../../Utils'; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { SettingsManager } from "../../util/SettingsManager"; @@ -20,29 +20,54 @@ import "./TopBar.scss"; */ @observer export class TopBar extends React.Component { - render() { - const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data); - return ( - //TODO:glr Add support for light / dark mode - <div style={{ pointerEvents: "all" }} className="topbar-container"> - <div className="topbar-bar" style={{ background: Colors.DARK_GRAY, borderBottom: Borders.STANDARD }}> - <div className="topbar-left"> + navigateToHome = () => { + Doc.UserDoc().activeDashboard = undefined + } + render() { + const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data); + const activeDashboard = Cast(Doc.UserDoc().activeDashboard, Doc, null) + return ( + //TODO:glr Add support for light / dark mode + <div style={{ pointerEvents: "all" }} className="topbar-container"> + <div className="topbar-bar" style={{ background: Colors.DARK_GRAY, borderBottom: Borders.STANDARD }}> + <div className="topbar-left"> + <div className="topbar-button-text" onClick={this.navigateToHome}>Home</div> + </div> + <div className="topbar-center" > + <div className="topbar-title"> + {activeDashboard ? StrCast(activeDashboard.title) : "Dash"} + </div> + </div> + <div className="topbar-right" > + <div className="topbar-button-icon" > + <FontAwesomeIcon icon="question-circle" /> + </div> + <div className="topbar-button-icon" onClick={() => SettingsManager.Instance.open()}> + <FontAwesomeIcon icon="cog" /> + </div> + </div> + + {/* <div className="topbar-left"> <div className="topbar-lozenge-user"> {`${Doc.CurrentUserEmail}`} </div> <div className="topbar-icon" onClick={() => window.location.assign(Utils.prepend("/logout"))}> {"Log out"} </div> - </div> - <div className="topbar-center" > + </div> */} + {/* <div className="topbar-center" > <div className="topbar-lozenge-dashboard"> - <select className="topbar-dashSelect" onChange={undoBatch(e => CurrentUserUtils.openDashboard(Doc.UserDoc(), myDashboards[Number(e.target.value)]))} + <div style={{ color: Colors.WHITE }}> + {activeDashboard ? StrCast(activeDashboard.title) : "Dash"} + </div> */} + + {/* <select className="topbar-dashSelect" onChange={undoBatch(e => CurrentUserUtils.openDashboard(Doc.UserDoc(), myDashboards[Number(e.target.value)]))} value={myDashboards.indexOf(CurrentUserUtils.ActiveDashboard)} style={{ color: Colors.WHITE }}> {myDashboards.map((dash, i) => <option key={dash[Id]} value={i}> {StrCast(dash.title)} </option>)} - </select> - </div> - <div className="topbar-dashboards"> + </select> */} + {/* </div> */} + {/* <div className="topbar-dashboards"> <Tooltip title={<div className="dash-tooltip">Create a new dashboard </div>} placement="bottom"><div className="topbar-icon" onClick={async () => { const batch = UndoManager.StartBatch("new dash"); await CurrentUserUtils.createNewDashboard(Doc.UserDoc()); @@ -65,19 +90,25 @@ export class TopBar extends React.Component { Explore<FontAwesomeIcon icon="map" /> </div> </Tooltip> - </div> - </div> - <div className="topbar-right" > - <div className="topbar-icon" onClick={() => window.open( + </div> */} + {/* </div> */} + {/* <div className="topbar-right" > */} + {/* <div onClick={() => window.open( "https://brown-dash.github.io/Dash-Documentation/", "_blank")}> - {"Help"}<FontAwesomeIcon icon="question-circle" /> - </div> - <div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}> - {"Settings"}<FontAwesomeIcon icon="cog" /> + <FontAwesomeIcon icon="question-circle" /> + </div> + <div onClick={() => SettingsManager.Instance.open()}> + <FontAwesomeIcon icon="cog" /> + </div> */} + {/* <div className="topbar-icon" > + <FontAwesomeIcon icon="question-circle" /> + </div> + <div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}> + <FontAwesomeIcon icon="cog" /> + </div> + </div> */} </div> - </div> - </div> - </div > - ); - } + </div > + ); + } }
\ No newline at end of file |