Commit 6b0a97e8 authored by Coung Ngo's avatar Coung Ngo Committed by Nicolò Maria Mezzopera

Add locked and confidential badge to issue sticky header

The normal issue header shows locked and confidential badges
when the issue has those properties. This information is
missing from the sticky header which this commit adds.
parent 497143d0
...@@ -136,6 +136,16 @@ export default { ...@@ -136,6 +136,16 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
isConfidential: {
type: Boolean,
required: false,
default: false,
},
isLocked: {
type: Boolean,
required: false,
default: false,
},
issuableType: { issuableType: {
type: String, type: String,
required: false, required: false,
...@@ -453,6 +463,12 @@ export default { ...@@ -453,6 +463,12 @@ export default {
<gl-icon :name="statusIcon" class="gl-display-block d-sm-none gl-h-6!" /> <gl-icon :name="statusIcon" class="gl-display-block d-sm-none gl-h-6!" />
<span class="gl-display-none d-sm-block">{{ statusText }}</span> <span class="gl-display-none d-sm-block">{{ statusText }}</span>
</p> </p>
<span v-if="isLocked" data-testid="locked" class="issuable-warning-icon">
<gl-icon name="lock" :aria-label="__('Locked')" />
</span>
<span v-if="isConfidential" data-testid="confidential" class="issuable-warning-icon">
<gl-icon name="eye-slash" :aria-label="__('Confidential')" />
</span>
<p <p
class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0" class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0"
:title="state.titleText" :title="state.titleText"
......
...@@ -17,6 +17,8 @@ export function initIssuableApp(issuableData, store) { ...@@ -17,6 +17,8 @@ export function initIssuableApp(issuableData, store) {
return createElement(IssuableApp, { return createElement(IssuableApp, {
props: { props: {
...issuableData, ...issuableData,
isConfidential: this.getNoteableData?.confidential,
isLocked: this.getNoteableData?.discussion_locked,
issuableStatus: this.getNoteableData?.state, issuableStatus: this.getNoteableData?.state,
}, },
}); });
......
.issuable-warning-icon { .issuable-warning-icon {
background-color: $orange-50; background-color: $orange-50;
border-radius: $border-radius-default; border-radius: $border-radius-default;
color: $orange-600;
width: $issuable-warning-size; width: $issuable-warning-size;
height: $issuable-warning-size; height: $issuable-warning-size;
text-align: center; text-align: center;
margin-right: $issuable-warning-icon-margin; margin-right: $issuable-warning-icon-margin;
line-height: $gl-line-height-24; line-height: $gl-line-height-24;
.icon {
fill: $orange-600;
vertical-align: text-bottom;
}
} }
.limit-container-width { .limit-container-width {
......
---
title: Add locked and confidential badge to issue sticky header
merge_request: 46996
author:
type: added
...@@ -17,6 +17,7 @@ import { ...@@ -17,6 +17,7 @@ import {
import IncidentTabs from '~/issue_show/components/incidents/incident_tabs.vue'; import IncidentTabs from '~/issue_show/components/incidents/incident_tabs.vue';
import DescriptionComponent from '~/issue_show/components/description.vue'; import DescriptionComponent from '~/issue_show/components/description.vue';
import PinnedLinks from '~/issue_show/components/pinned_links.vue'; import PinnedLinks from '~/issue_show/components/pinned_links.vue';
import { IssuableStatus, IssuableStatusText } from '~/issue_show/constants';
function formatText(text) { function formatText(text) {
return text.trim().replace(/\s\s+/g, ' '); return text.trim().replace(/\s\s+/g, ' ');
...@@ -36,6 +37,10 @@ describe('Issuable output', () => { ...@@ -36,6 +37,10 @@ describe('Issuable output', () => {
const findStickyHeader = () => wrapper.find('[data-testid="issue-sticky-header"]'); const findStickyHeader = () => wrapper.find('[data-testid="issue-sticky-header"]');
const findLockedBadge = () => wrapper.find('[data-testid="locked"]');
const findConfidentialBadge = () => wrapper.find('[data-testid="confidential"]');
const mountComponent = (props = {}, options = {}) => { const mountComponent = (props = {}, options = {}) => {
wrapper = mount(IssuableApp, { wrapper = mount(IssuableApp, {
propsData: { ...appProps, ...props }, propsData: { ...appProps, ...props },
...@@ -532,7 +537,7 @@ describe('Issuable output', () => { ...@@ -532,7 +537,7 @@ describe('Issuable output', () => {
describe('sticky header', () => { describe('sticky header', () => {
describe('when title is in view', () => { describe('when title is in view', () => {
it('is not shown', () => { it('is not shown', () => {
expect(wrapper.find('.issue-sticky-header').exists()).toBe(false); expect(findStickyHeader().exists()).toBe(false);
}); });
}); });
...@@ -542,24 +547,45 @@ describe('Issuable output', () => { ...@@ -542,24 +547,45 @@ describe('Issuable output', () => {
wrapper.find(GlIntersectionObserver).vm.$emit('disappear'); wrapper.find(GlIntersectionObserver).vm.$emit('disappear');
}); });
it('is shown with title', () => { it('shows with title', () => {
expect(findStickyHeader().text()).toContain('Sticky header title'); expect(findStickyHeader().text()).toContain('Sticky header title');
}); });
it('is shown with Open when status is opened', () => { it.each`
wrapper.setProps({ issuableStatus: 'opened' }); title | state
${'shows with Open when status is opened'} | ${IssuableStatus.Open}
${'shows with Closed when status is closed'} | ${IssuableStatus.Closed}
${'shows with Open when status is reopened'} | ${IssuableStatus.Reopened}
`('$title', async ({ state }) => {
wrapper.setProps({ issuableStatus: state });
return wrapper.vm.$nextTick(() => { await wrapper.vm.$nextTick();
expect(findStickyHeader().text()).toContain('Open');
}); expect(findStickyHeader().text()).toContain(IssuableStatusText[state]);
}); });
it('is shown with Closed when status is closed', () => { it.each`
wrapper.setProps({ issuableStatus: 'closed' }); title | isConfidential
${'does not show confidential badge when issue is not confidential'} | ${true}
${'shows confidential badge when issue is confidential'} | ${false}
`('$title', async ({ isConfidential }) => {
wrapper.setProps({ isConfidential });
return wrapper.vm.$nextTick(() => { await wrapper.vm.$nextTick();
expect(findStickyHeader().text()).toContain('Closed');
}); expect(findConfidentialBadge().exists()).toBe(isConfidential);
});
it.each`
title | isLocked
${'does not show locked badge when issue is not locked'} | ${true}
${'shows locked badge when issue is locked'} | ${false}
`('$title', async ({ isLocked }) => {
wrapper.setProps({ isLocked });
await wrapper.vm.$nextTick();
expect(findLockedBadge().exists()).toBe(isLocked);
}); });
}); });
}); });
......
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