Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboards): enable optional light mode for dashboards #17232

Merged
merged 33 commits into from
Mar 16, 2020
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0e835ae
refactor(ui): distill presentation mode toggle into discreet component
alexpaxton Mar 5, 2020
ec06fc8
refactor(ui): introduce foundations for Light Mode
alexpaxton Mar 6, 2020
6390d22
fix(ui): ensure light mode does not affect dashboards index view
alexpaxton Mar 6, 2020
29c2438
feat(ui): enable light mode for some chart types
alexpaxton Mar 6, 2020
0579d78
chore(ui): Merge branch 'master' into feat/light-mode-dashboards
alexpaxton Mar 11, 2020
74a1305
refactor(ui): adapt dashboard page title to light mode
alexpaxton Mar 11, 2020
8bd2c6f
refactor(ui): polish appearance of cells in light mode
alexpaxton Mar 11, 2020
334faa0
fix(ui): make detection of dashboard viewing more resilient and precise
alexpaxton Mar 11, 2020
f88734b
fix(ui): pass in missing prop
alexpaxton Mar 11, 2020
97f5573
feat(ui): allow gauge to render as either light or dark
alexpaxton Mar 11, 2020
ee87046
fix(ui): ensure light mode of gauge is scoped to dashboard cells and …
alexpaxton Mar 11, 2020
5899b22
feat(ui): refactor table graphs to conditionally render light mode
alexpaxton Mar 12, 2020
3024d56
feat(ui): enable Heatmap graphs to render in light mode
alexpaxton Mar 12, 2020
d1e2c7b
feat(ui): enable histograms to render in light mode
alexpaxton Mar 12, 2020
98b37fb
feat(ui): enable scatterplots to render in light mode
alexpaxton Mar 12, 2020
c835454
fix(ui): remove console log
alexpaxton Mar 12, 2020
3236b83
fix(ui): update test
alexpaxton Mar 12, 2020
476c6e3
refactor: calc theme state
121watts Mar 12, 2020
a689859
fix: type
121watts Mar 12, 2020
19b0f41
refactor: fix action types
121watts Mar 12, 2020
7878bdc
chore: remove dead code
121watts Mar 12, 2020
8650db5
refactor(ui): rename props from "lightMode" to "theme"
alexpaxton Mar 12, 2020
7100d23
Merge branch 'feat/light-mode-dashboards' of github.com:influxdata/in…
alexpaxton Mar 12, 2020
4b3d201
refactor(ui): make variables control bar respond to theme
alexpaxton Mar 12, 2020
a1a1854
fix(ui): update mockState to match current appState shape
alexpaxton Mar 12, 2020
5038ec2
fix(ui): update affected tests
alexpaxton Mar 12, 2020
4c2e1b5
chore: Merge branch 'master' into feat/light-mode-dashboards
alexpaxton Mar 13, 2020
1303234
refactor(theme): remove currentPage from localStorage
121watts Mar 16, 2020
927863c
chore(ui): update changelog
alexpaxton Mar 16, 2020
ded6c4f
Merge branch 'feat/light-mode-dashboards' of github.com:influxdata/in…
alexpaxton Mar 16, 2020
345ed0c
Merge branch 'master' into feat/light-mode-dashboards
alexpaxton Mar 16, 2020
a32df78
fix(ui): update test
alexpaxton Mar 16, 2020
be16888
Merge branch 'feat/light-mode-dashboards' of github.com:influxdata/in…
alexpaxton Mar 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 39 additions & 20 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Libraries
import React, {SFC, ReactChildren} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
import {connect} from 'react-redux'
import classnames from 'classnames'

// Components
import {AppWrapper} from '@influxdata/clockface'
Expand All @@ -13,44 +15,61 @@ import CloudNav from 'src/pageLayout/components/CloudNav'
import CloudOnly from 'src/shared/components/cloud/CloudOnly'

// Types
import {AppState} from 'src/types'
import {AppState, CurrentPage, Theme} from 'src/types'

interface StateProps {
inPresentationMode: boolean
currentPage: CurrentPage
theme: Theme
}
interface OwnProps {
children: ReactChildren
}

type Props = OwnProps & StateProps

const App: SFC<Props> = ({children, inPresentationMode}) => (
<>
<CloudOnly>
<CloudNav />
</CloudOnly>
<AppWrapper presentationMode={inPresentationMode}>
<Notifications />
<TooltipPortal />
<NotesPortal />
<OverlayController />
<Nav />
{children}
</AppWrapper>
</>
)
type Props = OwnProps & StateProps & WithRouterProps

const App: SFC<Props> = ({
children,
inPresentationMode,
currentPage,
theme,
}) => {
const appWrapperClass = classnames('', {
'dashboard-light-mode': currentPage === 'dashboard' && theme === 'light',
})

return (
<>
<CloudOnly>
<CloudNav />
</CloudOnly>
<AppWrapper
presentationMode={inPresentationMode}
className={appWrapperClass}
>
<Notifications />
<TooltipPortal />
<NotesPortal />
<OverlayController />
<Nav />
{children}
</AppWrapper>
</>
)
}

