Commit 290f691c authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch '250484-add-locked-and-confidential-badge-to-issue-sticky-header' into 'master'

Add lock and confidential badges to issue sticky header

See merge request gitlab-org/gitlab!46996
parents 2addba2b 6b0a97e8
...@@ -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