Commit a4fcb2d9 authored by David O'Regan's avatar David O'Regan Committed by Mayra Cabrera

Add published column

Add published column to
the incident list which
show if the incident is
published to the status page
parent b4665a80
......@@ -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,12 @@ 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>
......
......@@ -5,7 +5,8 @@ export const I18N = {
noIncidents: s__('IncidentManagement|No incidents to display.'),
unassigned: s__('IncidentManagement|Unassigned'),
createIncidentBtnLabel: s__('IncidentManagement|Create incident'),
searchPlaceholder: __('Search or filter results...'),
unPublished: s__('IncidentManagement|Unpublished'),
searchPlaceholder: __('Search results...'),
};
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: $green-500;
}
}
......@@ -10,3 +10,5 @@ module Projects::IncidentsHelper
}
end
end
Projects::IncidentsHelper.prepend_if_ee('EE::Projects::IncidentsHelper')
......@@ -4575,6 +4575,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
"""
......@@ -6208,6 +6213,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
"""
......
......@@ -12750,6 +12750,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",
......@@ -17106,6 +17120,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",
......@@ -759,6 +759,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 |
......@@ -925,6 +926,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>
......@@ -28,6 +28,9 @@ module EE
null: true,
description: 'Current health status. Returns null if `save_issuable_health_status` feature flag is disabled.',
resolve: -> (obj, _, _) { obj.supports_health_status? ? obj.health_status : nil }
field :status_page_published_incident, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates whether an issue is published to the status page'
end
end
end
......
# 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 published column
merge_request: 38439
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
......@@ -12779,12 +12779,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 ""
......@@ -20995,6 +21004,9 @@ msgstr ""
msgid "Search requirements"
msgstr ""
msgid "Search results..."
msgstr ""
msgid "Search users"
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