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-menu',
|
||||
'<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({
|
||||
text,
|
||||
language,
|
||||
callback,
|
||||
...rest
|
||||
}: {
|
||||
text: string;
|
||||
language: string;
|
||||
[key: string]: any;
|
||||
callback: (text: string) => void;
|
||||
}) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
useEffect(() => {
|
||||
@ -25,7 +27,13 @@ export function CodeBlock({
|
||||
}, [copied]);
|
||||
return (
|
||||
<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">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@ -4,7 +4,7 @@ import autolinkHeadings from 'rehype-autolink-headings';
|
||||
import gfm from 'remark-gfm';
|
||||
import slug from 'rehype-slug';
|
||||
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 { transformImagePath } from './renderers/transform-image-path';
|
||||
import { renderIframes } from './renderers/render-iframe';
|
||||
@ -16,7 +16,10 @@ export interface ContentProps {
|
||||
version: string;
|
||||
}
|
||||
|
||||
const components: any = {
|
||||
interface ComponentsConfig {
|
||||
readonly code: { callback: (command: string) => void };
|
||||
}
|
||||
const components: any = (config: ComponentsConfig) => ({
|
||||
code({ node, inline, className, children, ...props }) {
|
||||
const language = /language-(\w+)/.exec(className || '')?.[1];
|
||||
return !inline && language ? (
|
||||
@ -24,6 +27,7 @@ const components: any = {
|
||||
text={String(children).replace(/\n$/, '')}
|
||||
language={language}
|
||||
{...props}
|
||||
callback={(command) => config.code.callback(command)}
|
||||
/>
|
||||
) : (
|
||||
<code className={className} {...props}>
|
||||
@ -34,7 +38,7 @@ const components: any = {
|
||||
pre({ children }) {
|
||||
return <>{children}</>;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export function Content(props: ContentProps) {
|
||||
return (
|
||||
@ -52,7 +56,16 @@ export function Content(props: ContentProps) {
|
||||
document: props.document,
|
||||
})}
|
||||
className="prose max-w-none"
|
||||
components={components}
|
||||
components={components({
|
||||
code: {
|
||||
callback: () =>
|
||||
sendCustomEvent(
|
||||
'code-snippets',
|
||||
'click',
|
||||
props.document.filePath
|
||||
),
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"parserOptions": {
|
||||
"project": ["/nx-dev/feature-search/tsconfig.*?.json"]
|
||||
"project": ["nx-dev/feature-search/tsconfig.*?.json"]
|
||||
},
|
||||
"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 Link from 'next/link';
|
||||
import Head from 'next/head';
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import { sendPageViewEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||
import '../styles/main.css';
|
||||
|
||||
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 (
|
||||
<>
|
||||
<Head>
|
||||
@ -34,6 +44,23 @@ export default function CustomApp({ Component, pageProps }: AppProps) {
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<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>
|
||||
<div className="documentation-app text-gray-700 antialiased bg-white">
|
||||
<Component {...pageProps} />
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
@ -6,10 +8,11 @@ import {
|
||||
InlineCommand,
|
||||
NxUsersShowcase,
|
||||
} from '@nrwl/nx-dev/ui/common';
|
||||
import React from 'react';
|
||||
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||
import { useStorage } from '../lib/use-storage';
|
||||
|
||||
export function AngularPage() {
|
||||
const router = useRouter();
|
||||
const { value: storedFlavor } = useStorage('flavor');
|
||||
const { value: storedVersion } = useStorage('version');
|
||||
return (
|
||||
@ -116,6 +119,9 @@ export function AngularPage() {
|
||||
<InlineCommand
|
||||
language={'bash'}
|
||||
command={'npx create-nx-workspace --preset=angular'}
|
||||
callback={() =>
|
||||
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
Footer,
|
||||
@ -6,10 +8,11 @@ import {
|
||||
InlineCommand,
|
||||
NxUsersShowcase,
|
||||
} 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';
|
||||
|
||||
export function Index() {
|
||||
const router = useRouter();
|
||||
const { value: storedFlavor } = useStorage('flavor');
|
||||
const { value: storedVersion } = useStorage('version');
|
||||
return (
|
||||
@ -50,6 +53,13 @@ export function Index() {
|
||||
<InlineCommand
|
||||
language={'bash'}
|
||||
command={'npx create-nx-workspace'}
|
||||
callback={() =>
|
||||
sendCustomEvent(
|
||||
'code-snippets',
|
||||
'click',
|
||||
router.pathname
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
@ -6,7 +8,7 @@ import {
|
||||
InlineCommand,
|
||||
NxUsersShowcase,
|
||||
} from '@nrwl/nx-dev/ui/common';
|
||||
import React from 'react';
|
||||
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||
import { useStorage } from '../lib/use-storage';
|
||||
|
||||
export function Node() {
|
||||
@ -52,6 +54,7 @@ export function Node() {
|
||||
].join(' '),
|
||||
},
|
||||
];
|
||||
const router = useRouter();
|
||||
|
||||
const { value: storedFlavor } = useStorage('flavor');
|
||||
const { value: storedVersion } = useStorage('version');
|
||||
@ -232,6 +235,9 @@ export function Node() {
|
||||
<InlineCommand
|
||||
language={'bash'}
|
||||
command={'npx create-nx-workspace --preset=nest'}
|
||||
callback={() =>
|
||||
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -243,6 +249,9 @@ export function Node() {
|
||||
<InlineCommand
|
||||
language={'bash'}
|
||||
command={'npx create-nx-workspace --preset=express'}
|
||||
callback={() =>
|
||||
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
@ -6,10 +8,11 @@ import {
|
||||
InlineCommand,
|
||||
NxUsersShowcase,
|
||||
} from '@nrwl/nx-dev/ui/common';
|
||||
import React from 'react';
|
||||
import { sendCustomEvent } from '@nrwl/nx-dev/feature-analytics';
|
||||
import { useStorage } from '../lib/use-storage';
|
||||
|
||||
export function ReactPage() {
|
||||
const router = useRouter();
|
||||
const { value: storedFlavor } = useStorage('flavor');
|
||||
const { value: storedVersion } = useStorage('version');
|
||||
return (
|
||||
@ -107,6 +110,9 @@ export function ReactPage() {
|
||||
<InlineCommand
|
||||
language={'bash'}
|
||||
command={'npx create-nx-workspace --preset=react'}
|
||||
callback={() =>
|
||||
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -118,6 +124,9 @@ export function ReactPage() {
|
||||
<InlineCommand
|
||||
language={'bash'}
|
||||
command={'npx create-nx-workspace --preset=next'}
|
||||
callback={() =>
|
||||
sendCustomEvent('code-snippets', 'click', router.pathname)
|
||||
}
|
||||
/>
|
||||
</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 {
|
||||
language: 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);
|
||||
useEffect(() => {
|
||||
let t: NodeJS.Timeout;
|
||||
@ -23,7 +28,13 @@ export function InlineCommand({ language, command }: InlineCommandProps) {
|
||||
}, [copied]);
|
||||
return (
|
||||
<div className="relative">
|
||||
<CopyToClipboard text={command} onCopy={() => setCopied(true)}>
|
||||
<CopyToClipboard
|
||||
text={command}
|
||||
onCopy={() => {
|
||||
setCopied(true);
|
||||
if (typeof callback === 'function') callback(command);
|
||||
}}
|
||||
>
|
||||
<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"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
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 { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
|
||||
|
||||
|
||||
25
nx.json
25
nx.json
@ -1,9 +1,12 @@
|
||||
{
|
||||
"npmScope": "nrwl",
|
||||
"implicitDependencies": {
|
||||
"package.json": "*",
|
||||
".eslintrc.json": "*"
|
||||
},
|
||||
"affected": {
|
||||
"defaultBase": "master"
|
||||
},
|
||||
"npmScope": "nrwl",
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "@nrwl/nx-cloud",
|
||||
@ -54,7 +57,9 @@
|
||||
"nest": {
|
||||
"implicitDependencies": ["node", "linter"]
|
||||
},
|
||||
"linter": { "implicitDependencies": ["eslint-plugin-nx"] },
|
||||
"linter": {
|
||||
"implicitDependencies": ["eslint-plugin-nx"]
|
||||
},
|
||||
"express": {
|
||||
"implicitDependencies": ["node"]
|
||||
},
|
||||
@ -111,7 +116,9 @@
|
||||
"e2e-workspace": {
|
||||
"implicitDependencies": ["create-nx-workspace"]
|
||||
},
|
||||
"gatsby": { "tags": [] },
|
||||
"gatsby": {
|
||||
"tags": []
|
||||
},
|
||||
"dep-graph-dep-graph-e2e": {
|
||||
"implicitDependencies": ["dep-graph-dep-graph"]
|
||||
},
|
||||
@ -135,8 +142,14 @@
|
||||
"nx-dev-data-access-documents": {
|
||||
"tags": ["scope:nx-dev", "type:data-access"]
|
||||
},
|
||||
"nx-dev-feature-search": { "tags": ["scope:nx-dev", "type:feature"] },
|
||||
"docs": { "tags": ["scope:nx-dev"] }
|
||||
"nx-dev-feature-search": {
|
||||
"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": [
|
||||
"./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,
|
||||
"cli": {
|
||||
"defaultCollection": "@nrwl/react"
|
||||
},
|
||||
"generators": {
|
||||
"@nrwl/react": {
|
||||
"application": {
|
||||
"babel": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"nx": {
|
||||
"root": "packages/nx",
|
||||
@ -2374,9 +2384,29 @@
|
||||
"root": "docs",
|
||||
"sourceRoot": "docs",
|
||||
"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": {
|
||||
"defaultCollection": "@nrwl/workspace"
|
||||
"test": {
|
||||
"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