From 0194d1fbd94a72730654badf96e7a0809d2a700a Mon Sep 17 00:00:00 2001 From: Jen Evans Date: Fri, 30 Sep 2022 14:08:37 -0400 Subject: [PATCH 1/2] Add annotation to set schedule name --- docs/who-is-on-call-on-component-page.md | 9 +++++++++ src/api.ts | 7 +++++++ src/components/Entity/OnCallListCard.tsx | 16 ++++++++++++---- src/integration.ts | 1 + 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/who-is-on-call-on-component-page.md b/docs/who-is-on-call-on-component-page.md index 93eaec6..cb18158 100644 --- a/docs/who-is-on-call-on-component-page.md +++ b/docs/who-is-on-call-on-component-page.md @@ -44,3 +44,12 @@ annotations: ``` This annotation accepts any valid OpsGenie team name. + +If your OpsGenie teams do not directly own schedules (ie. shared schedule), specify the schedule name instead of a team +name and add an annotation to specify that the team name is actually a schedule: + +```yml +annotations: + opsgenie.com/team: 'Awesome Schedule' + opsgenie.com/isSchedule: 'true' +``` diff --git a/src/api.ts b/src/api.ts index dc8b1f0..897ef39 100644 --- a/src/api.ts +++ b/src/api.ts @@ -30,6 +30,7 @@ export interface Opsgenie { getSchedules(): Promise; getSchedulesForTeam(name: string): Promise; + getSchedulesByName(name: string): Promise; getOnCall(scheduleId: string): Promise; getTeams(): Promise; @@ -177,6 +178,12 @@ export class OpsgenieApi implements Opsgenie { return response.data.filter(schedule => schedule.ownerTeam && schedule.ownerTeam.name === name); } + async getSchedulesByName(name: string): Promise { + const response = await this.fetch("/v2/schedules"); + + return response.data.filter(schedule => schedule.name === name); + } + async getTeams(): Promise { const response = await this.fetch("/v2/teams"); diff --git a/src/components/Entity/OnCallListCard.tsx b/src/components/Entity/OnCallListCard.tsx index 204c024..dee67d9 100644 --- a/src/components/Entity/OnCallListCard.tsx +++ b/src/components/Entity/OnCallListCard.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useEntity } from '@backstage/plugin-catalog-react'; import { InfoCard, InfoCardVariants, MissingAnnotationEmptyState } from '@backstage/core-components'; -import { OPSGENIE_TEAM_ANNOTATION } from '../../integration'; +import { OPSGENIE_IS_SCHEDULE_ANNOTATION, OPSGENIE_TEAM_ANNOTATION } from '../../integration'; import { opsgenieApiRef } from '../../api'; import { OnCallForScheduleList } from '../OnCallList/OnCallList'; import { Progress } from '@backstage/core-components'; @@ -16,11 +16,18 @@ type OnCallListCardProps = { type OnCallListContentProps = { teamName: string; + isSchedule: boolean; } -const OnCallListCardContent = ({teamName}: OnCallListContentProps) => { +const OnCallListCardContent = ({teamName, isSchedule}: OnCallListContentProps) => { const opsgenieApi = useApi(opsgenieApiRef); - const { value, loading, error } = useAsync(async () => await opsgenieApi.getSchedulesForTeam(teamName)); + + const {value, loading, error} = useAsync(async () => { + if (isSchedule) { + return await opsgenieApi.getSchedulesByName(teamName); + } + return await opsgenieApi.getSchedulesForTeam(teamName); + }); if (loading) { return ; @@ -42,6 +49,7 @@ const OnCallListCardContent = ({teamName}: OnCallListContentProps) => { export const OnCallListCard = ({ title, variant }: OnCallListCardProps) => { const { entity } = useEntity(); const teamName = entity.metadata.annotations?.[OPSGENIE_TEAM_ANNOTATION]; + let isSchedule = entity.metadata.annotations?.[OPSGENIE_IS_SCHEDULE_ANNOTATION]?.toLowerCase() === 'true' || false; if (!teamName) { return ; @@ -49,7 +57,7 @@ export const OnCallListCard = ({ title, variant }: OnCallListCardProps) => { return ( - + ) }; diff --git a/src/integration.ts b/src/integration.ts index ada0fc3..f1b6881 100644 --- a/src/integration.ts +++ b/src/integration.ts @@ -2,6 +2,7 @@ import { Entity } from "@backstage/catalog-model"; export const OPSGENIE_ANNOTATION = 'opsgenie.com/component-selector'; export const OPSGENIE_TEAM_ANNOTATION = 'opsgenie.com/team'; +export const OPSGENIE_IS_SCHEDULE_ANNOTATION = 'opsgenie.com/isSchedule'; export const isOpsgenieAvailable = (entity: Entity) => Boolean(entity.metadata.annotations?.[OPSGENIE_ANNOTATION]); export const isOpsgenieOnCallListAvailable = (entity: Entity) => Boolean(entity.metadata.annotations?.[OPSGENIE_TEAM_ANNOTATION]); From c89d6ea25651a2af047473b942e5f09bd0d07f48 Mon Sep 17 00:00:00 2001 From: Jen Evans Date: Fri, 30 Sep 2022 14:10:14 -0400 Subject: [PATCH 2/2] yarn lint fix --- src/components/Entity/OnCallListCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Entity/OnCallListCard.tsx b/src/components/Entity/OnCallListCard.tsx index dee67d9..523832f 100644 --- a/src/components/Entity/OnCallListCard.tsx +++ b/src/components/Entity/OnCallListCard.tsx @@ -49,7 +49,7 @@ const OnCallListCardContent = ({teamName, isSchedule}: OnCallListContentProps) = export const OnCallListCard = ({ title, variant }: OnCallListCardProps) => { const { entity } = useEntity(); const teamName = entity.metadata.annotations?.[OPSGENIE_TEAM_ANNOTATION]; - let isSchedule = entity.metadata.annotations?.[OPSGENIE_IS_SCHEDULE_ANNOTATION]?.toLowerCase() === 'true' || false; + const isSchedule = entity.metadata.annotations?.[OPSGENIE_IS_SCHEDULE_ANNOTATION]?.toLowerCase() === 'true' || false; if (!teamName) { return ;