Commit f5dd3a30 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '218330-issue-list-health-status' into 'master'

Add health status in issuable list

Closes #218330

See merge request gitlab-org/gitlab!38040
parents d596b260 217734c3
......@@ -23,6 +23,8 @@ import IssueAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
import { isScopedLabel } from '~/lib/utils/common_utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { convertToCamelCase } from '~/lib/utils/text_utility';
export default {
i18n: {
openedAgo: __('opened %{timeAgoString} by %{user}'),
......@@ -34,6 +36,8 @@ export default {
GlLabel,
GlIcon,
GlSprintf,
IssueHealthStatus: () =>
import('ee_component/related_items_tree/components/issue_health_status.vue'),
},
directives: {
GlTooltip,
......@@ -195,6 +199,9 @@ export default {
},
];
},
healthStatus() {
return convertToCamelCase(this.issuable.health_status);
},
},
mounted() {
// TODO: Refactor user popover to use its own component instead of
......@@ -288,7 +295,7 @@ export default {
</div>
<div class="issuable-info">
<span class="js-ref-path">
<span class="js-ref-path gl-mr-4 mr-sm-0">
<span
v-if="isJiraIssue"
class="svg-container jira-logo-container"
......@@ -298,7 +305,7 @@ export default {
{{ referencePath }}
</span>
<span data-testid="openedByMessage" class="gl-display-none d-sm-inline-block gl-mr-2">
<span data-testid="openedByMessage" class="gl-display-none d-sm-inline-block gl-mr-4">
&middot;
<gl-sprintf
:message="isJiraIssue ? $options.i18n.openedAgoJira : $options.i18n.openedAgo"
......@@ -321,7 +328,7 @@ export default {
<gl-link
v-if="issuable.milestone"
v-gl-tooltip
class="gl-display-none d-sm-inline-block gl-mr-2 js-milestone"
class="gl-display-none d-sm-inline-block gl-mr-4 js-milestone milestone"
:href="milestoneLink"
:title="milestoneTooltipText"
>
......@@ -332,7 +339,7 @@ export default {
<span
v-if="dueDate"
v-gl-tooltip
class="gl-display-none d-sm-inline-block gl-mr-2 js-due-date"
class="gl-display-none d-sm-inline-block gl-mr-4 js-due-date"
:class="{ cred: isOverdue }"
:title="__('Due date')"
>
......@@ -340,6 +347,24 @@ export default {
{{ dueDateWords }}
</span>
<span
v-if="hasWeight"
v-gl-tooltip
:title="__('Weight')"
class="gl-display-none d-sm-inline-block gl-mr-4"
data-testid="weight"
data-qa-selector="issuable_weight_content"
>
<gl-icon name="weight" class="align-text-bottom" />
{{ issuable.weight }}
</span>
<issue-health-status
v-if="issuable.health_status"
:health-status="healthStatus"
class="gl-mr-4 issuable-tag-valign"
/>
<gl-label
v-for="label in issuable.labels"
:key="label.id"
......@@ -351,21 +376,9 @@ export default {
:title="label.name"
:scoped="isScoped(label)"
size="sm"
class="gl-mr-2"
class="gl-mr-2 issuable-tag-valign"
>{{ label.name }}</gl-label
>
<span
v-if="hasWeight"
v-gl-tooltip
:title="__('Weight')"
class="gl-display-none d-sm-inline-block"
data-testid="weight"
data-qa-selector="issuable_weight_content"
>
<gl-icon name="weight" class="align-text-bottom" />
{{ issuable.weight }}
</span>
</div>
</div>
......
......@@ -81,27 +81,6 @@ $item-remove-button-space: 42px;
max-width: 0;
}
.status {
&-at-risk {
color: $red-500;
background-color: $red-100;
}
&-needs-attention {
color: $orange-700;
background-color: $orange-100;
}
&-on-track {
color: $green-600;
background-color: $green-100;
}
}
.gl-label-text {
font-weight: $gl-font-weight-bold;
}
.bullet-separator {
font-size: 9px;
color: $gray-200;
......
......@@ -804,6 +804,10 @@
}
}
}
.milestone {
color: $gray-700;
}
}
@media(max-width: map-get($grid-breakpoints, lg)-1) {
......
......@@ -179,6 +179,20 @@ the `weight` parameter:
]
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also see
the `health_status` parameter:
```json
[
{
"state" : "opened",
"description" : "Ratione dolores corrupti mollitia soluta quia.",
"health_status": "on_track",
...
}
]
```
**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
......@@ -338,6 +352,20 @@ the `weight` parameter:
]
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also see
the `health_status` parameter:
```json
[
{
"project_id" : 4,
"description" : "Omnis vero earum sunt corporis dolor et placeat.",
"health_status": "at_risk",
...
}
]
```
**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
......@@ -503,6 +531,20 @@ the `weight` parameter:
]
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also see
the `health_status` parameter:
```json
[
{
"project_id" : 4,
"description" : "Omnis vero earum sunt corporis dolor et placeat.",
"health_status": "at_risk",
...
}
]
```
**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
......@@ -642,6 +684,20 @@ the `epic` property:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also additionally see
the `health_status` property:
```json
[
{
"project_id" : 4,
"description" : "Omnis vero earum sunt corporis dolor et placeat.",
"health_status": "on_track",
...
}
]
```
**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
......@@ -752,6 +808,20 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also see
the `health_status` parameter:
```json
[
{
"project_id" : 4,
"description" : "Omnis vero earum sunt corporis dolor et placeat.",
"health_status": "on_track",
...
}
]
```
**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
......@@ -874,6 +944,20 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also see
the `health_status` parameter:
```json
[
{
"project_id" : 4,
"description" : "Omnis vero earum sunt corporis dolor et placeat.",
"health_status": "on_track",
...
}
]
```
NOTE: **Note:**
At least one of following parameters is required to be passed for the request to be successful: `:assignee_id`, `:assignee_ids`, `:confidential`, `:created_at`, `:description`, `:discussion_locked`, `:due_date`, `:labels`, `:milestone_id`, `:state_event`, or `:title`.
......@@ -1027,6 +1111,20 @@ the `weight` parameter:
}
```
Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will also see
the `health_status` parameter:
```json
[
{
"project_id" : 4,
"description" : "Omnis vero earum sunt corporis dolor et placeat.",
"health_status": "on_track",
...
}
]
```
**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
**Note**: The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
......
......@@ -50,11 +50,11 @@ export default {
{{ healthStatus.issuesOnTrack }}
</span>
</span>
<span class="gl-mr-2 mr-md-2 gl-text-gray-700 health-label-long gl-display-none">
<span class="gl-mr-2 mr-md-2 gl-text-gray-700 health-label-long gl-display-none!">
{{ __('issues on track') }}
</span>
<span
class="gl-mr-2 mr-md-2 gl-text-gray-700 gl-str-truncated health-label-short gl-display-none"
class="gl-mr-2 mr-md-2 gl-text-gray-700 gl-str-truncated health-label-short gl-display-none!"
>{{ __('on track') }}</span
>
......@@ -63,11 +63,11 @@ export default {
{{ healthStatus.issuesNeedingAttention }}
</span>
</span>
<span class="gl-mr-2 mr-md-2 gl-text-gray-700 health-label-long gl-display-none">
<span class="gl-mr-2 mr-md-2 gl-text-gray-700 health-label-long gl-display-none!">
{{ __('issues need attention') }}
</span>
<span
class="gl-mr-2 mr-md-2 gl-text-gray-700 gl-str-truncated health-label-short gl-display-none"
class="gl-mr-2 mr-md-2 gl-text-gray-700 gl-str-truncated health-label-short gl-display-none!"
>{{ __('need attention') }}</span
>
......@@ -76,10 +76,10 @@ export default {
{{ healthStatus.issuesAtRisk }}
</span>
</span>
<span class="gl-text-gray-700 health-label-long gl-display-none">
<span class="gl-text-gray-700 health-label-long gl-display-none!">
{{ __('issues at risk') }}
</span>
<span class="gl-text-gray-700 gl-str-truncated health-label-short gl-display-none">
<span class="gl-text-gray-700 gl-str-truncated health-label-short gl-display-none!">
{{ __('at risk') }}
</span>
</div>
......
......@@ -199,7 +199,7 @@ export default {
<div
class="item-meta gl-display-flex gl-flex-wrap mt-xl-0 flex-xl-nowrap gl-align-items-center gl-py-2 gl-ml-6"
>
<span class="gl-mr-4">{{ itemHierarchy }}</span>
<span class="gl-mr-5">{{ itemHierarchy }}</span>
<gl-tooltip v-if="isEpic" :target="() => $refs.countBadge">
<p v-if="allowSubEpics" class="gl-font-weight-bold gl-m-0">
{{ __('Epics') }} &#8226;
......@@ -232,15 +232,12 @@ export default {
>
<span
v-if="allowSubEpics"
class="gl-display-inline-flex gl-align-items-center gl-mr-3"
class="gl-display-inline-flex gl-align-items-center gl-mr-5"
>
<gl-icon name="epic" class="gl-mr-2" />
{{ totalEpicsCount }}
</span>
<span
class="gl-display-inline-flex gl-align-items-center gl-mr-3"
:class="{ 'ml-2': allowSubEpics }"
>
<span class="gl-display-inline-flex gl-align-items-center gl-mr-5">
<gl-icon name="issues" class="gl-mr-2" />
{{ totalIssuesCount }}
</span>
......@@ -249,38 +246,40 @@ export default {
<item-milestone
v-if="hasMilestone"
:milestone="item.milestone"
class="item-milestone gl-display-flex gl-align-items-center gl-mr-4"
class="item-milestone gl-display-flex gl-align-items-center gl-mr-5"
/>
<item-due-date
v-if="item.dueDate"
:date="item.dueDate"
tooltip-placement="top"
css-class="item-due-date gl-display-flex gl-align-items-center gl-mr-4"
css-class="item-due-date gl-display-flex gl-align-items-center gl-mr-5!"
/>
<item-weight
v-if="item.weight"
:weight="item.weight"
class="item-weight gl-display-flex gl-align-items-center gl-mr-4"
class="item-weight gl-display-flex gl-align-items-center gl-mr-5!"
tag-name="span"
/>
<item-assignees
v-if="hasAssignees"
:assignees="item.assignees"
class="item-assignees gl-display-inline-flex gl-align-items-center gl-mr-4 mb-md-0 flex-xl-grow-0"
class="item-assignees gl-display-inline-flex gl-align-items-center gl-mr-5 mb-md-0 flex-xl-grow-0"
/>
<epic-health-status
v-if="showEpicHealthStatus"
:health-status="item.healthStatus"
data-testid="epic-health-status"
class="issuable-tag-valign"
/>
<issue-health-status
v-if="showIssueHealthStatus"
:health-status="item.healthStatus"
data-testid="issue-health-status"
class="issuable-tag-valign"
/>
</div>
</div>
......
......@@ -95,3 +95,32 @@
display: none;
}
}
.health-status {
line-height: $gl-line-height;
.status {
&-at-risk {
color: $red-500;
background-color: $red-100;
}
&-needs-attention {
color: $orange-700;
background-color: $orange-100;
}
&-on-track {
color: $green-600;
background-color: $green-100;
}
}
.gl-label-text {
font-weight: $gl-font-weight-bold;
}
}
.issuable-tag-valign {
vertical-align: 1px;
}
---
title: Add health status in issuable list
merge_request: 38040
author:
type: added
......@@ -20,6 +20,10 @@ module EE
issue.epic if ::Ability.allowed?(options[:current_user], :read_epic, issue.epic)
end
end
with_options if: -> (issue) { issue.project.feature_available?(:issuable_health_status) } do
expose :health_status
end
end
end
end
......
......@@ -16,6 +16,9 @@
"title": { "type": "string" },
"url": { "type": "string" }
}
},
"health_status": {
"type": ["string", "null"]
}
}
}
......
......@@ -99,6 +99,7 @@ describe('Issuable component', () => {
const findIssuableTitle = () => wrapper.find('[data-testid="issuable-title"]');
const findIssuableStatus = () => wrapper.find('[data-testid="issuable-status"]');
const containsJiraLogo = () => wrapper.contains('[data-testid="jira-logo"]');
const findHealthStatus = () => wrapper.find('.health-status');
describe('when mounted', () => {
it('initializes user popovers', () => {
......@@ -474,4 +475,19 @@ describe('Issuable component', () => {
});
});
});
if (IS_EE) {
describe('with health status', () => {
it('renders health status tag', () => {
factory({ issuable });
expect(findHealthStatus().exists()).toBe(true);
});
it('does not render when health status is absent', () => {
issuable.health_status = null;
factory({ issuable });
expect(findHealthStatus().exists()).toBe(false);
});
});
}
});
......@@ -30,6 +30,7 @@ export const simpleIssue = {
references: {
relative: 'html-boilerplate#45',
},
health_status: 'on_track',
};
export const testLabels = [
......
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