diff --git a/.eslintrc.js b/.eslintrc.js index 849758db1..d8c2b04e1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,6 +4,7 @@ module.exports = { 'plugin:@newrelic/eslint-plugin-newrelic/react', 'plugin:@newrelic/eslint-plugin-newrelic/prettier', 'plugin:jsx-a11y/recommended', + 'plugin:react-hooks/recommended', ], // https://github.com/yannickcr/eslint-plugin-react#configuration plugins: ['react', 'jsx-a11y'], diff --git a/package-lock.json b/package-lock.json index e88315cb4..2bab40225 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8854,9 +8854,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", - "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.4.tgz", + "integrity": "sha512-equAdEIsUETLFNCmmCkiCGq6rkSK5MoJhXFPFYeUebcjKgBmWWcgVOqZyQC8Bv1BwVCnTq9tBxgJFgAJTWoJtA==" }, "eslint-scope": { "version": "5.0.0", @@ -10750,6 +10750,11 @@ } } }, + "eslint-plugin-react-hooks": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==" + }, "gatsby-cli": { "version": "2.11.11", "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-2.11.11.tgz", @@ -19475,6 +19480,11 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" }, + "normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" + }, "npm-conf": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", diff --git a/package.json b/package.json index 968c3c9f8..2ce707688 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@mdx-js/react": "^1.6.4", "classnames": "^2.2.6", "date-fns": "^2.14.0", + "eslint-plugin-react-hooks": "^4.0.4", "gatsby": "^2.20.25", "gatsby-image": "^2.3.4", "gatsby-plugin-google-tagmanager": "^2.3.3", @@ -23,6 +24,7 @@ "gatsby-transformer-remark": "^2.7.3", "gatsby-transformer-sharp": "^2.4.6", "node-sass": "^4.13.1", + "normalize.css": "^8.0.1", "prism-react-renderer": "^1.1.1", "prop-types": "^15.7.2", "react": "^16.12.0", diff --git a/src/components/GuideTile.module.scss b/src/components/GuideTile.module.scss index 5a6b8b2b4..7fb015f33 100644 --- a/src/components/GuideTile.module.scss +++ b/src/components/GuideTile.module.scss @@ -5,7 +5,7 @@ 'main main main'; background-color: white; box-shadow: var(--boxshadow); - padding: 1.5rem; + padding: 0.5rem; button:hover { transform: translateY(-1px); @@ -40,5 +40,6 @@ font-size: 0.9rem; margin-bottom: 1.5rem; max-width: calc(100% - 4rem); - color: var(--color-neutrals-500); + color: var(--color-neutrals-600); + flex: 1; } diff --git a/src/components/IconGallery.js b/src/components/IconGallery.js index 82615b552..0f4197ea7 100644 --- a/src/components/IconGallery.js +++ b/src/components/IconGallery.js @@ -5,12 +5,13 @@ import IconReference from './IconReference'; const IconGallery = () => { if (typeof window === 'undefined') global.window = {}; + const [search, setSearch] = useState(''); + // Get the Icon component when available const { Icon } = window.__NR1_SDK__?.default ?? {}; if (!Icon) return null; // Basic search / filtering - const [search, setSearch] = useState(''); const types = Object.keys(Icon.TYPE); const filterByString = (input) => (str) => str.toLowerCase().includes(input.toLowerCase()); diff --git a/src/components/Layout.js b/src/components/Layout.js index 7cfb1fcbe..baa03e316 100644 --- a/src/components/Layout.js +++ b/src/components/Layout.js @@ -7,6 +7,7 @@ import GlobalHeader from './GlobalHeader'; import MobileHeader from './MobileHeader'; import Sidebar from './Sidebar'; import styles from './Layout.module.scss'; +import 'normalize.css'; import './styles.scss'; const Layout = ({ children }) => { diff --git a/src/components/Layout.module.scss b/src/components/Layout.module.scss index c4fe3aabe..cb72efcdc 100644 --- a/src/components/Layout.module.scss +++ b/src/components/Layout.module.scss @@ -5,7 +5,6 @@ } .main { - min-height: 100%; display: grid; grid-template-columns: 300px minmax(0, 1fr); width: 100%; diff --git a/src/components/Navigation.js b/src/components/Navigation.js index cdd2a1395..69f466fcd 100644 --- a/src/components/Navigation.js +++ b/src/components/Navigation.js @@ -9,9 +9,13 @@ import matchSearchString from '../utils/matchSearchString'; import styles from './Navigation.module.scss'; +// TODO: Add this implementation +const filterPages = (pages, _searchTerm) => pages; + // recursively create navigation const renderNav = (pages, searches, depthLevel = 0) => { const crumbs = useContext(BreadcrumbContext).flatMap((x) => x.displayName); + const isHomePage = crumbs.length === 0 && depthLevel === 0; const groupedPages = pages.reduce((groups, page) => { const { group = '' } = page; @@ -29,9 +33,7 @@ const renderNav = (pages, searches, depthLevel = 0) => { )} {pages.map((page) => { const [isExpanded, setIsExpanded] = useState( - searches !== undefined || - crumbs.includes(page.displayName) || - crumbs.length === depthLevel + isHomePage || crumbs.includes(page.displayName) ); const isCurrentPage = crumbs[crumbs.length - 1] === page.displayName; @@ -54,7 +56,13 @@ const renderNav = (pages, searches, depthLevel = 0) => { )} > {page.url ? ( - + {page.displayName} {isCurrentPage && ( { onKeyPress={() => setIsExpanded(!isExpanded)} tabIndex={0} > + {depthLevel > 0 && ( + + )} {page.displayName} )} diff --git a/src/components/Navigation.module.scss b/src/components/Navigation.module.scss index f747b3129..6a3b3cbf6 100644 --- a/src/components/Navigation.module.scss +++ b/src/components/Navigation.module.scss @@ -27,6 +27,11 @@ align-items: center; justify-content: space-between; text-decoration: none; + transition: 0.1s; + + &:not(.isCurrentPage):hover { + color: var(--color-neutrals-600); + } [data-depth='0'] > & { font-weight: bold; @@ -50,6 +55,15 @@ button.navLink { stroke-width: 4; } +.nestedChevron { + margin-right: 0.5rem; + stroke-width: 4; + transition: 0.2s; + &.isExpanded { + transform: rotate(90deg); + } +} + .groupName { color: var(--color-neutrals-600); font-weight: bold; diff --git a/src/components/Step.module.scss b/src/components/Step.module.scss index 1591bc1d6..4c6d999f8 100644 --- a/src/components/Step.module.scss +++ b/src/components/Step.module.scss @@ -19,7 +19,7 @@ h6:first-child { color: var(--color-neutrals-900); font-weight: bold; - margin-top: 0.5rem; + margin-top: 0; margin-bottom: 1rem; font-size: 1rem; } diff --git a/src/components/Video.module.scss b/src/components/Video.module.scss index c522733b8..e6cd9b9f4 100644 --- a/src/components/Video.module.scss +++ b/src/components/Video.module.scss @@ -1,6 +1,5 @@ .video { max-width: 560px; - margin: 1rem 0; iframe { width: 100%; diff --git a/src/components/styles.scss b/src/components/styles.scss index 1907c099b..7a07ed788 100644 --- a/src/components/styles.scss +++ b/src/components/styles.scss @@ -57,12 +57,12 @@ --color-teal-800: #003539; --color-teal-900: #002123; - --boxshadow: 0px 2.76726px 2.21381px rgba(0, 85, 90, 0.0168687), - 0px 6.6501px 5.32008px rgba(0, 85, 90, 0.0242336), - 0px 12.5216px 10.0172px rgba(0, 85, 90, 0.03), - 0px 22.3363px 17.869px rgba(0, 85, 90, 0.0357664), - 0px 41.7776px 33.4221px rgba(0, 85, 90, 0.0431313), - 0px 100px 80px rgba(0, 85, 90, 0.06); + --boxshadow: 0 0.24905px 0.55345px rgba(0, 0, 0, 0.00562291), + 0 0.59851px 1.33002px rgba(0, 0, 0, 0.00807786), + 0 1.12694px 2.50431px rgba(0, 0, 0, 0.01), + 0 2.01027px 4.46726px rgba(0, 0, 0, 0.0119221), + 0 3.75998px 8.35552px rgba(0, 0, 0, 0.0143771), + 0 9px 20px rgba(0, 0, 0, 0.02); --color-tile-background: rgb(215, 210, 233); --primary-font-family: 'open sans', sans-serif; @@ -74,19 +74,11 @@ --height-mobile-nav-bar: 60px; } -/*-- Reset --*/ -// https://github.com/necolas/normalize.css -html { - line-height: 1.15; - -webkit-text-size-adjust: 100%; -} - * { box-sizing: border-box; } body { - margin: 0; font-size: 16px; font-family: var(--primary-font-family); color: var(--color-neutrals-700); @@ -94,20 +86,12 @@ body { line-height: 1.5; } -main { - display: block; -} - a { cursor: pointer; text-decoration: none; color: var(--color-brand-800); } -img { - border-style: none; -} - p { margin-top: 0; margin-bottom: 1em; @@ -126,17 +110,6 @@ h6 { font-family: var(--primary-font-family); } -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - font-size: 100%; - line-height: 1.15; - margin: 0; -} - input, select { border: 1px solid var(--color-neutrals-400); @@ -149,7 +122,6 @@ button, [type='button'], [type='reset'], [type='submit'] { - -webkit-appearance: button; display: inline-flex; align-items: center; justify-content: center; @@ -177,6 +149,10 @@ code { font-family: var(--code-font); } +pre { + margin: 0; +} + :global { .intro-text { color: var(--color-neutrals-600); @@ -186,6 +162,6 @@ code { .site-container { max-width: 1460px; - margin: auto; + margin: 0 auto; } } diff --git a/src/data/sidenav.json b/src/data/sidenav.json index 1e5ff10d3..388831b20 100644 --- a/src/data/sidenav.json +++ b/src/data/sidenav.json @@ -8,15 +8,15 @@ "url": "/" }, { - "displayName": "OpenTelemetry Exporter", + "displayName": "OpenTelemetry exporter", "url": "/" }, { - "displayName": "Extend New Relic Agents", + "displayName": "Extend New Relic agents", "url": "/" }, { - "displayName": "Create Flex Integration", + "displayName": "Create a Flex integration", "url": "/" } ] @@ -26,41 +26,40 @@ "url": "/explore-data", "children": [ { - "displayName": "Write NRQL Queries", + "displayName": "Write NRQL queries", "url": "/" }, { - "displayName": "Build a NerdGraph Query", + "displayName": "Build a NerdGraph query", "url": "/" } ] }, { "displayName": "Build apps", - "url": "/build-apps", "children": [ { - "displayName": "Map Pageviews by Region", + "displayName": "Map pageviews by region", "url": "/build-apps/map-pageviews-by-region" }, { - "displayName": "Optimize Cloud Usage", + "displayName": "Optimize cloud usage", "url": "/build-apps/optimize-cloud-usage" }, { - "displayName": "Add a Time Picker", + "displayName": "Add a time picker", "url": "/build-apps/add-time-picker-guide" }, { - "displayName": "Use NerdGraph in an App", + "displayName": "Use NerdGraph in an app", "url": "/build-apps/use-nerdgraph-in-app" }, { - "displayName": "Build a Table", + "displayName": "Build a table", "url": "/build-apps/build-a-table" }, { - "displayName": "Persistent Storage for Apps", + "displayName": "Persistent storage for apps", "url": "/build-apps/persistent-storage-for-apps" } ] @@ -70,11 +69,11 @@ "url": "/automate-workflows", "children": [ { - "displayName": "Monitor, Alert, and Analyze", + "displayName": "Monitor, alert, and analyze", "url": "/automate-workflows/" }, { - "displayName": "OpenTelemetry Exporter", + "displayName": "OpenTelemetry exporter", "url": "/automate-workflows/" } ] diff --git a/src/hooks/useApiDoc.js b/src/hooks/useApiDoc.js index 74f9b8ef1..634e3a24b 100644 --- a/src/hooks/useApiDoc.js +++ b/src/hooks/useApiDoc.js @@ -86,7 +86,7 @@ const useApiDoc = (name) => { }; }), }; - }, [name, window.__NR1_SDK__]); + }, [name]); }; export default useApiDoc; diff --git a/src/hooks/useComponentDoc.js b/src/hooks/useComponentDoc.js index 926d964bf..5f53a6aa9 100644 --- a/src/hooks/useComponentDoc.js +++ b/src/hooks/useComponentDoc.js @@ -80,7 +80,7 @@ const useComponentDoc = (componentName) => { tagsFromComponentProperties.concat(tagsFromPropTypes) ), }; - }, [componentName, window?.__NR1_SDK__]); + }, [componentName]); }; export default useComponentDoc; diff --git a/src/markdown-pages/automate-workflows/workflow-automation.mdx b/src/markdown-pages/automate-workflows/workflow-automation.mdx new file mode 100644 index 000000000..6dfbf619a --- /dev/null +++ b/src/markdown-pages/automate-workflows/workflow-automation.mdx @@ -0,0 +1,84 @@ +--- +path: '/automate-workflows/workflow-automation' +title: 'Orchestrate observability workflows' +description: 'Tools to automate your observability ecosystem' +template: 'GuideTemplate' +--- + +## Define and automate observability + +As the maintainer of an increasingly complex software stack, you need to +pinpoint problems without filtering through all the noise. You need to automate +observability the way you automate infrastructure management, by embedding your +New Relic configuration in code. The [Terraform +Provider](https://www.terraform.io/docs/providers/newrelic/index.html) enables +observability as code -- the ability to monitor, alert, and analyze your +ecosystem in one place, in real time. Built on the New Relic Client, the +Terraform Provider provides a full implementation of APIs that enable you to +create alert policies and conditions, Synthetic monitors and Synthetics alert +conditions, notification policies and more. + +The [Terraform Provider getting started +guide](https://www.terraform.io/docs/providers/newrelic/guides/getting_started.html) +steps you through some fundamental configuration. The [New Relic APM Terraform +module](https://registry.terraform.io/modules/newrelic/apm/newrelic/0.0.4) +provides a monitoring strategy for application resources reporting into New +Relic. + +