Skip to content

Commit

Permalink
Merge pull request #1361 from newrelic/liz/pack-details
Browse files Browse the repository at this point in the history
Add o11y pack details template
  • Loading branch information
aswanson-nr authored Jun 4, 2021
2 parents 4ac0c56 + d078830 commit 2c97811
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 9 deletions.
44 changes: 41 additions & 3 deletions gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const path = require(`path`);
const { execSync } = require('child_process');
const { createFilePath } = require('gatsby-source-filesystem');

const MAX_RESULTS = 5;
const slugify = require('./src/utils/slugify.js');

const kebabCase = (string) =>
string
Expand Down Expand Up @@ -53,6 +52,17 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
}
}
}
allObservabilityPacks {
edges {
node {
fields {
slug
}
id
}
}
}
}
`);

Expand All @@ -62,7 +72,12 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
return;
}

const { allMdx, allNewRelicSdkComponent, allNewRelicSdkApi } = result.data;
const {
allMdx,
allNewRelicSdkComponent,
allNewRelicSdkApi,
allObservabilityPacks,
} = result.data;

allMdx.edges.forEach(({ node }) => {
const {
Expand Down Expand Up @@ -97,6 +112,21 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
});
});

allObservabilityPacks.edges.forEach(({ node }) => {
const {
fields: { slug },
id,
} = node;

createPage({
path: path.join(slug, '/'),
component: path.resolve('./src/templates/ObservabilityPackDetails.js'),
context: {
id,
},
});
});

allNewRelicSdkComponent.edges.forEach(({ node }) => {
const {
fields: { slug },
Expand Down Expand Up @@ -161,6 +191,14 @@ exports.onCreateNode = ({ node, getNode, actions }) => {
value: `/apis/${kebabCase(node.name)}`,
});
}

if (node.internal.type === 'ObservabilityPacks') {
createNodeField({
node,
name: 'slug',
value: `/observability-packs/${slugify(node.name)}/${node.id}`,
});
}
};

exports.onCreateWebpackConfig = ({ actions, plugins }) => {
Expand Down
3 changes: 3 additions & 0 deletions src/components/FeatherIcon.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ const ICONS = {
<polyline points="16 16 12 12 8 16" />
</>
),
star: (
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
),
sun: (
<>
<circle cx="12" cy="12" r="5" />
Expand Down
5 changes: 4 additions & 1 deletion src/components/PageLayout/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import React from 'react';
import PropTypes from 'prop-types';
import { css } from '@emotion/react';

const Header = ({ title, children }) => (
const Header = ({ title, children, className }) => (
<header
className={className}
css={css`
grid-area: page-header;
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: space-between;
border-bottom: 1px solid var(--divider-color);
Expand Down Expand Up @@ -37,6 +39,7 @@ const Header = ({ title, children }) => (
);

Header.propTypes = {
className: PropTypes.string,
children: PropTypes.node,
title: PropTypes.string.isRequired,
};
Expand Down
7 changes: 5 additions & 2 deletions src/components/Tabs/Bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ MobileTabControl.propTypes = {
children: PropTypes.node.isRequired,
};

