diff --git a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx index 3e4a59d15a..4fa65eb999 100644 --- a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx +++ b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx @@ -37,7 +37,7 @@ describe('Escalation', () => { expect(getByText('Empty escalation policy')).toBeInTheDocument(); }); - it('render Escalation list', () => { + it('render escalation list', () => { const { getByText } = render( wrapInTestApp(), ); diff --git a/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx b/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx index 8a2aacead9..cbce0ce4a3 100644 --- a/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx +++ b/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx @@ -29,7 +29,6 @@ export const EscalationPolicy = ({ users }: EscalationPolicyProps) => ( {users.length ? ( users.map((user, index) => ) ) : ( - // TODO: how does it look if we used an EmptyState component here )} diff --git a/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx b/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx index 3fa8ef8d65..e20a5f7567 100644 --- a/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx +++ b/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx @@ -27,7 +27,7 @@ import { } from '@material-ui/core'; import Avatar from '@material-ui/core/Avatar'; import EmailIcon from '@material-ui/icons/Email'; -import PagerdutyIcon from '../Pd'; +import PagerdutyIcon from '../PagerDutyIcon'; import { User } from '../types'; const useStyles = makeStyles({ diff --git a/plugins/pagerduty/src/components/Escalation/index.ts b/plugins/pagerduty/src/components/Escalation/index.ts new file mode 100644 index 0000000000..ac2db62cd9 --- /dev/null +++ b/plugins/pagerduty/src/components/Escalation/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { EscalationPolicy } from './EscalationPolicy'; diff --git a/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx b/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx index f01c99fc8c..4700583a8b 100644 --- a/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx +++ b/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx @@ -29,7 +29,7 @@ import { import { StatusError, StatusWarning } from '@backstage/core'; import moment from 'moment'; import { Incident } from '../types'; -import PagerdutyIcon from '../Pd'; +import PagerdutyIcon from '../PagerDutyIcon'; type IncidentListItemProps = { incident: Incident; diff --git a/plugins/pagerduty/src/components/Incident/index.ts b/plugins/pagerduty/src/components/Incident/index.ts new file mode 100644 index 0000000000..fb2702602b --- /dev/null +++ b/plugins/pagerduty/src/components/Incident/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { Incidents } from './Incidents'; diff --git a/plugins/pagerduty/src/components/Pd.tsx b/plugins/pagerduty/src/components/PagerDutyIcon.tsx similarity index 100% rename from plugins/pagerduty/src/components/Pd.tsx rename to plugins/pagerduty/src/components/PagerDutyIcon.tsx diff --git a/plugins/pagerduty/src/components/PagerDutyServiceCard.tsx b/plugins/pagerduty/src/components/PagerDutyServiceCard.tsx deleted file mode 100644 index 480e7cdbd6..0000000000 --- a/plugins/pagerduty/src/components/PagerDutyServiceCard.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { useApi } from '@backstage/core'; -import { Entity } from '@backstage/catalog-model'; -import { LinearProgress } from '@material-ui/core'; -import { Incidents } from './Incident/Incidents'; -import { EscalationPolicy } from './Escalation/EscalationPolicy'; -import { TriggerButton } from './TriggerButton'; -import { useAsync } from 'react-use'; -import { Alert } from '@material-ui/lab'; -import { pagerDutyApiRef } from '../api/pagerDutyClient'; -import { PagerdutyCard } from './PagerdutyCard'; - -export const PAGERDUTY_INTEGRATION_KEY = 'pagerduty.com/integration-key'; - -export const isPluginApplicableToEntity = (entity: Entity) => - Boolean(entity.metadata.annotations?.[PAGERDUTY_INTEGRATION_KEY]); - -type Props = { - entity: Entity; -}; - -export const PagerDutyServiceCard = ({ entity }: Props) => { - const api = useApi(pagerDutyApiRef); - - const { value, loading, error } = useAsync(async () => { - const integrationKey = entity.metadata.annotations![ - PAGERDUTY_INTEGRATION_KEY - ]; - - const services = await api.getServiceByIntegrationKey(integrationKey); - // TODO check services length - const service = services[0]; - const incidents = await api.getIncidentsByServiceId(service.id); - const oncalls = await api.getOnCallByPolicyId(service.escalation_policy.id); - const users = oncalls.map(item => item.user); - - return { - incidents, - users, - id: service.id, - name: service.name, - homepageUrl: service.html_url, - }; - }); - - if (error) { - return ( -
- - Error encountered while fetching information. {error.message} - -
- ); - } - - if (loading) { - return ; - } - - const pagerdutyLink = { - title: 'View in PagerDuty', - href: value!.homepageUrl, - }; - - const triggerAlarm = { - title: 'Trigger Alarm', - action: , - }; - - return ( - - - - - } - /> - ); -}; diff --git a/plugins/pagerduty/src/components/PagerdutyCard.tsx b/plugins/pagerduty/src/components/PagerdutyCard.tsx index 539bf69540..6b6d466850 100644 --- a/plugins/pagerduty/src/components/PagerdutyCard.tsx +++ b/plugins/pagerduty/src/components/PagerdutyCard.tsx @@ -1,18 +1,38 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import React from 'react'; +import { useApi, EmptyState } from '@backstage/core'; +import { Entity } from '@backstage/catalog-model'; import { Card, - CardHeader, CardContent, + CardHeader, Divider, - Link, + LinearProgress, makeStyles, } from '@material-ui/core'; -import LinkIcon from '@material-ui/icons/Link'; +import { Incidents } from './Incident'; +import { EscalationPolicy } from './Escalation'; +import { TriggerButton } from './TriggerButton'; +import { useAsync } from 'react-use'; +import { Alert } from '@material-ui/lab'; +import { pagerDutyApiRef, UnauthorizedError } from '../api'; +import { IconLinkVertical } from '@backstage/plugin-catalog'; +import PagerDutyIcon from './PagerDutyIcon'; import ReportProblemIcon from '@material-ui/icons/ReportProblem'; -import classnames from 'classnames'; -import PagerdutyIcon from './Pd'; - -// TODO: create a general component to use it in pagerduty and aboutCard const useStyles = makeStyles(theme => ({ links: { @@ -22,102 +42,98 @@ const useStyles = makeStyles(theme => ({ gridAutoColumns: 'min-content', gridGap: theme.spacing(3), }, - link: { - display: 'grid', - justifyItems: 'center', - gridGap: 4, - textAlign: 'center', - }, - label: { - fontSize: '0.7rem', - textTransform: 'uppercase', - fontWeight: 600, - letterSpacing: 1.2, - }, - trigger: { - color: theme.palette.secondary.main, - }, - svgButtonImage: { - height: '1.5em', - color: theme.palette.primary.main, - }, })); -type SubHeaderProps = { - ViewPagerduty: { title: string; href: string }; - TriggerAlarm: { title: string; action: React.ReactNode }; +export const PAGERDUTY_INTEGRATION_KEY = 'pagerduty.com/integration-key'; + +export const isPluginApplicableToEntity = (entity: Entity) => + Boolean(entity.metadata.annotations?.[PAGERDUTY_INTEGRATION_KEY]); + +type Props = { + entity: Entity; }; -type PagerdutyCardProps = { - title: string; - subheader: SubHeaderProps; - content: React.ReactNode; -}; - -type VerticalIconProps = { - label: string; - href?: string; - action?: React.ReactNode; - icon?: React.ReactNode; -}; - -const VerticalIcon = ({ - label, - href, - icon = , - action, -}: VerticalIconProps) => { +export const PagerDutyCard = ({ entity }: Props) => { const classes = useStyles(); - if (action) { + const api = useApi(pagerDutyApiRef); + + const { value, loading, error } = useAsync(async () => { + const integrationKey = entity.metadata.annotations![ + PAGERDUTY_INTEGRATION_KEY + ]; + + const services = await api.getServiceByIntegrationKey(integrationKey); + const incidents = await api.getIncidentsByServiceId(services[0].id); + const oncalls = await api.getOnCallByPolicyId( + services[0].escalation_policy.id, + ); + const users = oncalls.map(oncall => oncall.user); + + return { + incidents, + users, + id: services[0].id, + name: services[0].name, + homepageUrl: services[0].html_url, + }; + }); + + if (error) { + if (error instanceof UnauthorizedError) { + return ( + + ); + } + return ( - <> - - {icon} - {action} - - + + Error encountered while fetching information. {error.message} + ); } - return ( - <> - - {icon} - {label} - - - ); -}; -export const PagerdutyCard = ({ - title, - subheader, - content, -}: PagerdutyCardProps) => { - const classes = useStyles(); - const getSubheader = ({ ViewPagerduty, TriggerAlarm }: SubHeaderProps) => { - return ( - - ); + + if (loading) { + return ; + } + + const pagerdutyLink = { + title: 'View in PagerDuty', + href: value!.homepageUrl, + }; + + const triggerAlarm = { + title: 'Trigger Alarm', + action: , }; return ( + title="PagerDuty" + subheader={ + + } + /> - {content} + + + + ); }; diff --git a/plugins/pagerduty/src/components/TriggerButton.tsx b/plugins/pagerduty/src/components/TriggerButton/TriggerButton.tsx similarity index 93% rename from plugins/pagerduty/src/components/TriggerButton.tsx rename to plugins/pagerduty/src/components/TriggerButton/TriggerButton.tsx index 48bed68e2e..8feebf9e89 100644 --- a/plugins/pagerduty/src/components/TriggerButton.tsx +++ b/plugins/pagerduty/src/components/TriggerButton/TriggerButton.tsx @@ -16,9 +16,9 @@ import React, { useState } from 'react'; import { Button, makeStyles } from '@material-ui/core'; -import { TriggerDialog } from './TriggerDialog'; +import { TriggerDialog } from '../TriggerDialog'; import { Entity } from '@backstage/catalog-model'; -import { PAGERDUTY_INTEGRATION_KEY } from './PagerDutyServiceCard'; +import { PAGERDUTY_INTEGRATION_KEY } from '../PagerDutyCard'; const useStyles = makeStyles({ triggerAlarm: { diff --git a/plugins/pagerduty/src/components/TriggerButton/index.ts b/plugins/pagerduty/src/components/TriggerButton/index.ts new file mode 100644 index 0000000000..6a58a4f43f --- /dev/null +++ b/plugins/pagerduty/src/components/TriggerButton/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { TriggerButton } from './TriggerButton'; diff --git a/plugins/pagerduty/src/components/TriggerDialog.test.tsx b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx similarity index 96% rename from plugins/pagerduty/src/components/TriggerDialog.test.tsx rename to plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx index 387b168e05..7e26985136 100644 --- a/plugins/pagerduty/src/components/TriggerDialog.test.tsx +++ b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx @@ -24,8 +24,8 @@ import { IdentityApi, identityApiRef, } from '@backstage/core'; -import { pagerDutyApiRef } from '../api/pagerDutyClient'; -import { TriggerButton } from './TriggerButton'; +import { pagerDutyApiRef } from '../../api'; +import { TriggerButton } from '../TriggerButton'; import { Entity } from '@backstage/catalog-model'; import { act } from 'react-dom/test-utils'; diff --git a/plugins/pagerduty/src/components/TriggerDialog.tsx b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.tsx similarity index 98% rename from plugins/pagerduty/src/components/TriggerDialog.tsx rename to plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.tsx index 08044d02f6..91ec3cd27d 100644 --- a/plugins/pagerduty/src/components/TriggerDialog.tsx +++ b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.tsx @@ -26,7 +26,7 @@ import { } from '@material-ui/core'; import { Progress, useApi, alertApiRef, identityApiRef } from '@backstage/core'; import { useAsyncFn } from 'react-use'; -import { pagerDutyApiRef } from '../api/pagerDutyClient'; +import { pagerDutyApiRef } from '../../api'; const useStyles = makeStyles({ warningText: { diff --git a/plugins/pagerduty/src/components/TriggerDialog/index.ts b/plugins/pagerduty/src/components/TriggerDialog/index.ts new file mode 100644 index 0000000000..655cef8504 --- /dev/null +++ b/plugins/pagerduty/src/components/TriggerDialog/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { TriggerDialog } from './TriggerDialog'; diff --git a/plugins/pagerduty/src/components/types.tsx b/plugins/pagerduty/src/components/types.tsx index b229949cb4..9c9e29cb01 100644 --- a/plugins/pagerduty/src/components/types.tsx +++ b/plugins/pagerduty/src/components/types.tsx @@ -51,10 +51,6 @@ export type User = { name: string; }; -export type ClientApiConfig = { - token?: string; -}; - export type ServicesResponse = { services: Service[]; }; @@ -72,3 +68,8 @@ export type RequestOptions = { headers: HeadersInit; body?: BodyInit; }; + +export type ClientApiConfig = { + api_url: string; + events_url: string; +};