const mstp = (state: AppState): StateProps => {
const {
app: {
ephemeral: {inPresentationMode},
persisted: {currentPage, theme},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused why we have a separate state for determining the current page- isn't it available via router path?

Copy link
Contributor Author

@alexpaxton alexpaxton Mar 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@121watts I talked to @ebb-tide about our approach here a bit, and we concluded that it's unnecessary to have currentPage stored in persisted state. What do you think about moving it to ephemeral or somewhere else?

},
} = state

return {inPresentationMode}
return {inPresentationMode, currentPage, theme}
}

export default connect<StateProps, {}>(
mstp,
null
)(App)
)(withRouter(App))
32 changes: 29 additions & 3 deletions ui/src/dashboards/components/DashboardContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import DashboardPage from 'src/dashboards/components/DashboardPage'
import GetTimeRange from 'src/dashboards/components/GetTimeRange'
import DashboardRoute from 'src/shared/components/DashboardRoute'

// Actions
import {setCurrentPage} from 'src/shared/actions/app'

// Utils
import {GlobalAutoRefresher} from 'src/utils/AutoRefresher'

Expand All @@ -25,9 +28,18 @@ interface StateProps {
dashboard: string
}

type Props = StateProps
interface DispatchProps {
onSetCurrentPage: typeof setCurrentPage
}

type Props = StateProps & DispatchProps

