docs(core): analytics setup (#5894)
This commit is contained in:
parent
b4d27fcfd7
commit
20719ced3f
@ -26,5 +26,6 @@ module.exports = {
|
|||||||
'<rootDir>/nx-dev/data-access-documents',
|
'<rootDir>/nx-dev/data-access-documents',
|
||||||
'<rootDir>/nx-dev/data-access-menu',
|
'<rootDir>/nx-dev/data-access-menu',
|
||||||
'<rootDir>/nx-dev/feature-search',
|
'<rootDir>/nx-dev/feature-search',
|
||||||
|
'<rootDir>/nx-dev/feature-analytics',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
12
nx-dev/feature-analytics/.babelrc
Normal file
12
nx-dev/feature-analytics/.babelrc
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@nrwl/react/babel",
|
||||||
|
{
|
||||||
|
"runtime": "automatic",
|
||||||
|
"useBuiltIns": "usage"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": []
|
||||||
|
}
|
||||||
21
nx-dev/feature-analytics/.eslintrc.json
Normal file
21
nx-dev/feature-analytics/.eslintrc.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||||
|
"ignorePatterns": ["!**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"parserOptions": {
|
||||||
|
"project": ["nx-dev/feature-analytics/tsconfig.*?.json"]
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
7
nx-dev/feature-analytics/README.md
Normal file
7
nx-dev/feature-analytics/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# nx-dev-feature-analytics
|
||||||
|
|
||||||
|
This library was generated with [Nx](https://nx.dev).
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `nx test nx-dev-feature-analytics` to execute the unit tests via [Jest](https://jestjs.io).
|
||||||
9
nx-dev/feature-analytics/jest.config.js
Normal file
9
nx-dev/feature-analytics/jest.config.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module.exports = {
|
||||||
|
displayName: 'nx-dev-feature-analytics',
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
transform: {
|
||||||
|
'^.+\\.[tj]sx?$': 'babel-jest',
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
|
coverageDirectory: '../../coverage/nx-dev/feature-analytics',
|
||||||
|
};
|
||||||
1
nx-dev/feature-analytics/src/index.ts
Normal file
1
nx-dev/feature-analytics/src/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './lib/google-analytics';
|
||||||
40
nx-dev/feature-analytics/src/lib/google-analytics.ts
Normal file
40
nx-dev/feature-analytics/src/lib/google-analytics.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* [Gtag sending data documentation](https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data)
|
||||||
|
*
|
||||||
|
* [About Events](https://support.google.com/analytics/answer/1033068/about-events)
|
||||||
|
*/
|
||||||
|
import { Gtag } from './gtag';
|
||||||
|
|
||||||
|
declare const gtag: Gtag;
|
||||||
|
|
||||||
|
export function sendPageViewEvent(data: {
|
||||||
|
gaId: string;
|
||||||
|
path?: string;
|
||||||
|
title?: string;
|
||||||
|
}): void {
|
||||||
|
try {
|
||||||
|
gtag('config', data.gaId, {
|
||||||
|
...(!!data.path && { page_path: data.path }),
|
||||||
|
...(!!data.title && { page_title: data.title }),
|
||||||
|
});
|
||||||
|
} catch (exception) {
|
||||||
|
throw new Error(`Cannot send Google Tag event: ${exception}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sendCustomEvent(
|
||||||
|
action: string,
|
||||||
|
category: string,
|
||||||
|
label: string,
|
||||||
|
value?: number
|
||||||
|
): void {
|
||||||
|
try {
|
||||||
|
gtag('event', action, {
|
||||||
|
event_category: category,
|
||||||
|
event_label: label,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Cannot send Google Tag event: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
123
nx-dev/feature-analytics/src/lib/gtag.ts
Normal file
123
nx-dev/feature-analytics/src/lib/gtag.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
export interface Gtag {
|
||||||
|
(
|
||||||
|
command: 'config',
|
||||||
|
targetId: string,
|
||||||
|
config?: ConfigParams | ControlParams | EventParams | CustomParams
|
||||||
|
): void;
|
||||||
|
(command: 'set', targetId: string, config: CustomParams | boolean): void;
|
||||||
|
(command: 'set', config: CustomParams): void;
|
||||||
|
(command: 'js', config: Date): void;
|
||||||
|
(
|
||||||
|
command: 'event',
|
||||||
|
eventName: EventNames | string,
|
||||||
|
eventParams?: ControlParams | EventParams | CustomParams
|
||||||
|
): void;
|
||||||
|
(
|
||||||
|
command: 'get',
|
||||||
|
targetId: string,
|
||||||
|
fieldName: FieldNames | string,
|
||||||
|
callback?: (field: string) => any
|
||||||
|
): void;
|
||||||
|
(
|
||||||
|
command: 'consent',
|
||||||
|
consentArg: ConsentArg | string,
|
||||||
|
consentParams: ConsentParams
|
||||||
|
): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CustomParams {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConfigParams {
|
||||||
|
page_location?: string;
|
||||||
|
page_path?: string;
|
||||||
|
page_title?: string;
|
||||||
|
send_page_view?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ControlParams {
|
||||||
|
groups?: string | string[];
|
||||||
|
send_to?: string | string[];
|
||||||
|
event_callback?: () => void;
|
||||||
|
event_timeout?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventNames =
|
||||||
|
| 'add_payment_info'
|
||||||
|
| 'add_to_cart'
|
||||||
|
| 'add_to_wishlist'
|
||||||
|
| 'begin_checkout'
|
||||||
|
| 'checkout_progress'
|
||||||
|
| 'exception'
|
||||||
|
| 'generate_lead'
|
||||||
|
| 'login'
|
||||||
|
| 'page_view'
|
||||||
|
| 'purchase'
|
||||||
|
| 'refund'
|
||||||
|
| 'remove_from_cart'
|
||||||
|
| 'screen_view'
|
||||||
|
| 'search'
|
||||||
|
| 'select_content'
|
||||||
|
| 'set_checkout_option'
|
||||||
|
| 'share'
|
||||||
|
| 'sign_up'
|
||||||
|
| 'timing_complete'
|
||||||
|
| 'view_item'
|
||||||
|
| 'view_item_list'
|
||||||
|
| 'view_promotion'
|
||||||
|
| 'view_search_results';
|
||||||
|
|
||||||
|
interface EventParams {
|
||||||
|
checkout_option?: string;
|
||||||
|
checkout_step?: number;
|
||||||
|
content_id?: string;
|
||||||
|
content_type?: string;
|
||||||
|
coupon?: string;
|
||||||
|
currency?: string;
|
||||||
|
description?: string;
|
||||||
|
fatal?: boolean;
|
||||||
|
items?: Item[];
|
||||||
|
method?: string;
|
||||||
|
number?: string;
|
||||||
|
promotions?: Promotion[];
|
||||||
|
screen_name?: string;
|
||||||
|
search_term?: string;
|
||||||
|
shipping?: Currency;
|
||||||
|
tax?: Currency;
|
||||||
|
transaction_id?: string;
|
||||||
|
value?: number;
|
||||||
|
event_label?: string;
|
||||||
|
event_category?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Currency = string | number;
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
brand?: string;
|
||||||
|
category?: string;
|
||||||
|
creative_name?: string;
|
||||||
|
creative_slot?: string;
|
||||||
|
id?: string;
|
||||||
|
location_id?: string;
|
||||||
|
name?: string;
|
||||||
|
price?: Currency;
|
||||||
|
quantity?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Promotion {
|
||||||
|
creative_name?: string;
|
||||||
|
creative_slot?: string;
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldNames = 'client_id' | 'session_id' | 'gclid';
|
||||||
|
|
||||||
|
type ConsentArg = 'default' | 'update';
|
||||||
|
interface ConsentParams {
|
||||||
|
ad_storage?: 'granted' | 'denied';
|
||||||
|
analytics_storage?: 'granted' | 'denied';
|
||||||
|
wait_for_update?: number;
|
||||||
|
region?: string[];
|
||||||
|
}
|
||||||
19
nx-dev/feature-analytics/tsconfig.json
Normal file
19
nx-dev/feature-analytics/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"files": [],
|
||||||
|
"include": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.lib.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
13
nx-dev/feature-analytics/tsconfig.lib.json
Normal file
13
nx-dev/feature-analytics/tsconfig.lib.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||||
|
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
|
||||||
|
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||||
|
}
|
||||||
15
nx-dev/feature-analytics/tsconfig.spec.json
Normal file
15
nx-dev/feature-analytics/tsconfig.spec.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.spec.tsx",
|
||||||
|
"**/*.spec.js",
|
||||||
|
"**/*.spec.jsx",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -5,11 +5,13 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|||||||
export function CodeBlock({
|
export function CodeBlock({
|
||||||
text,
|
text,
|
||||||
language,
|
language,
|
||||||
|
callback,
|
||||||
...rest
|
...rest
|
||||||
}: {
|
}: {
|
||||||
text: string;
|
text: string;
|
||||||
language: string;
|
language: string;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
callback: (text: string) => void;
|
||||||
}) {
|
}) {
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -25,7 +27,13 @@ export function CodeBlock({
|
|||||||
}, [copied]);
|
}, [copied]);
|
||||||
return (
|
return (
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
<CopyToClipboard text={text} onCopy={() => setCopied(true)}>
|
<CopyToClipboard
|
||||||
|
text={text}
|
||||||
|
onCopy={() => {
|
||||||
|
setCopied(true);
|
||||||
|
callback(text);
|
||||||
|
}}
|
||||||
|
>
|
||||||
<button className="flex absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
<button className="flex absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import autolinkHeadings from 'rehype-autolink-headings';
|
|||||||
import gfm from 'remark-gfm';
|
import gfm from 'remark-gfm';
|
||||||
import slug from 'rehype-slug';
|
import slug from 'rehype-slug';
|
||||||
import { DocumentData } from '@nrwl/nx-dev/data-access-documents';
|
import { DocumentData } from '@nrwl/nx-dev/data-access-documents';
|
||||||
|
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||||
import { transformLinkPath } from './renderers/transform-link-path';
|
import { transformLinkPath } from './renderers/transform-link-path';
|
||||||
import { transformImagePath } from './renderers/transform-image-path';
|
import { transformImagePath } from './renderers/transform-image-path';
|
||||||
import { renderIframes } from './renderers/render-iframe';
|
import { renderIframes } from './renderers/render-iframe';
|
||||||
@ -16,7 +16,10 @@ export interface ContentProps {
|
|||||||
version: string;
|
version: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const components: any = {
|
interface ComponentsConfig {
|
||||||
|
readonly code: { callback: (command: string) => void };
|
||||||
|
}
|
||||||
|
const components: any = (config: ComponentsConfig) => ({
|
||||||
code({ node, inline, className, children, ...props }) {
|
code({ node, inline, className, children, ...props }) {
|
||||||
const language = /language-(\w+)/.exec(className || '')?.[1];
|
const language = /language-(\w+)/.exec(className || '')?.[1];
|
||||||
return !inline && language ? (
|
return !inline && language ? (
|
||||||
@ -24,6 +27,7 @@ const components: any = {
|
|||||||
text={String(children).replace(/\n$/, '')}
|
text={String(children).replace(/\n$/, '')}
|
||||||
language={language}
|
language={language}
|
||||||
{...props}
|
{...props}
|
||||||
|
callback={(command) => config.code.callback(command)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<code className={className} {...props}>
|
<code className={className} {...props}>
|
||||||
@ -34,7 +38,7 @@ const components: any = {
|
|||||||
pre({ children }) {
|
pre({ children }) {
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
export function Content(props: ContentProps) {
|
export function Content(props: ContentProps) {
|
||||||
return (
|
return (
|
||||||
@ -52,7 +56,16 @@ export function Content(props: ContentProps) {
|
|||||||
document: props.document,
|
document: props.document,
|
||||||
})}
|
})}
|
||||||
className="prose max-w-none"
|
className="prose max-w-none"
|
||||||
components={components}
|
components={components({
|
||||||
|
code: {
|
||||||
|
callback: () =>
|
||||||
|
sendCustomEvent(
|
||||||
|
'code-snippets',
|
||||||
|
'click',
|
||||||
|
props.document.filePath
|
||||||
|
),
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"project": ["/nx-dev/feature-search/tsconfig.*?.json"]
|
"project": ["nx-dev/feature-search/tsconfig.*?.json"]
|
||||||
},
|
},
|
||||||
"rules": {}
|
"rules": {}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback, useRef, useEffect } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
|||||||
@ -1,9 +1,19 @@
|
|||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { AppProps } from 'next/app';
|
import { AppProps } from 'next/app';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { sendPageViewEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||||
import '../styles/main.css';
|
import '../styles/main.css';
|
||||||
|
|
||||||
export default function CustomApp({ Component, pageProps }: AppProps) {
|
export default function CustomApp({ Component, pageProps }: AppProps) {
|
||||||
|
const router = useRouter();
|
||||||
|
const gaMeasurementId = 'UA-88380372-10';
|
||||||
|
useEffect(() => {
|
||||||
|
const handleRouteChange = (url: URL) =>
|
||||||
|
sendPageViewEvent(gaMeasurementId, { path: url });
|
||||||
|
router.events.on('routeChangeStart', (url) => handleRouteChange(url));
|
||||||
|
return () => router.events.off('routeChangeStart', handleRouteChange);
|
||||||
|
}, [router]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
@ -34,6 +44,23 @@ export default function CustomApp({ Component, pageProps }: AppProps) {
|
|||||||
<meta name="msapplication-TileColor" content="#da532c" />
|
<meta name="msapplication-TileColor" content="#da532c" />
|
||||||
<meta name="theme-color" content="#ffffff" />
|
<meta name="theme-color" content="#ffffff" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
{/* Global Site Tag (gtag.js) - Google Analytics */}
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
src={`https://www.googletagmanager.com/gtag/js?id=${gaMeasurementId}`}
|
||||||
|
/>
|
||||||
|
<script
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){ dataLayer.push(arguments); }
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', '${gaMeasurementId}', {
|
||||||
|
page_path: window.location.pathname,
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
<div className="documentation-app text-gray-700 antialiased bg-white">
|
<div className="documentation-app text-gray-700 antialiased bg-white">
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {
|
import {
|
||||||
@ -6,10 +8,11 @@ import {
|
|||||||
InlineCommand,
|
InlineCommand,
|
||||||
NxUsersShowcase,
|
NxUsersShowcase,
|
||||||
} from '@nrwl/nx-dev/ui/common';
|
} from '@nrwl/nx-dev/ui/common';
|
||||||
import React from 'react';
|
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||||
import { useStorage } from '../lib/use-storage';
|
import { useStorage } from '../lib/use-storage';
|
||||||
|
|
||||||
export function AngularPage() {
|
export function AngularPage() {
|
||||||
|
const router = useRouter();
|
||||||
const { value: storedFlavor } = useStorage('flavor');
|
const { value: storedFlavor } = useStorage('flavor');
|
||||||
const { value: storedVersion } = useStorage('version');
|
const { value: storedVersion } = useStorage('version');
|
||||||
return (
|
return (
|
||||||
@ -116,6 +119,9 @@ export function AngularPage() {
|
|||||||
<InlineCommand
|
<InlineCommand
|
||||||
language={'bash'}
|
language={'bash'}
|
||||||
command={'npx create-nx-workspace --preset=angular'}
|
command={'npx create-nx-workspace --preset=angular'}
|
||||||
|
callback={() =>
|
||||||
|
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {
|
import {
|
||||||
Footer,
|
Footer,
|
||||||
@ -6,10 +8,11 @@ import {
|
|||||||
InlineCommand,
|
InlineCommand,
|
||||||
NxUsersShowcase,
|
NxUsersShowcase,
|
||||||
} from '@nrwl/nx-dev/ui/common';
|
} from '@nrwl/nx-dev/ui/common';
|
||||||
import Image from 'next/image';
|
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||||
import { useStorage } from '../lib/use-storage';
|
import { useStorage } from '../lib/use-storage';
|
||||||
|
|
||||||
export function Index() {
|
export function Index() {
|
||||||
|
const router = useRouter();
|
||||||
const { value: storedFlavor } = useStorage('flavor');
|
const { value: storedFlavor } = useStorage('flavor');
|
||||||
const { value: storedVersion } = useStorage('version');
|
const { value: storedVersion } = useStorage('version');
|
||||||
return (
|
return (
|
||||||
@ -50,6 +53,13 @@ export function Index() {
|
|||||||
<InlineCommand
|
<InlineCommand
|
||||||
language={'bash'}
|
language={'bash'}
|
||||||
command={'npx create-nx-workspace'}
|
command={'npx create-nx-workspace'}
|
||||||
|
callback={() =>
|
||||||
|
sendCustomEvent(
|
||||||
|
'code-snippets',
|
||||||
|
'click',
|
||||||
|
router.pathname
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {
|
import {
|
||||||
@ -6,7 +8,7 @@ import {
|
|||||||
InlineCommand,
|
InlineCommand,
|
||||||
NxUsersShowcase,
|
NxUsersShowcase,
|
||||||
} from '@nrwl/nx-dev/ui/common';
|
} from '@nrwl/nx-dev/ui/common';
|
||||||
import React from 'react';
|
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||||
import { useStorage } from '../lib/use-storage';
|
import { useStorage } from '../lib/use-storage';
|
||||||
|
|
||||||
export function Node() {
|
export function Node() {
|
||||||
@ -52,6 +54,7 @@ export function Node() {
|
|||||||
].join(' '),
|
].join(' '),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const { value: storedFlavor } = useStorage('flavor');
|
const { value: storedFlavor } = useStorage('flavor');
|
||||||
const { value: storedVersion } = useStorage('version');
|
const { value: storedVersion } = useStorage('version');
|
||||||
@ -232,6 +235,9 @@ export function Node() {
|
|||||||
<InlineCommand
|
<InlineCommand
|
||||||
language={'bash'}
|
language={'bash'}
|
||||||
command={'npx create-nx-workspace --preset=nest'}
|
command={'npx create-nx-workspace --preset=nest'}
|
||||||
|
callback={() =>
|
||||||
|
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -243,6 +249,9 @@ export function Node() {
|
|||||||
<InlineCommand
|
<InlineCommand
|
||||||
language={'bash'}
|
language={'bash'}
|
||||||
command={'npx create-nx-workspace --preset=express'}
|
command={'npx create-nx-workspace --preset=express'}
|
||||||
|
callback={() =>
|
||||||
|
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {
|
import {
|
||||||
@ -6,10 +8,11 @@ import {
|
|||||||
InlineCommand,
|
InlineCommand,
|
||||||
NxUsersShowcase,
|
NxUsersShowcase,
|
||||||
} from '@nrwl/nx-dev/ui/common';
|
} from '@nrwl/nx-dev/ui/common';
|
||||||
import React from 'react';
|
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||||
import { useStorage } from '../lib/use-storage';
|
import { useStorage } from '../lib/use-storage';
|
||||||
|
|
||||||
export function ReactPage() {
|
export function ReactPage() {
|
||||||
|
const router = useRouter();
|
||||||
const { value: storedFlavor } = useStorage('flavor');
|
const { value: storedFlavor } = useStorage('flavor');
|
||||||
const { value: storedVersion } = useStorage('version');
|
const { value: storedVersion } = useStorage('version');
|
||||||
return (
|
return (
|
||||||
@ -107,6 +110,9 @@ export function ReactPage() {
|
|||||||
<InlineCommand
|
<InlineCommand
|
||||||
language={'bash'}
|
language={'bash'}
|
||||||
command={'npx create-nx-workspace --preset=react'}
|
command={'npx create-nx-workspace --preset=react'}
|
||||||
|
callback={() =>
|
||||||
|
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -118,6 +124,9 @@ export function ReactPage() {
|
|||||||
<InlineCommand
|
<InlineCommand
|
||||||
language={'bash'}
|
language={'bash'}
|
||||||
command={'npx create-nx-workspace --preset=next'}
|
command={'npx create-nx-workspace --preset=next'}
|
||||||
|
callback={() =>
|
||||||
|
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
@ -6,9 +6,14 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|||||||
export interface InlineCommandProps {
|
export interface InlineCommandProps {
|
||||||
language: string;
|
language: string;
|
||||||
command: string;
|
command: string;
|
||||||
|
callback?: (command: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function InlineCommand({ language, command }: InlineCommandProps) {
|
export function InlineCommand({
|
||||||
|
language,
|
||||||
|
command,
|
||||||
|
callback,
|
||||||
|
}: InlineCommandProps) {
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let t: NodeJS.Timeout;
|
let t: NodeJS.Timeout;
|
||||||
@ -23,7 +28,13 @@ export function InlineCommand({ language, command }: InlineCommandProps) {
|
|||||||
}, [copied]);
|
}, [copied]);
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<CopyToClipboard text={command} onCopy={() => setCopied(true)}>
|
<CopyToClipboard
|
||||||
|
text={command}
|
||||||
|
onCopy={() => {
|
||||||
|
setCopied(true);
|
||||||
|
if (typeof callback === 'function') callback(command);
|
||||||
|
}}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="max-w-full text-sm flex-none bg-white text-gray-400 hover:text-gray-900 font-mono leading-6 py-1 sm:px-3 border border-gray-200 rounded-xl flex items-center justify-center space-x-2 sm:space-x-4 focus:ring-2 focus:ring-offset-2 focus:ring-offset-white focus:ring-gray-300 focus:outline-none transition-colors duration-180"
|
className="max-w-full text-sm flex-none bg-white text-gray-400 hover:text-gray-900 font-mono leading-6 py-1 sm:px-3 border border-gray-200 rounded-xl flex items-center justify-center space-x-2 sm:space-x-4 focus:ring-2 focus:ring-offset-2 focus:ring-offset-white focus:ring-gray-300 focus:outline-none transition-colors duration-180"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
declare const window: any;
|
declare const window: any;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { Fragment, useState } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { Listbox, Transition } from '@headlessui/react';
|
import { Listbox, Transition } from '@headlessui/react';
|
||||||
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
|
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
|
||||||
|
|
||||||
|
|||||||
25
nx.json
25
nx.json
@ -1,9 +1,12 @@
|
|||||||
{
|
{
|
||||||
"npmScope": "nrwl",
|
|
||||||
"implicitDependencies": {
|
"implicitDependencies": {
|
||||||
"package.json": "*",
|
"package.json": "*",
|
||||||
".eslintrc.json": "*"
|
".eslintrc.json": "*"
|
||||||
},
|
},
|
||||||
|
"affected": {
|
||||||
|
"defaultBase": "master"
|
||||||
|
},
|
||||||
|
"npmScope": "nrwl",
|
||||||
"tasksRunnerOptions": {
|
"tasksRunnerOptions": {
|
||||||
"default": {
|
"default": {
|
||||||
"runner": "@nrwl/nx-cloud",
|
"runner": "@nrwl/nx-cloud",
|
||||||
@ -54,7 +57,9 @@
|
|||||||
"nest": {
|
"nest": {
|
||||||
"implicitDependencies": ["node", "linter"]
|
"implicitDependencies": ["node", "linter"]
|
||||||
},
|
},
|
||||||
"linter": { "implicitDependencies": ["eslint-plugin-nx"] },
|
"linter": {
|
||||||
|
"implicitDependencies": ["eslint-plugin-nx"]
|
||||||
|
},
|
||||||
"express": {
|
"express": {
|
||||||
"implicitDependencies": ["node"]
|
"implicitDependencies": ["node"]
|
||||||
},
|
},
|
||||||
@ -111,7 +116,9 @@
|
|||||||
"e2e-workspace": {
|
"e2e-workspace": {
|
||||||
"implicitDependencies": ["create-nx-workspace"]
|
"implicitDependencies": ["create-nx-workspace"]
|
||||||
},
|
},
|
||||||
"gatsby": { "tags": [] },
|
"gatsby": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
"dep-graph-dep-graph-e2e": {
|
"dep-graph-dep-graph-e2e": {
|
||||||
"implicitDependencies": ["dep-graph-dep-graph"]
|
"implicitDependencies": ["dep-graph-dep-graph"]
|
||||||
},
|
},
|
||||||
@ -135,8 +142,14 @@
|
|||||||
"nx-dev-data-access-documents": {
|
"nx-dev-data-access-documents": {
|
||||||
"tags": ["scope:nx-dev", "type:data-access"]
|
"tags": ["scope:nx-dev", "type:data-access"]
|
||||||
},
|
},
|
||||||
"nx-dev-feature-search": { "tags": ["scope:nx-dev", "type:feature"] },
|
"nx-dev-feature-search": {
|
||||||
"docs": { "tags": ["scope:nx-dev"] }
|
"tags": ["scope:nx-dev", "type:feature"]
|
||||||
},
|
},
|
||||||
"affected": { "defaultBase": "master" }
|
"docs": {
|
||||||
|
"tags": ["scope:nx-dev"]
|
||||||
|
},
|
||||||
|
"nx-dev-feature-analytics": {
|
||||||
|
"tags": ["scope:nx-dev", "type:feature"]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,7 +52,10 @@
|
|||||||
"@nrwl/nx-dev/data-access-documents": [
|
"@nrwl/nx-dev/data-access-documents": [
|
||||||
"./nx-dev/data-access-documents/src/index.ts"
|
"./nx-dev/data-access-documents/src/index.ts"
|
||||||
],
|
],
|
||||||
"@nrwl/nx-dev/feature-search": ["./nx-dev/feature-search/src/index.ts"]
|
"@nrwl/nx-dev/feature-search": ["./nx-dev/feature-search/src/index.ts"],
|
||||||
|
"@nrwl/nx-dev/feature-analytics": [
|
||||||
|
"./nx-dev/feature-analytics/src/index.ts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,15 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
|
"cli": {
|
||||||
|
"defaultCollection": "@nrwl/react"
|
||||||
|
},
|
||||||
|
"generators": {
|
||||||
|
"@nrwl/react": {
|
||||||
|
"application": {
|
||||||
|
"babel": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"projects": {
|
"projects": {
|
||||||
"nx": {
|
"nx": {
|
||||||
"root": "packages/nx",
|
"root": "packages/nx",
|
||||||
@ -2374,9 +2384,29 @@
|
|||||||
"root": "docs",
|
"root": "docs",
|
||||||
"sourceRoot": "docs",
|
"sourceRoot": "docs",
|
||||||
"projectType": "library"
|
"projectType": "library"
|
||||||
|
},
|
||||||
|
"nx-dev-feature-analytics": {
|
||||||
|
"root": "nx-dev/feature-analytics",
|
||||||
|
"sourceRoot": "nx-dev/feature-analytics/src",
|
||||||
|
"projectType": "library",
|
||||||
|
"targets": {
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nrwl/linter:eslint",
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": [
|
||||||
|
"nx-dev/feature-analytics/**/*.{ts,tsx,js,jsx}"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cli": {
|
"test": {
|
||||||
"defaultCollection": "@nrwl/workspace"
|
"executor": "@nrwl/jest:jest",
|
||||||
|
"outputs": ["coverage/nx-dev/feature-analytics"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "nx-dev/feature-analytics/jest.config.js",
|
||||||
|
"passWithNoTests": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user