Skip to content

Commit

Permalink
Merge branch 'cayla/clear-search' of github.com:newrelic/developer-we…
Browse files Browse the repository at this point in the history
…bsite into cayla/clear-search
Cayla Hamann committed Jun 25, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents eebf794 + 0e20507 commit 04b4128
Showing 26 changed files with 1,244 additions and 94 deletions.
6 changes: 6 additions & 0 deletions src/components/FeatherIcon.js
Original file line number Diff line number Diff line change
@@ -97,10 +97,16 @@ const ICONS = {
<polyline points="16 16 12 12 8 16" />
</>
),

x: (
<>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
),
award: (
<>
<circle cx="12" cy="8" r="7" />
<polyline points="8.21 13.89 7 23 12 20 17 23 15.79 13.88" />
</>
),
};
1 change: 1 addition & 0 deletions src/components/IconReference.module.scss
Original file line number Diff line number Diff line change
@@ -34,5 +34,6 @@
position: absolute;
font-size: 0.85rem;
top: calc(100% + 0.5rem);
right: 0;
z-index: 1;
}
54 changes: 41 additions & 13 deletions src/components/NavigationItems.js
Original file line number Diff line number Diff line change
@@ -8,6 +8,17 @@ import { BreadcrumbContext } from './BreadcrumbContext';
import styles from './NavigationItems.module.scss';
import { link } from '../types';

const iconLibrary = {
'Collect data': 'collectData',
'Build apps': 'buildApps',
'Automate workflows': 'automation',
'Explore docs': 'developerDocs',
};

const featherIconLibrary = {
'Developer champions': 'award',
};

const getHighlightedText = (text, highlight) => {
const parts = text.split(new RegExp(`(${highlight})`, 'gi'));
return (
@@ -59,6 +70,28 @@ const NavigationItems = ({
});
};

const NavIcon = ({ page }) => {
if (featherIconLibrary[page.displayName]) {
return (
<FeatherIcon
className={styles.headerIcon}
name={featherIconLibrary[page.displayName]}
/>
);
}

if (iconLibrary[page.displayName]) {
return (
<NewRelicIcon
className={styles.headerIcon}
name={iconLibrary[page.displayName]}
/>
);
}

return null;
};

const NavItem = ({ page, depthLevel, searchTerm, filteredPageNames }) => {
const crumbs = useContext(BreadcrumbContext).flatMap((x) => x.displayName);
const isHomePage = crumbs.length === 0 && depthLevel === 0;
@@ -67,19 +100,8 @@ const NavItem = ({ page, depthLevel, searchTerm, filteredPageNames }) => {
isHomePage || crumbs.includes(page.displayName)
);

const iconLibrary = {
'Collect data': 'collectData',
'Build apps': 'buildApps',
'Automate workflows': 'automation',
'Explore docs': 'developerDocs',
};
const isCurrentPage = crumbs[crumbs.length - 1] === page.displayName;
const headerIcon = depthLevel === 0 && (
<NewRelicIcon
className={styles.headerIcon}
name={iconLibrary[page.displayName]}
/>
);
const headerIcon = depthLevel === 0 && <NavIcon page={page} />;
const display = filteredPageNames
? getHighlightedText(page.displayName, searchTerm)
: page.displayName;
@@ -104,7 +126,7 @@ const NavItem = ({ page, depthLevel, searchTerm, filteredPageNames }) => {
)}
to={page.url}
>
<span>
<span className={styles.navLinkText}>
{headerIcon}
{display}
</span>
@@ -154,6 +176,12 @@ const NavItem = ({ page, depthLevel, searchTerm, filteredPageNames }) => {
);
};

NavIcon.propTypes = {
page: PropTypes.shape({
displayName: PropTypes.string.isRequired,
}),
};

NavigationItems.propTypes = {
pages: PropTypes.array.isRequired,
filteredPageNames: PropTypes.array,
5 changes: 5 additions & 0 deletions src/components/NavigationItems.module.scss
Original file line number Diff line number Diff line change
@@ -51,6 +51,11 @@ button.navLink {
}
}

.navLinkText {
display: flex;
align-items: center;
}

.currentPageIndicator {
stroke-width: 4;
}
Binary file added src/images/nrone-table-guide/added-table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/app-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/clicked.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/demo-app-button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/hovered.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/newtable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/nrone-launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/predefined.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/nrone-table-guide/table-new-cells.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/time-picker-guide/add-timepicker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/time-picker-guide/console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
162 changes: 162 additions & 0 deletions src/markdown-pages/5-min-tag-resources.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
path: '/guides/5-min-tag-resources'
duration: '5 min'
title: 'Quickly tag a set of resources'
template: 'GuideTemplate'
description: 'Add tags to applications you instrument for easier filtering and organization.'
---

<Intro>

[Tags](https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/core-concepts/tagging-use-tags-organize-group-what-you-monitor) help you group, search, filter, and focus the data about your [entities](https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/core-concepts/what-entity-new-relic), which can be anything from applications to hosts to services. Tagging entities using the New Relic CLI is a good candidate for automation.

