From 15884c25f6a40729ba4c44e14ca3cfc3453172d7 Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Thu, 17 Feb 2022 16:31:47 -0500 Subject: [PATCH 01/11] enable 'read only' mode Splunk OnCall option This exposes a `splunkOnCall.readOnly` configuration option to address issue #9634 Signed-off-by: Mike Ball --- .../EntitySplunkOnCallCard.test.tsx | 40 +++++++++++++++++++ .../src/components/EntitySplunkOnCallCard.tsx | 12 ++++-- .../components/Incident/IncidentListItem.tsx | 18 ++++++--- .../components/Incident/Incidents.test.tsx | 40 +++++++++++++++++++ .../src/components/Incident/Incidents.tsx | 4 +- 5 files changed, 104 insertions(+), 10 deletions(-) diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx index a83db136e4..6944dee4c9 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx @@ -53,6 +53,14 @@ const mockSplunkOnCallApi: Partial = { const configApi: ConfigApi = new ConfigReader({ splunkOnCall: { eventsRestEndpoint: 'EXAMPLE_REST_ENDPOINT', + readOnly: false, + }, +}); + +const readOnlyConfigApi: ConfigApi = new ConfigReader({ + splunkOnCall: { + eventsRestEndpoint: 'EXAMPLE_REST_ENDPOINT', + readOnly: true, }, }); @@ -62,6 +70,12 @@ const apis = TestApiRegistry.from( [alertApiRef, {}], ); +const readOnlyApis = TestApiRegistry.from( + [splunkOnCallApiRef, mockSplunkOnCallApi], + [configApiRef, readOnlyConfigApi], + [alertApiRef, {}], +); + const mockEntity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -131,6 +145,32 @@ describe('SplunkOnCallCard', () => { expect(getByText('Empty escalation policy')).toBeInTheDocument(); }); + it('does not render a "Create incident" link in read only mode', async () => { + mockSplunkOnCallApi.getUsers = jest + .fn() + .mockImplementationOnce(async () => [MOCKED_USER]); + mockSplunkOnCallApi.getTeams = jest + .fn() + .mockImplementation(async () => [MOCK_TEAM_NO_INCIDENTS]); + + const { getByText, queryByTestId } = render( + wrapInTestApp( + + + + + , + ), + ); + await waitFor(() => !queryByTestId('progress')); + expect(() => getByText('Create Incident')).toThrow(); + await waitFor( + () => expect(getByText('Nice! No incidents found!')).toBeInTheDocument(), + { timeout: 2000 }, + ); + expect(getByText('Empty escalation policy')).toBeInTheDocument(); + }); + it('handles a "splunk.com/on-call-routing-key" annotation', async () => { mockSplunkOnCallApi.getUsers = jest .fn() diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx index 4a6f983636..1727e462c1 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx @@ -124,7 +124,9 @@ export const EntitySplunkOnCallCard = () => { : undefined; const eventsRestEndpoint = - config.getOptionalString('splunkOnCall.eventsRestEndpoint') || null; + config.getOptionalString('splunkOnCall.eventsRestEndpoint') || true; + + const readOnly = config.getOptionalBoolean('splunkOnCall.readOnly') || false; const handleRefresh = useCallback(() => { setRefreshIncidents(x => !x); @@ -218,7 +220,11 @@ export const EntitySplunkOnCallCard = () => { return ( <> - + {usersHashMap && team && ( )} @@ -259,7 +265,7 @@ export const EntitySplunkOnCallCard = () => { , , ]} /> diff --git a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx index 4c9975bd06..8078f07fc7 100644 --- a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx +++ b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx @@ -64,6 +64,7 @@ type Props = { team: string; incident: Incident; onIncidentAction: () => void; + readOnly: boolean; }; const IncidentPhaseStatus = ({ @@ -135,6 +136,7 @@ const IncidentAction = ({ export const IncidentListItem = ({ incident, + readOnly, onIncidentAction, team, }: Props) => { @@ -241,12 +243,16 @@ export const IncidentListItem = ({ {incident.incidentLink && incident.incidentNumber && ( - + {!readOnly ? ( + + ) : ( + '' + )} { expect(getAllByTitle('View in Splunk On-Call').length).toEqual(1); }); + it('does not render incident action buttons in read only mode', async () => { + mockSplunkOnCallApi.getIncidents.mockResolvedValue([MOCK_INCIDENT]); + mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]); + + const { + getByText, + getByTitle, + getAllByTitle, + getByLabelText, + queryByTestId, + } = render( + wrapInTestApp( + + + , + ), + ); + await waitFor(() => !queryByTestId('progress')); + await waitFor( + () => + expect( + getByText('user', { + exact: false, + }), + ).toBeInTheDocument(), + { timeout: 2000 }, + ); + expect(getByText('test-incident')).toBeInTheDocument(); + expect(getByLabelText('Status warning')).toBeInTheDocument(); + expect(() => getAllByTitle('Acknowledge')).toThrow( + 'Unable to find an element with the title: Acknowledge.', + ); + expect(() => getAllByTitle('Resolve')).toThrow( + 'Unable to find an element with the title: Resolve.', + ); + + // assert links, mailto and hrefs, date calculation + expect(getAllByTitle('View in Splunk On-Call').length).toEqual(1); + }); + it('Handle errors', async () => { mockSplunkOnCallApi.getIncidents.mockRejectedValueOnce( new Error('Error occurred'), diff --git a/plugins/splunk-on-call/src/components/Incident/Incidents.tsx b/plugins/splunk-on-call/src/components/Incident/Incidents.tsx index 3c557773fd..e2ec9609bd 100644 --- a/plugins/splunk-on-call/src/components/Incident/Incidents.tsx +++ b/plugins/splunk-on-call/src/components/Incident/Incidents.tsx @@ -49,9 +49,10 @@ const useStyles = makeStyles((theme: Theme) => type Props = { refreshIncidents: boolean; team: string; + readOnly: boolean; }; -export const Incidents = ({ refreshIncidents, team }: Props) => { +export const Incidents = ({ readOnly, refreshIncidents, team }: Props) => { const classes = useStyles(); const api = useApi(splunkOnCallApiRef); @@ -108,6 +109,7 @@ export const Incidents = ({ refreshIncidents, team }: Props) => { key={index} team={team} incident={incident} + readOnly={readOnly} /> )) )} From 40dddac068135f4f57d8ced23a3f7440ccde99b7 Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Thu, 17 Feb 2022 16:52:05 -0500 Subject: [PATCH 02/11] add 'read only' mode README documentation Signed-off-by: Mike Ball --- plugins/splunk-on-call/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index 0200cacc50..967e1e0940 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -74,6 +74,28 @@ proxy: In addition, to make certain API calls (trigger-resolve-acknowledge an incident) you need to add the `PATCH` method to the backend `cors` methods list: `[GET, POST, PUT, DELETE, PATCH]`. +**WARNING**: In current implementation, the Splunk OnCall plugin requires the `/splunk-on-call` proxy endpoint be exposed by the Backstage backend as an unprotected endpoint, in effect enabling Splunk OnCall API access using the configured `SPLUNK_ON_CALL_API_KEY` for any user or process with access to the `/splunk-on-call` Backstage backend endpoint. See below for further configuration options enabling protection of this endpoint. + +### Read Only mode + +The Splunk OnCall plugin also supports a "read only" mode if you wish to suppress the rendering of UI controls to trigger-resolve-acknowledge incidents. + +```yaml +# enable readOnly mode +splunkOnCall: + readOnly: true + +proxy: + # ... + '/splunk-on-call': + target: https://api.victorops.com/api-public + headers: + X-VO-Api-Id: ${SPLUNK_ON_CALL_API_ID} + X-VO-Api-Key: ${SPLUNK_ON_CALL_API_KEY} + # prohibit non-GET requests from the /splunk-on-call proxy + allowedMethods: ['GET'] +``` + ### Adding your team name to the entity annotation The information displayed for each entity is based on either an associated team name or an associated routing key. From 02faa6781bd710caf4c78eaff7ef85e5e1f3cd39 Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Thu, 17 Feb 2022 16:57:16 -0500 Subject: [PATCH 03/11] add changeset documenting 'read only' configuration Signed-off-by: Mike Ball --- .changeset/spicy-elephants-decide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spicy-elephants-decide.md diff --git a/.changeset/spicy-elephants-decide.md b/.changeset/spicy-elephants-decide.md new file mode 100644 index 0000000000..dd35f04422 --- /dev/null +++ b/.changeset/spicy-elephants-decide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-splunk-on-call': patch +--- + +Splunk OnCall plugin now supports a "read only" mode configuration option for optionally suppressing the rendering of incident trigger-acknowledge-resolve controls from the Backstage UI. From f7ebb1b5da3ff30db95f7c347f984c3f5fa2ac62 Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Thu, 17 Feb 2022 17:07:26 -0500 Subject: [PATCH 04/11] improve README language Signed-off-by: Mike Ball --- plugins/splunk-on-call/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index 967e1e0940..6824fde74f 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -86,13 +86,12 @@ splunkOnCall: readOnly: true proxy: - # ... '/splunk-on-call': target: https://api.victorops.com/api-public headers: X-VO-Api-Id: ${SPLUNK_ON_CALL_API_ID} X-VO-Api-Key: ${SPLUNK_ON_CALL_API_KEY} - # prohibit non-GET requests from the /splunk-on-call proxy + # prohibit the `/splunk-on-call` proxy endpoint from servicing non-GET requests allowedMethods: ['GET'] ``` From 9a33293425e8dc90e642b72ed0ac38ff414067db Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Thu, 17 Feb 2022 17:07:44 -0500 Subject: [PATCH 05/11] address lint errors Signed-off-by: Mike Ball --- .../src/components/Incident/Incidents.test.tsx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx b/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx index 4c844e936f..c180a4f637 100644 --- a/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx +++ b/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx @@ -44,7 +44,7 @@ describe('Incidents', () => { const { getByText, queryByTestId } = render( wrapInTestApp( - + , ), ); @@ -68,7 +68,7 @@ describe('Incidents', () => { } = render( wrapInTestApp( - + , ), ); @@ -94,13 +94,7 @@ describe('Incidents', () => { mockSplunkOnCallApi.getIncidents.mockResolvedValue([MOCK_INCIDENT]); mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]); - const { - getByText, - getByTitle, - getAllByTitle, - getByLabelText, - queryByTestId, - } = render( + const { getByText, getAllByTitle, getByLabelText, queryByTestId } = render( wrapInTestApp( @@ -139,7 +133,7 @@ describe('Incidents', () => { const { getByText, queryByTestId } = render( wrapInTestApp( - + , ), ); From 262a2a2d51a21f712f4113702619ecde3effe83f Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Tue, 22 Feb 2022 12:05:10 -0500 Subject: [PATCH 06/11] configure readOnly via simple component prop This eliminates the use of YAML configuration and instead relies on a simple property to enable `readOnly` mode, per code review feedback. Signed-off-by: Mike Ball --- plugins/splunk-on-call/README.md | 18 +++++++++--------- .../components/EntitySplunkOnCallCard.test.tsx | 18 ++---------------- .../src/components/EntitySplunkOnCallCard.tsx | 11 +++++++---- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index 6824fde74f..5078dfa38b 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -45,6 +45,14 @@ const overviewContent = ( ``` +### `readOnly` mode + +To suppress the rendering of the actionable create-acknowledge-resolve incident buttons and UI controls, the `EntitySplunkOnCallCard` can also be instantiated in `readOnly` mode: + +```ts + +``` + ## Client configuration In order to be able to perform certain actions (create-acknowledge-resolve an action), you need to provide a REST Endpoint. @@ -74,17 +82,9 @@ proxy: In addition, to make certain API calls (trigger-resolve-acknowledge an incident) you need to add the `PATCH` method to the backend `cors` methods list: `[GET, POST, PUT, DELETE, PATCH]`. -**WARNING**: In current implementation, the Splunk OnCall plugin requires the `/splunk-on-call` proxy endpoint be exposed by the Backstage backend as an unprotected endpoint, in effect enabling Splunk OnCall API access using the configured `SPLUNK_ON_CALL_API_KEY` for any user or process with access to the `/splunk-on-call` Backstage backend endpoint. See below for further configuration options enabling protection of this endpoint. - -### Read Only mode - -The Splunk OnCall plugin also supports a "read only" mode if you wish to suppress the rendering of UI controls to trigger-resolve-acknowledge incidents. +**WARNING**: In current implementation, the Splunk OnCall plugin requires the `/splunk-on-call` proxy endpoint be exposed by the Backstage backend as an unprotected endpoint, in effect enabling Splunk OnCall API access using the configured `SPLUNK_ON_CALL_API_KEY` for any user or process with access to the `/splunk-on-call` Backstage backend endpoint. See below for further configuration options enabling protection of this endpoint. If you regard this as problematic, consider using the plugin in `readOnly` mode (``) using the following proxy configuration: ```yaml -# enable readOnly mode -splunkOnCall: - readOnly: true - proxy: '/splunk-on-call': target: https://api.victorops.com/api-public diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx index 6944dee4c9..0688fb8237 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx @@ -53,14 +53,6 @@ const mockSplunkOnCallApi: Partial = { const configApi: ConfigApi = new ConfigReader({ splunkOnCall: { eventsRestEndpoint: 'EXAMPLE_REST_ENDPOINT', - readOnly: false, - }, -}); - -const readOnlyConfigApi: ConfigApi = new ConfigReader({ - splunkOnCall: { - eventsRestEndpoint: 'EXAMPLE_REST_ENDPOINT', - readOnly: true, }, }); @@ -70,12 +62,6 @@ const apis = TestApiRegistry.from( [alertApiRef, {}], ); -const readOnlyApis = TestApiRegistry.from( - [splunkOnCallApiRef, mockSplunkOnCallApi], - [configApiRef, readOnlyConfigApi], - [alertApiRef, {}], -); - const mockEntity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -155,9 +141,9 @@ describe('SplunkOnCallCard', () => { const { getByText, queryByTestId } = render( wrapInTestApp( - + - + , ), diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx index 1727e462c1..ed452ab487 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx @@ -109,7 +109,12 @@ const useStyles = makeStyles({ }, }); -export const EntitySplunkOnCallCard = () => { +type Props = { + readOnly?: boolean; +}; + +export const EntitySplunkOnCallCard = ({ readOnly }: Props) => { + const readOnlyMode = readOnly || false; const classes = useStyles(); const config = useApi(configApiRef); const api = useApi(splunkOnCallApiRef); @@ -126,8 +131,6 @@ export const EntitySplunkOnCallCard = () => { const eventsRestEndpoint = config.getOptionalString('splunkOnCall.eventsRestEndpoint') || true; - const readOnly = config.getOptionalBoolean('splunkOnCall.readOnly') || false; - const handleRefresh = useCallback(() => { setRefreshIncidents(x => !x); }, []); @@ -221,7 +224,7 @@ export const EntitySplunkOnCallCard = () => { return ( <> From 716242c08105fd16d6986de57d710637e82ae06b Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Tue, 22 Feb 2022 12:08:56 -0500 Subject: [PATCH 07/11] Splunk On-Call changeset reflects `readOnly` property Signed-off-by: Mike Ball --- .changeset/spicy-elephants-decide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spicy-elephants-decide.md b/.changeset/spicy-elephants-decide.md index dd35f04422..2444a60b05 100644 --- a/.changeset/spicy-elephants-decide.md +++ b/.changeset/spicy-elephants-decide.md @@ -2,4 +2,4 @@ '@backstage/plugin-splunk-on-call': patch --- -Splunk OnCall plugin now supports a "read only" mode configuration option for optionally suppressing the rendering of incident trigger-acknowledge-resolve controls from the Backstage UI. +The Splunk On-Call plugin now supports an optional `readOnly` property (``) for suppressing the rendering of incident trigger-acknowledge-resolve controls from the Backstage UI. From 59864eaebe1057447dd9bb025057a7dbd25e026d Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Tue, 22 Feb 2022 12:39:32 -0500 Subject: [PATCH 08/11] update splunk-on-call API report Signed-off-by: Mike Ball --- plugins/splunk-on-call/api-report.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/splunk-on-call/api-report.md b/plugins/splunk-on-call/api-report.md index 8e8076d9e8..7e9a8294f1 100644 --- a/plugins/splunk-on-call/api-report.md +++ b/plugins/splunk-on-call/api-report.md @@ -15,7 +15,11 @@ import { RouteRef } from '@backstage/core-plugin-api'; // Warning: (ae-missing-release-tag) "EntitySplunkOnCallCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EntitySplunkOnCallCard: () => JSX.Element; +export const EntitySplunkOnCallCard: ({ + readOnly, +}: { + readOnly?: boolean | undefined; +}) => JSX.Element; // Warning: (ae-missing-release-tag) "isSplunkOnCallAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // From 7b45dd6f9275da434d719fb99222ffd6e581f006 Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Wed, 23 Feb 2022 15:23:09 -0500 Subject: [PATCH 09/11] restore accidentally-committed change This restores `eventsRestEndpoint` to its proper state. Signed-off-by: Mike Ball --- .../splunk-on-call/src/components/EntitySplunkOnCallCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx index ed452ab487..5784ccd8be 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx @@ -129,7 +129,7 @@ export const EntitySplunkOnCallCard = ({ readOnly }: Props) => { : undefined; const eventsRestEndpoint = - config.getOptionalString('splunkOnCall.eventsRestEndpoint') || true; + config.getOptionalString('splunkOnCall.eventsRestEndpoint') || null; const handleRefresh = useCallback(() => { setRefreshIncidents(x => !x); From 2a7b83c8aa40bb381287f45c1514d60adcda0e02 Mon Sep 17 00:00:00 2001 From: Mike Ball Date: Wed, 23 Feb 2022 15:27:59 -0500 Subject: [PATCH 10/11] simplify component rendering logic Per feedback here: https://github.com/backstage/backstage/pull/9635#discussion_r813156878 Signed-off-by: Mike Ball --- .../src/components/Incident/IncidentListItem.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx index 8078f07fc7..d8b6a56efc 100644 --- a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx +++ b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx @@ -243,15 +243,13 @@ export const IncidentListItem = ({ {incident.incidentLink && incident.incidentNumber && ( - {!readOnly ? ( + {!readOnly && ( - ) : ( - '' )} Date: Wed, 23 Feb 2022 15:46:29 -0500 Subject: [PATCH 11/11] improve EntitySplunkOnCallCard props * export the props * rename the props to match component, * unpack the props inside the function * mark both with `/** public */` ...per code review feedback here: https://github.com/backstage/backstage/pull/9635#discussion_r813155577 Signed-off-by: Mike Ball --- plugins/splunk-on-call/api-report.md | 9 ++++----- .../src/components/EntitySplunkOnCallCard.tsx | 10 ++++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/splunk-on-call/api-report.md b/plugins/splunk-on-call/api-report.md index 7e9a8294f1..60ec38ca6d 100644 --- a/plugins/splunk-on-call/api-report.md +++ b/plugins/splunk-on-call/api-report.md @@ -12,14 +12,13 @@ import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { RouteRef } from '@backstage/core-plugin-api'; +// Warning: (ae-forgotten-export) The symbol "EntitySplunkOnCallCardProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "EntitySplunkOnCallCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EntitySplunkOnCallCard: ({ - readOnly, -}: { - readOnly?: boolean | undefined; -}) => JSX.Element; +export const EntitySplunkOnCallCard: ( + props: EntitySplunkOnCallCardProps, +) => JSX.Element; // Warning: (ae-missing-release-tag) "isSplunkOnCallAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx index 5784ccd8be..4f6bcd9a0e 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx @@ -109,12 +109,14 @@ const useStyles = makeStyles({ }, }); -type Props = { +/** @public */ +export type EntitySplunkOnCallCardProps = { readOnly?: boolean; }; -export const EntitySplunkOnCallCard = ({ readOnly }: Props) => { - const readOnlyMode = readOnly || false; +/** @public */ +export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { + const { readOnly } = props; const classes = useStyles(); const config = useApi(configApiRef); const api = useApi(splunkOnCallApiRef); @@ -224,7 +226,7 @@ export const EntitySplunkOnCallCard = ({ readOnly }: Props) => { return ( <>