Incidents mapped to /alert-groups (#1678)
# What this PR does Reopened old reverted PR that @Ukochka worked on. In addition it has fixed the redirect from `?page=incident` to `/alert-groups` --------- Co-authored-by: Yulia Shanyrova <yulia.shanyrova@grafana.com> Co-authored-by: Joey Orlando <joey.orlando@grafana.com>
This commit is contained in:
parent
2b3e269e28
commit
0acac58af0
18 changed files with 79 additions and 45 deletions
|
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Changes
|
||||
|
||||
- Renamed routes from /incidents to /alert-groups ([#1678](https://github.com/grafana/oncall/pull/1678))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix team search when filtering resources by @vadimkerr ([#1680](https://github.com/grafana/oncall/pull/1680))
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ const Tutorial: FC<TutorialProps> = (props) => {
|
|||
</div>
|
||||
<Arrow />
|
||||
<div className={cx('step')}>
|
||||
<PluginLink query={{ page: 'incidents' }}>
|
||||
<PluginLink query={{ page: 'alert-groups' }}>
|
||||
<div className={cx('icon', { icon_active: step === TutorialStep.Incidents })}>
|
||||
<img src={bellIcon} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const AlertReceiveChannelCard = observer((props: AlertReceiveChannelCardProps) =
|
|||
</Text>
|
||||
{alertReceiveChannelCounter && (
|
||||
<PluginLink
|
||||
query={{ page: 'incidents', integration: alertReceiveChannel.id }}
|
||||
query={{ page: 'alert-groups', integration: alertReceiveChannel.id }}
|
||||
className={cx('alertsInfoText')}
|
||||
>
|
||||
<Badge
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ interface AlertRulesState {
|
|||
const Notification: React.FC = () => (
|
||||
<div>
|
||||
Demo alert was generated. Find it on the
|
||||
<PluginLink query={{ page: 'incidents' }}> "Alert Groups" </PluginLink>
|
||||
<PluginLink query={{ page: 'alert-groups' }}> "Alert Groups" </PluginLink>
|
||||
page and make sure it didn't freak out your colleagues 😉
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -63,15 +63,15 @@ const AttachIncidentForm = observer(({ id, onUpdate, onHide }: AttachIncidentFor
|
|||
title={
|
||||
<HorizontalGroup>
|
||||
<Icon size="lg" name="link" />
|
||||
<Text.Title level={4}>Attach to another incident</Text.Title>
|
||||
<Text.Title level={4}>Attach to another alert group</Text.Title>
|
||||
</HorizontalGroup>
|
||||
}
|
||||
className={cx('root')}
|
||||
onDismiss={onHide}
|
||||
>
|
||||
<Field
|
||||
label="Incident to be attached with"
|
||||
description="Linking incidents together can help the team investigate the underlying issue."
|
||||
label="Alert group to be attached with"
|
||||
description="Linking alert groups together can help the team investigate the underlying issue."
|
||||
>
|
||||
<WithPermissionControlTooltip userAction={UserActions.AlertGroupsWrite}>
|
||||
<GSelect
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ const IncidentMatcher = observer((props: IncidentMatcherProps) => {
|
|||
{selectedAlertItem ? (
|
||||
<SourceCode noMaxHeight>{JSON.stringify(selectedAlertItem, null, 2)}</SourceCode>
|
||||
) : (
|
||||
<Text type="secondary">← Select incident first</Text>
|
||||
<Text type="secondary">← Select alert group first</Text>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ const IntegrationSettings = observer((props: IntegrationSettingsProps) => {
|
|||
const [expanded, _setExpanded] = useState(false);
|
||||
|
||||
const handleSwitchToTemplate = (templateName: string) => {
|
||||
setActiveTab(IntegrationSettingsTab.Templates);
|
||||
setSelectedTemplate(templateName);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,12 @@
|
|||
padding: 4px 8px;
|
||||
margin-top: 8px;
|
||||
min-width: 500px;
|
||||
width: 520px;
|
||||
width: 620px;
|
||||
}
|
||||
|
||||
.autoresolve-div {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.warning-icon-color {
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ const Autoresolve = ({ alertReceiveChannelId, onSwitchToTemplate, alertGroupId }
|
|||
<Label>
|
||||
<div className={cx('settings-label')}>
|
||||
Autoresolve
|
||||
<Text type="secondary">How should this integration resolve incidents?</Text>
|
||||
<Text type="secondary">How should this integration resolve alert groups?</Text>
|
||||
</div>
|
||||
</Label>
|
||||
<div className={cx('team-select')}>
|
||||
|
|
@ -172,9 +172,9 @@ const Autoresolve = ({ alertReceiveChannelId, onSwitchToTemplate, alertGroupId }
|
|||
{autoresolveSelected && (
|
||||
<>
|
||||
<Block shadowed bordered className={cx('autoresolve-block')}>
|
||||
<div>
|
||||
<div className={cx('autoresolve-div')}>
|
||||
<Text type="secondary" size="small">
|
||||
<Icon name="info-circle" /> Incident will be automatically resolved when it matches{' '}
|
||||
<Icon name="info-circle" /> Alert group will be automatically resolved when it matches{' '}
|
||||
</Text>
|
||||
<Button fill="text" size="sm" onClick={handleGoToTemplateSettingsCllick}>
|
||||
autoresolve condition
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export const form: { name: string; fields: FormItem[] } = {
|
|||
},
|
||||
{
|
||||
value: MaintenanceMode.Maintenance,
|
||||
label: 'Maintenance (collect everything in one incident)',
|
||||
label: 'Maintenance (collect everything in one alert group)',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
}
|
||||
|
||||
.draggable {
|
||||
top: 0;
|
||||
top: 10%;
|
||||
position: absolute;
|
||||
|
||||
/* transition: transform 300ms ease; */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class EscalationChainsPage extends React.Component<EscalationChainsPageProps, Es
|
|||
.loadItem(id, true)
|
||||
.catch((error) => this.setState({ errorData: { ...getWrongTeamResponseInfo(error) } }));
|
||||
|
||||
await escalationChainStore.updateEscalationChainDetails(id);
|
||||
if (!escalationChain) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class IncidentPage extends React.Component<IncidentPageProps, IncidentPageState>
|
|||
<VerticalGroup spacing="lg" align="center">
|
||||
<Text.Title level={1}>404</Text.Title>
|
||||
<Text.Title level={4}>Alert group not found</Text.Title>
|
||||
<PluginLink query={{ page: 'incidents', cursor, start, perpage }}>
|
||||
<PluginLink query={{ page: 'alert-groups', cursor, start, perpage }}>
|
||||
<Button variant="secondary" icon="arrow-left" size="md">
|
||||
Go to Alert Groups page
|
||||
</Button>
|
||||
|
|
@ -244,7 +244,7 @@ class IncidentPage extends React.Component<IncidentPageProps, IncidentPageState>
|
|||
<VerticalGroup>
|
||||
<HorizontalGroup justify="space-between">
|
||||
<HorizontalGroup className={cx('title')}>
|
||||
<PluginLink query={{ page: 'incidents', cursor, start, perpage }}>
|
||||
<PluginLink query={{ page: 'alert-groups', cursor, start, perpage }}>
|
||||
<IconButton name="arrow-left" size="xxl" />
|
||||
</PluginLink>
|
||||
{/* @ts-ignore*/}
|
||||
|
|
@ -256,12 +256,12 @@ class IncidentPage extends React.Component<IncidentPageProps, IncidentPageState>
|
|||
{incident.root_alert_group && (
|
||||
<Text type="secondary">
|
||||
Attached to{' '}
|
||||
<PluginLink query={{ page: 'incident', id: incident.root_alert_group.pk }}>
|
||||
<PluginLink query={{ page: 'alert-groups', id: incident.root_alert_group.pk }}>
|
||||
#{incident.root_alert_group.inside_organization_number}{' '}
|
||||
{incident.root_alert_group.render_for_web.title}
|
||||
</PluginLink>{' '}
|
||||
<WithPermissionControlTooltip userAction={UserActions.AlertGroupsWrite}>
|
||||
<Button variant="secondary" onClick={this.getUnattachClickHandler(incident.pk)} size="sm">
|
||||
<Button variant="secondary" onClick={() => this.getUnattachClickHandler(incident.pk)} size="sm">
|
||||
Unattach
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
|
|
@ -421,9 +421,7 @@ class IncidentPage extends React.Component<IncidentPageProps, IncidentPageState>
|
|||
getUnattachClickHandler = (pk: Alert['pk']) => {
|
||||
const { store } = this.props;
|
||||
|
||||
return () => {
|
||||
store.alertGroupStore.unattachAlert(pk).then(this.update);
|
||||
};
|
||||
return store.alertGroupStore.unattachAlert(pk).then(this.update);
|
||||
};
|
||||
|
||||
renderTimeline = () => {
|
||||
|
|
@ -762,7 +760,7 @@ function AttachedIncidentsList({
|
|||
{alerts.map((incident) => {
|
||||
return (
|
||||
<HorizontalGroup key={incident.pk} justify={'space-between'}>
|
||||
<PluginLink query={{ page: 'incident', id: incident.pk }}>
|
||||
<PluginLink query={{ page: 'alert-groups', id: incident.pk }}>
|
||||
#{incident.inside_organization_number} {incident.render_for_web.title}
|
||||
</PluginLink>
|
||||
<WithPermissionControlTooltip userAction={UserActions.AlertGroupsWrite}>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ class Incidents extends React.Component<IncidentsPageProps, IncidentsPageState>
|
|||
this.setState({ showAddAlertGroupForm: false });
|
||||
}}
|
||||
onCreate={(id: Alert['pk']) => {
|
||||
history.push(`${PLUGIN_ROOT}/incidents/${id}`);
|
||||
history.push(`${PLUGIN_ROOT}/alert-groups/${id}`);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -557,7 +557,13 @@ class Incidents extends React.Component<IncidentsPageProps, IncidentsPageState>
|
|||
<VerticalGroup spacing="none" justify="center">
|
||||
<div className={'table__wrap-column'}>
|
||||
<PluginLink
|
||||
query={{ page: 'incidents', id: record.pk, cursor: incidentsCursor, perpage: incidentsItemsPerPage, start }}
|
||||
query={{
|
||||
page: 'alert-groups',
|
||||
id: record.pk,
|
||||
cursor: incidentsCursor,
|
||||
perpage: incidentsItemsPerPage,
|
||||
start,
|
||||
}}
|
||||
>
|
||||
<Tooltip placement="top" content={record.render_for_web.title}>
|
||||
<span>{record.render_for_web.title}</span>
|
||||
|
|
|
|||
|
|
@ -27,24 +27,11 @@ function getPath(name = '') {
|
|||
export const pages: { [id: string]: PageDefinition } = [
|
||||
{
|
||||
icon: 'bell',
|
||||
id: 'incidents',
|
||||
id: 'alert-groups',
|
||||
hideFromBreadcrumbs: true,
|
||||
text: 'Alert Groups',
|
||||
hideTitle: true,
|
||||
path: getPath('incidents'),
|
||||
action: UserActions.AlertGroupsRead,
|
||||
},
|
||||
{
|
||||
icon: 'bell',
|
||||
id: 'incident',
|
||||
text: '',
|
||||
hideFromTabs: true,
|
||||
hideFromBreadcrumbs: true,
|
||||
parentItem: {
|
||||
text: 'Incident',
|
||||
url: `${PLUGIN_ROOT}/incidents`,
|
||||
},
|
||||
path: getPath('incident'),
|
||||
path: getPath('alert-groups'),
|
||||
action: UserActions.AlertGroupsRead,
|
||||
},
|
||||
{
|
||||
|
|
@ -189,8 +176,8 @@ export const pages: { [id: string]: PageDefinition } = [
|
|||
}, {});
|
||||
|
||||
export const ROUTES = {
|
||||
incidents: ['incidents'],
|
||||
incident: ['incidents/:id'],
|
||||
'alert-groups': ['alert-groups'],
|
||||
'alert-group': ['alert-groups/:id'],
|
||||
users: ['users', 'users/:id'],
|
||||
integrations: ['integrations', 'integrations/:id'],
|
||||
escalations: ['escalations', 'escalations/:id'],
|
||||
|
|
@ -205,6 +192,10 @@ export const ROUTES = {
|
|||
'live-settings': ['live-settings'],
|
||||
cloud: ['cloud'],
|
||||
test: ['test'],
|
||||
|
||||
// backwards compatible to redirect to new alert-groups
|
||||
incident: ['incidents/:id'],
|
||||
incidents: ['incidents'],
|
||||
};
|
||||
|
||||
export const getRoutesForPage = (name: string) => {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
{
|
||||
"type": "page",
|
||||
"name": "Alert Groups",
|
||||
"path": "/a/grafana-oncall-app/incidents",
|
||||
"path": "/a/grafana-oncall-app/alert-groups",
|
||||
"role": "Viewer",
|
||||
"action": "grafana-oncall-app.alert-groups:read",
|
||||
"addToNav": true
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import weekday from 'dayjs/plugin/weekday';
|
|||
import { observer, Provider } from 'mobx-react';
|
||||
import Header from 'navbar/Header/Header';
|
||||
import LegacyNavTabsBar from 'navbar/LegacyNavTabsBar';
|
||||
import { Route, Switch, useLocation } from 'react-router-dom';
|
||||
import { Redirect, Route, Switch, useLocation } from 'react-router-dom';
|
||||
import { AppRootProps } from 'types';
|
||||
|
||||
import Unauthorized from 'components/Unauthorized';
|
||||
|
|
@ -138,10 +138,10 @@ export const Root = observer((props: AppRootProps) => {
|
|||
>
|
||||
{userHasAccess ? (
|
||||
<Switch>
|
||||
<Route path={getRoutesForPage('incidents')} exact>
|
||||
<Route path={getRoutesForPage('alert-groups')} exact>
|
||||
<Incidents query={query} />
|
||||
</Route>
|
||||
<Route path={getRoutesForPage('incident')} exact>
|
||||
<Route path={getRoutesForPage('alert-group')} exact>
|
||||
<Incident query={query} />
|
||||
</Route>
|
||||
<Route path={getRoutesForPage('users')} exact>
|
||||
|
|
@ -183,6 +183,33 @@ export const Root = observer((props: AppRootProps) => {
|
|||
<Route path={getRoutesForPage('cloud')} exact>
|
||||
<CloudPage />
|
||||
</Route>
|
||||
|
||||
{/* Backwards compatibility redirect routes */}
|
||||
<Route
|
||||
path={getRoutesForPage('incident')}
|
||||
exact
|
||||
render={({ location }) => (
|
||||
<Redirect
|
||||
to={{
|
||||
...location,
|
||||
pathname: location.pathname.replace(/incident/, 'alert-group'),
|
||||
}}
|
||||
></Redirect>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path={getRoutesForPage('incidents')}
|
||||
exact
|
||||
render={({ location }) => (
|
||||
<Redirect
|
||||
to={{
|
||||
...location,
|
||||
pathname: location.pathname.replace(/incidents/, 'alert-groups'),
|
||||
}}
|
||||
></Redirect>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
<Route path="*">
|
||||
<NoMatch />
|
||||
</Route>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export const GRAFANA_LICENSE_OSS = 'OpenSource';
|
|||
export const BREAKPOINT_TABS = 1024;
|
||||
|
||||
// Default redirect page
|
||||
export const DEFAULT_PAGE = 'incidents';
|
||||
export const DEFAULT_PAGE = 'alert-groups';
|
||||
|
||||
export const PLUGIN_ROOT = '/a/grafana-oncall-app';
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue