Skip to content

Commit

Permalink
feat: add ability to specify project. Update MDX to use code
Browse files Browse the repository at this point in the history
  • Loading branch information
jerelmiller committed Oct 14, 2020
1 parent 5d0fdc6 commit 1095bd1
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 44 deletions.
2 changes: 2 additions & 0 deletions src/components/MDXContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Intro from './Intro';
import Iframe from './Iframe';
import Tutorial from './Tutorial';
import TutorialStep from './TutorialStep';
import Project from './Project';
import { MDXCodeBlock, Video } from '@newrelic/gatsby-theme-newrelic';

import styles from './MDXContainer.module.scss';
Expand All @@ -22,6 +23,7 @@ const components = {
Step,
Steps,
Tutorial,
Project,
TutorialStep,
Caution,
Important,
Expand Down
6 changes: 6 additions & 0 deletions src/components/Project.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Does not render. Will be used by the `Tutorial` component
const Project = () => {
return null;
};

export default Project;
96 changes: 60 additions & 36 deletions src/components/Tutorial.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,68 @@
import React, { Children, cloneElement } from 'react';
import { Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import parseCodeBlockProps from '../utils/parseCodeBlockProps';
import { isCodeBlock, isShellCommand } from '../utils/codeBlock';

const Tutorial = ({ children }) => {
const initialState = Children.toArray(children)
children = Children.toArray(children);

const initialState =
children[0].props.mdxType === 'Project'
? parseFileInfoFromConfig(children[0])
: parseFileInfoFromChildren(children);

return children
.filter((child) => child.props.mdxType === 'TutorialStep')
.reduce((steps, stepElement, idx, arr) => {
const codeBlock = Children.toArray(stepElement.props.children).find(
(child) => isCodeBlock(child) && !isShellCommand(child)
);

if (!codeBlock) {
return [
...steps,
cloneElement(stepElement, { index: idx, totalSteps: arr.length }),
];
}

const previousStep =
idx === 0
? new Map(initialState)
: new Map(steps[idx - 1].props.step || initialState);

const { fileName, code, language } = parseCodeBlockProps(codeBlock);

return [
...steps,
cloneElement(stepElement, {
initialSelectedFile: fileName,
step: previousStep.set(fileName, { code, language }),
index: idx,
totalSteps: arr.length,
children: Children.toArray(stepElement.props.children).filter(
(child) => isShellCommand(child) || !isCodeBlock(child)
),
}),
];
}, []);
};

Tutorial.propTypes = {
children: PropTypes.node,
};

const parseFileInfoFromConfig = (configElement) => {
return Children.toArray(configElement.props.children)
.filter((child) => isCodeBlock(child) && !isShellCommand(child))
.reduce((map, child) => {
const { code, fileName, language } = parseCodeBlockProps(child);

return map.has(fileName) ? map : map.set(fileName, { code, language });
}, new Map());
};

const parseFileInfoFromChildren = (children) => {
return children
.flatMap((child) => Children.toArray(child.props.children))
.filter((child) => isCodeBlock(child) && !isShellCommand(child))
.reduce((map, child) => {
Expand All @@ -14,40 +72,6 @@ const Tutorial = ({ children }) => {
? map
: map.set(fileName, { code: '', language });
}, new Map());

return Children.toArray(children).reduce((steps, stepElement, idx, arr) => {
const codeBlock = Children.toArray(stepElement.props.children).find(
(child) => isCodeBlock(child) && !isShellCommand(child)
);

if (!codeBlock) {
return [...steps, stepElement];
}

const previousStep =
idx === 0
? new Map(initialState)
: new Map(steps[idx - 1].props.step || initialState);

const { fileName, code, language } = parseCodeBlockProps(codeBlock);

return [
...steps,
cloneElement(stepElement, {
initialSelectedFile: fileName,
step: previousStep.set(fileName, { code, language }),
index: idx,
totalSteps: arr.length,
children: Children.toArray(stepElement.props.children).filter(
(child) => isShellCommand(child) || !isCodeBlock(child)
),
}),
];
}, []);
};

Tutorial.propTypes = {
children: PropTypes.node,
};

export default Tutorial;
70 changes: 62 additions & 8 deletions src/markdown-pages/build-apps/map-pageviews-by-region.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,23 @@ If you don't have any results at this point, ensure your query doesn't have any

<Tutorial>

<Project>

```jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';

export default class PageViewApp extends React.Component {
render() {
return <h1>Hello, pageview-app-nerdlet Nerdlet!</h1>;
}
}
```

```css fileName=pageview-app-nerdlet/styles.scss
```

</Project>

<TutorialStep title="Create and serve a new Nerdpack">

To get started, create a new Nerdpack, and serve it up to New Relic from your local development environment:
Expand Down Expand Up @@ -109,7 +126,15 @@ When you select the launcher, you see a `Hello` message.
For the purposes of this exercise and for your convenience, hard code your account ID. In the `pageview-app-nerdlet` directory, in the `index.js` file, add this code between the `import` and `export` lines. ([Read about finding your account ID here](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id)).

```jsx fileName=pageview-app-nerdlet/index.js
const accountId = [Replace with your account ID];
import React from 'react';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
render() {
return <h1>Hello, pageview-app-nerdlet Nerdlet!</h1>;
}
}
```

</TutorialStep>
Expand All @@ -119,7 +144,16 @@ const accountId = [Replace with your account ID];
To show your data in a table chart, import the [`TableChart` component](/client-side-sdk/index.html#charts/TableChart) from New Relic One. To do so, in `index.js`, add this code under `import React`.

```jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
render() {
return <h1>Hello, pageview-app-nerdlet Nerdlet!</h1>;
}
}
```

</TutorialStep>
Expand All @@ -129,6 +163,11 @@ import { TableChart } from 'nr1';
To add a table with a single row, in the `index.js` file, replace this line with this `export` code:

```jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
render() {
return (
Expand All @@ -149,7 +188,7 @@ You can use standard CSS to customize the look of your components.
In the `styles.scss` file, add this CSS.
Feel free to customize this CSS to your taste.

```css fileName=styles.scss
```css fileName=pageview-app-nerdlet/styles.scss
.container {
width: 100%;
height: 99vh;
Expand All @@ -175,12 +214,27 @@ Now that you've got a table, you can drop a `TableChart` populated with data fro
Put this code into the `row` div.

```jsx fileName=pageview-app-nerdlet/index.js
<TableChart
accountId={accountId}
query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
fullWidth
className="chart"
/>
import React from 'react';
import { TableChart } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
render() {
return (
<div className="container">
<div className="row">
<TableChart
accountId={accountId}
query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
fullWidth
className="chart"
/>
</div>
</div>
);
}
}
```

Go to New Relic One and click your app to see your data in the table. (You might need to serve your app to New Relic again.)
Expand Down

0 comments on commit 1095bd1

Please sign in to comment.