const DashboardContainer: FC<Props> = ({autoRefresh, dashboard, children}) => {
const DashboardContainer: FC<Props> = ({
autoRefresh,
dashboard,
children,
onSetCurrentPage,
}) => {
useEffect(() => {
if (autoRefresh.status === Active) {
GlobalAutoRefresher.poll(autoRefresh.interval)
Expand All @@ -41,6 +53,13 @@ const DashboardContainer: FC<Props> = ({autoRefresh, dashboard, children}) => {
}
}, [autoRefresh.status, autoRefresh.interval])

useEffect(() => {
onSetCurrentPage('dashboard')
return () => {
onSetCurrentPage('not set')
}
}, [])

return (
<DashboardRoute>
<GetResource resources={[{type: ResourceType.Dashboards, id: dashboard}]}>
Expand All @@ -63,4 +82,11 @@ const mstp = (state: AppState): StateProps => {
}
}

export default connect<StateProps>(mstp)(DashboardContainer)
const mdtp: DispatchProps = {
onSetCurrentPage: setCurrentPage,
}

export default connect<StateProps, DispatchProps>(
mstp,
mdtp
)(DashboardContainer)
24 changes: 5 additions & 19 deletions ui/src/dashboards/components/DashboardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ import {withRouter, WithRouterProps} from 'react-router'
// Components
import AutoRefreshDropdown from 'src/shared/components/dropdown_auto_refresh/AutoRefreshDropdown'
import TimeRangeDropdown from 'src/shared/components/TimeRangeDropdown'
import PresentationModeToggle from 'src/shared/components/PresentationModeToggle'
import DashboardLightModeToggle from 'src/dashboards/components/DashboardLightModeToggle'
import GraphTips from 'src/shared/components/graph_tips/GraphTips'
import RenamablePageTitle from 'src/pageLayout/components/RenamablePageTitle'
import TimeZoneDropdown from 'src/shared/components/TimeZoneDropdown'
import {
SquareButton,
Button,
IconFont,
ComponentColor,
Page,
} from '@influxdata/clockface'
import {Button, IconFont, ComponentColor, Page} from '@influxdata/clockface'

// Actions
import {delayEnablePresentationMode} from 'src/shared/actions/app'
import {toggleShowVariablesControls} from 'src/userSettings/actions'
import {updateDashboard} from 'src/dashboards/actions/thunks'
import {
Expand Down Expand Up @@ -65,7 +60,6 @@ interface StateProps {
}

interface DispatchProps {
handleClickPresentationButton: typeof delayEnablePresentationMode
toggleShowVariablesControls: typeof toggleShowVariablesControls
updateDashboard: typeof updateDashboard
onSetAutoRefreshStatus: typeof setAutoRefreshStatus
Expand Down Expand Up @@ -121,11 +115,8 @@ class DashboardHeader extends Component<Props> {
: ComponentColor.Default
}
/>
<SquareButton
icon={IconFont.ExpandA}
titleText="Enter Presentation Mode"
onClick={this.handleClickPresentationButton}
/>
<DashboardLightModeToggle />
<PresentationModeToggle />
<GraphTips />
</Page.ControlBarLeft>
<Page.ControlBarRight>
Expand Down Expand Up @@ -161,10 +152,6 @@ class DashboardHeader extends Component<Props> {
updateDashboard(dashboard.id, {name})
}

private handleClickPresentationButton = (): void => {
this.props.handleClickPresentationButton()
}

private handleChooseAutoRefresh = (milliseconds: number) => {
const {
handleChooseAutoRefresh,
Expand Down Expand Up @@ -234,7 +221,6 @@ const mstp = (state: AppState): StateProps => {
const mdtp: DispatchProps = {
toggleShowVariablesControls: toggleShowVariablesControls,
updateDashboard: updateDashboard,
handleClickPresentationButton: delayEnablePresentationMode,
onSetAutoRefreshStatus: setAutoRefreshStatus,
updateQueryParams: updateQueryParams,
setDashboardTimeRange: setDashboardTimeRange,
Expand Down
106 changes: 106 additions & 0 deletions ui/src/dashboards/components/DashboardLightMode.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
Light Mode for Dashboards
------------------------------------------------------------------------------
*/

.clockface--app-wrapper.dashboard-light-mode {
background-color: $g18-cloud;
color: $g8-storm;

.cf-page-contents > .cf-dapper-scrollbars--track-y {
background-color: $g15-platinum !important;
}

.cf-page--sub-title {
color: $g13-mist;
}

.cell {
background-color: $g20-white;
}

.cell--dot-grid,
.cell--dot-grid:before,
.cell--dot-grid:after {
background-color: $g13-mist;
}

.cell:hover .cell--dot-grid,
.cell:hover .cell--dot-grid:before,
.cell:hover .cell--dot-grid:after {
background-color: $g8-storm;
}

.cell:hover .cell--draggable:hover .cell--dot-grid,
.cell:hover .cell--draggable:hover .cell--dot-grid:before,
.cell:hover .cell--draggable:hover .cell--dot-grid:after {
background-color: $c-pool;
}

.cell--context {
color: $g13-mist;
}
.cell:hover .cell--context {
color: $g8-storm;
}
.cell:hover .cell--context:hover,
.cell .cell--context.cell--context__active,
.cell:hover .cell--context.cell--context__active {
color: $c-pool;
}

.cell--note-indicator {
color: $g13-mist;

&.cell--note-indicator__active,
&:hover,
.cell:hover &:hover {
color: $c-pool;
}
}

.markdown-format {
color: $g7-graphite;

code {
font-weight: 700;
color: $c-star;
}
}

.cell--view-empty {
color: $g11-sidewalk;
}
.variables-control-bar--empty,
.variables-control-bar--full {
background-color: $g20-white;
}
}

/*
Light Mode Cells
------------------------------------------------------------------------------
*/

.clockface--app-wrapper.dashboard-light-mode {
.react-resizable-handle {
border-right-color: $g14-chromium;
border-bottom-color: $g14-chromium;

&:before,
&:after {
background-color: $g20-white;
}

&:hover {
border-right-color: $c-comet;
border-bottom-color: $c-comet;
}
}
.react-grid-item.resizing .react-resizable-handle,
.react-grid-item.react-draggable-dragging .react-resizable-handle {
opacity: 1;
border-right-color: $c-comet;
border-bottom-color: $c-comet;
}
}
66 changes: 66 additions & 0 deletions ui/src/dashboards/components/DashboardLightModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Libraries
import React, {FC} from 'react'
import {connect} from 'react-redux'

// Components
import {SelectGroup} from '@influxdata/clockface'

// Actions
import {setTheme} from 'src/shared/actions/app'

// Types
import {AppState, Theme} from 'src/types'

interface StateProps {
theme: Theme
}

interface DispatchProps {
onSetTheme: typeof setTheme
}

interface OwnProps {}

type Props = OwnProps & StateProps & DispatchProps

const DashboardLightModeToggle: FC<Props> = ({theme, onSetTheme}) => {
return (
<SelectGroup testID="presentation-mode-toggle">
<SelectGroup.Option
onClick={() => onSetTheme('dark')}
value={false}
id="presentation-mode-toggle--dark"
active={theme === 'dark'}
>
Dark
</SelectGroup.Option>
<SelectGroup.Option
onClick={() => onSetTheme('light')}
id="presentation-mode-toggle--light"
value={true}
active={theme === 'light'}
>
Light
</SelectGroup.Option>
</SelectGroup>
)
}

const mstp = (state: AppState): StateProps => {
const {
app: {
persisted: {theme},
},
} = state

return {theme}
}

const mdtp: DispatchProps = {
onSetTheme: setTheme,
}

export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(DashboardLightModeToggle)
2 changes: 2 additions & 0 deletions ui/src/mockState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const localState: LocalStorage = {
autoRefresh: 0,
showTemplateControlBar: false,
timeZone: 'Local' as TimeZone,
theme: 'dark',
currentPage: 'not set',
},
},
VERSION: '2.0.0',
Expand Down
Loading