From 3e581853466e4525182100e48e516b4e592d83b4 Mon Sep 17 00:00:00 2001 From: Remi Date: Thu, 4 Feb 2021 23:42:01 +0100 Subject: [PATCH] feat(splunk-on-call-plugin): add TriggerDialog --- .../TriggerDialog/TriggerDialog.tsx | 310 ++++++++++++++++++ .../src/components/TriggerDialog/index.ts | 17 + 2 files changed, 327 insertions(+) create mode 100644 plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx create mode 100644 plugins/splunk-on-call/src/components/TriggerDialog/index.ts diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx new file mode 100644 index 0000000000..d6c069d4d2 --- /dev/null +++ b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx @@ -0,0 +1,310 @@ +/* + * 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, { useState, useEffect } from 'react'; +import { + Dialog, + DialogTitle, + TextField, + DialogActions, + Button, + DialogContent, + Typography, + CircularProgress, + Select, + MenuItem, + Input, + Chip, + createStyles, + makeStyles, + Theme, + FormControl, + InputLabel, +} from '@material-ui/core'; +import { useApi, alertApiRef, identityApiRef } from '@backstage/core'; +import { useAsync, useAsyncFn } from 'react-use'; +import { splunkOnCallApiRef } from '../../api'; +import { Alert } from '@material-ui/lab'; +import { User } from '../types'; +import { IncidentTarget, TargetType } from '../../api/types'; + +const MenuProps = { + PaperProps: { + style: { + width: 250, + }, + }, +}; + +type Props = { + // name: string; + users: User[]; + showDialog: boolean; + handleDialog: () => void; + onIncidentCreated: () => void; +}; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + chips: { + display: 'flex', + flexWrap: 'wrap', + }, + chip: { + margin: 2, + }, + formControl: { + margin: theme.spacing(1), + minWidth: '100%', + }, + }), +); + +export const TriggerDialog = ({ + users, + showDialog, + handleDialog, + onIncidentCreated: onIncidentCreated, +}: Props) => { + const alertApi = useApi(alertApiRef); + const identityApi = useApi(identityApiRef); + const userName = identityApi.getUserId(); + const api = useApi(splunkOnCallApiRef); + const classes = useStyles(); + + const [userTargets, setUserTargets] = useState([]); + const [policyTargets, setPolicyTargets] = useState([]); + const [details, setDetails] = useState(''); + const [summary, setSummary] = useState(''); + const [isMultiResponder, setIsMultiResponder] = useState(''); + + const [ + { value, loading: triggerLoading, error: triggerError }, + handleTriggerAlarm, + ] = useAsyncFn( + async ( + summary: string, + details: string, + userName: string, + targets: IncidentTarget[], + isMultiResponder: boolean, + ) => + await api.triggerAlarm({ + summary, + details, + userName, + targets, + isMultiResponder, + }), + ); + + const { value: policies, loading, error } = useAsync(async () => { + const policies = await api.getEscalationPolicies(); + return policies; + }); + + const handleUserTargets = (event: React.ChangeEvent<{ value: unknown }>) => { + setUserTargets(event.target.value as string[]); + }; + + const handlePolicyTargets = ( + event: React.ChangeEvent<{ value: unknown }>, + ) => { + setPolicyTargets(event.target.value as string[]); + }; + + const detailsChanged = (event: React.ChangeEvent) => { + setDetails(event.target.value); + }; + + const summaryChanged = (event: React.ChangeEvent) => { + setSummary(event.target.value); + }; + + const isMultiResponderChanged = ( + event: React.ChangeEvent<{ value: unknown }>, + ) => { + setIsMultiResponder(event.target.value as string); + }; + + const targets = (): IncidentTarget[] => [ + ...userTargets.map(user => ({ slug: user, type: TargetType.User })), + ...policyTargets.map(user => ({ + slug: user, + type: TargetType.EscalationPolicy, + })), + ]; + + useEffect(() => { + if (value) { + alertApi.post({ + message: `Alarm successfully triggered`, + }); + onIncidentCreated(); + handleDialog(); + } + }, [value, alertApi, handleDialog, userName, onIncidentCreated]); + + if (triggerError) { + alertApi.post({ + message: `Failed to trigger alarm. ${triggerError.message}`, + severity: 'error', + }); + } + + return ( + + This action will trigger an incident. + + + + If the issue you are seeing does not need urgent attention, please + get in touch with the responsible team using their preferred + communications channel. You can find information about the owner of + this entity in the "About" card. If the issue is urgent, please + don't hesitate to trigger the alert. + + + + Please describe the problem you want to report. Be as descriptive as + possible. Your signed in user and a reference to the current page will + automatically be amended to the alarm so that the receiver can reach + out to you if necessary. + + + Select users + + + + Select an escalation poilicy + + + + Acknowledge Behavior + + + + + + + + + + + ); +}; diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/index.ts b/plugins/splunk-on-call/src/components/TriggerDialog/index.ts new file mode 100644 index 0000000000..655cef8504 --- /dev/null +++ b/plugins/splunk-on-call/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';