In this 5-minute guide, you are going to use the New Relic CLI to add multiple tags to one of your entities.

</Intro>

## Before you begin

For this guide you need your New Relic [personal API Key](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#personal-api-key): Create it at the **Account settings** screen of your New Relic account.

<Steps>
<Step>

## Install the New Relic CLI

You can download the New Relic CLI via [Homebrew](https://brew.sh/) (macOS), [Scoop](https://scoop.sh/) (Windows), and [Snapcraft](https://snapcraft.io/) (Linux). You can also download [pre-built binaries](https://github.com/newrelic/newrelic-cli/releases) for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer.

* #### Linux

With [Snapcraft](https://snapcraft.io/) installed, run:

`sudo snap install newrelic-cli`

* #### macOS

With [Homebrew](https://brew.sh/) installed, run:

`brew install newrelic-cli`

* #### Windows

With [Scoop](https://scoop.sh/) installed, run:

`scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git`<br />
`scoop install newrelic-cli`

</Step><Step>

## Create your New Relic CLI profile

New Relic CLI profiles contain credentials and settings that you can apply to any CLI command.

To create your first CLI profile, run the [`profiles add`](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic_profile_add.md) command. Don't forget to set the [region](https://docs.newrelic.com/docs/using-new-relic/welcome-new-relic/get-started/our-eu-us-region-data-centers) of your New Relic account: use `-r` to set either `us` or `eu` (this is required).

```bash lineNumbers=false
# Create the tutorial account for the US region
newrelic profiles add -n tutorial --apiKey API_KEY -r us
# Set the profile as default
newrelic profiles default -n tutorial
```

</Step><Step>

## Search for an entity

Your New Relic account may have hundreds of entities: Have a quick look by opening the [Entity explorer](https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/ui-data/new-relic-one-entity-explorer-view-performance-across-apps-services-hosts).

In the terminal, run [`entity search`](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic_entity_search.md) to retrieve a list of entities from your account as JSON. In the example, you're searching for all entities with "test" in their name.

```bash lineNumbers=false
# Change the `name` to match any of your existing entities
newrelic entity search --name "test"
```

</Step><Step>

If there are matching entities in your account, the query yields data in JSON format, similar to this workload example.

Select an entity from the results and look for its `guid` value; the `guid` is the unique identifier of the entity. Write it down.

```json lineNumbers=false copy=false
{
"accountId": 123456789,
"domain": "NR1",
"entityType": "WORKLOAD_ENTITY",
"guid": "F7B7AE59FDED4204B846FB08423DB18E",
"name": "Test workload",
"reporting": true,
"type": "WORKLOAD"
},
```
</Step><Step>

## Add tags and tag lists to your entity

With your entity `guid`, you can add tags right away. You can do so by invoking the [`entities tags create`](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic_entity_tags_create.md) command.

What if you want to add multiple tags? You can use tag sets for that: While tags are key-value pairs separated by colons, tag sets are comma-separated lists of tags. For example:

`tag1:value1,tag2:value2`

<Important>Adding tags is an asynchronous operation: it could take a little while for the tags to get created.</Important>

```bash lineNumbers=false
# Adding a single tag
newrelic entity tags create --guid GUID --tag key:value
# Adding multiple tags
newrelic entity tags create --guid GUID --tag tag1:test,tag2:test
```
</Step><Step>

## Check that the tags are there

To make sure that the tags have been added to your entities, retrieve them using the [`entity tags get`](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic_entity_tags_get.md) command. All tags associated with your entity are retrieved as a JSON array.

`newrelic entity tags get --guid GUID`

<Tip>

Tags can be deleted at any time by invoking the [`entity tags delete`](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic_entity_tags_delete.md) command followed by the same arguments you used to create them.

</Tip>


```json lineNumbers=false
[
{
"Key": "tag1",
"Values": [
"true"
]
},
{
"Key": "tag2",
"Values": [
"test"
]
},
{
"Key": "tag3",
"Values": [
"testing"
]
}
// ...
]
```
</Step></Steps>

## Next steps

Have a look at [all the New Relic CLI commands](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic.md). For example, you could create a [New Relic workflow](https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/core-concepts/new-relic-one-workloads-isolate-resolve-incidents-faster) using [`workload create`](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic_workload_create.md).

If you'd like to engage with other community members, visit our [New Relic Explorers Hub](https://discuss.newrelic.com/c/build-on-new-relic/developer-toolkit) page. We welcome feature requests or bug reports on [GitHub](https://github.com/newrelic/newrelic-cli).

## Related info

- [Understanding Entity Explorer (Video)](https://www.youtube.com/watch?v=IGZQup8ZEmE)
- [Tagging: Use tags to organize and group what you monitor](https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/core-concepts/tagging-use-tags-organize-group-what-you-monitor)
- [New Relic CLI commands reference](https://github.com/newrelic/newrelic-cli/blob/master/docs/cli/newrelic.md)
- [New Relic CLI repository on GitHub](https://github.com/newrelic/newrelic-cli)

402 changes: 379 additions & 23 deletions src/markdown-pages/add-time-picker-guide.mdx

Large diffs are not rendered by default.

295 changes: 295 additions & 0 deletions src/markdown-pages/automate-workflows/get-started-terraform.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
---
path: '/automate-workflows/get-started-terraform'
duration: '20 min'
title: 'Set up New Relic using Terraform'
template: 'GuideTemplate'
description: "Learn how to provision New Relic resources using [Terraform](https://www.terraform.io/)."
---
<Intro>

[Terraform](https://www.terraform.io/) is a popular infrastructure as code software tool by HashiCorp. You can use it to provision all kind of infrastructure and services, including New Relic entities.

In this guide you'll learn how to set up New Relic for the first time with [Terraform](https://www.terraform.io/). More specifically, you are going to provision an alert policy with notifications in your New Relic account using Terraform.

<Video id="vifxeilp2h" type="wistia"/>

</Intro>
<Intro>

## Before you begin

To use this guide, you should have some basic knowledge of both New Relic and Terraform.

* If you haven't deployed a New Relic agent yet, [install New Relic](https://docs.newrelic.com/docs/agents/manage-apm-agents/installation/install-agent) for your application.
* [Install Terraform CLI](https://www.terraform.io/intro/getting-started/install.html).

</Intro>
<Steps>
<Step>

## Bootstrap your provider configuration

New Relic's Terraform Provider detects the environment variables above when running Terraform commands.

You can set the environment variables in your `.bash_profile` or `.bashrc` file.

Set the following environment variables:

* Set your [New Relic Personal API key](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#personal-api-key) with the `NEW_RELIC_API_KEY` environment variable. Most Personal API keys begin with the prefix `NRAK-`.
* Set your [New Relic Admin API key](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#admin) with the `NEW_RELIC_ADMIN_API_KEY` environment variable. Most Admin API keys begin with the prefix `NRAA-`.
* Set your [New Relic Account ID](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id) with the `NEW_RELIC_ACCOUNT_ID` environment variable.
* Set your New Relic [region](https://docs.newrelic.com/docs/using-new-relic/welcome-new-relic/get-started/our-eu-us-region-data-centers#verifying-account) with the `NEW_RELIC_REGION` environment variable. Your region is `US` if your account settings page is located at `rpm.newrelic.com`, and `EU` if your account is located at `rpm.eu.newrelic.com`.

```bash lineNumbers=false
# Add this to your .bash_profile
export NEW_RELIC_API_KEY=NRAK-...
export NEW_RELIC_ADMIN_API_KEY=NRAA-...
export NEW_RELIC_ACCOUNT_ID=12345
export NEW_RELIC_REGION=US
# Or set it inline when running `terraform plan` or `terraform apply`:
$ NEW_RELIC_API_KEY=NRAK-... terraform apply
```
</Step>
<Step>

## Start with a provider configuration

To connect Terraform with New Relic, you need to set New Relic as a provider in your Terraform configuration file, so that Terraform can create and manage New Relic resources in your account.

To set New Relic as a provider, create a Terraform configuration file (`main.tf`). This code sets `newrelic` as the Terraform provider and provisions an empty [alert policy](/docs/alerts/new-relic-alerts/configuring-alert-policies/create-edit-or-find-alert-policy) as the resource.

```hcl lineNumbers=false
provider "newrelic" {}
resource "newrelic_alert_policy" "alert_policy_name" {
name = "My Alert Policy Name"
}
```

</Step>
<Step>

## Initialize and test your setup

After adding New Relic as a provider, [initialize](https://www.terraform.io/docs/commands/init.html) the working directory from the command line using `terraform init`.

Once you've successfully initialized the working directory, test Terraform's [execution plan](https://www.terraform.io/docs/commands/plan.html) using `terraform plan` to confirm that you've the right setup.

```bash lineNumbers=false
# Initialize the working directory
$ terraform init

# Test the Terraform plan
$ terraform plan
```

`plan` performs a [dry run](https://en.wikipedia.org/wiki/Dry_run_(testing)) of your Terraform configuration, so nothing is actually provisioned. Always run `plan` to test your configuration before applying it.
</Step>
<Step>

## Add a data source

The alert policy you defined in `main.tf` does not contain any alert condition. You are going to add an alert condition linked to your application.

To store your application's information, you need to add a [data source](https://www.terraform.io/docs/configuration-0-11/data-sources.html).

```hcl lineNumbers=false
provider "newrelic" {}
# Data Source
data "newrelic_entity" "app_name" {
name = "my-app" # This must be an exact match of your app name in New Relic (case sensitive)
domain = "APM"
type = "APPLICATION"
}
resource "newrelic_alert_policy" "alert_policy_name" {
name = "My Alert Policy Name"
}
```
</Step>
<Step>

## Add an alert condition to the alert policy

Now you can add the alert condition. For example, you can create a `critical` alert condition that is triggered when the [Apdex](https://docs.newrelic.com/docs/apm/new-relic-apm/apdex/apdex-measure-user-satisfaction) of your application falls below `0.75` for five minutes.

```hcl lineNumbers=false
provider "newrelic" {}
data "newrelic_entity" "app_name" {
name = "my-app"
domain = "APM"
type = "APPLICATION"
}
resource "newrelic_alert_policy" "alert_policy_name" {
name = "My Alert Policy Name"
}
# Alert condition
resource "newrelic_alert_condition" "alert_condition_name" {
policy_id = newrelic_alert_policy.alert_policy_name.id
name = "My Alert Condition Name"
type = "apm_app_metric"
entities = [data.newrelic_entity.app_name.application_id]
metric = "apdex"
runbook_url = "https://www.example.com"
condition_scope = "application"
term {
duration = 5
operator = "below"
priority = "critical"
threshold = "0.75"
time_function = "all"
}
}
```
</Step>
<Step>

## Add a notification channel

Alert policies use [notification channels](https://docs.newrelic.com/docs/alerts/new-relic-alerts/managing-notification-channels/notification-channels-control-where-send-alerts) to inform you about incidents and active alerts. To add a notification channel to your alert policy, add the following snippet to your configuration file.

When the alert condition is triggered, the notification channel sends an email to the specified `recipients`. You can send notifications using different tools and channels, such as Slack, by changing the `type` of your [alert channel](https://www.terraform.io/docs/providers/newrelic/r/alert_channel.html).

```hcl lineNumbers=false
# Notification channel
resource "newrelic_alert_channel" "alert_notification_email" {
name = "paul@example.com"
type = "email"
config {
recipients = "fab@example.com"
include_json_attachment = "1"
}
}
# Link the above notification channel to your policy
resource "newrelic_alert_policy_channel" "alert_policy_email" {
policy_id = newrelic_alert_policy.alert_policy_name.id
channel_ids = [
newrelic_alert_channel.alert_notification_email.id
]
}
```

</Step>
<Step>

## Apply your Terraform configuration

The last step is provisioning the resources you've configured in `main.tf`, so that the alert policy is enabled in your New Relic account for your application.

To [apply](https://www.terraform.io/docs/commands/apply.html) the Terraform configuration and provision the resources in your New Relic account, run `terraform apply`.

Answer `yes` when prompted to apply the changes. Once the `apply` process is complete, you should see the new alert policy you've provisioned using Terraform, and its alert conditions, in your New Relic account.

You can run `terraform apply` every time you need to make changes to your configuration. To eliminate the resources you've provisioned, run [`terraform destroy`](https://www.terraform.io/docs/commands/destroy.html).
</Step>

<Step>

## Optional: Use the `apm` module for faster configuration

In the Terraform Registry you can find [our `apm` module](https://registry.terraform.io/modules/newrelic/apm/newrelic/0.0.4), which simplifies Terraform's configuration. `apm` creates an alert policy, a [Synthetics monitor](https://docs.newrelic.com/docs/synthetics/new-relic-synthetics/using-monitors/add-edit-monitors), and several alert conditions for a given application reporting data into New Relic.

To use our `apm` module with Terraform:

1. Set `newrelic/apm/newrelic` as the module source.
2. Add your `account_id` and `application_name`.
3. Define your `application_url` (if any).

Here is a configuration example with overridden default values. Initialize the working directory using `terraform init`to download and enable the module.

<Tip>

The `apm` module doesn't create a notification channel, so you would still have to define one.

</Tip>

```hcl lineNumbers=false
data "newrelic_alert_channel" "pager" {
name = "Page Developer Toolkit Team"
}
module "dummy-app-monitor" {
source = "newrelic/apm/newrelic"
account_id = 2520528
application_name = "Dummy App"
# An Apdex alert condition will be created with sensible defaults without the use of these attributes.
apdex_warning_threshold = 0.9
apdex_critical_threshold = 0.8
# An error rate alert condition will be created with sensible defaults without the use of these attributes.
error_rate_warning_threshold = 5
error_rate_critical_threshold = 10
# Specifying an application URL will provision a Synthetics monitor and associated alert condition.
application_url = "https://www.dummyapp.com"
synthetics_monitor_verify_ssl = true
# Response time alert condition will not be provisioned unless a critical violation threshold is specified.
response_time_critical_threshold = 3
channel_ids = [data.newrelic_alert_channel.pager.id]
}
```

</Step></Steps>

## Tip: Avoid resources being marked as "sensitive"

When API results are deemed to be secret and are obfuscated, Terraform may be unable to detect the state of a resource, marking it as changed. Consider this example:

```hcl lineNumbers=false
resource "newrelic_alert_channel" "slack" {
name = "slack"
type = "slack"
config {
channel = "test"
url = "https://hooks.slack.com/services/xxxx/xxxxx"
}
}
```
<br />

Running `terraform plan` yields the following:

```
-/+ newrelic_alert_channel.slack (new resource required)
id: "2344397" => <computed> (forces new resource)
config.%: "1" => "2" (forces new resource)
config.channel: <sensitive> => <sensitive> (attribute changed)
config.url: <sensitive> => <sensitive> (forces new resource)
name: "slack" => "slack"
type: "slack" => "slack"
```
<br />

To prevent Terraform from wrongly marking a resource as changed, add an [`ignore_changes`](https://www.terraform.io/docs/configuration/resources.html#ignore_changes) directive:

```hcl lineNumbers=false
resource "newrelic_alert_channel" "slack" {
...
lifecycle {
ignore_changes = ["config"]
}
}
...
```
<br />

This avoids changes to resources caused by obfuscated items.

## Related info

- [Terraform New Relic Provider](https://www.terraform.io/docs/providers/newrelic/index.html)
- [New Relic documentation](https://docs.newrelic.com)
- [Terraform documentation](https://www.terraform.io/docs/index.html)
2 changes: 1 addition & 1 deletion src/markdown-pages/example.mdx
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ This guide requires that you have the following:
But it doesn't include a code snippet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel orci dignissim, egestas turpis non, ultricies erat. Nullam id magna molestie, volutpat ipsum vitae, bibendum ligula.
</Step>

<Step>
<Step>

This is a step with no title or code snippet, only description. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel orci dignissim, egestas turpis non, ultricies erat. Nullam id magna molestie, volutpat ipsum vitae, bibendum ligula.

270 changes: 270 additions & 0 deletions src/markdown-pages/howto-use-nrone-table-components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
---
path: '/guides/howto-use-nrone-table-components'
duration: '30 min'
title: 'Add tables to your New Relic One application'
template: 'GuideTemplate'
description: 'Tables are great for displaying data in New Relic One. This guides explains how to create tables using the nr1 library.'
---

<Intro>

Tables are a popular way of displaying data in New Relic applications. For example, with the <a href="https://docs.newrelic.com/docs/chart-builder/use-chart-builder/get-started/introduction-chart-builder">chart builder</a> you can create tables from <a href="https://docs-dev.newrelic.com/docs/query-data/nrql-new-relic-query-language/getting-started/introduction-nrql">NRQL queries</a>.

Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application.

In this guide, you are going to build a sample table using various components of the <var>NR1</var> library.

<Video id="28nnlbhrvg" type="wistia"/>

</Intro>

## Before you begin

Follow the [instructions in New Relic One](https://one.newrelic.com/launcher/developer-center.launcher) to create an API key and download and configure your NR1 CLI profile.
<br/>
This guide requires that you have Git and node.js installed on your machine.

<br/>

<Steps>
<Step>

## Clone the example application

In this guide you are going to experiment with tables. To do that, you need a New Relic One application you can modify and test on your computer.

There's a demo application for you in the [nr1-how-to](https://github.com/newrelic/nr1-how-to) repository. Start by cloning the repository from GitHub to your local machine. Then, navigate to the app directory.

```sh lineNumbers=false copy=false
git clone https://github.com/newrelic/nr1-how-to.git`
cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet`
```

</Step><Step>

Edit the `index.json` file and set `this.accountId` to [your Account ID](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id) as shown in the example.

```js lineNumbers=false
export default class Nr1HowtoAddTimePicker extends React.Component {
constructor(props){
super(props)
this.accountId = YOUR_ACCOUNT_ID;
}
...
}
```

</Step>
<Step>

## Run the demo application

Change the directory back to `nr1-how-to/create-a-table`. Before you can load the demo application, you need to [update its unique id](https://developer.newrelic.com/build-tools/new-relic-one-applications/guide-to-authentication--data-access--and-permissions) by invoking the NR1 CLI.

Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser.

```bash lineNumbers=false copy=false
nr1 nerdpack:uuid -gf # Update the app unique ID
npm install # Install dependencies
nr1 nerdpack:serve # Serve the demo app locally
```

</Step>
<Step>

Open [one.newrelic.com/?nerdpacks=local](https://one.newrelic.com/?nerdpacks=local) in your browser. You should see a **Create a table** button in your launcher: That's the demo application you are going to work on. Go ahead and select it.

![app-launcher](../images/nrone-table-guide/demo-app-button.png)

Have a good look at the demo app: There is a `TableChart` on the left side named **Transaction Overview**, with an `AreaChart` next to it. You are going to use `Table` components to add a new table in the second row.

![app-launcher](../images/nrone-table-guide/app-overview.png)

</Step>
<Step>

## Import the Table components

Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file.

Add the following components to the import statement at the top of the file so that it looks like the example:

* `Table`
* `TableHeader`
* `TableHeaderCell`
* `TableRow`
* `TableRowCell`


```jsx lineNumbers=false
import {
Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart,
} from 'nr1';
```

</Step>
<Step>

## Add a basic Table component
Locate the empty `GridItem` in `index.js`: This is where you start building the table.

Add the initial `<Table>` component. The `items` property collects the data by calling `_getItems()`, which contains sample values.

```jsx lineNumbers=false
<GridItem className="primary-content-container" columnSpan={12}>
<Table items={this._getItems()}>
</Table>
</GridItem>
```

</Step>
<Step>

## Add the header and rows

As the [`Table`](https://developer.newrelic.com/client-side-sdk/index.html#components/Table) component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows.

Inside of the `Table` component, add the `TableHeader` and then a `TableHeaderCell` child for each heading.

Since you don't know how many rows you'll need, your best bet is to call a function to build as many `TableRows` as items returned by `_getItems()`.


```jsx lineNumbers=false
<TableHeader>
<TableHeaderCell>Application</TableHeaderCell>
<TableHeaderCell>Size</TableHeaderCell>
<TableHeaderCell>Company</TableHeaderCell>
<TableHeaderCell>Team</TableHeaderCell>
<TableHeaderCell>Commit</TableHeaderCell>
</TableHeader>
{({ item }) => (
<TableRow>
<TableRowCell>{item.name}</TableRowCell>
<TableRowCell>{item.value}</TableRowCell>
<TableRowCell>{item.company}</TableRowCell>
<TableRowCell>{item.team}</TableRowCell>
<TableRowCell>{item.commit}</TableRowCell>
</TableRow>
)}

```

</Step>
<Step>

Take a look at the application running in New Relic One: you should see something similar to the screenshot below.

![added-table](../images/nrone-table-guide/newtable.png)

</Step>
<Step>

## Replace standard table cells with smart cells

The NR1 library includes cell components that can automatically format certain data types, like users, metrics, and entity names.

The table you've just created contains columns that can benefit from those components: **Application** (an entity name) and **Size** (a metric).

Before you can use `EntityTitleTableRowCell` and `MetricTableRowCell`, you have to add them to the import statement first.

```jsx lineNumbers=false copy=false
import {
EntityTitleTableRowCell,
MetricTableRowCell,
... /* All previous components */
} from 'nr1';

```

</Step>
<Step>

Update your table rows by replacing the first and second `TableRowCell`s with entity and metric cells.

Notice that [`EntityTitleTableRowCell`](https://developer.newrelic.com/client-side-sdk/index.html#components/EntityTitleTableRowCell) and [`MetricTableRowCell`](https://developer.newrelic.com/client-side-sdk/index.html#components/MetricTableRowCell) are self-closing tags.

```jsx lineNumbers=false
{({ item }) => (
<TableRow>
<EntityTitleTableRowCell value={item}/>
<MetricTableRowCell type={MetricTableRowCell.TYPE.APDEX} value={item.value} />
<TableRowCell>{item.company}</TableRowCell>
<TableRowCell>{item.team}</TableRowCell>
<TableRowCell>{item.commit}</TableRowCell>
</TableRow>
)}

```

</Step>
<Step>

Time to give your table a second look: The cell components you've added take care of properly formatting the data.

![new-components](../images/nrone-table-guide/table-new-cells.png)

</Step>
<Step>

## Add some action to your table!

Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row.

Add the `_getActions()` method to your `index.js` file, right before `_getItems()`.

As you may have guessed from the code, `_getActions()` spawns an alert box when you click **Team** or **Commit** cells.

```jsx lineNumbers=false
_getActions() {
return [
{
label: 'Alert Team',
iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT,
onClick: (evt, { item, index }) => {
alert(`Alert Team: ${item.team}`);
},
},
{
label: 'Rollback Version',
iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO,
onClick: (evt, { item, index }) => {
alert(`Rollback from: ${item.commit}`);
},
},
];
}

```

</Step>
<Step>

Find the `TableRow` component in your `return` statement and point the `actions` property to `_getActions()`.

The `TableRow` actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an `onClick` callback, but can also display an icon or be disabled if needed.

```jsx lineNumbers=false
<TableRow actions={this._getActions()}>
```

</Step>
<Step>

Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser.

![interactive-table](../images/nrone-table-guide/interactive-table.png)

</Step>
</Steps>

## Next steps

You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done!

Keep exploring the `Table` components, their properties, and how to use them, in our [SDK documentation](https://developer.newrelic.com/client-side-sdk/index.html#components/Table).

### Related info

- [Community page for how to use NR1 table components ](https://discuss.newrelic.com/t/how-to-use-nr1-table-components/98934)
- [New Relic SDK documentation](https://developer.newrelic.com/client-side-sdk/index.html)

Original file line number Diff line number Diff line change
@@ -6,34 +6,35 @@ template: 'GuideTemplate'
description: 'Learn to explore NerdGraph, our GraphQL API, and build the queries you need.'
---

## What is the NerdGraph API Explorer
<Intro>

NerdGraph is New Relic's [GraphQL](https://graphql.org/) API. With NerdGraph, you can get all the information you need in a single request. No matter how much data you pull into New Relic, our GraphQL API can help you navigate that complexity and gain more insight.

NerdGraph is different from REST APIs in that you don't need to chain together several calls to obtain the required data. Instead, you use the Graph query language to retrieve JSON objects from our graph, which is spread across our many microservices.
NerdGraph is New Relic's [GraphQL](https://graphql.org/) API. It allows you to get all the information you need in a single request.

With NerdGraph API Explorer you don't need to know the query format: using the Query Builder you can browse our entire graph and compose queries just by selecting the items you want and filling out their required values.

This guide shows you how to use NerdGraph to compose queries, and how to turn them into cURL or New Relic CLI snippets.
</Intro>

## Before you begin

Go to [api.newrelic.com/graphiql](https://api.newrelic.com/graphiql) and log in using your New Relic user ID and password: the NerdGraph API Explorer load up. Before you begin, make sure you have a valid New Relic API key. You can create one directly from the NerdGraph API Explorer.
Go to [api.newrelic.com/graphiql](https://api.newrelic.com/graphiql) and log in using your New Relic user ID and password: the NerdGraph API Explorer loads up.

Make sure you have a valid New Relic API key. You can create one directly from the NerdGraph API Explorer.

![Create a NerdGraph API key](../../images/graphql-guide/create-account.png)

The Query Builder is in the left sidebar and lets you search, browse, and select graph fields. The center is the GraphQL query editor, which comes with syntax highlighting and autocompletion. Clicking the play button runs the query; the results appear as JSON on the right sidebar.
<Steps>
<Step>

## Build a query to retrieve your name

Time for your first NerdGraph query! You are going to search for your name in the New Relic database:
Time for your first NerdGraph query. You are going to search for your name in the New Relic database:

1. Erase everything in the query editor.
2. Select the following fields in the query explorer in this order: `actor`, `user`, `name`.

This GraphQL snippet appears in the editor:
This GraphQL snippet appears in the editor.

```jsx
```jsx lineNumbers=false
{
actor {
user {
@@ -42,29 +43,27 @@ This GraphQL snippet appears in the editor:
}
}
```
</Step>
<Step>

With this query, you're telling NerdGraph to retrieve your name. You're asking for the `name` field, which is nested within the `user` field. This refers to the user who owns the API key, which in turn is nested within `actor`. Click the **play** button to see the result:
## Click the play button to see the result

```jsx
{
"data": {
"actor": {
"user": {
"name": "Your name"
}
}
},
"extensions": {...}
}
```
With this query, you're telling NerdGraph to retrieve your name. You're asking for the `name` field, which is nested within the `user` field. This refers to the user who owns the API key, which in turn is nested within `actor`.

Click the **play** button to see the result: It has almost the same shape as the request. All the fields in the Query Builder make up what's called the GraphQL schema, which describes all the available data types and their attributes. To learn more about each field, click the **Docs** button, or hover over a field in the editor.

The result has almost the same shape as the request; all the fields in the Query Builder make up what's called the GraphQL schema, which describes all the available data types and their attributes. To learn more about each field, click the **Docs** button, or hover over a field in the editor.

![NerdGraph documentation and tooltips](../../images/graphql-guide/graphql-documentation.png)

Now you can try adding more fields to your query. The simplest way is clicking the fields in the Query Builder: The NerdGraph API Explorer knows where the attributes should go in the query. In the example below, you add the account `id` and `email` fields.
</Step><Step>

## Add more fields to your query

```jsx
Now you can try adding more fields to your query. The simplest way is clicking the fields in the Query Builder: The API Explorer knows where the attributes should go in the query. In the example, you add the account `id` and `email` fields.

Once again, running the GraphQL query results in just the data you need, without over or under-fetching data. Notice that the `id` field has an argument: passing arguments is a powerful way of customizing your NerdGraph queries. Every field and object can contain arguments, so instead of running multiple queries, you just compose the one that you need.

```jsx lineNumbers=false
{
actor {
user {
@@ -76,7 +75,7 @@ Now you can try adding more fields to your query. The simplest way is clicking t
}
```

Once again, running the GraphQL query results in just the data you need, without over or under-fetching data. Notice that the `id` field has an argument: passing arguments is a powerful way of customizing your NerdGraph queries. Every field and object can contain arguments, so instead of running multiple queries, you just compose the one that you need.
</Step><Step>

## Experiment with mutations

@@ -92,7 +91,13 @@ Ready for your first mutation?

In this case, you're trying to add a custom tag to an entity. Notice that the editor complains if you don't select `errors`: mutations must have a way of telling you how the operation performed in the backend (failed requests result in null responses).

> Unlike REST, GraphQL APIs like NerdGraph can return partial responses. For example, if you try adding tags to multiple entities, some mutations can fail and others succeed; all is logged in the GraphQL response you get.
<Tip>

Unlike REST, GraphQL APIs like NerdGraph can return partial responses. For example, if you try adding tags to multiple entities, some mutations can fail and others succeed; all is logged in the GraphQL response you get.

</Tip>

</Step><Step>

## Try your NerdGraph query in the terminal

@@ -103,19 +108,15 @@ Let's say that you've built a NerdGraph query you're happy with and you want to

![Tools menu](../../images/graphql-guide/tools-menu.png)

Here's what the first query you created in this guide would look like as cURL:

```sh
```bash lineNumbers=false
# cURL version
curl https://api.newrelic.com/graphql \
-H 'Content-Type: application/json' \
-H 'API-Key: API_KEY_REDACTED' \
--data-binary '{"query":"{\n actor {\n user {\n name\n email\n }\n account(id: 12345678)\n }\n}\n", "variables":""}'
```

And here's its New Relic CLI equivalent:

```sh
NEW_RELIC_REGION=US NEW_RELIC_API_KEY=API_KEY_REDACTED newrelic nerdgraph query '{
# New Relic CLI version
newrelic nerdgraph query '{
actor {
user {
name
@@ -126,16 +127,18 @@ NEW_RELIC_REGION=US NEW_RELIC_API_KEY=API_KEY_REDACTED newrelic nerdgraph query
}
'
```
</Step>
</Steps>

Now you know the basics of composing and testing NerdGraph queries, but how do you turn them into client or server code? Solutions such as [GraphQL Code Generator](https://graphql-code-generator.com/) can help you turn the NerdGraph queries into code for your implementation.
## Next steps

## What’s next?
Now you know the basics of composing and testing NerdGraph queries, but how do you turn them into client or server code? Solutions such as [GraphQL Code Generator](https://graphql-code-generator.com/) can help you turn the NerdGraph queries into code for your implementation.

Try creating more complex queries by clicking fields and expanding objects in the Query Builder (be careful with mutations though, since they could write data to your account).

For more information on NerdGraph and explore other projects from the developer community, check out the [threads on the Explorer’s Hub](https://discuss.newrelic.com/search?q=nerdgraph).

## Useful links
## Related info

- [Introduction to New Relic NerdGraph](https://docs.newrelic.com/docs/apis/nerdgraph/get-started/introduction-new-relic-nerdgraph)
- [NerdGraph tutorials](https://docs.newrelic.com/docs/apis/nerdgraph/tutorials)
- [NerdGraph tutorials](https://docs.newrelic.com/docs/apis/nerdgraph/tutorials)
47 changes: 31 additions & 16 deletions src/pages/index.js
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@ import SEO from '../components/Seo';
import GuideListing from '../components/GuideListing/GuideListing';
import GuideTile from '../components/GuideTile';
import PageTitle from '../components/PageTitle';
import Section from '../components/Section';
import Video from '../components/Video';
import FeatherIcon from '../components/FeatherIcon';
import ExternalLink from '../components/ExternalLink';
@@ -77,21 +76,15 @@ const IndexPage = ({ data, pageContext }) => {
<section className={styles.intro}>
<div className={styles.introText}>
<p>
Welcome to the New Relic developer site! Here, you’ll find the
tools and resources you need to build on and customize the
platform.
Whether you're new to New Relic or already a data nerd, you can
start building right now. For free.
</p>
<p>
You need custom data that improves performance. We have tools for
that! Learn how to collect data from any source and visualize it
the way you need. Build out solutions in your own custom apps, and
then automate them. From how-to guides to video tutorials,
community projects, and more - we’ve got you covered.
</p>
<p>
Best of all? This open source site is built for you — your
suggestions, feedback, and comments are just a Pull Request away.
With our platform as your foundation, create custom observability
apps fast. Answer your unique questions, improve your software,
and deliver new value to your business.
</p>
<p>We're glad you are here. Let's start building.</p>
</div>
<Video
className={styles.introVideo}
@@ -101,7 +94,7 @@ const IndexPage = ({ data, pageContext }) => {
/>
</section>

<Section backgroundBanner>
<section className={cx(styles.section, styles.stripedSection)}>
<GuideListing className={styles.guideListing}>
<header className={styles.guideListingHeader}>
<GuideListing.Heading className={cx(styles.guideListingHeading)}>
@@ -117,9 +110,9 @@ const IndexPage = ({ data, pageContext }) => {
))}
</GuideListing.List>
</GuideListing>
</Section>
</section>

<GuideListing className={styles.guideListing}>
<GuideListing className={styles.section}>
<GuideListing.Heading className={styles.guideListingHeading}>
Get inspired
</GuideListing.Heading>
@@ -152,6 +145,24 @@ const IndexPage = ({ data, pageContext }) => {
</ExternalLink>{' '}
built by the New Relic community.
</p>

<section className={cx(styles.section, styles.stripedSection)}>
<h1>New Relic developer champions</h1>
<p>
New Relic Champions are solving big problems using New Relic as
their linchpin and are recognized as experts and leaders in the New
Relic technical community.
</p>
<ExternalLink href="https://forms.gle/Zkdub5e1x4MNqSKW9">
<button type="button">
Nominate a Developer Champion
<FeatherIcon
className={styles.externalLinkIcon}
name="external-link"
/>
</button>
</ExternalLink>
</section>
</Layout>
</PageContext.Provider>
);
@@ -181,4 +192,8 @@ export const pageQuery = graphql`
}
`;

IndexPage.propTypes = {
pageContext,
};

export default IndexPage;
11 changes: 10 additions & 1 deletion src/pages/index.module.scss
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@
}

.guideListing {
margin-top: 6rem;
margin-top: 0;
}

.guideListingHeader {
@@ -69,3 +69,12 @@
.externalLinkIcon {
margin-left: 0.25rem;
}

.section {
margin-top: 4rem;
}

.stripedSection {
padding: 2rem;
background: var(--color-neutrals-100);
}

0 comments on commit 04b4128

Please sign in to comment.