Commit 69b8670e authored by Rajat Jain's avatar Rajat Jain

Add health status in issuable list

Adds health status in the issuable list
parent 025aeb49
......@@ -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) {
......
......@@ -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
......@@ -21,6 +21,7 @@ module API
issue.assignees.first
end
expose(:health_status) { |issue, options| issue.health_status }
expose(:user_notes_count) { |issue, options| issuable_metadata.user_notes_count }
expose(:merge_requests_count) { |issue, options| issuable_metadata.merge_requests_count }
expose(:upvotes) { |issue, options| issuable_metadata.upvotes }
......
......@@ -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,17 @@ describe('Issuable component', () => {
});
});
});
describe('with health status', () => {
it('renders', () => {
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