Skip to content

Commit

Permalink
Merge pull request #1566 from alex-mckay/addDefaultFilter
Browse files Browse the repository at this point in the history
add default entity filter to datadog plugin (new FE sys only)
  • Loading branch information
Xantier authored Sep 16, 2024
2 parents 4c0543b + 301eb5c commit 050f49c
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .changeset/rude-bananas-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@roadiehq/backstage-plugin-datadog': patch
---

Filter entity cards and content to components and resources by default, add documentation on how to override if needed
29 changes: 29 additions & 0 deletions plugins/frontend/backstage-plugin-datadog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ const serviceEntityPage = (
);
```

### Integrating with `EntityPage` (New Frontend System)

Follow this section if you are using Backstage's [new frontend system](https://backstage.io/docs/frontend-system/).

1. Import `datadogPlugin` in your `App.tsx` and add it to your app's `features` array:

```typescript
import datadogPlugin from '@roadiehq/backstage-plugin-datadog/alpha';
// ...
export const app = createApp({
features: [
// ...
datadogPlugin,
// ...
],
});
```

2. Next, enable your desired extensions in `app-config.yaml`. By default, the content and cards will only appear on entities that are components or resources. You can override that behavior by adding a config block, demonstrated on the 'datadog-graph' card.

```yaml
app:
extensions:
- entity-content:datadog/entity
- entity-card:datadog/datadog-graph:
config:
filter: kind:component,api,resource
```
## Specify datadog domain
Datadog embedded graph is using `datadoghq.eu`as default top-level domain, when other is not specified. If you are using other domain, you need to specify it with corresponding annotations `datadoghq.com/site`.
Expand Down
16 changes: 9 additions & 7 deletions plugins/frontend/backstage-plugin-datadog/src/alpha/apis.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
createApiExtension,
ApiBlueprint,
createApiFactory,
discoveryApiRef,
} from '@backstage/frontend-plugin-api';
Expand All @@ -8,10 +8,12 @@ import { datadogApiRef, DatadogApiClient } from '../api';
/**
* @alpha
*/
export const datadogApi = createApiExtension({
factory: createApiFactory({
api: datadogApiRef,
deps: { discoveryApi: discoveryApiRef },
factory: ({ discoveryApi }) => new DatadogApiClient({ discoveryApi }),
}),
export const datadogApi = ApiBlueprint.make({
params: {
factory: createApiFactory({
api: datadogApiRef,
deps: { discoveryApi: discoveryApiRef },
factory: ({ discoveryApi }) => new DatadogApiClient({ discoveryApi }),
}),
},
});
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import { screen, waitFor } from '@testing-library/react';
import { createExtensionTester } from '@backstage/frontend-test-utils';
import { entityDatadogGraphCard } from './entityCards';
import {
createApiExtension,
createApiFactory,
} from '@backstage/frontend-plugin-api';
createExtensionTester,
renderInTestApp,
TestApiProvider,
} from '@backstage/frontend-test-utils';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { entityDatadogGraphCard } from './entityCards';
import { DatadogApi, datadogApiRef } from '../api';
import { entityWithDatadogAnnotations } from '../mocks/mocks';

jest.mock('@backstage/plugin-catalog-react', () => ({
...jest.requireActual('@backstage/plugin-catalog-react'),
useEntity: () => entityWithDatadogAnnotations,
}));
import React from 'react';

describe('Entity content extensions', () => {
const mockDatadogApi = createApiExtension({
factory: createApiFactory({
api: datadogApiRef,
deps: {},
factory: () => ({} as unknown as DatadogApi),
}),
});
const mockDatadogApi = {
api: datadogApiRef,
deps: {},
factory: () => ({} as unknown as DatadogApi),
};

it('should render the graph card on an entity with the correct annotation', async () => {
createExtensionTester(entityDatadogGraphCard).add(mockDatadogApi).render();
renderInTestApp(
<TestApiProvider apis={[[datadogApiRef, mockDatadogApi]]}>
<EntityProvider entity={entityWithDatadogAnnotations.entity}>
{createExtensionTester(entityDatadogGraphCard).reactElement()}
</EntityProvider>
</TestApiProvider>,
);
await waitFor(
() => {
expect(screen.getByText('Datadog Graph')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React from 'react';
import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha';
import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha';

/**
* @alpha
*/
export const entityDatadogGraphCard = createEntityCardExtension({
export const entityDatadogGraphCard = EntityCardBlueprint.make({
name: 'datadog-graph',
loader: () =>
import('../components/GraphWidget').then(m => <m.GraphWidget />),
params: {
filter: 'kind:component,resource',
loader: () =>
import('../components/GraphWidget').then(m => <m.GraphWidget />),
},
});
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
import { screen, waitFor } from '@testing-library/react';
import { createExtensionTester } from '@backstage/frontend-test-utils';
import { entityDatadogContent } from './entityContent';
import {
createApiExtension,
createApiFactory,
} from '@backstage/frontend-plugin-api';
createExtensionTester,
renderInTestApp,
TestApiProvider,
} from '@backstage/frontend-test-utils';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { entityDatadogContent } from './entityContent';
import { DatadogApi, datadogApiRef } from '../api';
import { entityWithDatadogAnnotations } from '../mocks/mocks';

jest.mock('@backstage/plugin-catalog-react', () => ({
...jest.requireActual('@backstage/plugin-catalog-react'),
useEntity: () => entityWithDatadogAnnotations,
}));

jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
useRouteRef: () => () => '/datadog',
}));
import React from 'react';

describe('Entity content extensions', () => {
const mockDatadogApi = createApiExtension({
factory: createApiFactory({
api: datadogApiRef,
deps: {},
factory: () => ({} as unknown as DatadogApi),
}),
});
const mockDatadogApi = {
api: datadogApiRef,
deps: {},
factory: () => ({} as unknown as DatadogApi),
};

it('should render the dashboard on an entity with the correct annotation', async () => {
createExtensionTester(entityDatadogContent).add(mockDatadogApi).render();
renderInTestApp(
<TestApiProvider apis={[[datadogApiRef, mockDatadogApi]]}>
<EntityProvider entity={entityWithDatadogAnnotations.entity}>
{createExtensionTester(entityDatadogContent).reactElement()}
</EntityProvider>
</TestApiProvider>,
);
await waitFor(
() => {
expect(screen.getByTestId('Datadog dashboard 0')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import {
compatWrapper,
convertLegacyRouteRef,
} from '@backstage/core-compat-api';
import { createEntityContentExtension } from '@backstage/plugin-catalog-react/alpha';
import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';
import { entityContentRouteRef } from '../plugin';
import React from 'react';

/**
* @alpha
*/
export const entityDatadogContent = createEntityContentExtension({
defaultPath: '/datadog',
defaultTitle: 'Datadog',
export const entityDatadogContent = EntityContentBlueprint.make({
name: 'entity',
routeRef: convertLegacyRouteRef(entityContentRouteRef),
loader: () => import('../Router').then(m => compatWrapper(<m.Router />)),
params: {
defaultPath: '/datadog',
defaultTitle: 'Datadog',
filter: 'kind:component,resource',
routeRef: convertLegacyRouteRef(entityContentRouteRef),
loader: () => import('../Router').then(m => compatWrapper(<m.Router />)),
},
});

0 comments on commit 050f49c

Please sign in to comment.