From 0b70f58614a643bb95fd20b4830e037ccfa4634f Mon Sep 17 00:00:00 2001 From: Kyle Knight Date: Thu, 15 Dec 2016 08:44:45 -0600 Subject: [PATCH] Styling Manage Hosts [Grid View] (#602) --- .../components/buttons/Rocker/_styles.scss | 2 + .../components/hosts/HostDetails/_styles.scss | 35 ++++++++- .../QueryPageWrapper/QueryPageWrapper.jsx | 12 +-- .../PanelGroupItem/PanelGroupItem.jsx | 2 +- .../SecondarySidePanelContainer/_styles.scss | 4 +- frontend/layouts/CoreLayout/CoreLayout.jsx | 13 +--- frontend/layouts/CoreLayout/_styles.scss | 6 +- .../hosts/ManageHostsPage/ManageHostsPage.jsx | 37 ++++++--- .../pages/hosts/ManageHostsPage/_styles.scss | 77 +++++++++++++++++-- .../pages/queries/QueryPage/QueryPage.jsx | 2 +- frontend/styles/global/_global.scss | 17 +++- .../icon_class_for_label.js} | 2 +- 12 files changed, 162 insertions(+), 47 deletions(-) rename frontend/{components/side_panels/HostSidePanel/PanelGroupItem/helpers.js => utilities/icon_class_for_label.js} (93%) diff --git a/frontend/components/buttons/Rocker/_styles.scss b/frontend/components/buttons/Rocker/_styles.scss index fedb38edea..10e38e2874 100644 --- a/frontend/components/buttons/Rocker/_styles.scss +++ b/frontend/components/buttons/Rocker/_styles.scss @@ -1,4 +1,6 @@ .kolide-rocker { + box-shadow: 0 0 9px 0 rgba(72, 81, 109, 0.1); + &__label { position: relative; cursor: pointer; diff --git a/frontend/components/hosts/HostDetails/_styles.scss b/frontend/components/hosts/HostDetails/_styles.scss index 683c30151a..393e7ef507 100644 --- a/frontend/components/hosts/HostDetails/_styles.scss +++ b/frontend/components/hosts/HostDetails/_styles.scss @@ -1,16 +1,35 @@ .host-details { + @include flex-grow(1); background-color: $white; border: 1px solid $silver; border-radius: 3px; box-shadow: 0 2px 8px 0 rgba($black, 0.05); box-sizing: border-box; - display: inline-block; height: 286px; padding: $pad-half; - margin: $pad-base 0 0 $pad-base; + margin: 30px 15px 0 0; position: relative; text-align: center; - width: 240px; + min-width: 240px; + max-width: 300px; + + @media (min-width: 1619px) { + &:nth-child(4n) { + margin-right: 0; + } + } + + @media (min-width: 1364px) and (max-width: 1618px) { + &:nth-child(3n) { + margin-right: 0; + } + } + + @media (max-width: 1363px) { + &:nth-child(2n) { + margin-right: 0; + } + } &--online { border-top: 6px solid $success; @@ -20,6 +39,10 @@ border-top: 6px solid $alert; } + &--mia { + border-top: 6px solid $text-dark; + } + &__separator { border-top: 1px solid $accent-light; margin-top: $pad-half; @@ -38,7 +61,7 @@ &__icon { color: $text-dark; - font-size: $mini; + font-size: $medium; margin-right: 3px; } @@ -60,6 +83,10 @@ &--offline { color: $alert; } + + &--mia { + color: $text-dark; + } } &__host-content { diff --git a/frontend/components/queries/QueryPageWrapper/QueryPageWrapper.jsx b/frontend/components/queries/QueryPageWrapper/QueryPageWrapper.jsx index 8e14d113dc..1ddf639f84 100644 --- a/frontend/components/queries/QueryPageWrapper/QueryPageWrapper.jsx +++ b/frontend/components/queries/QueryPageWrapper/QueryPageWrapper.jsx @@ -1,4 +1,4 @@ -import React, { Component, PropTypes } from 'react'; +import { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import entityGetter from 'redux/utilities/entityGetter'; @@ -27,11 +27,11 @@ class QueryPageWrapper extends Component { render () { const { children } = this.props; - return ( -
- {children} -
- ); + if (!children) { + return false; + } + + return children; } } diff --git a/frontend/components/side_panels/HostSidePanel/PanelGroupItem/PanelGroupItem.jsx b/frontend/components/side_panels/HostSidePanel/PanelGroupItem/PanelGroupItem.jsx index d7a1dee8f2..b805b18fe3 100644 --- a/frontend/components/side_panels/HostSidePanel/PanelGroupItem/PanelGroupItem.jsx +++ b/frontend/components/side_panels/HostSidePanel/PanelGroupItem/PanelGroupItem.jsx @@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react'; import classnames from 'classnames'; import Icon from 'components/Icon'; -import { iconClassForLabel } from './helpers'; +import iconClassForLabel from 'utilities/icon_class_for_label'; const baseClass = 'panel-group-item'; diff --git a/frontend/components/side_panels/SecondarySidePanelContainer/_styles.scss b/frontend/components/side_panels/SecondarySidePanelContainer/_styles.scss index c50ec16e4e..c8d636e218 100644 --- a/frontend/components/side_panels/SecondarySidePanelContainer/_styles.scss +++ b/frontend/components/side_panels/SecondarySidePanelContainer/_styles.scss @@ -1,9 +1,11 @@ .secondary-side-panel-container { - @include position(fixed, 0 0 0 null); + @include align-self(stretch); background-color: $white; border-left: 1px solid $border-medium; box-shadow: -2px 0 8px 0 rgba($black, 0.1); box-sizing: border-box; overflow: scroll; width: 300px; + margin-left: $pad-base; + min-height: 100%; } diff --git a/frontend/layouts/CoreLayout/CoreLayout.jsx b/frontend/layouts/CoreLayout/CoreLayout.jsx index 8de2b6c21a..4cec26d8c6 100644 --- a/frontend/layouts/CoreLayout/CoreLayout.jsx +++ b/frontend/layouts/CoreLayout/CoreLayout.jsx @@ -1,6 +1,5 @@ import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; -import classnames from 'classnames'; import { logoutUser } from 'redux/nodes/auth/actions'; import { push } from 'react-router-redux'; @@ -18,7 +17,6 @@ export class CoreLayout extends Component { config: configInterface, dispatch: PropTypes.func, notifications: notificationInterface, - showRightSidePanel: PropTypes.bool, user: userInterface, }; @@ -64,11 +62,7 @@ export class CoreLayout extends Component { } render () { - const { children, config, notifications, showRightSidePanel, user } = this.props; - const wrapperClass = classnames( - 'core-wrapper', - { 'core-wrapper--show-panel': showRightSidePanel } - ); + const { children, config, notifications, user } = this.props; if (!user) return false; @@ -91,7 +85,7 @@ export class CoreLayout extends Component { user={user} /> -
+
{ const { - app: { config, showRightSidePanel }, + app: { config }, auth: { user }, notifications, } = state; @@ -114,7 +108,6 @@ const mapStateToProps = (state) => { return { config, notifications, - showRightSidePanel, user, }; }; diff --git a/frontend/layouts/CoreLayout/_styles.scss b/frontend/layouts/CoreLayout/_styles.scss index d6b59c37b7..89d8dad1fd 100644 --- a/frontend/layouts/CoreLayout/_styles.scss +++ b/frontend/layouts/CoreLayout/_styles.scss @@ -6,11 +6,7 @@ .core-wrapper { @include flex-grow(1); margin: 0; - padding: $pad-base $pad-base 0; - - &--show-panel { - margin-right: 300px; - } + padding: 0 0 0 $pad-base; } .site-nav { diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx index 00a0ccec48..8405400dd4 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx @@ -23,8 +23,10 @@ import { selectOsqueryTable } from 'redux/nodes/components/QueryPages/actions'; import { setDisplay } from 'redux/nodes/components/ManageHostsPage/actions'; import { showRightSidePanel, removeRightSidePanel } from 'redux/nodes/app/actions'; import validateQuery from 'components/forms/validators/validate_query'; +import iconClassForLabel from 'utilities/icon_class_for_label'; const NEW_LABEL_HASH = '#new_label'; +const baseClass = 'manage-hosts'; export class ManageHostsPage extends Component { static propTypes = { @@ -180,9 +182,12 @@ export class ManageHostsPage extends Component { }; return ( -
- - {displayText} +
+

+ + {displayText} +

+ { query && } -

Description

-

{description}

-

{count} Hosts Total

-
+ +
+

Description

+

{description}

+
+ +
+

{count} Hosts Total

- {renderHeader()} - {renderForm()} - {renderHosts()} +
+
+ {renderHeader()} + {renderForm()} +
+ {renderHosts()} +
+
+ {renderSidePanel()}
); diff --git a/frontend/pages/hosts/ManageHostsPage/_styles.scss b/frontend/pages/hosts/ManageHostsPage/_styles.scss index 555415293a..a1e8de3b96 100644 --- a/frontend/pages/hosts/ManageHostsPage/_styles.scss +++ b/frontend/pages/hosts/ManageHostsPage/_styles.scss @@ -1,23 +1,88 @@ .manage-hosts { padding: $pad-base; + + &__header { + .ace-kolide { + margin: 12px 0; + } + } + + &__title { + margin: 0; + font-weight: $light; + font-size: 20px; + letter-spacing: 1px; + color: $text-medium; + + .kolidecon { + color: $text-light; + margin-right: 15px; + } + } + + &__description { + line-height: 1.54; + letter-spacing: 0.5px; + margin: 0; + + h2 { + text-transform: uppercase; + color: $text-dark; + font-weight: $light; + font-size: 16px; + } + + p { + color: $text-medium; + margin: 0; + font-size: 13px; + } + } + + &__topper { + @include display(flex); + @include align-items(flex-end); + border-bottom: solid 1px $accent-light; + padding-bottom: 10px; + } + + &__host-count { + @include flex-grow(1); + font-size: 14px; + font-weight: $light; + letter-spacing: 0.9px; + color: $text-dark; + margin: 0; + display: inline-block; + } + + &__list { + &--grid { + @include display(flex); + @include justify-content(center); + @include flex-wrap(wrap); + max-width: $medium-width; + margin: 0 auto; + } + } } .hosts-page-side-panel { &-enter { - right: -300px; + margin-right: -250px; &.hosts-page-side-panel-enter-active { - right: 0; - transition: right 300ms ease-in; + @include transition(margin 3000ms ease-in); + margin-right: 0; } } &-leave { - right: 0; + margin-right: 0; &.hosts-page-side-panel-leave-active { - right: -300px; - transition: right 200ms ease-in; + @include transition(margin 300ms ease-in); + margin-right: -250px; } } } diff --git a/frontend/pages/queries/QueryPage/QueryPage.jsx b/frontend/pages/queries/QueryPage/QueryPage.jsx index 5d8ec89f79..1b61fc7fc1 100644 --- a/frontend/pages/queries/QueryPage/QueryPage.jsx +++ b/frontend/pages/queries/QueryPage/QueryPage.jsx @@ -171,7 +171,7 @@ class QueryPage extends Component { } = this.props; return ( -
+
{ } }; -export default { iconClassForLabel }; +export default iconClassForLabel;