const Bar = ({ children }) => {
const Bar = ({ children, className }) => {
const detectMobile = useMobileDetect();
const isMobile = detectMobile.isMobile();

Expand All @@ -53,11 +53,13 @@ const Bar = ({ children }) => {

return (
<div
className={className}
role="tablist"
css={css`
display: flex;
width: 100%;
margin-bottom: 1em;
overflow: scroll;
overflow: auto;
`}
>
{React.Children.map(children, (child, index) =>
Expand All @@ -69,6 +71,7 @@ const Bar = ({ children }) => {

Bar.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
};

export default Bar;
3 changes: 1 addition & 2 deletions src/components/Tabs/BarItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const BarItem = ({ index, children, id, count, disabled }) => {
user-select: none;
white-space: nowrap;
.dark-mode & {
border-bottom-color: var(--color-dark-300);
}
Expand Down Expand Up @@ -123,7 +122,7 @@ const BarItem = ({ index, children, id, count, disabled }) => {
};

BarItem.propTypes = {
index: PropTypes.number.isRequired,
index: PropTypes.number,
children: PropTypes.node.isRequired,
id: PropTypes.string.isRequired,
count: PropTypes.number,
Expand Down
Binary file added src/images/no-image-placeholder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion src/pages/observability-packs.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ const ObservabilityPacksPage = ({ data, location }) => {
featuredImageUrl={
imgSrc || 'https://via.placeholder.com/400x275.png?text=Image'
}
to={`/observability-packs/${pack.name}/${pack.id}`}
to={`${pack.fields.slug}`}
/>
);
})}
Expand All @@ -277,6 +277,9 @@ export const pageQuery = graphql`
query {
allObservabilityPacks {
nodes {
fields {
slug
}
id
name
website
Expand Down
192 changes: 192 additions & 0 deletions src/templates/ObservabilityPackDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import React from 'react';
import { graphql } from 'gatsby';
import { css } from '@emotion/react';
import DevSiteSeo from '../components/DevSiteSeo';
import PropTypes from 'prop-types';
import PageLayout from '../components/PageLayout';
import Tabs from '../components/Tabs';
import noImagePlaceholder from '../images/no-image-placeholder.png';
import { Layout, PageTools, Button } from '@newrelic/gatsby-theme-newrelic';

const ObservabilityPackDetails = ({ data, location }) => {
const pack = data.observabilityPacks;

return (
<>
<DevSiteSeo title={pack.name} location={location} />
<Tabs>
<PageLayout type={PageLayout.TYPE.RELATED_CONTENT}>
<PageLayout.Header
title={pack.name}
css={css`
border-bottom: none;
`}
>
<Button variant={Button.VARIANT.PRIMARY} size={Button.SIZE.MEDIUM}>
Install
</Button>
<Tabs.Bar
css={css`
margin-top: 1rem;
`}
>
<Tabs.BarItem id="overview">Overview</Tabs.BarItem>
<Tabs.BarItem id="dependencies">Dependencies</Tabs.BarItem>
<Tabs.BarItem
id="dashboards"
disabled={!(pack.dashboards?.length ?? 0)}
count={pack.dashboards?.length ?? 0}
>
Dashboards
</Tabs.BarItem>
<Tabs.BarItem
id="alerts"
disabled={!(pack.alerts?.length ?? 0)}
count={pack.alerts?.length ?? 0}
>
Alerts
</Tabs.BarItem>
<Tabs.BarItem
id="synthetics"
disabled={!(pack.synthetics?.length ?? 0)}
count={pack.synthetics?.length ?? 0}
>
Synthetics checks
</Tabs.BarItem>
<Tabs.BarItem
id="visualizations"
disabled={!(pack.visualizations?.length ?? 0)}
count={pack.visualizations?.length ?? 0}
>
Visualizations
</Tabs.BarItem>
<Tabs.BarItem
id="nerdpacks"
disabled={!(pack.nerdpacks?.length ?? 0)}
count={pack.nerdpacks?.length ?? 0}
>
Nerdpacks
</Tabs.BarItem>
</Tabs.Bar>
</PageLayout.Header>

<Layout.Content>
{/* carousel component if we decide to use multiple images */}
<Tabs.Pages>
<Tabs.Page id="overview">
<img
src={noImagePlaceholder}
alt="placeholder"
height="250px"
/>
<h3>Description</h3>
<p>{pack.description}</p>
</Tabs.Page>
<Tabs.Page id="dashboards">
{pack.dashboards?.map((dashboard) => (
<>
<h3>{dashboard.name}</h3>
{dashboard.screenshots?.map((screenshot, index) => (
<img
key={index}
alt="dashboard example"
src={screenshot}
css={css`
height: 200px;
margin: 1rem;
`}
/>
))}
{dashboard.description && (
<>
<h4>Description</h4>
<p>{dashboard.description}</p>
</>
)}
</>
))}
</Tabs.Page>
<Tabs.Page id="alerts">
{pack.alerts?.map((alert) => (
<>
<h3>{alert.name}</h3>
{alert.description && (
<>
<h4>Description</h4>
<p>{alert.description}</p>
</>
)}
</>
))}
</Tabs.Page>
</Tabs.Pages>
</Layout.Content>
<Layout.PageTools
css={css`
p,
li {
font-size: 0.85rem;
}
`}
>
<PageTools.Section>
<PageTools.Title>How to use this pack</PageTools.Title>
<ol>
<li>
Sign up for a free New Relic account (or log in to your
existing account)
</li>
<li>Click the green install button above</li>
<li>
Follow the instructions to install the necessary
instrumentation to get the data used in this pack
</li>
<li>
Enjoy the dashboards, alerts, and appications filled with
insights on our environment and services.
</li>
</ol>
</PageTools.Section>
<PageTools.Section>
<PageTools.Title>Authors</PageTools.Title>
<p>{pack.authors.join(', ')}</p>
</PageTools.Section>
</Layout.PageTools>
</PageLayout>
</Tabs>
</>
);
};

ObservabilityPackDetails.propTypes = {
data: PropTypes.object,
location: PropTypes.object.isRequired,
};

export const pageQuery = graphql`
query($id: String!) {
observabilityPacks(id: { eq: $id }) {
name
website
logo
level
id
icon
description
alerts {
name
definition
url
}
dashboards {
description
name
screenshots
url
}
authors
}
}
`;

export default ObservabilityPackDetails;
9 changes: 9 additions & 0 deletions src/utils/slugify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const slugify = (str) =>
str
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/-+/, '-')
.replace(/[^a-z0-9-]/g, '');

module.exports = slugify;

0 comments on commit 2c97811

Please sign in to comment.