diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 6272dd485b..03157d8989 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -2,7 +2,6 @@ import React, {SFC, ReactChildren} from 'react' import SideNav from 'src/side_nav' import Notifications from 'src/shared/components/Notifications' -import Overlay from 'src/shared/components/OverlayTechnology' interface Props { children: ReactChildren @@ -10,7 +9,6 @@ interface Props { const App: SFC = ({children}) => (
- {children} diff --git a/ui/src/dashboards/components/DashboardsPageContents.tsx b/ui/src/dashboards/components/DashboardsPageContents.tsx index a8c1fbbb00..c09b14dfcf 100644 --- a/ui/src/dashboards/components/DashboardsPageContents.tsx +++ b/ui/src/dashboards/components/DashboardsPageContents.tsx @@ -1,5 +1,4 @@ import React, {Component, MouseEvent} from 'react' -import {connect} from 'react-redux' import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' @@ -8,11 +7,7 @@ import ImportDashboardOverlay from 'src/dashboards/components/ImportDashboardOve import SearchBar from 'src/hosts/components/SearchBar' import FancyScrollbar from 'src/shared/components/FancyScrollbar' import {ErrorHandling} from 'src/shared/decorators/errors' -import { - showOverlay as showOverlayAction, - ShowOverlayActionCreator, -} from 'src/shared/actions/overlayTechnology' -import {OverlayContext} from 'src/shared/components/OverlayTechnology' +import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology' import {Dashboard} from 'src/types' import {Notification} from 'src/types/notifications' @@ -27,12 +22,12 @@ interface Props { onExportDashboard: (dashboard: Dashboard) => () => void onImportDashboard: (dashboard: Dashboard) => void notify: (message: Notification) => void - showOverlay: ShowOverlayActionCreator dashboardLink: string } interface State { searchTerm: string + isOverlayVisible: boolean } @ErrorHandling @@ -42,6 +37,7 @@ class DashboardsPageContents extends Component { this.state = { searchTerm: '', + isOverlayVisible: false, } } @@ -83,31 +79,34 @@ class DashboardsPageContents extends Component { const {onCreateDashboard} = this.props return ( -
-

{this.panelTitle}

-
- - - <> - - - - + <> +
+

{this.panelTitle}

+
+ + + <> + + + + +
-
+ {this.renderImportOverlay} + ) } @@ -136,30 +135,24 @@ class DashboardsPageContents extends Component { this.setState({searchTerm}) } - private showImportOverlay = (): void => { - const {showOverlay, onImportDashboard, notify} = this.props - const options = { - dismissOnClickOutside: false, - dismissOnEscape: false, - } + private handleToggleOverlay = (): void => { + this.setState({isOverlayVisible: !this.state.isOverlayVisible}) + } - showOverlay( - - {({onDismissOverlay}) => ( - - )} - , - options + private get renderImportOverlay(): JSX.Element { + const {onImportDashboard, notify} = this.props + const {isOverlayVisible} = this.state + + return ( + + + ) } } -const mapDispatchToProps = { - showOverlay: showOverlayAction, -} - -export default connect(null, mapDispatchToProps)(DashboardsPageContents) +export default DashboardsPageContents diff --git a/ui/src/dashboards/components/ImportDashboardOverlay.tsx b/ui/src/dashboards/components/ImportDashboardOverlay.tsx index c89dba6fc8..502d14e17d 100644 --- a/ui/src/dashboards/components/ImportDashboardOverlay.tsx +++ b/ui/src/dashboards/components/ImportDashboardOverlay.tsx @@ -1,9 +1,9 @@ import React, {PureComponent} from 'react' import _ from 'lodash' -import Container from 'src/shared/components/overlay/OverlayContainer' -import Heading from 'src/shared/components/overlay/OverlayHeading' -import Body from 'src/shared/components/overlay/OverlayBody' +import Container from 'src/reusable_ui/components/overlays/OverlayContainer' +import Heading from 'src/reusable_ui/components/overlays/OverlayHeading' +import Body from 'src/reusable_ui/components/overlays/OverlayBody' import DragAndDrop from 'src/shared/components/DragAndDrop' import {notifyDashboardImportFailed} from 'src/shared/copy/notifications' diff --git a/ui/src/data_explorer/containers/DataExplorer.tsx b/ui/src/data_explorer/containers/DataExplorer.tsx index 69156f4e98..18e87ce439 100644 --- a/ui/src/data_explorer/containers/DataExplorer.tsx +++ b/ui/src/data_explorer/containers/DataExplorer.tsx @@ -13,7 +13,7 @@ import QueryMaker from 'src/data_explorer/components/QueryMaker' import Visualization from 'src/data_explorer/components/Visualization' import WriteDataForm from 'src/data_explorer/components/WriteDataForm' import ResizeContainer from 'src/shared/components/ResizeContainer' -import OverlayTechnologies from 'src/shared/components/OverlayTechnologies' +import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology' import ManualRefresh from 'src/shared/components/ManualRefresh' import AutoRefreshDropdown from 'src/shared/components/AutoRefreshDropdown' import TimeRangeDropdown from 'src/shared/components/TimeRangeDropdown' @@ -49,7 +49,7 @@ interface Props { } interface State { - showWriteForm: boolean + isWriteFormVisible: boolean } @ErrorHandling @@ -58,7 +58,7 @@ export class DataExplorer extends PureComponent { super(props) this.state = { - showWriteForm: false, + isWriteFormVisible: false, } } @@ -101,21 +101,19 @@ export class DataExplorer extends PureComponent { queryConfigActions, } = this.props - const {showWriteForm} = this.state + const {isWriteFormVisible} = this.state return ( <> - {showWriteForm ? ( - - - - ) : null} + + + { } private handleCloseWriteData = (): void => { - this.setState({showWriteForm: false}) + this.setState({isWriteFormVisible: false}) } private handleOpenWriteData = (): void => { - this.setState({showWriteForm: true}) + this.setState({isWriteFormVisible: true}) } private handleChooseTimeRange = (timeRange: TimeRange): void => { diff --git a/ui/src/flux/components/EmptyFluxPage.tsx b/ui/src/flux/components/EmptyFluxPage.tsx new file mode 100644 index 0000000000..c03a9501c1 --- /dev/null +++ b/ui/src/flux/components/EmptyFluxPage.tsx @@ -0,0 +1,25 @@ +import React, {SFC} from 'react' + +import PageHeader from 'src/shared/components/PageHeader' + +interface Props { + onShowOverlay: () => void + overlay: JSX.Element +} + +const EmptyFluxPage: SFC = ({onShowOverlay, overlay}) => ( +
+ +
+
+

You do not have a configured Flux source

+ +
+
+ {overlay} +
+) + +export default EmptyFluxPage diff --git a/ui/src/flux/components/FluxHeader.tsx b/ui/src/flux/components/FluxHeader.tsx index d833ce48cf..d6ac9769da 100644 --- a/ui/src/flux/components/FluxHeader.tsx +++ b/ui/src/flux/components/FluxHeader.tsx @@ -1,60 +1,70 @@ import React, {PureComponent} from 'react' -import {connect} from 'react-redux' import FluxOverlay from 'src/flux/components/FluxOverlay' -import {OverlayContext} from 'src/shared/components/OverlayTechnology' +import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology' import PageHeader from 'src/shared/components/PageHeader' -import { - showOverlay, - ShowOverlayActionCreator, -} from 'src/shared/actions/overlayTechnology' import {Service} from 'src/types' interface Props { - showOverlay: ShowOverlayActionCreator service: Service } -class FluxHeader extends PureComponent { +interface State { + isOverlayVisible: boolean +} + +class FluxHeader extends PureComponent { + constructor(props: Props) { + super(props) + + this.state = { + isOverlayVisible: false, + } + } + public render() { return ( - + <> + + {this.overlay} + ) } + private handleToggleOverlay = (): void => { + this.setState({isOverlayVisible: !this.state.isOverlayVisible}) + } + private get optionsComponents(): JSX.Element { return ( - ) } - private overlay = () => { + private get overlay(): JSX.Element { const {service} = this.props + const {isOverlayVisible} = this.state - this.props.showOverlay( - - {({onDismissOverlay}) => ( - - )} - , - {} + return ( + + + ) } } -const mdtp = { - showOverlay, -} - -export default connect(null, mdtp)(FluxHeader) +export default FluxHeader diff --git a/ui/src/flux/containers/CheckServices.tsx b/ui/src/flux/containers/CheckServices.tsx index fe546efed1..057a1f4981 100644 --- a/ui/src/flux/containers/CheckServices.tsx +++ b/ui/src/flux/containers/CheckServices.tsx @@ -3,8 +3,9 @@ import {connect} from 'react-redux' import {WithRouterProps} from 'react-router' import {FluxPage} from 'src/flux' +import EmptyFluxPage from 'src/flux/components/EmptyFluxPage' import FluxOverlay from 'src/flux/components/FluxOverlay' -import {OverlayContext} from 'src/shared/components/OverlayTechnology' +import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology' import {Source, Service, Notification} from 'src/types' import {Links} from 'src/types/flux' import {notify as notifyAction} from 'src/shared/actions/notifications' @@ -12,26 +13,37 @@ import { updateScript as updateScriptAction, UpdateScript, } from 'src/flux/actions' -import * as a from 'src/shared/actions/overlayTechnology' -import * as b from 'src/shared/actions/services' +import * as actions from 'src/shared/actions/services' export const NotificationContext = React.createContext() -const actions = {...a, ...b} - interface Props { sources: Source[] services: Service[] children: ReactChildren - showOverlay: a.ShowOverlayActionCreator - fetchServicesAsync: b.FetchServicesAsync + fetchServicesAsync: actions.FetchServicesAsync notify: (message: Notification) => void updateScript: UpdateScript script: string links: Links } -export class CheckServices extends PureComponent { +interface State { + isOverlayShown: boolean +} + +export class CheckServices extends PureComponent< + Props & WithRouterProps, + State +> { + constructor(props: Props & WithRouterProps) { + super(props) + + this.state = { + isOverlayShown: false, + } + } + public async componentDidMount() { const source = this.props.sources.find( s => s.id === this.props.params.sourceID @@ -44,7 +56,7 @@ export class CheckServices extends PureComponent { await this.props.fetchServicesAsync(source) if (!this.props.services.length) { - this.overlay() + this.setState({isOverlayShown: true}) } } @@ -52,7 +64,12 @@ export class CheckServices extends PureComponent { const {services, notify, updateScript, links, script} = this.props if (!this.props.services.length) { - return null // put loading spinner here + return ( + + ) } return ( @@ -65,6 +82,7 @@ export class CheckServices extends PureComponent { notify={notify} updateScript={updateScript} /> + {this.renderOverlay} ) } @@ -75,31 +93,31 @@ export class CheckServices extends PureComponent { return sources.find(s => s.id === params.sourceID) } - private overlay() { - const {showOverlay, services} = this.props + private get renderOverlay(): JSX.Element { + const {isOverlayShown} = this.state - if (services.length) { - return - } - - showOverlay( - - {({onDismissOverlay}) => ( - - )} - , - {} + return ( + + + ) } + + private handleShowOverlay = (): void => { + this.setState({isOverlayShown: true}) + } + + private handleDismissOverlay = (): void => { + this.setState({isOverlayShown: false}) + } } const mdtp = { fetchServicesAsync: actions.fetchServicesAsync, - showOverlay: actions.showOverlay, updateScript: updateScriptAction, notify: notifyAction, } diff --git a/ui/src/shared/components/overlay/OverlayBody.tsx b/ui/src/reusable_ui/components/overlays/OverlayBody.tsx similarity index 100% rename from ui/src/shared/components/overlay/OverlayBody.tsx rename to ui/src/reusable_ui/components/overlays/OverlayBody.tsx diff --git a/ui/src/shared/components/overlay/OverlayContainer.tsx b/ui/src/reusable_ui/components/overlays/OverlayContainer.tsx similarity index 100% rename from ui/src/shared/components/overlay/OverlayContainer.tsx rename to ui/src/reusable_ui/components/overlays/OverlayContainer.tsx diff --git a/ui/src/shared/components/overlay/OverlayHeading.tsx b/ui/src/reusable_ui/components/overlays/OverlayHeading.tsx similarity index 93% rename from ui/src/shared/components/overlay/OverlayHeading.tsx rename to ui/src/reusable_ui/components/overlays/OverlayHeading.tsx index c37034d16a..9f302d24c0 100644 --- a/ui/src/shared/components/overlay/OverlayHeading.tsx +++ b/ui/src/reusable_ui/components/overlays/OverlayHeading.tsx @@ -1,7 +1,7 @@ import React, {PureComponent, ReactChildren} from 'react' interface Props { - children?: ReactChildren + children?: ReactChildren | JSX.Element title: string onDismiss?: () => void } diff --git a/ui/src/reusable_ui/components/overlays/OverlayTechnology.tsx b/ui/src/reusable_ui/components/overlays/OverlayTechnology.tsx new file mode 100644 index 0000000000..0d0f14f9fd --- /dev/null +++ b/ui/src/reusable_ui/components/overlays/OverlayTechnology.tsx @@ -0,0 +1,76 @@ +import React, {Component} from 'react' +import classnames from 'classnames' +import {ErrorHandling} from 'src/shared/decorators/errors' + +interface Props { + children: JSX.Element + visible: boolean +} + +interface State { + showChildren: boolean +} + +@ErrorHandling +class OverlayTechnology extends Component { + public static getDerivedStateFromProps(props) { + if (props.visible) { + return {showChildren: true} + } + + return {} + } + + private animationTimer: number + + constructor(props: Props) { + super(props) + + this.state = { + showChildren: false, + } + } + + public componentDidUpdate(prevProps) { + if (prevProps.visible && !this.props.visible) { + clearTimeout(this.animationTimer) + this.animationTimer = window.setTimeout(this.hideChildren, 300) + } + } + + public render() { + return ( +
+ {this.childContainer} +
+
+ ) + } + + private get childContainer(): JSX.Element { + const {children} = this.props + const {showChildren} = this.state + + if (showChildren) { + return ( +
+ {children} +
+ ) + } + + return
+ } + + private get overlayClass(): string { + const {visible} = this.props + + return classnames('overlay-tech', {show: visible}) + } + + private hideChildren = (): void => { + this.setState({showChildren: false}) + } +} + +export default OverlayTechnology diff --git a/ui/src/shared/actions/overlayTechnology.ts b/ui/src/shared/actions/overlayTechnology.ts deleted file mode 100644 index 400dd7f9b1..0000000000 --- a/ui/src/shared/actions/overlayTechnology.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {ReactElement} from 'react' - -type OverlayNodeType = ReactElement - -interface Options { - dismissOnClickOutside?: boolean - dismissOnEscape?: boolean - transitionTime?: number -} - -export type ShowOverlayActionCreator = ( - OverlayNode: OverlayNodeType, - options: Options -) => ShowOverlayAction - -interface ShowOverlayAction { - type: 'SHOW_OVERLAY' - payload: { - OverlayNode - options - } -} - -export const showOverlay = ( - OverlayNode: OverlayNodeType, - options: Options -): ShowOverlayAction => ({ - type: 'SHOW_OVERLAY', - payload: {OverlayNode, options}, -}) - -export const dismissOverlay = () => ({ - type: 'DISMISS_OVERLAY', -}) diff --git a/ui/src/shared/components/OverlayTechnology.tsx b/ui/src/shared/components/OverlayTechnology.tsx deleted file mode 100644 index ad1d3ccb5f..0000000000 --- a/ui/src/shared/components/OverlayTechnology.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, {PureComponent, Component} from 'react' -import {connect} from 'react-redux' -import {ErrorHandling} from 'src/shared/decorators/errors' - -import {dismissOverlay} from 'src/shared/actions/overlayTechnology' - -interface Props { - OverlayNode?: Component - dismissOnClickOutside?: boolean - dismissOnEscape?: boolean - transitionTime?: number - handleDismissOverlay: () => void -} - -interface State { - visible: boolean -} - -export const OverlayContext = React.createContext() - -@ErrorHandling -class Overlay extends PureComponent { - public static defaultProps: Partial = { - dismissOnClickOutside: false, - dismissOnEscape: false, - transitionTime: 300, - } - - private animationTimer: number - - constructor(props) { - super(props) - - this.state = { - visible: false, - } - } - - public componentDidUpdate(prevProps) { - if (prevProps.OverlayNode === null && this.props.OverlayNode) { - return this.setState({visible: true}) - } - } - - public render() { - const {OverlayNode} = this.props - - return ( - -
-
{OverlayNode}
-
-
- - ) - } - - private get overlayClass(): string { - const {visible} = this.state - return `overlay-tech ${visible ? 'show' : ''}` - } - - public handleClickOutside = () => { - const {handleDismissOverlay, dismissOnClickOutside} = this.props - - if (dismissOnClickOutside) { - handleDismissOverlay() - } - } - - public handleAnimateDismiss = () => { - const {transitionTime} = this.props - this.setState({visible: false}) - this.animationTimer = window.setTimeout(this.handleDismiss, transitionTime) - } - - public handleDismiss = () => { - const {handleDismissOverlay} = this.props - handleDismissOverlay() - clearTimeout(this.animationTimer) - } -} - -const mapStateToProps = ({ - overlayTechnology: { - OverlayNode, - options: {dismissOnClickOutside, dismissOnEscape, transitionTime}, - }, -}) => ({ - OverlayNode, - dismissOnClickOutside, - dismissOnEscape, - transitionTime, -}) - -const mapDispatchToProps = { - handleDismissOverlay: dismissOverlay, -} - -export default connect(mapStateToProps, mapDispatchToProps)(Overlay) diff --git a/ui/src/shared/components/SimpleOverlayTechnology.tsx b/ui/src/shared/components/SimpleOverlayTechnology.tsx deleted file mode 100644 index 6841374ac8..0000000000 --- a/ui/src/shared/components/SimpleOverlayTechnology.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React, {SFC} from 'react' - -const SimpleOverlayTechnology: SFC = ({children}) => { - return ( -
-
{children}
-
-
- ) -} - -export default SimpleOverlayTechnology diff --git a/ui/src/shared/reducers/overlayTechnology.ts b/ui/src/shared/reducers/overlayTechnology.ts deleted file mode 100644 index e8c685df45..0000000000 --- a/ui/src/shared/reducers/overlayTechnology.ts +++ /dev/null @@ -1,29 +0,0 @@ -const initialState = { - options: { - dismissOnClickOutside: false, - dismissOnEscape: false, - transitionTime: 300, - }, - OverlayNode: null, -} - -export default function overlayTechnology(state = initialState, action) { - switch (action.type) { - case 'SHOW_OVERLAY': { - const {OverlayNode, options} = action.payload - - return {...state, OverlayNode, options} - } - - case 'DISMISS_OVERLAY': { - const {options} = initialState - return { - ...state, - OverlayNode: null, - options, - } - } - } - - return state -} diff --git a/ui/src/store/configureStore.js b/ui/src/store/configureStore.js index 764230fbac..351c125fd5 100644 --- a/ui/src/store/configureStore.js +++ b/ui/src/store/configureStore.js @@ -14,7 +14,6 @@ import adminReducers from 'src/admin/reducers' import kapacitorReducers from 'src/kapacitor/reducers' import dashboardUI from 'src/dashboards/reducers/ui' import cellEditorOverlay from 'src/dashboards/reducers/cellEditorOverlay' -import overlayTechnology from 'src/shared/reducers/overlayTechnology' import dashTimeV1 from 'src/dashboards/reducers/dashTimeV1' import persistStateEnhancer from './persistStateEnhancer' import servicesReducer from 'src/shared/reducers/services' @@ -28,7 +27,6 @@ const rootReducer = combineReducers({ ...adminReducers, dashboardUI, cellEditorOverlay, - overlayTechnology, dashTimeV1, logs: logsReducer, routing: routerReducer, diff --git a/ui/src/style/components/edit-template-variable.scss b/ui/src/style/components/edit-template-variable.scss index 18a75a2976..2a3ea8bc45 100644 --- a/ui/src/style/components/edit-template-variable.scss +++ b/ui/src/style/components/edit-template-variable.scss @@ -1,85 +1,29 @@ -$padding: 20px 30px; - -.edit-temp-var { - margin: 0 auto; - width: 650px; -} - -.edit-temp-var--header { - background-color: $g0-obsidian; - padding: $padding; - display: flex; - align-items: center; - justify-content: space-between; -} - -.edit-temp-var--header > h1 { - color: #eeeff2; - letter-spacing: 0; - font-size: 19px; - font-weight: 400; -} - -.edit-temp-var--header-controls > button { - display: inline-block; - margin: 0 5px; -} - -.edit-temp-var--body { - @include gradient-v($g3-castle, $g1-raven); - padding: $padding; - - .delete { - margin: 20px auto 10px auto; - width: 90px; - } -} - -.edit-temp-var--body-row { - display: flex; - - .name { - flex: 1 1 50%; - padding-right: 10px; - - input { - color: $c-potassium; - font-weight: bold; - } - - } - - .template-type { - flex: 1 1 50%; - padding-left: 10px; - } - - .dropdown { - display: block; - width: 100%; - } - - .dropdown-toggle, .dropdown-placeholder { - width: 100%; - } -} - -.temp-builder { - width: 100%; -} +/* + Create / Edit Template Variable Overlay + ------------------------------------------------------------------------------ +*/ .temp-builder--mq-controls { background: $g3-castle; - border-radius: $radius-small; display: flex; - padding: 10px 10px 0 10px; + padding: 2px 10px; - &:last-child { - padding-bottom: 10px; + &:first-of-type { + padding-top: 10px; + border-top-left-radius: $radius; + border-top-right-radius: $radius; } - > .temp-builder--mq-text, > .dropdown, .dropdown-placeholder { - margin-right: 5px; + &:last-of-type { + padding-bottom: 10px; + border-bottom-left-radius: $radius; + border-bottom-right-radius: $radius; + } + + > .temp-builder--mq-text, + > .dropdown, + .dropdown-placeholder { + margin-right: 4px; flex-grow: 1; &:last-child { @@ -92,18 +36,16 @@ $padding: 20px 30px; @include no-user-select(); background-color: $g5-pepper; border-radius: $radius-small; - padding: 8px; + padding: 0 8px; + height: 30px; + line-height: 30px; white-space: nowrap; color: $c-pool; - font-size: 14px; + font-size: 13px; font-weight: 600; font-family: $code-font; } -.temp-builder .temp-builder-results { - margin-top: 30px; -} - @keyframes pulse { 0% { color: $g19-ghost; @@ -118,18 +60,21 @@ $padding: 20px 30px; } } -.temp-builder-results > p { +.temp-builder--validation { + @include no-user-select(); text-align: center; - font-weight: bold; - color: $g19-ghost; - margin: 15px 0; + font-weight: 500; + color: $g13-mist; + margin: 0 0 8px 0; &.error { color: $c-fire; + font-weight: 600; } &.warning { color: $c-pineapple; + font-weight: 600; } &.loading { @@ -137,24 +82,34 @@ $padding: 20px 30px; } > strong { - color: $c-potassium; + color: $c-comet; + } + + &:only-child { + margin-bottom: 0; } } -.temp-builder-results--list { +.temp-builder--results { + margin-top: 22px; +} + +.temp-builder--results-list { max-height: 250px; padding: 0; margin: 0; - - li { - background-color: $g3-castle; - padding: 0 10px; - display: flex; - align-items: center; - border-radius: $radius-small; - margin: 0; - color: $g19-ghost; - font-weight: bold; - list-style: none; - } +} + +.temp-builder--results-item { + @include no-user-select(); + background-color: $g3-castle; + padding: 0 10px; + display: flex; + align-items: center; + border-radius: $radius; + font-size: 12px; + margin: 0; + color: $g13-mist; + font-weight: 600; + list-style: none; } diff --git a/ui/src/style/pages/kapacitor.scss b/ui/src/style/pages/kapacitor.scss index 443b05ce3d..63447b40ac 100644 --- a/ui/src/style/pages/kapacitor.scss +++ b/ui/src/style/pages/kapacitor.scss @@ -551,12 +551,6 @@ $rule-builder--radius-lg: 5px; padding-bottom: $rule-builder--padding-lg; } } -.endpoint-tab--parameters .faux-form { - margin-left: -6px; - margin-right: -6px; - width: calc(100% + 12px); - display: inline-block; -} .endpoint-tab--parameters--empty { align-items: center; justify-content: center; diff --git a/ui/src/style/pages/time-machine.scss b/ui/src/style/pages/time-machine.scss index 2ee1971572..a490385cb9 100644 --- a/ui/src/style/pages/time-machine.scss +++ b/ui/src/style/pages/time-machine.scss @@ -8,4 +8,21 @@ @import '../components/time-machine/flux-builder'; @import '../components/time-machine/flux-explorer'; @import '../components/time-machine/visualization'; -@import '../components/time-machine/add-func-button'; \ No newline at end of file +@import '../components/time-machine/add-func-button'; + +// Flux Page Empty state +.flux-empty { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + display: inline-flex; + flex-direction: column; + align-items: center; + + > p { + color: $g11-sidewalk; + font-size: 16px; + @include no-user-select(); + } +} \ No newline at end of file diff --git a/ui/src/style/theme/_buttons.scss b/ui/src/style/theme/_buttons.scss index 343890f0ab..b3da352d83 100644 --- a/ui/src/style/theme/_buttons.scss +++ b/ui/src/style/theme/_buttons.scss @@ -423,3 +423,42 @@ button.btn-link-alert { $c-thunder ); } + +/* + Buttons Groups + ----------------------------------------------------------------------------- +*/ + +.btn-group--left, +.btn-group--center, +.btn-group--right { + display: flex; + align-items: center; +} + +.btn-group--left > .btn { + margin-right: 4px; + &:last-child { + margin-right: 0; + } +} + +.btn-group--center > .btn { + margin-left: 2px; + margin-right: 2px; + + &:first-child { + margin-left: 0; + } + + &:last-child { + margin-right: 0; + } +} + +.btn-group--right > .btn { + margin-left: 4px; + &:first-child { + margin-left: 0; + } +} \ No newline at end of file diff --git a/ui/src/style/theme/_grid.scss b/ui/src/style/theme/_grid.scss index a6703e8016..23c7169bf9 100644 --- a/ui/src/style/theme/_grid.scss +++ b/ui/src/style/theme/_grid.scss @@ -43,7 +43,7 @@ $grid--col-12: 100%; } .form-group-submit { - margin-top: 30px; + margin-top: 22px; } .col { @@ -220,3 +220,68 @@ $grid--col-12: 100%; &-11 { margin-left: $grid--col-11; } } } + +// Wrapp form sets to ensure proper spacing +// ---------------------------------------------------------------------------- +div.faux-form { + width: calc(100% + 12px); + margin-left: -6px; + margin-right: -6px; + display: inline-block; + + .form-group.col-xs-1, + .form-group.col-xs-2, + .form-group.col-xs-3, + .form-group.col-xs-4, + .form-group.col-xs-5, + .form-group.col-xs-6, + .form-group.col-xs-7, + .form-group.col-xs-8, + .form-group.col-xs-9, + .form-group.col-xs-10, + .form-group.col-xs-11, + .form-group.col-xs-12, + .form-group.col-sm-1, + .form-group.col-sm-2, + .form-group.col-sm-3, + .form-group.col-sm-4, + .form-group.col-sm-5, + .form-group.col-sm-6, + .form-group.col-sm-7, + .form-group.col-sm-8, + .form-group.col-sm-9, + .form-group.col-sm-10, + .form-group.col-sm-11, + .form-group.col-sm-12, + .form-group.col-md-1, + .form-group.col-md-2, + .form-group.col-md-3, + .form-group.col-md-4, + .form-group.col-md-5, + .form-group.col-md-6, + .form-group.col-md-7, + .form-group.col-md-8, + .form-group.col-md-9, + .form-group.col-md-10, + .form-group.col-md-11, + .form-group.col-md-12, + .form-group.col-lg-1, + .form-group.col-lg-2, + .form-group.col-lg-3, + .form-group.col-lg-4, + .form-group.col-lg-5, + .form-group.col-lg-6, + .form-group.col-lg-7, + .form-group.col-lg-8, + .form-group.col-lg-9, + .form-group.col-lg-10, + .form-group.col-lg-11, + .form-group.col-lg-12 { + padding-left: 6px; + padding-right: 6px; + } + + > *:last-child { + margin-bottom: 0; + } +} diff --git a/ui/src/style/unsorted.scss b/ui/src/style/unsorted.scss index 779282e25d..1daf427fea 100644 --- a/ui/src/style/unsorted.scss +++ b/ui/src/style/unsorted.scss @@ -484,65 +484,6 @@ $dash-editable-header-padding: 7px; } } -/* - Fake form padding without
- -*/ - -div.faux-form { - .form-group.col-xs-1, - .form-group.col-xs-2, - .form-group.col-xs-3, - .form-group.col-xs-4, - .form-group.col-xs-5, - .form-group.col-xs-6, - .form-group.col-xs-7, - .form-group.col-xs-8, - .form-group.col-xs-9, - .form-group.col-xs-10, - .form-group.col-xs-11, - .form-group.col-xs-12, - .form-group.col-sm-1, - .form-group.col-sm-2, - .form-group.col-sm-3, - .form-group.col-sm-4, - .form-group.col-sm-5, - .form-group.col-sm-6, - .form-group.col-sm-7, - .form-group.col-sm-8, - .form-group.col-sm-9, - .form-group.col-sm-10, - .form-group.col-sm-11, - .form-group.col-sm-12, - .form-group.col-md-1, - .form-group.col-md-2, - .form-group.col-md-3, - .form-group.col-md-4, - .form-group.col-md-5, - .form-group.col-md-6, - .form-group.col-md-7, - .form-group.col-md-8, - .form-group.col-md-9, - .form-group.col-md-10, - .form-group.col-md-11, - .form-group.col-md-12, - .form-group.col-lg-1, - .form-group.col-lg-2, - .form-group.col-lg-3, - .form-group.col-lg-4, - .form-group.col-lg-5, - .form-group.col-lg-6, - .form-group.col-lg-7, - .form-group.col-lg-8, - .form-group.col-lg-9, - .form-group.col-lg-10, - .form-group.col-lg-11, - .form-group.col-lg-12 { - padding-left: 6px; - padding-right: 6px; - } -} - /* Stretch to fit Dropdowns ----------------------------------------------------------------------------- diff --git a/ui/src/tempVars/components/CSVTemplateBuilder.tsx b/ui/src/tempVars/components/CSVTemplateBuilder.tsx index 63ed0b8b74..abb557567e 100644 --- a/ui/src/tempVars/components/CSVTemplateBuilder.tsx +++ b/ui/src/tempVars/components/CSVTemplateBuilder.tsx @@ -28,20 +28,20 @@ class CSVTemplateBuilder extends PureComponent { const pluralizer = templateValues.length === 1 ? '' : 's' return ( -
-
+ <> +