Commit 2d8b8494 authored by Vitali Tatarintev's avatar Vitali Tatarintev

Merge branch '229532-status-page-incidents' into 'master'

Add published column

See merge request gitlab-org/gitlab!37971
parents e1294e95 42ab722c
......@@ -72,11 +72,18 @@ export default {
GlPagination,
GlTabs,
GlTab,
PublishedCell: () => import('ee_component/incidents/components/published_cell.vue'),
},
directives: {
GlTooltip: GlTooltipDirective,
},
inject: ['projectPath', 'newIssuePath', 'incidentTemplateName', 'issuePath'],
inject: [
'projectPath',
'newIssuePath',
'incidentTemplateName',
'issuePath',
'publishedAvailable',
],
apollo: {
incidents: {
query: getIncidents,
......@@ -144,6 +151,20 @@ export default {
newIncidentPath() {
return mergeUrlParams({ issuable_template: this.incidentTemplateName }, this.newIssuePath);
},
availableFields() {
return this.publishedAvailable
? [
...this.$options.fields,
...[
{
key: 'published',
label: s__('IncidentManagement|Published'),
thClass: 'gl-pointer-events-none',
},
],
]
: this.$options.fields;
},
},
methods: {
onInputChange: debounce(function debounceSearch(input) {
......@@ -230,7 +251,7 @@ export default {
</h4>
<gl-table
:items="incidents.list || []"
:fields="$options.fields"
:fields="availableFields"
:show-empty="true"
:busy="loading"
stacked="md"
......@@ -245,7 +266,7 @@ export default {
<gl-icon
v-if="item.state === 'closed'"
name="issue-close"
class="gl-fill-blue-500"
class="gl-ml-1 gl-fill-blue-500"
data-testid="incident-closed"
/>
</div>
......@@ -285,6 +306,13 @@ export default {
</div>
</template>
<template v-if="publishedAvailable" #cell(published)="{ item }">
<published-cell
:status-page-published-incident="item.statusPagePublishedIncident"
:un-published="$options.i18n.unPublished"
/>
</template>
<template #table-busy>
<gl-loading-icon size="lg" color="dark" class="mt-3" />
</template>
......
......@@ -6,6 +6,7 @@ export const I18N = {
unassigned: s__('IncidentManagement|Unassigned'),
createIncidentBtnLabel: s__('IncidentManagement|Create incident'),
searchPlaceholder: __('Search or filter results...'),
unPublished: s__('IncidentManagement|Unpublished'),
};
export const INCIDENT_STATE_TABS = [
......
......@@ -37,6 +37,7 @@ query getIncidents(
webUrl
}
}
statusPagePublishedIncident
}
pageInfo {
hasNextPage
......
......@@ -8,7 +8,13 @@ export default () => {
const selector = '#js-incidents';
const domEl = document.querySelector(selector);
const { projectPath, newIssuePath, incidentTemplateName, issuePath } = domEl.dataset;
const {
projectPath,
newIssuePath,
incidentTemplateName,
issuePath,
publishedAvailable,
} = domEl.dataset;
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
......@@ -21,6 +27,7 @@ export default () => {
incidentTemplateName,
newIssuePath,
issuePath,
publishedAvailable,
},
apolloProvider,
components: {
......
......@@ -98,4 +98,9 @@
@include gl-w-full;
}
}
// TODO: Abstract to `@gitlab/ui` utility set: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/921
.gl-fill-green-500 {
fill: $gray-500;
}
}
......@@ -97,6 +97,9 @@ module Types
field :design_collection, Types::DesignManagement::DesignCollectionType, null: true,
description: 'Collection of design images associated with this issue'
field :status_page_published_incident, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates whether an issue is published to the status page'
end
end
......
......@@ -10,3 +10,5 @@ module Projects::IncidentsHelper
}
end
end
Projects::IncidentsHelper.prepend_if_ee('EE::Projects::IncidentsHelper')
......@@ -4470,6 +4470,11 @@ type EpicIssue implements Noteable {
"""
state: IssueState!
"""
Indicates whether an issue is published to the status page
"""
statusPagePublishedIncident: Boolean
"""
Indicates the currently logged in user is subscribed to the issue
"""
......@@ -6103,6 +6108,11 @@ type Issue implements Noteable {
"""
state: IssueState!
"""
Indicates whether an issue is published to the status page
"""
statusPagePublishedIncident: Boolean
"""
Indicates the currently logged in user is subscribed to the issue
"""
......
......@@ -12461,6 +12461,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "statusPagePublishedIncident",
"description": "Indicates whether an issue is published to the status page",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "subscribed",
"description": "Indicates the currently logged in user is subscribed to the issue",
......@@ -16817,6 +16831,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "statusPagePublishedIncident",
"description": "Indicates whether an issue is published to the status page",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "subscribed",
"description": "Indicates the currently logged in user is subscribed to the issue",
......@@ -750,6 +750,7 @@ Relationship between an epic and an issue
| `relationPath` | String | URI path of the epic-issue relation |
| `relativePosition` | Int | Relative position of the issue (used for positioning in epic tree and issue boards) |
| `state` | IssueState! | State of the issue |
| `statusPagePublishedIncident` | Boolean | Indicates whether an issue is published to the status page |
| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue |
| `taskCompletionStatus` | TaskCompletionStatus! | Task completion status of the issue |
| `timeEstimate` | Int! | Time estimate of the issue |
......@@ -916,6 +917,7 @@ Represents a Group Member
| `reference` | String! | Internal reference of the issue. Returned in shortened format by default |
| `relativePosition` | Int | Relative position of the issue (used for positioning in epic tree and issue boards) |
| `state` | IssueState! | State of the issue |
| `statusPagePublishedIncident` | Boolean | Indicates whether an issue is published to the status page |
| `subscribed` | Boolean! | Indicates the currently logged in user is subscribed to the issue |
| `taskCompletionStatus` | TaskCompletionStatus! | Task completion status of the issue |
| `timeEstimate` | Int! | Time estimate of the issue |
......
<script>
import { GlIcon } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
i18n: {
published: s__('IncidentManagement|Published to status page'),
},
components: {
GlIcon,
},
props: {
statusPagePublishedIncident: {
type: Boolean,
required: false,
default: null,
},
unPublished: {
type: String,
required: true,
},
},
};
</script>
<template>
<div data-testid="published-cell">
<gl-icon
v-if="statusPagePublishedIncident"
name="status_success"
class="gl-fill-green-500"
:aria-label="$options.i18n.published"
/>
<div v-else>{{ unPublished }}</div>
</div>
</template>
# frozen_string_literal: true
module EE
module Projects
module IncidentsHelper
extend ::Gitlab::Utils::Override
override :incidents_data
def incidents_data(project)
super.merge(
incidents_data_published_available(project)
)
end
private
def incidents_data_published_available(project)
return {} unless project.feature_available?(:status_page)
{
'published-available' => 'true'
}
end
end
end
end
---
title: Add status page published column for incidents
merge_request: 37971
author:
type: changed
import { shallowMount } from '@vue/test-utils';
import { GlIcon } from '@gitlab/ui';
import PublishedCell from 'ee/incidents/components/published_cell.vue';
describe('Incidents Published Cell', () => {
let wrapper;
const findCell = () => wrapper.find("[data-testid='published-cell']");
function mountComponent({
props = { statusPagePublishedIncident: null, unPublished: 'Unpublished' },
}) {
wrapper = shallowMount(PublishedCell, {
propsData: {
...props,
},
stubs: {
GlIcon: true,
},
});
}
afterEach(() => {
if (wrapper) {
wrapper.destroy();
wrapper = null;
}
});
describe('Published cell', () => {
beforeEach(() => {
mountComponent({});
});
it('render a cell with unpublished by default', () => {
expect(
findCell()
.find(GlIcon)
.exists(),
).toBe(false);
expect(findCell().text()).toBe('Unpublished');
});
it('render a status success icon if statusPagePublishedIncident returns true', () => {
wrapper.setProps({ statusPagePublishedIncident: true });
return wrapper.vm.$nextTick().then(() => {
expect(
findCell()
.find(GlIcon)
.exists(),
).toBe(true);
});
});
});
});
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::IncidentsHelper do
include Gitlab::Routing.url_helpers
let_it_be(:project) { create(:project) }
let(:project_path) { project.full_path }
let(:new_issue_path) { new_project_issue_path(project) }
let(:issue_path) { project_issues_path(project) }
describe '#incidents_data' do
let(:expected_incidents_data) do
{
'project-path' => project_path,
'new-issue-path' => new_issue_path,
'incident-template-name' => 'incident',
'issue-path' => issue_path
}
end
subject { helper.incidents_data(project) }
before do
allow(project).to receive(:feature_available?).with(:status_page).and_return(status_page_feature_available)
end
context 'when status page feature is available' do
let(:status_page_feature_available) { true }
it { is_expected.to eq(expected_incidents_data.merge('published-available' => 'true')) }
end
context 'when status page issue is not available' do
let(:status_page_feature_available) { false }
it { is_expected.to eq(expected_incidents_data) }
end
end
end
......@@ -12743,12 +12743,21 @@ msgstr ""
msgid "IncidentManagement|Open"
msgstr ""
msgid "IncidentManagement|Published"
msgstr ""
msgid "IncidentManagement|Published to status page"
msgstr ""
msgid "IncidentManagement|There was an error displaying the incidents."
msgstr ""
msgid "IncidentManagement|Unassigned"
msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
msgid "IncidentSettings|Alert integration"
msgstr ""
......
......@@ -56,6 +56,7 @@ describe('Incidents List', () => {
newIssuePath,
incidentTemplateName,
issuePath: '/project/isssues',
publishedAvailable: true,
},
stubs: {
GlButton: true,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment