diff --git a/.changeset/analytics-glimmering-radio-station.md b/.changeset/analytics-glimmering-radio-station.md index fb0c404eee..2bc5aef678 100644 --- a/.changeset/analytics-glimmering-radio-station.md +++ b/.changeset/analytics-glimmering-radio-station.md @@ -1,8 +1,8 @@ --- -'@backstage/plugin-analytics-provider-ga': patch +'@backstage/plugin-analytics-module-ga': patch --- -Initial Google Analytics API provider for the Backstage Analytics API, which: +Initial Google Analytics implementation for the Backstage Analytics API, which: - Handles pageview and custom event instrumentation idiomatically. - Enables custom dimension and metric collection via app config. diff --git a/packages/core-app-api/src/routing/RouteTracker.tsx b/packages/core-app-api/src/routing/RouteTracker.tsx index 64e7643762..cce4692928 100644 --- a/packages/core-app-api/src/routing/RouteTracker.tsx +++ b/packages/core-app-api/src/routing/RouteTracker.tsx @@ -41,39 +41,46 @@ const getExtensionDomain = ( pathname: string, routes: RouteObjects, ): RoutableAnalyticsDomain | {} => { - const cleanPath = pathname.replace(/\/+$/, ''); - const matches = matchRoutes(routes, { pathname }); - const RouteElement = matches - ?.filter(match => { - const pathsMatch = match.pathname.replace(/\/+$/, '') === cleanPath; - const hasRoutableElement = !!(match.route.element as React.ReactElement) - ?.props?.element; - return pathsMatch && hasRoutableElement; - }) - .pop()?.route?.element; - const RoutableElement = (RouteElement as React.ReactElement)?.props?.element; + try { + const cleanPath = pathname.replace(/\/+$/, ''); + const matches = matchRoutes(routes, { pathname }); + const RouteElement = matches + ?.filter(match => { + const pathsMatch = match.pathname.replace(/\/+$/, '') === cleanPath; + const hasRoutableElement = !!(match.route.element as React.ReactElement) + ?.props?.element; + return pathsMatch && hasRoutableElement; + }) + .pop()?.route?.element; + const RoutableElement = (RouteElement as React.ReactElement)?.props + ?.element; - if (RoutableElement) { - const plugin: BackstagePlugin | undefined = getComponentData( - RoutableElement, - 'core.plugin', - ); - const mountPoint: { id?: string } | undefined = getComponentData( - RoutableElement, - 'core.mountPoint', - ); - if (plugin && mountPoint) { - return { - pluginId: plugin.getId(), - componentName: 'App', - routeRef: mountPoint?.id || '', - }; + if (RoutableElement) { + const plugin: BackstagePlugin | undefined = getComponentData( + RoutableElement, + 'core.plugin', + ); + const mountPoint: { id?: string } | undefined = getComponentData( + RoutableElement, + 'core.mountPoint', + ); + if (plugin && mountPoint) { + return { + pluginId: plugin.getId(), + componentName: 'App', + routeRef: mountPoint?.id || '', + }; + } } - } - // Try again, one path-level shallower. - const nextLevelPath = cleanPath.split('/').slice(0, -1).join('/'); - return nextLevelPath !== '' ? getExtensionDomain(nextLevelPath, routes) : {}; + // Try again, one path-level shallower. + const nextLevelPath = cleanPath.split('/').slice(0, -1).join('/'); + return nextLevelPath !== '' + ? getExtensionDomain(nextLevelPath, routes) + : {}; + } catch { + return {}; + } }; /** diff --git a/plugins/analytics-provider-ga/.eslintrc.js b/plugins/analytics-module-ga/.eslintrc.js similarity index 100% rename from plugins/analytics-provider-ga/.eslintrc.js rename to plugins/analytics-module-ga/.eslintrc.js diff --git a/plugins/analytics-provider-ga/README.md b/plugins/analytics-module-ga/README.md similarity index 93% rename from plugins/analytics-provider-ga/README.md rename to plugins/analytics-module-ga/README.md index e7a603a34a..09bbdeb88b 100644 --- a/plugins/analytics-provider-ga/README.md +++ b/plugins/analytics-module-ga/README.md @@ -1,4 +1,4 @@ -# Analytics Provider: Google Analytics +# Analytics Module: Google Analytics This plugin provides an opinionated implementation of the Backstage Analytics API for Google Analytics. Once installed and configured, analytics events will @@ -8,9 +8,10 @@ This plugin contains no (and will never contain any) other functionality. ## Installation -1. Install this plugin in your Backstage instance: `yarn add @backstage/plugin-analytics-provider-ga` +1. Install this plugin in your Backstage app: + `cd packages/app && yarn add @backstage/plugin-analytics-module-ga` 2. Register the plugin with your App. In most instances of Backstage, this is - as simple as adding `export { analyticsProviderGA } from '@backstage/plugin-analytics-provider-ga';` + as simple as adding `export { analyticsModuleGA } from '@backstage/plugin-analytics-module-ga';` to your `packages/app/src/plugins.ts` file. 3. Configure the plugin (see below). diff --git a/plugins/analytics-module-ga/api-report.md b/plugins/analytics-module-ga/api-report.md new file mode 100644 index 0000000000..6208ebe795 --- /dev/null +++ b/plugins/analytics-module-ga/api-report.md @@ -0,0 +1,14 @@ +## API Report File for "@backstage/plugin-analytics-module-ga" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/core-plugin-api'; + +// Warning: (ae-missing-release-tag) "analyticsModuleGA" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const analyticsModuleGA: BackstagePlugin<{}, {}>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/analytics-provider-ga/config.d.ts b/plugins/analytics-module-ga/config.d.ts similarity index 92% rename from plugins/analytics-provider-ga/config.d.ts rename to plugins/analytics-module-ga/config.d.ts index 0b08b75f1e..78772d932a 100644 --- a/plugins/analytics-provider-ga/config.d.ts +++ b/plugins/analytics-module-ga/config.d.ts @@ -16,7 +16,10 @@ export interface Config { app: { - analytics: { + // TODO: Only marked as optional because backstage-cli config:check in the + // context of the monorepo is too strict. Ideally, this would be marked as + // required. + analytics?: { provider: 'ga'; ga: { /** diff --git a/plugins/analytics-provider-ga/dev/Playground.tsx b/plugins/analytics-module-ga/dev/Playground.tsx similarity index 100% rename from plugins/analytics-provider-ga/dev/Playground.tsx rename to plugins/analytics-module-ga/dev/Playground.tsx diff --git a/plugins/analytics-provider-ga/dev/index.tsx b/plugins/analytics-module-ga/dev/index.tsx similarity index 90% rename from plugins/analytics-provider-ga/dev/index.tsx rename to plugins/analytics-module-ga/dev/index.tsx index 4e4e9082bb..74b3439cff 100644 --- a/plugins/analytics-provider-ga/dev/index.tsx +++ b/plugins/analytics-module-ga/dev/index.tsx @@ -15,11 +15,11 @@ */ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { analyticsProviderGA } from '../src/plugin'; +import { analyticsModuleGA } from '../src/plugin'; import { Playground } from './Playground'; createDevApp() - .registerPlugin(analyticsProviderGA) + .registerPlugin(analyticsModuleGA) .addPage({ path: '/ga', title: 'GA Playground', diff --git a/plugins/analytics-provider-ga/package.json b/plugins/analytics-module-ga/package.json similarity index 76% rename from plugins/analytics-provider-ga/package.json rename to plugins/analytics-module-ga/package.json index af60d0cb5c..464151b614 100644 --- a/plugins/analytics-provider-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,5 +1,5 @@ { - "name": "@backstage/plugin-analytics-provider-ga", + "name": "@backstage/plugin-analytics-module-ga", "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", @@ -21,10 +21,10 @@ }, "dependencies": { "@backstage/config": "^0.1.5", - "@backstage/core-components": "^0.1.6", - "@backstage/core-plugin-api": "^0.1.3", - "@backstage/theme": "^0.2.8", - "@material-ui/core": "^4.11.0", + "@backstage/core-components": "^0.2.0", + "@backstage/core-plugin-api": "^0.1.4", + "@backstage/theme": "^0.2.9", + "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", @@ -33,10 +33,10 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.7.4", - "@backstage/core-app-api": "^0.1.4", - "@backstage/dev-utils": "^0.2.2", - "@backstage/test-utils": "^0.1.14", + "@backstage/cli": "^0.7.6", + "@backstage/core-app-api": "^0.1.6", + "@backstage/dev-utils": "^0.2.4", + "@backstage/test-utils": "^0.1.16", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^13.1.8", diff --git a/plugins/analytics-provider-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.test.ts b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.test.ts similarity index 100% rename from plugins/analytics-provider-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.test.ts rename to plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.test.ts diff --git a/plugins/analytics-provider-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts similarity index 100% rename from plugins/analytics-provider-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts rename to plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/GoogleAnalytics.ts diff --git a/plugins/analytics-provider-ga/src/apis/implementations/AnalyticsApi/index.ts b/plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/index.ts similarity index 100% rename from plugins/analytics-provider-ga/src/apis/implementations/AnalyticsApi/index.ts rename to plugins/analytics-module-ga/src/apis/implementations/AnalyticsApi/index.ts diff --git a/plugins/analytics-provider-ga/src/index.ts b/plugins/analytics-module-ga/src/index.ts similarity index 92% rename from plugins/analytics-provider-ga/src/index.ts rename to plugins/analytics-module-ga/src/index.ts index 8dbf2d6210..d9d3222ac0 100644 --- a/plugins/analytics-provider-ga/src/index.ts +++ b/plugins/analytics-module-ga/src/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { analyticsProviderGA } from './plugin'; +export { analyticsModuleGA } from './plugin'; diff --git a/plugins/analytics-provider-ga/src/plugin.test.ts b/plugins/analytics-module-ga/src/plugin.test.ts similarity index 87% rename from plugins/analytics-provider-ga/src/plugin.test.ts rename to plugins/analytics-module-ga/src/plugin.test.ts index 92d12ea6db..394e5fc070 100644 --- a/plugins/analytics-provider-ga/src/plugin.test.ts +++ b/plugins/analytics-module-ga/src/plugin.test.ts @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { analyticsProviderGA } from './plugin'; +import { analyticsModuleGA } from './plugin'; describe('google-analytics', () => { it('should export plugin', () => { - expect(analyticsProviderGA).toBeDefined(); + expect(analyticsModuleGA).toBeDefined(); }); }); diff --git a/plugins/analytics-provider-ga/src/plugin.ts b/plugins/analytics-module-ga/src/plugin.ts similarity index 95% rename from plugins/analytics-provider-ga/src/plugin.ts rename to plugins/analytics-module-ga/src/plugin.ts index e84dbbcd04..e339965d91 100644 --- a/plugins/analytics-provider-ga/src/plugin.ts +++ b/plugins/analytics-module-ga/src/plugin.ts @@ -21,7 +21,7 @@ import { } from '@backstage/core-plugin-api'; import { GoogleAnalytics } from './apis/implementations/AnalyticsApi'; -export const analyticsProviderGA = createPlugin({ +export const analyticsModuleGA = createPlugin({ id: 'analytics-provider-ga', apis: [ createApiFactory({ diff --git a/plugins/analytics-provider-ga/src/setupTests.ts b/plugins/analytics-module-ga/src/setupTests.ts similarity index 100% rename from plugins/analytics-provider-ga/src/setupTests.ts rename to plugins/analytics-module-ga/src/setupTests.ts diff --git a/plugins/analytics-provider-ga/dev/app-config.yaml b/plugins/analytics-provider-ga/dev/app-config.yaml deleted file mode 100644 index 3d5b23a356..0000000000 --- a/plugins/analytics-provider-ga/dev/app-config.yaml +++ /dev/null @@ -1,3 +0,0 @@ -app: - analytics: - provider: ga diff --git a/plugins/search/src/components/SearchPage/SearchPage.test.tsx b/plugins/search/src/components/SearchPage/SearchPage.test.tsx index 5ff61a3dbe..bc3b8ceb0b 100644 --- a/plugins/search/src/components/SearchPage/SearchPage.test.tsx +++ b/plugins/search/src/components/SearchPage/SearchPage.test.tsx @@ -75,8 +75,8 @@ describe('SearchPage', () => { const expectedFilters = { [expectedFilterField]: expectedFilterValue }; const expectedPageCursor = 'SOMEPAGE'; - // e.g. ?query=petstore&pageCursor=SOMEPAGE&filters[lifecycle][]=experimental&filters[kind]=Component - (useLocation as jest.Mock).mockReturnValueOnce({ + // e.g. ?query=petstore&pageCursor=1&filters[lifecycle][]=experimental&filters[kind]=Component + (useLocation as jest.Mock).mockReturnValue({ search: `?query=${expectedTerm}&types[]=${expectedTypes[0]}&filters[${expectedFilterField}]=${expectedFilterValue}&pageCursor=${expectedPageCursor}`, });