diff --git a/assets/fonts/kolidecons/kolidecons.woff b/assets/fonts/kolidecons/kolidecons.woff
index 9b256430a4..c1e936d2a5 100755
Binary files a/assets/fonts/kolidecons/kolidecons.woff and b/assets/fonts/kolidecons/kolidecons.woff differ
diff --git a/assets/fonts/kolidecons/kolidecons.woff2 b/assets/fonts/kolidecons/kolidecons.woff2
index 0f7b2bdc61..68e8675260 100755
Binary files a/assets/fonts/kolidecons/kolidecons.woff2 and b/assets/fonts/kolidecons/kolidecons.woff2 differ
diff --git a/assets/images/laptop-plus.svg b/assets/images/laptop-plus.svg
new file mode 100644
index 0000000000..db1a850975
--- /dev/null
+++ b/assets/images/laptop-plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/swoop-arrow.svg b/assets/images/swoop-arrow.svg
new file mode 100644
index 0000000000..ea56b8fd35
--- /dev/null
+++ b/assets/images/swoop-arrow.svg
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/frontend/components/hosts/LonelyHost/LonelyHost.jsx b/frontend/components/hosts/LonelyHost/LonelyHost.jsx
new file mode 100644
index 0000000000..1fb326ac7f
--- /dev/null
+++ b/frontend/components/hosts/LonelyHost/LonelyHost.jsx
@@ -0,0 +1,34 @@
+import React, { PropTypes } from 'react';
+import { noop } from 'lodash';
+
+import Button from 'components/buttons/Button';
+import laptop from '../../../../assets/images/laptop-plus.svg';
+import swoop from '../../../../assets/images/swoop-arrow.svg';
+
+const baseClass = 'lonely-host';
+
+const LonelyHost = ({ onAddHostClick = noop }) => {
+ return (
+
+
+
+
+
It's Kinda Lonely In Here...
+
Get started adding hosts to Kolide.
+
This can be done individually or across your entire fleet.
+

+
+
+ );
+};
+
+LonelyHost.propTypes = {
+ onAddHostClick: PropTypes.func,
+};
+
+export default LonelyHost;
diff --git a/frontend/components/hosts/LonelyHost/_styles.scss b/frontend/components/hosts/LonelyHost/_styles.scss
new file mode 100644
index 0000000000..131d6e259e
--- /dev/null
+++ b/frontend/components/hosts/LonelyHost/_styles.scss
@@ -0,0 +1,74 @@
+.lonely-host {
+ @include display(flex);
+ padding: 16px 8px;
+
+ &__add-host-btn {
+ width: 244px;
+ height: 286px;
+ border-radius: 2px;
+ background-color: $white;
+ box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.07);
+ border: solid 1px rgba(73, 143, 226, 0.22);
+ padding: 15px;
+
+ &::before {
+ @include position(absolute, 0 null null -1px);
+ content: '';
+ background-color: $link;
+ height: 6px;
+ width: calc(100% + 2px);
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ }
+ }
+
+ &__title {
+ font-size: 16px;
+ font-weight: $bold;
+ letter-spacing: 1px;
+ text-align: center;
+ color: $link;
+ border-bottom: solid 1px #eaeefb;
+ padding-bottom: 15px;
+ margin-bottom: 15px;
+ display: block;
+ }
+
+ &__icon {
+ display: block;
+ background-color: $bg-medium;
+ }
+
+ &__laptop {
+ width: 82px;
+ margin: 60px 0;
+ fill: $alert;
+ }
+
+ &__content {
+ margin-left: 30px;
+
+ h1 {
+ font-size: 28px;
+ font-weight: $normal;
+ color: #48c586;
+ padding-left: 5px;
+ }
+
+ h2 {
+ font-size: 16px;
+ font-weight: $bold;
+ line-height: 1.5;
+ letter-spacing: -0.5px;
+ color: rgba(32, 37, 50, 0.66);
+ padding-left: 5px;
+ }
+
+ p {
+ font-size: 15px;
+ line-height: 1.6;
+ color: rgba(32, 37, 50, 0.66);
+ padding-left: 5px;
+ }
+ }
+}
diff --git a/frontend/components/hosts/LonelyHost/index.js b/frontend/components/hosts/LonelyHost/index.js
new file mode 100644
index 0000000000..7d7d44686c
--- /dev/null
+++ b/frontend/components/hosts/LonelyHost/index.js
@@ -0,0 +1 @@
+export default from './LonelyHost';
diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx
index 3e77b46920..6167e8dd52 100644
--- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx
+++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx
@@ -15,6 +15,7 @@ import HostDetails from 'components/hosts/HostDetails';
import hostInterface from 'interfaces/host';
import HostSidePanel from 'components/side_panels/HostSidePanel';
import HostsTable from 'components/hosts/HostsTable';
+import LonelyHost from 'components/hosts/LonelyHost';
import Icon from 'components/icons/Icon';
import PlatformIcon from 'components/icons/PlatformIcon';
import osqueryTableInterface from 'interfaces/osquery_table';
@@ -326,7 +327,7 @@ export class ManageHostsPage extends Component {
}
renderHosts = () => {
- const { display, isAddLabel } = this.props;
+ const { display, isAddLabel, selectedLabel } = this.props;
const { onHostDetailActionClick, filterHosts, sortHosts, renderNoHosts } = this;
if (isAddLabel) {
@@ -337,6 +338,10 @@ export class ManageHostsPage extends Component {
const sortedHosts = sortHosts(filteredHosts);
if (sortedHosts.length === 0) {
+ if (selectedLabel && selectedLabel.type === 'all') {
+ return ;
+ }
+
return renderNoHosts();
}
diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx
index 664223b642..f8b159d159 100644
--- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx
+++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx
@@ -91,6 +91,18 @@ describe('ManageHostsPage - component', () => {
});
describe('host rendering', () => {
+ it('render LonelyHost if no hosts available', () => {
+ const page = mount();
+
+ expect(page.find('LonelyHost').length).toEqual(1);
+ });
+
+ it('renders message if no hosts available and not on All Hosts', () => {
+ const page = mount();
+
+ expect(page.find('.manage-hosts__no-hosts').length).toEqual(1);
+ });
+
it('renders hosts as HostDetails by default', () => {
const page = mount();
diff --git a/frontend/styles/global/_icons.scss b/frontend/styles/global/_icons.scss
index 4fad7e2544..47fe3b2c6a 100644
--- a/frontend/styles/global/_icons.scss
+++ b/frontend/styles/global/_icons.scss
@@ -14,342 +14,346 @@
}
.kolidecon-lg {
- font-size: 1.33333333em;
- line-height: 0.75em;
- vertical-align: -15%;
+ font-size: 1.33333333em;
+ line-height: 0.75em;
+ vertical-align: -15%;
}
.kolidecon-2x {
- font-size: 2em;
+ font-size: 2em;
}
.kolidecon-3x {
- font-size: 3em;
+ font-size: 3em;
}
.kolidecon-4x {
- font-size: 4em;
+ font-size: 4em;
}
.kolidecon-5x {
- font-size: 5em;
+ font-size: 5em;
}
.kolidecon-fw {
- width: 1.28571429em;
- text-align: center;
+ width: 1.28571429em;
+ text-align: center;
}
.kolidecon-kolide-logo-flat:before {
- content: '\f000';
+ content: '\f000';
}
.kolidecon-chevrondown:before {
- content: '\f004';
+ content: '\f004';
}
.kolidecon-chevronleft:before {
- content: '\f006';
+ content: '\f006';
}
.kolidecon-chevronright:before {
- content: '\f008';
+ content: '\f008';
}
.kolidecon-chevronup:before {
- content: '\f00a';
+ content: '\f00a';
}
.kolidecon-cpu:before {
- content: '\f00c';
+ content: '\f00c';
}
.kolidecon-downcarat:before {
- content: '\f00d';
+ content: '\f00d';
}
.kolidecon-filter:before {
- content: '\f00f';
+ content: '\f00f';
}
.kolidecon-mac:before {
- content: '\f012';
+ content: '\f012';
}
.kolidecon-memory:before {
- content: '\f013';
+ content: '\f013';
}
.kolidecon-storage:before {
- content: '\f019';
+ content: '\f019';
}
.kolidecon-upcarat:before {
- content: '\f01b';
+ content: '\f01b';
}
.kolidecon-uptime:before {
- content: '\f01c';
+ content: '\f01c';
}
.kolidecon-world:before {
- content: '\f01d';
+ content: '\f01d';
}
.kolidecon-osquery:before {
- content: '\f021';
+ content: '\f021';
}
.kolidecon-join:before {
- content: '\f022';
+ content: '\f022';
}
.kolidecon-add-button:before {
- content: '\f029';
+ content: '\f029';
}
.kolidecon-packs:before {
- content: '\f02f';
+ content: '\f02f';
}
.kolidecon-help:before {
- content: '\f030';
+ content: '\f030';
}
.kolidecon-admin:before {
- content: '\f031';
+ content: '\f031';
}
.kolidecon-config:before {
- content: '\f032';
+ content: '\f032';
}
.kolidecon-mia:before {
- content: '\f034';
+ content: '\f034';
}
.kolidecon-success-check:before {
- content: '\f035';
+ content: '\f035';
}
.kolidecon-offline:before {
- content: '\f036';
+ content: '\f036';
}
.kolidecon-windows:before {
- content: '\f037';
+ content: '\f037';
}
.kolidecon-centos:before {
- content: '\f038';
+ content: '\f038';
}
.kolidecon-ubuntu:before {
- content: '\f039';
+ content: '\f039';
}
.kolidecon-apple:before {
- content: '\f03a';
+ content: '\f03a';
}
.kolidecon-search:before {
- content: '\f03b';
+ content: '\f03b';
}
.kolidecon-all-hosts:before {
- content: '\f03c';
+ content: '\f03c';
}
.kolidecon-alerts:before {
- content: '\f03e';
+ content: '\f03e';
}
.kolidecon-logout:before {
- content: '\f03f';
+ content: '\f03f';
}
.kolidecon-user-settings:before {
- content: '\f040';
+ content: '\f040';
}
.kolidecon-clipboard:before {
- content: '\f043';
+ content: '\f043';
}
.kolidecon-list-select:before {
- content: '\f044';
+ content: '\f044';
}
.kolidecon-grid-select:before {
- content: '\f045';
+ content: '\f045';
}
.kolidecon-label:before {
- content: '\f033';
+ content: '\f033';
}
.kolidecon-docker:before {
- content: '\f046';
+ content: '\f046';
}
.kolidecon-cloud:before {
- content: '\f047';
+ content: '\f047';
}
.kolidecon-self-hosted:before {
- content: '\f048';
+ content: '\f048';
}
.kolidecon-help-solid:before {
- content: '\f049';
+ content: '\f049';
}
.kolidecon-help-stroke:before {
- content: '\f04a';
+ content: '\f04a';
}
.kolidecon-warning-filled:before {
- content: '\f04b';
+ content: '\f04b';
}
.kolidecon-delete-cloud:before {
- content: '\f04c';
+ content: '\f04c';
}
.kolidecon-pdf:before {
- content: '\f04d';
+ content: '\f04d';
}
.kolidecon-credit-card-small:before {
- content: '\f04e';
+ content: '\f04e';
}
.kolidecon-billing-card:before {
- content: '\f04f';
+ content: '\f04f';
}
.kolidecon-lock-big:before {
- content: '\f050';
+ content: '\f050';
}
.kolidecon-link-big:before {
- content: '\f051';
+ content: '\f051';
}
.kolidecon-briefcase:before {
- content: '\f052';
+ content: '\f052';
}
.kolidecon-name-card:before {
- content: '\f053';
+ content: '\f053';
}
.kolidecon-kolide-logo:before {
- content: '\f054';
+ content: '\f054';
}
.kolidecon-business:before {
- content: '\f055';
+ content: '\f055';
}
.kolidecon-clock:before {
- content: '\f056';
+ content: '\f056';
}
.kolidecon-host-large:before {
- content: '\f057';
+ content: '\f057';
}
.kolidecon-single-host:before {
- content: '\f03d';
+ content: '\f03d';
}
.kolidecon-username:before {
- content: '\f02a';
+ content: '\f02a';
}
.kolidecon-password:before {
- content: '\f02b';
+ content: '\f02b';
}
.kolidecon-email:before {
- content: '\f02c';
+ content: '\f02c';
}
.kolidecon-hosts:before {
- content: '\f02e';
+ content: '\f02e';
}
.kolidecon-query:before {
- content: '\f02d';
+ content: '\f02d';
}
.kolidecon-import:before {
- content: '\f058';
+ content: '\f058';
}
.kolidecon-pencil:before {
- content: '\f059';
+ content: '\f059';
}
.kolidecon-add-plus:before {
- content: '\f05a';
+ content: '\f05a';
}
.kolidecon-x:before {
- content: '\f05b';
+ content: '\f05b';
}
.kolidecon-kill-kolide:before {
- content: '\f05c';
+ content: '\f05c';
}
.kolidecon-right-arrow:before {
- content: '\f05d';
+ content: '\f05d';
}
.kolidecon-camera:before {
- content: '\f05e';
+ content: '\f05e';
}
.kolidecon-plus-minus:before {
- content: '\f05f';
+ content: '\f05f';
}
.kolidecon-bold-plus:before {
- content: '\f060';
+ content: '\f060';
}
.kolidecon-linux:before {
- content: '\f061';
+ content: '\f061';
}
.kolidecon-clock2:before {
- content: '\f063';
+ content: '\f063';
}
.kolidecon-trash:before {
- content: '\f064';
+ content: '\f064';
+}
+
+.kolidecon-laptop-plus:before {
+ content: '\f065';
}
.sr-only {
-position: absolute;
-width: 1px;
-height: 1px;
-padding: 0;
-margin: -1px;
-overflow: hidden;
-clip: rect(0, 0, 0, 0);
-border: 0
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
-position: static;
-width: auto;
-height: auto;
-margin: 0;
-overflow: visible;
-clip: auto
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto
}