diff --git a/.changeset/many-boats-cough.md b/.changeset/many-boats-cough.md new file mode 100644 index 0000000000..5a9a909398 --- /dev/null +++ b/.changeset/many-boats-cough.md @@ -0,0 +1,23 @@ +--- +'@backstage/plugin-splunk-on-call': minor +--- + +Updates the Splunk On-Call plugin for the [composability system +migration](https://backstage.io/docs/plugins/composability#porting-existing-plugins). + +To upgrade, modify your `EntityPage` to use the updated export names. The +`EntitySplunkOnCallCard` should be wrapped in an `` condition as +shown in the plugin README, which you may already have in place. + +```diff +import { +- isPluginApplicableToEntity as isSplunkOnCallAvailable, ++ isSplunkOnCallAvailable, +- SplunkOnCallCard ++ EntitySplunkOnCallCard, +} from '@backstage/plugin-splunk-on-call'; + +... +- ++ +``` diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index 33cfa091ca..52803473b0 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -25,27 +25,24 @@ cd packages/app yarn add @backstage/plugin-splunk-on-call ``` -Add it to the app in `plugins.ts`: - -```ts -export { plugin as SplunkOnCall } from '@backstage/plugin-splunk-on-call'; -``` - -Add it to the `EntityPage.tsx`: +Add it to your `EntityPage`: ```ts +// packages/app/src/components/catalog/EntityPage.tsx import { - isPluginApplicableToEntity as isSplunkOnCallAvailable, - SplunkOnCallCard, + isSplunkOnCallAvailable, + EntitySplunkOnCallCard, } from '@backstage/plugin-splunk-on-call'; // ... -{ - isSplunkOnCallAvailable(entity) && ( - - - - ); -} +const overviewContent = ( + + + + + + + + ``` ## Client configuration diff --git a/plugins/splunk-on-call/src/components/SplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx similarity index 80% rename from plugins/splunk-on-call/src/components/SplunkOnCallCard.test.tsx rename to plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx index bb0a57f848..119a6fc1f7 100644 --- a/plugins/splunk-on-call/src/components/SplunkOnCallCard.test.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx @@ -14,10 +14,8 @@ * limitations under the License. */ import React from 'react'; -import { render, waitFor, fireEvent, act } from '@testing-library/react'; -import { SplunkOnCallCard } from './SplunkOnCallCard'; +import { act, fireEvent, render, waitFor } from '@testing-library/react'; import { Entity } from '@backstage/catalog-model'; -import { wrapInTestApp } from '@backstage/test-utils'; import { alertApiRef, ApiProvider, @@ -27,10 +25,12 @@ import { ConfigReader, createApiRef, } from '@backstage/core'; +import { EntityContext } from '@backstage/plugin-catalog-react'; +import { wrapInTestApp } from '@backstage/test-utils'; import { splunkOnCallApiRef, - UnauthorizedError, SplunkOnCallClient, + UnauthorizedError, } from '../api'; import { ESCALATION_POLICIES, @@ -39,6 +39,7 @@ import { MOCK_INCIDENT, MOCK_TEAM, } from '../api/mocks'; +import { EntitySplunkOnCallCard } from './EntitySplunkOnCallCard'; const mockSplunkOnCallApi: Partial = { getUsers: async () => [], @@ -65,15 +66,20 @@ const apis = ApiRegistry.from([ }), ], ]); -const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'splunkoncall-test', - annotations: { - 'splunk.com/on-call-team': 'Example', + +const mockEntityData = { + loading: false, + error: undefined, + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'splunkoncall-test', + annotations: { + 'splunk.com/on-call-team': 'Example', + }, }, - }, + } as Entity, }; describe('SplunkOnCallCard', () => { @@ -85,7 +91,9 @@ describe('SplunkOnCallCard', () => { const { getByText, queryByTestId } = render( wrapInTestApp( - + + + , ), ); @@ -106,7 +114,9 @@ describe('SplunkOnCallCard', () => { const { getByText, queryByTestId } = render( wrapInTestApp( - + + + , ), ); @@ -123,7 +133,9 @@ describe('SplunkOnCallCard', () => { const { getByText, queryByTestId } = render( wrapInTestApp( - + + + , ), ); @@ -144,7 +156,9 @@ describe('SplunkOnCallCard', () => { const { getByText, queryByTestId, getByRole } = render( wrapInTestApp( - + + + , ), ); diff --git a/plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx similarity index 94% rename from plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx rename to plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx index a7079841a8..b6da351aaf 100644 --- a/plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx @@ -13,33 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useState, useCallback } from 'react'; +import React, { useCallback, useState } from 'react'; +import { useAsync } from 'react-use'; import { - useApi, - Progress, - HeaderIconLinkRow, - MissingAnnotationEmptyState, configApiRef, EmptyState, + HeaderIconLinkRow, IconLinkVerticalProps, + MissingAnnotationEmptyState, + Progress, + useApi, } from '@backstage/core'; import { Entity } from '@backstage/catalog-model'; +import { useEntity } from '@backstage/plugin-catalog-react'; import { Card, + CardContent, CardHeader, Divider, - CardContent, Typography, } from '@material-ui/core'; -import { Incidents } from './Incident'; -import { EscalationPolicy } from './Escalation'; +import AlarmAddIcon from '@material-ui/icons/AlarmAdd'; import WebIcon from '@material-ui/icons/Web'; -import { useAsync } from 'react-use'; import { Alert } from '@material-ui/lab'; import { splunkOnCallApiRef, UnauthorizedError } from '../api'; -import AlarmAddIcon from '@material-ui/icons/AlarmAdd'; -import { TriggerDialog } from './TriggerDialog'; import { MissingApiKeyOrApiIdError } from './Errors/MissingApiKeyOrApiIdError'; +import { EscalationPolicy } from './Escalation'; +import { Incidents } from './Incident'; +import { TriggerDialog } from './TriggerDialog'; import { User } from './types'; export const SPLUNK_ON_CALL_TEAM = 'splunk.com/on-call-team'; @@ -58,16 +59,13 @@ export const MissingEventsRestEndpoint = () => ( ); -export const isPluginApplicableToEntity = (entity: Entity) => +export const isSplunkOnCallAvailable = (entity: Entity) => Boolean(entity.metadata.annotations?.[SPLUNK_ON_CALL_TEAM]); -type Props = { - entity: Entity; -}; - -export const SplunkOnCallCard = ({ entity }: Props) => { +export const EntitySplunkOnCallCard = () => { const config = useApi(configApiRef); const api = useApi(splunkOnCallApiRef); + const { entity } = useEntity(); const [showDialog, setShowDialog] = useState(false); const [refreshIncidents, setRefreshIncidents] = useState(false); const team = entity.metadata.annotations![SPLUNK_ON_CALL_TEAM]; diff --git a/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx b/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx index 4222cbfbeb..40695a87e9 100644 --- a/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx +++ b/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx @@ -23,8 +23,7 @@ import { Header, SupportButton, } from '@backstage/core'; -import { SplunkOnCallCard } from './SplunkOnCallCard'; -import { useEntity } from '@backstage/plugin-catalog-react'; +import { EntitySplunkOnCallCard } from './EntitySplunkOnCallCard'; const useStyles = makeStyles(() => ({ overflowXScroll: { @@ -44,7 +43,6 @@ export const SplunkOnCallPage = ({ pageTitle, }: SplunkOnCallPageProps): JSX.Element => { const classes = useStyles(); - const { entity } = useEntity(); return ( @@ -57,7 +55,7 @@ export const SplunkOnCallPage = ({ - + diff --git a/plugins/splunk-on-call/src/index.ts b/plugins/splunk-on-call/src/index.ts index c8de96f8ea..fa9ccee05a 100644 --- a/plugins/splunk-on-call/src/index.ts +++ b/plugins/splunk-on-call/src/index.ts @@ -14,14 +14,12 @@ * limitations under the License. */ export { + SplunkOnCallCard, splunkOnCallPlugin, splunkOnCallPlugin as plugin, SplunkOnCallPage, } from './plugin'; -export { - isPluginApplicableToEntity, - SplunkOnCallCard, -} from './components/SplunkOnCallCard'; +export { isSplunkOnCallAvailable } from './components/EntitySplunkOnCallCard'; export { SplunkOnCallClient, splunkOnCallApiRef, diff --git a/plugins/splunk-on-call/src/plugin.ts b/plugins/splunk-on-call/src/plugin.ts index 835cda48df..a94a13c032 100644 --- a/plugins/splunk-on-call/src/plugin.ts +++ b/plugins/splunk-on-call/src/plugin.ts @@ -20,6 +20,7 @@ import { discoveryApiRef, configApiRef, createRoutableExtension, + createComponentExtension, } from '@backstage/core'; import { splunkOnCallApiRef, SplunkOnCallClient } from './api'; @@ -49,3 +50,14 @@ export const SplunkOnCallPage = splunkOnCallPlugin.provide( mountPoint: rootRouteRef, }), ); + +export const SplunkOnCallCard = splunkOnCallPlugin.provide( + createComponentExtension({ + component: { + lazy: () => + import('./components/EntitySplunkOnCallCard').then( + m => m.EntitySplunkOnCallCard, + ), + }, + }), +);