Commit 39eccc97 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab-ce master

parents 7e5e9f9c 48ca0ddf
...@@ -337,6 +337,8 @@ Please check your network connection and try again.`; ...@@ -337,6 +337,8 @@ Please check your network connection and try again.`;
v-if="hasWarning(getNoteableData)" v-if="hasWarning(getNoteableData)"
:is-locked="isLocked(getNoteableData)" :is-locked="isLocked(getNoteableData)"
:is-confidential="isConfidential(getNoteableData)" :is-confidential="isConfidential(getNoteableData)"
:locked-issue-docs-path="lockedIssueDocsPath"
:confidential-issue-docs-path="confidentialIssueDocsPath"
/> />
<markdown-field <markdown-field
......
<script> <script>
import { GlLink } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { __, sprintf } from '~/locale';
import Issuable from '~/vue_shared/mixins/issuable'; import Issuable from '~/vue_shared/mixins/issuable';
import issuableStateMixin from '../mixins/issuable_state';
export default { export default {
components: { components: {
Icon, Icon,
GlLink,
},
mixins: [Issuable, issuableStateMixin],
computed: {
lockedIssueWarning() {
return sprintf(
__('This %{issuableDisplayName} is locked. Only project members can comment.'),
{ issuableDisplayName: this.issuableDisplayName },
);
},
}, },
mixins: [Issuable],
}; };
</script> </script>
...@@ -15,7 +27,11 @@ export default { ...@@ -15,7 +27,11 @@ export default {
<span class="issuable-note-warning inline"> <span class="issuable-note-warning inline">
<icon :size="16" name="lock" class="icon" /> <icon :size="16" name="lock" class="icon" />
<span> <span>
This {{ issuableDisplayName }} is locked. Only <b>project members</b> can comment. {{ lockedIssueWarning }}
<gl-link :href="lockedIssueDocsPath" target="_blank" class="learn-more">
{{ __('Learn more') }}
</gl-link>
</span> </span>
</span> </span>
</div> </div>
......
...@@ -234,6 +234,8 @@ export default { ...@@ -234,6 +234,8 @@ export default {
v-if="hasWarning(getNoteableData)" v-if="hasWarning(getNoteableData)"
:is-locked="isLocked(getNoteableData)" :is-locked="isLocked(getNoteableData)"
:is-confidential="isConfidential(getNoteableData)" :is-confidential="isConfidential(getNoteableData)"
:locked-issue-docs-path="lockedIssueDocsPath"
:confidential-issue-docs-path="confidentialIssueDocsPath"
/> />
<markdown-field <markdown-field
......
import { mapGetters } from 'vuex';
export default { export default {
computed: {
...mapGetters(['getNoteableDataByProp']),
lockedIssueDocsPath() {
return this.getNoteableDataByProp('locked_discussion_docs_path');
},
confidentialIssueDocsPath() {
return this.getNoteableDataByProp('confidential_issues_docs_path');
},
},
methods: { methods: {
isConfidential(issue) { isConfidential(issue) {
return Boolean(issue.confidential); return Boolean(issue.confidential);
......
<script> <script>
import { GlLink } from '@gitlab/ui';
import _ from 'underscore';
import { sprintf } from '~/locale';
import icon from '../../../vue_shared/components/icon.vue'; import icon from '../../../vue_shared/components/icon.vue';
function buildDocsLinkStart(path) {
return `<a href="${_.escape(path)}" target="_blank" rel="noopener noreferrer">`;
}
export default { export default {
components: { components: {
icon, icon,
GlLink,
}, },
props: { props: {
isLocked: { isLocked: {
...@@ -16,6 +24,16 @@ export default { ...@@ -16,6 +24,16 @@ export default {
default: false, default: false,
required: false, required: false,
}, },
lockedIssueDocsPath: {
type: String,
required: false,
default: '',
},
confidentialIssueDocsPath: {
type: String,
required: false,
default: '',
},
}, },
computed: { computed: {
warningIcon() { warningIcon() {
...@@ -27,6 +45,17 @@ export default { ...@@ -27,6 +45,17 @@ export default {
isLockedAndConfidential() { isLockedAndConfidential() {
return this.isConfidential && this.isLocked; return this.isConfidential && this.isLocked;
}, },
confidentialAndLockedDiscussionText() {
return sprintf(
'This issue is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}.',
{
confidentialLinkStart: buildDocsLinkStart(this.confidentialIssueDocsPath),
lockedLinkStart: buildDocsLinkStart(this.lockedIssueDocsPath),
linkEnd: '</a>',
},
false,
);
},
}, },
}; };
</script> </script>
...@@ -35,20 +64,26 @@ export default { ...@@ -35,20 +64,26 @@ export default {
<icon v-if="!isLockedAndConfidential" :name="warningIcon" :size="16" class="icon inline" /> <icon v-if="!isLockedAndConfidential" :name="warningIcon" :size="16" class="icon inline" />
<span v-if="isLockedAndConfidential"> <span v-if="isLockedAndConfidential">
{{ __('This issue is confidential and locked.') }} <span v-html="confidentialAndLockedDiscussionText"></span>
{{ {{
__(`People without permission will never __(`People without permission will never get a notification and won't be able to comment.`)
get a notification and won't be able to comment.`)
}} }}
</span> </span>
<span v-else-if="isConfidential"> <span v-else-if="isConfidential">
{{ __('This is a confidential issue.') }} {{ __('This is a confidential issue.') }}
{{ __('Your comment will not be visible to the public.') }} {{ __('People without permission will never get a notification.') }}
<gl-link :href="confidentialIssueDocsPath" target="_blank">
{{ __('Learn more') }}
</gl-link>
</span> </span>
<span v-else-if="isLocked"> <span v-else-if="isLocked">
{{ __('This issue is locked.') }} {{ __('Only project members can comment.') }} {{ __('This issue is locked.') }}
{{ __('Only project members can comment.') }}
<gl-link :href="lockedIssueDocsPath" target="_blank">
{{ __('Learn more') }}
</gl-link>
</span> </span>
</div> </div>
</template> </template>
...@@ -103,6 +103,11 @@ ...@@ -103,6 +103,11 @@
margin: auto; margin: auto;
align-items: center; align-items: center;
a {
color: $orange-600;
text-decoration: underline;
}
.icon { .icon {
margin-right: $issuable-warning-icon-margin; margin-right: $issuable-warning-icon-margin;
vertical-align: text-bottom; vertical-align: text-bottom;
......
...@@ -762,7 +762,7 @@ $note-form-margin-left: 72px; ...@@ -762,7 +762,7 @@ $note-form-margin-left: 72px;
background-color: $white-light; background-color: $white-light;
} }
a { a:not(.learn-more) {
color: $blue-600; color: $blue-600;
} }
} }
......
...@@ -45,4 +45,12 @@ class IssueEntity < IssuableEntity ...@@ -45,4 +45,12 @@ class IssueEntity < IssuableEntity
expose :preview_note_path do |issue| expose :preview_note_path do |issue|
preview_markdown_path(issue.project, target_type: 'Issue', target_id: issue.iid) preview_markdown_path(issue.project, target_type: 'Issue', target_id: issue.iid)
end end
expose :confidential_issues_docs_path, if: -> (issue) { issue.confidential? } do |issue|
help_page_path('user/project/issues/confidential_issues.md')
end
expose :locked_discussion_docs_path, if: -> (issue) { issue.discussion_locked? } do |issue|
help_page_path('user/discussions/index.md', anchor: 'lock-discussions')
end
end end
---
title: Add documentation links for confidental and locked discussions
merge_request: 29073
author:
type: changed
...@@ -15,31 +15,37 @@ function formatWarning(string) { ...@@ -15,31 +15,37 @@ function formatWarning(string) {
describe('Issue Warning Component', () => { describe('Issue Warning Component', () => {
describe('isLocked', () => { describe('isLocked', () => {
it('should render locked issue warning information', () => { it('should render locked issue warning information', () => {
const vm = mountComponent(IssueWarning, { const props = {
isLocked: true, isLocked: true,
}); lockedIssueDocsPath: 'docs/issues/locked',
};
const vm = mountComponent(IssueWarning, props);
expect( expect(
vm.$el.querySelector('.icon use').getAttributeNS('http://www.w3.org/1999/xlink', 'href'), vm.$el.querySelector('.icon use').getAttributeNS('http://www.w3.org/1999/xlink', 'href'),
).toMatch(/lock$/); ).toMatch(/lock$/);
expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual( expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual(
'This issue is locked. Only project members can comment.', 'This issue is locked. Only project members can comment. Learn more',
); );
expect(vm.$el.querySelector('a').href).toContain(props.lockedIssueDocsPath);
}); });
}); });
describe('isConfidential', () => { describe('isConfidential', () => {
it('should render confidential issue warning information', () => { it('should render confidential issue warning information', () => {
const vm = mountComponent(IssueWarning, { const props = {
isConfidential: true, isConfidential: true,
}); confidentialIssueDocsPath: '/docs/issues/confidential',
};
const vm = mountComponent(IssueWarning, props);
expect( expect(
vm.$el.querySelector('.icon use').getAttributeNS('http://www.w3.org/1999/xlink', 'href'), vm.$el.querySelector('.icon use').getAttributeNS('http://www.w3.org/1999/xlink', 'href'),
).toMatch(/eye-slash$/); ).toMatch(/eye-slash$/);
expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual( expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual(
'This is a confidential issue. Your comment will not be visible to the public.', 'This is a confidential issue. People without permission will never get a notification. Learn more',
); );
expect(vm.$el.querySelector('a').href).toContain(props.confidentialIssueDocsPath);
}); });
}); });
......
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