Commit e4d2dc41 authored by peterhegman's avatar peterhegman Committed by Peter Hegman

Display icon for hidden issues on group/project issue boards

Issues created by banned users are hidden from all users except admins.
This commit adds an icon to hidden issues on group/project issue
boards.

Changelog: added
parent 518de54a
...@@ -214,6 +214,14 @@ export default { ...@@ -214,6 +214,14 @@ export default {
class="confidential-icon gl-mr-2" class="confidential-icon gl-mr-2"
:aria-label="__('Confidential')" :aria-label="__('Confidential')"
/> />
<gl-icon
v-if="item.hidden"
v-gl-tooltip
name="spam"
:title="__('This issue is hidden because its author has been banned')"
class="gl-mr-2 hidden-icon"
data-testid="hidden-icon"
/>
<a <a
:href="item.path || item.webUrl || ''" :href="item.path || item.webUrl || ''"
:title="item.title" :title="item.title"
......
...@@ -12,6 +12,7 @@ fragment IssueNode on Issue { ...@@ -12,6 +12,7 @@ fragment IssueNode on Issue {
humanTotalTimeSpent humanTotalTimeSpent
emailsDisabled emailsDisabled
confidential confidential
hidden
webUrl webUrl
relativePosition relativePosition
assignees { assignees {
......
...@@ -248,7 +248,8 @@ ...@@ -248,7 +248,8 @@
margin-right: 4px; margin-right: 4px;
} }
.confidential-icon { .confidential-icon,
.hidden-icon {
color: var(--orange-500, $orange-500); color: var(--orange-500, $orange-500);
cursor: help; cursor: help;
} }
......
...@@ -12,6 +12,7 @@ fragment IssueNode on Issue { ...@@ -12,6 +12,7 @@ fragment IssueNode on Issue {
humanTotalTimeSpent humanTotalTimeSpent
weight weight
confidential confidential
hidden
webUrl webUrl
blocked blocked
blockedByCount blockedByCount
......
...@@ -2,6 +2,7 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui'; ...@@ -2,6 +2,7 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash'; import { range } from 'lodash';
import Vuex from 'vuex'; import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper'; import setWindowLocation from 'helpers/set_window_location_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardBlockedIcon from '~/boards/components/board_blocked_icon.vue'; import BoardBlockedIcon from '~/boards/components/board_blocked_icon.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue'; import BoardCardInner from '~/boards/components/board_card_inner.vue';
...@@ -44,6 +45,7 @@ describe('Board card component', () => { ...@@ -44,6 +45,7 @@ describe('Board card component', () => {
const findEpicBadgeProgress = () => wrapper.findByTestId('epic-progress'); const findEpicBadgeProgress = () => wrapper.findByTestId('epic-progress');
const findEpicCountablesTotalWeight = () => wrapper.findByTestId('epic-countables-total-weight'); const findEpicCountablesTotalWeight = () => wrapper.findByTestId('epic-countables-total-weight');
const findEpicProgressTooltip = () => wrapper.findByTestId('epic-progress-tooltip-content'); const findEpicProgressTooltip = () => wrapper.findByTestId('epic-progress-tooltip-content');
const findHiddenIssueIcon = () => wrapper.findByTestId('hidden-icon');
const createStore = ({ isEpicBoard = false, isProjectBoard = false } = {}) => { const createStore = ({ isEpicBoard = false, isProjectBoard = false } = {}) => {
store = new Vuex.Store({ store = new Vuex.Store({
...@@ -72,6 +74,9 @@ describe('Board card component', () => { ...@@ -72,6 +74,9 @@ describe('Board card component', () => {
GlLabel: true, GlLabel: true,
GlLoadingIcon: true, GlLoadingIcon: true,
}, },
directives: {
GlTooltip: createMockDirective(),
},
mocks: { mocks: {
$apollo: { $apollo: {
queries: { queries: {
...@@ -122,6 +127,10 @@ describe('Board card component', () => { ...@@ -122,6 +127,10 @@ describe('Board card component', () => {
expect(wrapper.find('.confidential-icon').exists()).toBe(false); expect(wrapper.find('.confidential-icon').exists()).toBe(false);
}); });
it('does not render hidden issue icon', () => {
expect(findHiddenIssueIcon().exists()).toBe(false);
});
it('renders issue ID with #', () => { it('renders issue ID with #', () => {
expect(wrapper.find('.board-card-number').text()).toContain(`#${issue.iid}`); expect(wrapper.find('.board-card-number').text()).toContain(`#${issue.iid}`);
}); });
...@@ -184,6 +193,30 @@ describe('Board card component', () => { ...@@ -184,6 +193,30 @@ describe('Board card component', () => {
}); });
}); });
describe('hidden issue', () => {
beforeEach(() => {
wrapper.setProps({
item: {
...wrapper.props('item'),
hidden: true,
},
});
});
it('renders hidden issue icon', () => {
expect(findHiddenIssueIcon().exists()).toBe(true);
});
it('displays a tooltip which explains the meaning of the icon', () => {
const tooltip = getBinding(findHiddenIssueIcon().element, 'gl-tooltip');
expect(tooltip).toBeDefined();
expect(findHiddenIssueIcon().attributes('title')).toBe(
'This issue is hidden because its author has been banned',
);
});
});
describe('with assignee', () => { describe('with assignee', () => {
describe('with avatar', () => { describe('with avatar', () => {
beforeEach(() => { beforeEach(() => {
......
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