Styling Manage Hosts [Grid View] (#602)

This commit is contained in:
Kyle Knight
2016-12-15 08:44:45 -06:00
committed by GitHub
parent 216e1b58fa
commit 0b70f58614
12 changed files with 162 additions and 47 deletions
@@ -1,4 +1,6 @@
.kolide-rocker {
box-shadow: 0 0 9px 0 rgba(72, 81, 109, 0.1);
&__label {
position: relative;
cursor: pointer;
@@ -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 {
@@ -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 (
<div>
{children}
</div>
);
if (!children) {
return false;
}
return children;
}
}
@@ -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';
@@ -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%;
}
+3 -10
View File
@@ -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}
/>
</nav>
<div className={wrapperClass}>
<div className="core-wrapper">
<FlashMessage
notification={notifications}
onRemoveFlash={onRemoveFlash}
@@ -106,7 +100,7 @@ export class CoreLayout extends Component {
const mapStateToProps = (state) => {
const {
app: { config, showRightSidePanel },
app: { config },
auth: { user },
notifications,
} = state;
@@ -114,7 +108,6 @@ const mapStateToProps = (state) => {
return {
config,
notifications,
showRightSidePanel,
user,
};
};
+1 -5
View File
@@ -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 {
@@ -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 (
<div>
<Icon name="label" />
<span>{displayText}</span>
<div className={`${baseClass}__header`}>
<h1 className={`${baseClass}__title`}>
<Icon name={iconClassForLabel(selectedLabel)} />
<span>{displayText}</span>
</h1>
{ query &&
<AceEditor
editorProps={{ $blockScrolling: Infinity }}
@@ -200,10 +205,14 @@ export class ManageHostsPage extends Component {
fontSize={14}
/>
}
<p>Description</p>
<p>{description}</p>
<p>{count} Hosts Total</p>
<div>
<div className={`${baseClass}__description`}>
<h2>Description</h2>
<p>{description}</p>
</div>
<div className={`${baseClass}__topper`}>
<p className={`${baseClass}__host-count`}>{count} Hosts Total</p>
<Rocker
handleChange={onToggleDisplay}
name="host-display-toggle"
@@ -308,12 +317,18 @@ export class ManageHostsPage extends Component {
render () {
const { renderForm, renderHeader, renderHosts, renderSidePanel } = this;
const { display } = this.props;
return (
<div className="manage-hosts body-wrap">
{renderHeader()}
{renderForm()}
{renderHosts()}
<div className="has-sidebar">
<div className={`${baseClass} body-wrap`}>
{renderHeader()}
{renderForm()}
<div className={`${baseClass}__list ${baseClass}__list--${display.toLowerCase()}`}>
{renderHosts()}
</div>
</div>
{renderSidePanel()}
</div>
);
@@ -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;
}
}
}
@@ -171,7 +171,7 @@ class QueryPage extends Component {
} = this.props;
return (
<div>
<div className="has-sidebar">
<QueryComposer
onFetchTargets={onFetchTargets}
onOsqueryTableSelect={onOsqueryTableSelect}
+16 -1
View File
@@ -14,7 +14,7 @@ body {
font-family: 'Oxygen', sans-serif;
font-size: $base;
line-height: 1.6;
min-width: $min-width;
min-width: $medium-width;
height: 100%;
}
@@ -49,6 +49,21 @@ h3 {
background-color: $white;
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.1);
border: solid 1px $silver;
min-width: 630px;
box-sizing: border-box;
margin-top: $pad-base;
margin-right: $pad-base;
}
.has-sidebar {
@include display(flex);
height: 100%;
.body-wrap {
@include flex-grow(1);
@include align-self(flex-start);
margin-right: 0;
}
}
.cf {
@@ -16,4 +16,4 @@ export const iconClassForLabel = (label) => {
}
};
export default { iconClassForLabel };
export default iconClassForLabel;