Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/alert_management
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/alert_management')
-rw-r--r--app/assets/javascripts/alert_management/components/alert_details.vue106
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_empty_state.vue22
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_table.vue41
-rw-r--r--app/assets/javascripts/alert_management/components/alert_status.vue14
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue8
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue38
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue2
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue2
-rw-r--r--app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue84
-rw-r--r--app/assets/javascripts/alert_management/details.js5
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql6
-rw-r--r--app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.graphql11
-rw-r--r--app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql10
-rw-r--r--app/assets/javascripts/alert_management/graphql/mutations/alert_todo_mark_done.mutation.graphql8
-rw-r--r--app/assets/javascripts/alert_management/graphql/queries/alert_help_url.query.graphql3
-rw-r--r--app/assets/javascripts/alert_management/list.js9
-rw-r--r--app/assets/javascripts/alert_management/router.js13
17 files changed, 233 insertions, 149 deletions
diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue
index 0731349630c..5d260fcc200 100644
--- a/app/assets/javascripts/alert_management/components/alert_details.vue
+++ b/app/assets/javascripts/alert_management/components/alert_details.vue
@@ -35,13 +35,24 @@ export default {
errorMsg: s__(
'AlertManagement|There was an error displaying the alert. Please refresh the page to try again.',
),
- fullAlertDetailsTitle: s__('AlertManagement|Alert details'),
- overviewTitle: s__('AlertManagement|Overview'),
- metricsTitle: s__('AlertManagement|Metrics'),
reportedAt: s__('AlertManagement|Reported %{when}'),
reportedAtWithTool: s__('AlertManagement|Reported %{when} by %{tool}'),
},
severityLabels: ALERTS_SEVERITY_LABELS,
+ tabsConfig: [
+ {
+ id: 'overview',
+ title: s__('AlertManagement|Overview'),
+ },
+ {
+ id: 'fullDetails',
+ title: s__('AlertManagement|Alert details'),
+ },
+ {
+ id: 'metrics',
+ title: s__('AlertManagement|Metrics'),
+ },
+ ],
components: {
GlBadge,
GlAlert,
@@ -102,8 +113,8 @@ export default {
errored: false,
sidebarStatus: false,
isErrorDismissed: false,
- createIssueError: '',
- issueCreationInProgress: false,
+ createIncidentError: '',
+ incidentCreationInProgress: false,
sidebarErrorMessage: '',
};
},
@@ -119,6 +130,18 @@ export default {
showErrorMsg() {
return this.errored && !this.isErrorDismissed;
},
+ activeTab() {
+ return this.$route.params.tabId || this.$options.tabsConfig[0].id;
+ },
+ currentTabIndex: {
+ get() {
+ return this.$options.tabsConfig.findIndex(tab => tab.id === this.activeTab);
+ },
+ set(tabIdx) {
+ const tabId = this.$options.tabsConfig[tabIdx].id;
+ this.$router.replace({ name: 'tab', params: { tabId } });
+ },
+ },
},
mounted() {
this.trackPageViews();
@@ -149,8 +172,8 @@ export default {
this.errored = true;
this.sidebarErrorMessage = errorMessage;
},
- createIssue() {
- this.issueCreationInProgress = true;
+ createIncident() {
+ this.incidentCreationInProgress = true;
this.$apollo
.mutate({
@@ -162,18 +185,18 @@ export default {
})
.then(({ data: { createAlertIssue: { errors, issue } } }) => {
if (errors?.length) {
- [this.createIssueError] = errors;
- this.issueCreationInProgress = false;
+ [this.createIncidentError] = errors;
+ this.incidentCreationInProgress = false;
} else if (issue) {
- visitUrl(this.issuePath(issue.iid));
+ visitUrl(this.incidentPath(issue.iid));
}
})
.catch(error => {
- this.createIssueError = error;
- this.issueCreationInProgress = false;
+ this.createIncidentError = error;
+ this.incidentCreationInProgress = false;
});
},
- issuePath(issueId) {
+ incidentPath(issueId) {
return joinPaths(this.projectIssuesPath, issueId);
},
trackPageViews() {
@@ -190,12 +213,12 @@ export default {
<p v-html="sidebarErrorMessage || $options.i18n.errorMsg"></p>
</gl-alert>
<gl-alert
- v-if="createIssueError"
+ v-if="createIncidentError"
variant="danger"
- data-testid="issueCreationError"
- @dismiss="createIssueError = null"
+ data-testid="incidentCreationError"
+ @dismiss="createIncidentError = null"
>
- {{ createIssueError }}
+ {{ createIncidentError }}
</gl-alert>
<div v-if="loading"><gl-loading-icon size="lg" class="gl-mt-5" /></div>
<div
@@ -204,19 +227,12 @@ export default {
:class="{ 'pr-sm-8': sidebarStatus }"
>
<div
- class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid flex-column flex-sm-row"
+ class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid gl-flex-direction-column gl-sm-flex-direction-row"
>
- <div
- data-testid="alert-header"
- class="gl-display-flex gl-align-items-center gl-justify-content-center"
- >
- <div
- class="gl-display-inline-flex gl-align-items-center gl-justify-content-space-between"
- >
- <gl-badge class="gl-mr-3">
- <strong>{{ s__('AlertManagement|Alert') }}</strong>
- </gl-badge>
- </div>
+ <div data-testid="alert-header">
+ <gl-badge class="gl-mr-3">
+ <strong>{{ s__('AlertManagement|Alert') }}</strong>
+ </gl-badge>
<span>
<gl-sprintf :message="reportedAtMessage">
<template #when>
@@ -228,24 +244,24 @@ export default {
</div>
<gl-button
v-if="alert.issueIid"
- class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-issue-button"
- data-testid="viewIssueBtn"
- :href="issuePath(alert.issueIid)"
+ class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-incident-button"
+ data-testid="viewIncidentBtn"
+ :href="incidentPath(alert.issueIid)"
category="primary"
variant="success"
>
- {{ s__('AlertManagement|View issue') }}
+ {{ s__('AlertManagement|View incident') }}
</gl-button>
<gl-button
v-else
- class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-issue-button"
- data-testid="createIssueBtn"
- :loading="issueCreationInProgress"
+ class="gl-mt-3 mt-sm-0 align-self-center align-self-sm-baseline alert-details-incident-button"
+ data-testid="createIncidentBtn"
+ :loading="incidentCreationInProgress"
category="primary"
variant="success"
- @click="createIssue()"
+ @click="createIncident()"
>
- {{ s__('AlertManagement|Create issue') }}
+ {{ s__('AlertManagement|Create incident') }}
</gl-button>
<gl-button
:aria-label="__('Toggle sidebar')"
@@ -264,8 +280,8 @@ export default {
>
<h2 data-testid="title">{{ alert.title }}</h2>
</div>
- <gl-tabs v-if="alert" data-testid="alertDetailsTabs">
- <gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle">
+ <gl-tabs v-if="alert" v-model="currentTabIndex" data-testid="alertDetailsTabs">
+ <gl-tab :data-testid="$options.tabsConfig[0].id" :title="$options.tabsConfig[0].title">
<div v-if="alert.severity" class="gl-mt-3 gl-mb-5 gl-display-flex">
<div class="gl-font-weight-bold gl-w-13 gl-text-right gl-pr-3">
{{ s__('AlertManagement|Severity') }}:
@@ -308,6 +324,12 @@ export default {
</div>
<div class="gl-pl-2" data-testid="service">{{ alert.service }}</div>
</div>
+ <div v-if="alert.runbook" class="gl-my-5 gl-display-flex">
+ <div class="bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Runbook') }}:
+ </div>
+ <div class="gl-pl-2" data-testid="runbook">{{ alert.runbook }}</div>
+ </div>
<template>
<div v-if="alert.notes.nodes" class="issuable-discussion py-5">
<ul class="notes main-notes-list timeline">
@@ -316,7 +338,7 @@ export default {
</div>
</template>
</gl-tab>
- <gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle">
+ <gl-tab :data-testid="$options.tabsConfig[1].id" :title="$options.tabsConfig[1].title">
<gl-table
class="alert-management-details-table"
:items="[{ key: 'Value', ...alert }]"
@@ -332,7 +354,7 @@ export default {
</template>
</gl-table>
</gl-tab>
- <gl-tab data-testId="metricsTab" :title="$options.i18n.metricsTitle">
+ <gl-tab :data-testid="$options.tabsConfig[2].id" :title="$options.tabsConfig[2].title">
<alert-metrics :dashboard-url="alert.metricsDashboardUrl" />
</gl-tab>
</gl-tabs>
diff --git a/app/assets/javascripts/alert_management/components/alert_management_empty_state.vue b/app/assets/javascripts/alert_management/components/alert_management_empty_state.vue
index 13b6a8e6653..68443166f40 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_empty_state.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_empty_state.vue
@@ -1,6 +1,7 @@
<script>
-import { GlEmptyState, GlButton } from '@gitlab/ui';
+import { GlEmptyState, GlButton, GlLink } from '@gitlab/ui';
import { s__ } from '~/locale';
+import alertsHelpUrlQuery from '../graphql/queries/alert_help_url.query.graphql';
export default {
i18n: {
@@ -25,6 +26,12 @@ export default {
components: {
GlEmptyState,
GlButton,
+ GlLink,
+ },
+ apollo: {
+ alertsHelpUrl: {
+ query: alertsHelpUrlQuery,
+ },
},
props: {
enableAlertManagementPath: {
@@ -50,6 +57,11 @@ export default {
default: '',
},
},
+ data() {
+ return {
+ alertsHelpUrl: '',
+ };
+ },
computed: {
emptyState() {
return {
@@ -71,13 +83,9 @@ export default {
<template #description>
<div class="gl-display-block">
<span>{{ emptyState.info }}</span>
- <a
- v-if="!opsgenieMvcEnabled"
- href="/help/user/project/operations/alert_management.html"
- target="_blank"
- >
+ <gl-link v-if="!opsgenieMvcEnabled" :href="alertsHelpUrl" target="_blank">
{{ $options.i18n.moreInformation }}
- </a>
+ </gl-link>
</div>
<div v-if="alertsCanBeEnabled" class="gl-display-block center gl-pt-4">
<gl-button category="primary" variant="success" :href="emptyState.link">
diff --git a/app/assets/javascripts/alert_management/components/alert_management_table.vue b/app/assets/javascripts/alert_management/components/alert_management_table.vue
index 7dd3d7b5dc3..92fd85c6217 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_table.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_table.vue
@@ -12,8 +12,8 @@ import {
GlSearchBoxByType,
GlSprintf,
} from '@gitlab/ui';
-import { __, s__ } from '~/locale';
import { debounce, trim } from 'lodash';
+import { __, s__ } from '~/locale';
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
import { fetchPolicies } from '~/lib/graphql';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
@@ -60,15 +60,15 @@ export default {
{
key: 'severity',
label: s__('AlertManagement|Severity'),
- tdClass: `${tdClass} rounded-top text-capitalize`,
thClass: `${thClass} gl-w-eighth`,
+ tdClass: `${tdClass} rounded-top text-capitalize sortable-cell`,
sortable: true,
},
{
key: 'startedAt',
label: s__('AlertManagement|Start time'),
thClass: `${thClass} js-started-at w-15p`,
- tdClass,
+ tdClass: `${tdClass} sortable-cell`,
sortable: true,
},
{
@@ -81,7 +81,7 @@ export default {
key: 'eventCount',
label: s__('AlertManagement|Events'),
thClass: `${thClass} text-right gl-w-12`,
- tdClass: `${tdClass} text-md-right`,
+ tdClass: `${tdClass} text-md-right sortable-cell`,
sortable: true,
},
{
@@ -89,7 +89,6 @@ export default {
label: s__('AlertManagement|Issue'),
thClass: 'gl-w-12 gl-pointer-events-none',
tdClass,
- sortable: false,
},
{
key: 'assignees',
@@ -99,9 +98,9 @@ export default {
},
{
key: 'status',
- thClass: `${thClass} w-15p`,
label: s__('AlertManagement|Status'),
- tdClass: `${tdClass} rounded-bottom`,
+ thClass: `${thClass} w-15p`,
+ tdClass: `${tdClass} rounded-bottom sortable-cell`,
sortable: true,
},
],
@@ -169,7 +168,7 @@ export default {
};
},
error() {
- this.errored = true;
+ this.hasError = true;
},
},
alertsCount: {
@@ -188,10 +187,9 @@ export default {
data() {
return {
searchTerm: '',
- errored: false,
+ hasError: false,
errorMessage: '',
isAlertDismissed: false,
- isErrorAlertDismissed: false,
sort: 'STARTED_AT_DESC',
statusFilter: [],
filteredByStatus: '',
@@ -204,16 +202,13 @@ export default {
computed: {
showNoAlertsMsg() {
return (
- !this.errored &&
+ !this.hasError &&
!this.loading &&
this.alertsCount?.all === 0 &&
!this.searchTerm &&
!this.isAlertDismissed
);
},
- showErrorMsg() {
- return this.errored && !this.isErrorAlertDismissed;
- },
loading() {
return this.$apollo.queries.alerts.loading;
},
@@ -307,11 +302,11 @@ export default {
};
},
handleAlertError(errorMessage) {
- this.errored = true;
+ this.hasError = true;
this.errorMessage = errorMessage;
},
dismissError() {
- this.isErrorAlertDismissed = true;
+ this.hasError = false;
this.errorMessage = '';
},
},
@@ -319,7 +314,7 @@ export default {
</script>
<template>
<div>
- <div class="alert-management-list">
+ <div class="incident-management-list">
<gl-alert v-if="showNoAlertsMsg" @dismiss="isAlertDismissed = true">
<gl-sprintf :message="$options.i18n.noAlertsMsg">
<template #link="{ content }">
@@ -333,16 +328,14 @@ export default {
</template>
</gl-sprintf>
</gl-alert>
- <gl-alert
- v-if="showErrorMsg"
- variant="danger"
- data-testid="alert-error"
- @dismiss="dismissError"
- >
+ <gl-alert v-if="hasError" variant="danger" data-testid="alert-error" @dismiss="dismissError">
<p v-html="errorMessage || $options.i18n.errorMsg"></p>
</gl-alert>
- <gl-tabs content-class="gl-p-0" @input="filterAlertsByStatus">
+ <gl-tabs
+ content-class="gl-p-0 gl-border-b-solid gl-border-b-1 gl-border-gray-100"
+ @input="filterAlertsByStatus"
+ >
<gl-tab v-for="tab in $options.statusTabs" :key="tab.status">
<template slot="title">
<span>{{ tab.title }}</span>
diff --git a/app/assets/javascripts/alert_management/components/alert_status.vue b/app/assets/javascripts/alert_management/components/alert_status.vue
index 9b726fe2944..8531ca1374e 100644
--- a/app/assets/javascripts/alert_management/components/alert_status.vue
+++ b/app/assets/javascripts/alert_management/components/alert_status.vue
@@ -1,5 +1,5 @@
<script>
-import { GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui';
+import { GlDeprecatedDropdown, GlDeprecatedDropdownItem, GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import { trackAlertStatusUpdateOptions } from '../constants';
@@ -18,8 +18,8 @@ export default {
RESOLVED: s__('AlertManagement|Resolved'),
},
components: {
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
GlButton,
},
props: {
@@ -91,7 +91,7 @@ export default {
<template>
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
- <gl-dropdown
+ <gl-deprecated-dropdown
ref="dropdown"
right
:text="$options.statuses[alert.status]"
@@ -112,7 +112,7 @@ export default {
/>
</div>
<div class="dropdown-content dropdown-body">
- <gl-dropdown-item
+ <gl-deprecated-dropdown-item
v-for="(label, field) in $options.statuses"
:key="field"
data-testid="statusDropdownItem"
@@ -122,8 +122,8 @@ export default {
@click="updateAlertStatus(label)"
>
{{ label }}
- </gl-dropdown-item>
+ </gl-deprecated-dropdown-item>
</div>
- </gl-dropdown>
+ </gl-deprecated-dropdown>
</div>
</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue
index df07038151e..0a1478ef5fe 100644
--- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignee.vue
@@ -1,9 +1,9 @@
<script>
-import { GlDropdownItem } from '@gitlab/ui';
+import { GlDeprecatedDropdownItem } from '@gitlab/ui';
export default {
components: {
- GlDropdownItem,
+ GlDeprecatedDropdownItem,
},
props: {
user: {
@@ -24,7 +24,7 @@ export default {
</script>
<template>
- <gl-dropdown-item
+ <gl-deprecated-dropdown-item
:key="user.username"
data-testid="assigneeDropdownItem"
class="assignee-dropdown-item gl-vertical-align-middle"
@@ -47,5 +47,5 @@ export default {
</strong>
<span class="dropdown-menu-user-username"> {{ user.username }}</span>
</span>
- </gl-dropdown-item>
+ </gl-deprecated-dropdown-item>
</template>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue
index cb32a5ffd4f..4af5c83b30c 100644
--- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_assignees.vue
@@ -1,20 +1,20 @@
<script>
import {
GlIcon,
- GlDropdown,
- GlDropdownDivider,
- GlDropdownHeader,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownDivider,
+ GlDeprecatedDropdownHeader,
+ GlDeprecatedDropdownItem,
GlLoadingIcon,
GlTooltip,
GlButton,
GlSprintf,
} from '@gitlab/ui';
+import { debounce } from 'lodash';
import axios from '~/lib/utils/axios_utils';
import { s__, __ } from '~/locale';
import alertSetAssignees from '../../graphql/mutations/alert_set_assignees.mutation.graphql';
import SidebarAssignee from './sidebar_assignee.vue';
-import { debounce } from 'lodash';
const DATA_REFETCH_DELAY = 250;
@@ -33,10 +33,10 @@ export default {
},
components: {
GlIcon,
- GlDropdown,
- GlDropdownItem,
- GlDropdownDivider,
- GlDropdownHeader,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
+ GlDeprecatedDropdownDivider,
+ GlDeprecatedDropdownHeader,
GlLoadingIcon,
GlTooltip,
GlButton,
@@ -213,7 +213,7 @@ export default {
</p>
<div class="dropdown dropdown-menu-selectable" :class="dropdownClass">
- <gl-dropdown
+ <gl-deprecated-dropdown
ref="dropdown"
:text="assignedUser"
class="w-100"
@@ -243,18 +243,18 @@ export default {
</div>
<div class="dropdown-content dropdown-body">
<template v-if="userListValid">
- <gl-dropdown-item
+ <gl-deprecated-dropdown-item
:active="!userName"
active-class="is-active"
@click="updateAlertAssignees('')"
>
{{ __('Unassigned') }}
- </gl-dropdown-item>
- <gl-dropdown-divider />
+ </gl-deprecated-dropdown-item>
+ <gl-deprecated-dropdown-divider />
- <gl-dropdown-header class="mt-0">
+ <gl-deprecated-dropdown-header class="mt-0">
{{ __('Assignee') }}
- </gl-dropdown-header>
+ </gl-deprecated-dropdown-header>
<sidebar-assignee
v-for="user in sortedUsers"
:key="user.username"
@@ -263,17 +263,17 @@ export default {
@update-alert-assignees="updateAlertAssignees"
/>
</template>
- <gl-dropdown-item v-else-if="userListEmpty">
+ <gl-deprecated-dropdown-item v-else-if="userListEmpty">
{{ __('No Matching Results') }}
- </gl-dropdown-item>
+ </gl-deprecated-dropdown-item>
<gl-loading-icon v-else />
</div>
- </gl-dropdown>
+ </gl-deprecated-dropdown>
</div>
<gl-loading-icon v-if="isUpdating" :inline="true" />
<p v-else-if="!isDropdownShowing" class="value gl-m-0" :class="{ 'no-value': !userName }">
- <span v-if="userName" class="gl-text-gray-700" data-testid="assigned-users">{{
+ <span v-if="userName" class="gl-text-gray-500" data-testid="assigned-users">{{
assignedUser
}}</span>
<span v-else class="gl-display-flex gl-align-items-center">
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue
index fd40b5d9f65..70902a204f8 100644
--- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_header.vue
@@ -27,7 +27,7 @@ export default {
<template>
<div class="block gl-display-flex gl-justify-content-space-between">
<span class="issuable-header-text hide-collapsed">
- {{ __('To Do') }}
+ {{ __('To-Do') }}
</span>
<sidebar-todo
v-if="!sidebarCollapsed"
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue
index 44a81aba828..0a2bad5510b 100644
--- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_status.vue
@@ -107,7 +107,7 @@ export default {
>
<span
v-if="$options.statuses[alert.status]"
- class="gl-text-gray-700"
+ class="gl-text-gray-500"
data-testid="status"
>{{ $options.statuses[alert.status] }}</span
>
diff --git a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue
index 7d3135ad50d..5bd69a1f0ec 100644
--- a/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue
+++ b/app/assets/javascripts/alert_management/components/sidebar/sidebar_todo.vue
@@ -1,13 +1,14 @@
<script>
import { s__ } from '~/locale';
import Todo from '~/sidebar/components/todo_toggle/todo.vue';
-import axios from '~/lib/utils/axios_utils';
-import createAlertTodo from '../../graphql/mutations/alert_todo_create.graphql';
+import createAlertTodo from '../../graphql/mutations/alert_todo_create.mutation.graphql';
+import todoMarkDone from '../../graphql/mutations/alert_todo_mark_done.mutation.graphql';
+import alertQuery from '../../graphql/queries/details.query.graphql';
export default {
i18n: {
UPDATE_ALERT_TODO_ERROR: s__(
- 'AlertManagement|There was an error while updating the To Do of the alert.',
+ 'AlertManagement|There was an error while updating the To-Do of the alert.',
),
},
components: {
@@ -30,14 +31,24 @@ export default {
data() {
return {
isUpdating: false,
- isTodo: false,
- todo: '',
};
},
computed: {
alertID() {
return parseInt(this.alert.iid, 10);
},
+ firstToDoId() {
+ return this.alert?.todos?.nodes[0]?.id;
+ },
+ hasPendingTodos() {
+ return this.alert?.todos?.nodes.length > 0;
+ },
+ getAlertQueryVariables() {
+ return {
+ fullPath: this.projectPath,
+ alertId: this.alert.iid,
+ };
+ },
},
methods: {
updateToDoCount(add) {
@@ -51,11 +62,7 @@ export default {
return document.dispatchEvent(headerTodoEvent);
},
- toggleTodo() {
- if (this.todo) {
- return this.markAsDone();
- }
-
+ addToDo() {
this.isUpdating = true;
return this.$apollo
.mutate({
@@ -65,24 +72,14 @@ export default {
projectPath: this.projectPath,
},
})
- .then(({ data: { alertTodoCreate: { todo = {}, errors = [] } } = {} } = {}) => {
+ .then(({ data: { errors = [] } }) => {
if (errors[0]) {
- return this.$emit(
- 'alert-error',
- `${this.$options.i18n.UPDATE_ALERT_TODO_ERROR} ${errors[0]}.`,
- );
+ return this.throwError(errors[0]);
}
-
- this.todo = todo.id;
return this.updateToDoCount(true);
})
.catch(() => {
- this.$emit(
- 'alert-error',
- `${this.$options.i18n.UPDATE_ALERT_TODO_ERROR} ${s__(
- 'AlertManagement|Please try again.',
- )}`,
- );
+ this.throwError();
})
.finally(() => {
this.isUpdating = false;
@@ -90,20 +87,45 @@ export default {
},
markAsDone() {
this.isUpdating = true;
-
- return axios
- .delete(`/dashboard/todos/${this.todo.split('/').pop()}`)
- .then(() => {
- this.todo = '';
+ return this.$apollo
+ .mutate({
+ mutation: todoMarkDone,
+ variables: {
+ id: this.firstToDoId,
+ },
+ update: this.updateCache,
+ })
+ .then(({ data: { errors = [] } }) => {
+ if (errors[0]) {
+ return this.throwError(errors[0]);
+ }
return this.updateToDoCount(false);
})
.catch(() => {
- this.$emit('alert-error', this.$options.i18n.UPDATE_ALERT_TODO_ERROR);
+ this.throwError();
})
.finally(() => {
this.isUpdating = false;
});
},
+ updateCache(store) {
+ const data = store.readQuery({
+ query: alertQuery,
+ variables: this.getAlertQueryVariables,
+ });
+
+ data.project.alertManagementAlerts.nodes[0].todos.nodes.shift();
+
+ store.writeQuery({
+ query: alertQuery,
+ variables: this.getAlertQueryVariables,
+ data,
+ });
+ },
+ throwError(err = '') {
+ const error = err || s__('AlertManagement|Please try again.');
+ this.$emit('alert-error', `${this.$options.i18n.UPDATE_ALERT_TODO_ERROR} ${error}`);
+ },
},
};
</script>
@@ -114,10 +136,10 @@ export default {
data-testid="alert-todo-button"
:collapsed="sidebarCollapsed"
:issuable-id="alertID"
- :is-todo="todo !== ''"
+ :is-todo="hasPendingTodos"
:is-action-active="isUpdating"
issuable-type="alert"
- @toggleTodo="toggleTodo"
+ @toggleTodo="hasPendingTodos ? markAsDone() : addToDo()"
/>
</div>
</template>
diff --git a/app/assets/javascripts/alert_management/details.js b/app/assets/javascripts/alert_management/details.js
index 2820bcb9665..dccf990f0b4 100644
--- a/app/assets/javascripts/alert_management/details.js
+++ b/app/assets/javascripts/alert_management/details.js
@@ -1,7 +1,8 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import createDefaultClient from '~/lib/graphql';
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import createDefaultClient from '~/lib/graphql';
+import createRouter from './router';
import AlertDetails from './components/alert_details.vue';
import sidebarStatusQuery from './graphql/queries/sidebar_status.query.graphql';
@@ -10,6 +11,7 @@ Vue.use(VueApollo);
export default selector => {
const domEl = document.querySelector(selector);
const { alertId, projectPath, projectIssuesPath, projectId } = domEl.dataset;
+ const router = createRouter();
const resolvers = {
Mutation: {
@@ -54,6 +56,7 @@ export default selector => {
components: {
AlertDetails,
},
+ router,
render(createElement) {
return createElement('alert-details', {});
},
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
index 18fab429164..0712ff12c23 100644
--- a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
+++ b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
@@ -11,6 +11,12 @@ fragment AlertDetailItem on AlertManagementAlert {
updatedAt
endedAt
details
+ runbook
+ todos {
+ nodes {
+ id
+ }
+ }
notes {
nodes {
...AlertNote
diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.graphql
deleted file mode 100644
index cdf3d763302..00000000000
--- a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.graphql
+++ /dev/null
@@ -1,11 +0,0 @@
-mutation($projectPath: ID!, $iid: String!) {
- alertTodoCreate(input: { iid: $iid, projectPath: $projectPath }) {
- errors
- alert {
- iid
- }
- todo {
- id
- }
- }
-}
diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql
new file mode 100644
index 00000000000..ac9858c104f
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_create.mutation.graphql
@@ -0,0 +1,10 @@
+#import "../fragments/detail_item.fragment.graphql"
+
+mutation alertTodoCreate($projectPath: ID!, $iid: String!) {
+ alertTodoCreate(input: { iid: $iid, projectPath: $projectPath }) {
+ errors
+ alert {
+ ...AlertDetailItem
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_mark_done.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_mark_done.mutation.graphql
new file mode 100644
index 00000000000..4d59b4d94cd
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/mutations/alert_todo_mark_done.mutation.graphql
@@ -0,0 +1,8 @@
+mutation todoMarkDone($id: ID!) {
+ todoMarkDone(input: { id: $id }) {
+ errors
+ todo {
+ id
+ }
+ }
+}
diff --git a/app/assets/javascripts/alert_management/graphql/queries/alert_help_url.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/alert_help_url.query.graphql
new file mode 100644
index 00000000000..05a8bc7c736
--- /dev/null
+++ b/app/assets/javascripts/alert_management/graphql/queries/alert_help_url.query.graphql
@@ -0,0 +1,3 @@
+query alertsHelpUrl {
+ alertsHelpUrl @client
+}
diff --git a/app/assets/javascripts/alert_management/list.js b/app/assets/javascripts/alert_management/list.js
index 3f78ca66a59..e180ab5f7e3 100644
--- a/app/assets/javascripts/alert_management/list.js
+++ b/app/assets/javascripts/alert_management/list.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import createDefaultClient from '~/lib/graphql';
import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import AlertManagementList from './components/alert_management_list_wrapper.vue';
@@ -16,6 +16,7 @@ export default () => {
enableAlertManagementPath,
emptyAlertSvgPath,
populatingAlertsHelpUrl,
+ alertsHelpUrl,
opsgenieMvcTargetUrl,
} = domEl.dataset;
let { alertManagementEnabled, userCanEnableAlertManagement, opsgenieMvcEnabled } = domEl.dataset;
@@ -41,6 +42,12 @@ export default () => {
),
});
+ apolloProvider.clients.defaultClient.cache.writeData({
+ data: {
+ alertsHelpUrl,
+ },
+ });
+
return new Vue({
el: selector,
apolloProvider,
diff --git a/app/assets/javascripts/alert_management/router.js b/app/assets/javascripts/alert_management/router.js
new file mode 100644
index 00000000000..5687fe4e0f5
--- /dev/null
+++ b/app/assets/javascripts/alert_management/router.js
@@ -0,0 +1,13 @@
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import { joinPaths } from '~/lib/utils/url_utility';
+
+Vue.use(VueRouter);
+
+export default function createRouter(base) {
+ return new VueRouter({
+ mode: 'hash',
+ base: joinPaths(gon.relative_url_root || '', base),
+ routes: [{ path: '/:tabId', name: 'tab' }],
+ });
+}