diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index d012264ae2..5d0f0da52e 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -46,6 +46,7 @@ configmaps configs const cookiecutter +cors css dariddler dataflow diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md index 518bd906c0..cc32735164 100644 --- a/plugins/splunk-on-call/README.md +++ b/plugins/splunk-on-call/README.md @@ -60,6 +60,15 @@ splunkoncall: The user supplied must be a valid Splunk On-Call user and a member of your organization. +In order to be able to make certain API calls you need to add the `PATCH` method to the backend cors methods list. + +```yaml +backend: + # ... + cors: + methods: [GET, POST, PUT, DELETE, PATCH] +``` + ### Adding your team name to the entity annotation The information displayed for each entity is based on the team name. diff --git a/plugins/splunk-on-call/src/api/client.ts b/plugins/splunk-on-call/src/api/client.ts index 02b560b1db..e974f27b83 100644 --- a/plugins/splunk-on-call/src/api/client.ts +++ b/plugins/splunk-on-call/src/api/client.ts @@ -52,6 +52,10 @@ export class SplunkOnCallClient implements SplunkOnCallApi { } constructor(private readonly config: ClientApiConfig) {} + getUsername(): string | undefined { + return this.config.username as string; + } + async getIncidents(): Promise { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', diff --git a/plugins/splunk-on-call/src/api/types.ts b/plugins/splunk-on-call/src/api/types.ts index 3d6d325f58..4cfa5037f1 100644 --- a/plugins/splunk-on-call/src/api/types.ts +++ b/plugins/splunk-on-call/src/api/types.ts @@ -18,7 +18,6 @@ import { EscalationPolicyInfo, Incident, OnCall, - Service, Team, User, } from '../components/types'; @@ -84,6 +83,11 @@ export interface SplunkOnCallApi { * Get a list of escalation policies for your organization. */ getEscalationPolicies(): Promise; + + /** + * Get the current user username. + */ + getUsername(): string | undefined; } export type PatchIncidentRequest = { @@ -101,10 +105,6 @@ export type ListUserResponse = { _selfUrl?: string; }; -export type ServicesResponse = { - services: Service[]; -}; - export type IncidentsResponse = { incidents: Incident[]; }; diff --git a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx index b1108988e2..eb29bc2aad 100644 --- a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx +++ b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx @@ -36,7 +36,7 @@ import { alertApiRef, } from '@backstage/core'; import { formatDistanceToNowStrict } from 'date-fns'; -import { Incident } from '../types'; +import { Incident, IncidentPhase } from '../types'; import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; import { splunkOnCallApiRef } from '../../api/client'; import { useAsyncFn } from 'react-use'; @@ -66,7 +66,11 @@ type Props = { onIncidentAction: () => void; }; -const IncidentPhase = ({ currentPhase }: { currentPhase: string }) => { +const IncidentPhaseStatus = ({ + currentPhase, +}: { + currentPhase: IncidentPhase; +}) => { switch (currentPhase) { case 'UNACKED': return ; @@ -77,6 +81,17 @@ const IncidentPhase = ({ currentPhase }: { currentPhase: string }) => { } }; +const incidentPhaseTooltip = (currentPhase: IncidentPhase) => { + switch (currentPhase) { + case 'UNACKED': + return 'Triggered'; + case 'ACKED': + return 'Acknowledged'; + default: + return 'Resolved'; + } +}; + const IncidentAction = ({ currentPhase, userName, @@ -190,9 +205,12 @@ export const IncidentListItem = ({ incident, onIncidentAction }: Props) => { return ( - +
- +
diff --git a/plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx index 5d012bf650..7149ce524f 100644 --- a/plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx +++ b/plugins/splunk-on-call/src/components/SplunkOnCallCard.tsx @@ -23,6 +23,7 @@ import { CardHeader, Divider, CardContent, + Typography, } from '@material-ui/core'; import { Incidents } from './Incident'; import { EscalationPolicy } from './Escalation'; @@ -122,8 +123,11 @@ export const SplunkOnCallCard = ({ entity }: Props) => { return ( } + title="Splunk On-Call" + subheader={[ + Team: {team}, + , + ]} /> diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx index 0617099926..b2bc50cf33 100644 --- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx +++ b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx @@ -118,6 +118,10 @@ export const TriggerDialog = ({ }), ); + const username = api.getUsername(); + + const currentUser = users.find(user => user.username === username); + const { value: policies, loading: policiesLoaading, @@ -180,6 +184,12 @@ export const TriggerDialog = ({ This action will trigger an incident. + + Created by:{' '} + + {currentUser?.firstName} {currentUser?.lastName} + + If the issue you are seeing does not need urgent attention, please diff --git a/plugins/splunk-on-call/src/components/types.ts b/plugins/splunk-on-call/src/components/types.ts index b5415ac57a..de5718cb28 100644 --- a/plugins/splunk-on-call/src/components/types.ts +++ b/plugins/splunk-on-call/src/components/types.ts @@ -16,31 +16,6 @@ import { IncidentTarget } from '../api/types'; -export type Service = { - id: string; - name: string; - html_url: string; - integrationKey: string; - escalation_policy: { - id: string; - user: User; - }; -}; - -export type Assignee = { - id: string; - summary: string; - html_url: string; -}; - -export type SubHeaderLink = { - title: string; - href?: string; - icon: React.ReactNode; - action?: React.ReactNode; -}; - -// GET Teams export type Team = { name?: string; slug?: string; @@ -53,7 +28,6 @@ export type Team = { _adminsUrl?: string; }; -// GET oncall export type OnCall = { team?: OnCallTeamResource; oncallNow?: OnCallNowResource[]; @@ -82,7 +56,6 @@ export type OnCallUser = { username?: string; }; -// GET /api-public/v2/user export type User = { firstName?: string; lastName?: string; @@ -95,7 +68,6 @@ export type User = { _selfUrl?: string; }; -// Incident creation export type CreateIncidentRequest = { summary: string; details: string; @@ -104,11 +76,12 @@ export type CreateIncidentRequest = { isMultiResponder: boolean; }; -// GET incidents +export type IncidentPhase = 'UNACKED' | 'ACKED' | 'RESOLVED'; + export type Incident = { incidentNumber?: string; startTime?: string; - currentPhase?: string; + currentPhase: IncidentPhase; entityState?: string; entityType?: string; routingKey?: string;