diff options
-rw-r--r-- | app/assets/javascripts/notes/components/comment_form.vue | 2 | ||||
-rw-r--r-- | app/assets/javascripts/notes/components/discussion_locked_widget.vue | 20 | ||||
-rw-r--r-- | app/assets/javascripts/notes/components/note_form.vue | 2 | ||||
-rw-r--r-- | app/assets/javascripts/notes/mixins/issuable_state.js | 11 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/issue/issue_warning.vue | 45 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/note_form.scss | 5 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/notes.scss | 2 | ||||
-rw-r--r-- | app/serializers/issue_entity.rb | 8 | ||||
-rw-r--r-- | changelogs/unreleased/37495.yml | 5 | ||||
-rw-r--r-- | locale/gitlab.pot | 12 | ||||
-rw-r--r-- | spec/frontend/vue_shared/components/issue/issue_warning_spec.js | 18 |
11 files changed, 110 insertions, 20 deletions
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue index 688c06878ac..075c28e8d07 100644 --- a/app/assets/javascripts/notes/components/comment_form.vue +++ b/app/assets/javascripts/notes/components/comment_form.vue @@ -337,6 +337,8 @@ Please check your network connection and try again.`; v-if="hasWarning(getNoteableData)" :is-locked="isLocked(getNoteableData)" :is-confidential="isConfidential(getNoteableData)" + :locked-issue-docs-path="lockedIssueDocsPath" + :confidential-issue-docs-path="confidentialIssueDocsPath" /> <markdown-field diff --git a/app/assets/javascripts/notes/components/discussion_locked_widget.vue b/app/assets/javascripts/notes/components/discussion_locked_widget.vue index c469a6b7bcd..53f509185a8 100644 --- a/app/assets/javascripts/notes/components/discussion_locked_widget.vue +++ b/app/assets/javascripts/notes/components/discussion_locked_widget.vue @@ -1,12 +1,24 @@ <script> +import { GlLink } from '@gitlab/ui'; import Icon from '~/vue_shared/components/icon.vue'; +import { __, sprintf } from '~/locale'; import Issuable from '~/vue_shared/mixins/issuable'; +import issuableStateMixin from '../mixins/issuable_state'; export default { components: { Icon, + GlLink, + }, + mixins: [Issuable, issuableStateMixin], + computed: { + lockedIssueWarning() { + return sprintf( + __('This %{issuableDisplayName} is locked. Only project members can comment.'), + { issuableDisplayName: this.issuableDisplayName }, + ); + }, }, - mixins: [Issuable], }; </script> @@ -15,7 +27,11 @@ export default { <span class="issuable-note-warning inline"> <icon :size="16" name="lock" class="icon" /> <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> </div> diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue index acbb91ce7be..09ecb695214 100644 --- a/app/assets/javascripts/notes/components/note_form.vue +++ b/app/assets/javascripts/notes/components/note_form.vue @@ -234,6 +234,8 @@ export default { v-if="hasWarning(getNoteableData)" :is-locked="isLocked(getNoteableData)" :is-confidential="isConfidential(getNoteableData)" + :locked-issue-docs-path="lockedIssueDocsPath" + :confidential-issue-docs-path="confidentialIssueDocsPath" /> <markdown-field diff --git a/app/assets/javascripts/notes/mixins/issuable_state.js b/app/assets/javascripts/notes/mixins/issuable_state.js index ded0ac3cfa9..d97d9f6850a 100644 --- a/app/assets/javascripts/notes/mixins/issuable_state.js +++ b/app/assets/javascripts/notes/mixins/issuable_state.js @@ -1,4 +1,15 @@ +import { mapGetters } from 'vuex'; + export default { + computed: { + ...mapGetters(['getNoteableDataByProp']), + lockedIssueDocsPath() { + return this.getNoteableDataByProp('locked_discussion_docs_path'); + }, + confidentialIssueDocsPath() { + return this.getNoteableDataByProp('confidential_issues_docs_path'); + }, + }, methods: { isConfidential(issue) { return Boolean(issue.confidential); diff --git a/app/assets/javascripts/vue_shared/components/issue/issue_warning.vue b/app/assets/javascripts/vue_shared/components/issue/issue_warning.vue index e92babc499b..e438ff16a41 100644 --- a/app/assets/javascripts/vue_shared/components/issue/issue_warning.vue +++ b/app/assets/javascripts/vue_shared/components/issue/issue_warning.vue @@ -1,9 +1,17 @@ <script> +import { GlLink } from '@gitlab/ui'; +import _ from 'underscore'; +import { sprintf } from '~/locale'; import icon from '../../../vue_shared/components/icon.vue'; +function buildDocsLinkStart(path) { + return `<a href="${_.escape(path)}" target="_blank" rel="noopener noreferrer">`; +} + export default { components: { icon, + GlLink, }, props: { isLocked: { @@ -16,6 +24,16 @@ export default { default: false, required: false, }, + lockedIssueDocsPath: { + type: String, + required: false, + default: '', + }, + confidentialIssueDocsPath: { + type: String, + required: false, + default: '', + }, }, computed: { warningIcon() { @@ -27,6 +45,17 @@ export default { isLockedAndConfidential() { 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> @@ -35,20 +64,26 @@ export default { <icon v-if="!isLockedAndConfidential" :name="warningIcon" :size="16" class="icon inline" /> <span v-if="isLockedAndConfidential"> - {{ __('This issue is confidential and locked.') }} + <span v-html="confidentialAndLockedDiscussionText"></span> {{ - __(`People without permission will never -get a notification and won't be able to comment.`) + __(`People without permission will never get a notification and won't be able to comment.`) }} </span> <span v-else-if="isConfidential"> {{ __('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 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> </div> </template> diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 8c7b124dd33..267fdfa5d86 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -103,6 +103,11 @@ margin: auto; align-items: center; + a { + color: $orange-600; + text-decoration: underline; + } + .icon { margin-right: $issuable-warning-icon-margin; vertical-align: text-bottom; diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 32477c20db6..52677b7df60 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -762,7 +762,7 @@ $note-form-margin-left: 72px; background-color: $white-light; } - a { + a:not(.learn-more) { color: $blue-600; } } diff --git a/app/serializers/issue_entity.rb b/app/serializers/issue_entity.rb index 914ad628a99..36e601f45c5 100644 --- a/app/serializers/issue_entity.rb +++ b/app/serializers/issue_entity.rb @@ -44,4 +44,12 @@ class IssueEntity < IssuableEntity expose :preview_note_path do |issue| preview_markdown_path(issue.project, target_type: 'Issue', target_id: issue.iid) 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 diff --git a/changelogs/unreleased/37495.yml b/changelogs/unreleased/37495.yml new file mode 100644 index 00000000000..f6d421fc45b --- /dev/null +++ b/changelogs/unreleased/37495.yml @@ -0,0 +1,5 @@ +--- +title: Add documentation links for confidental and locked discussions +merge_request: 29073 +author: +type: changed diff --git a/locale/gitlab.pot b/locale/gitlab.pot index eee686bcb27..b53d211c0ac 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6994,6 +6994,9 @@ msgstr "" msgid "People without permission will never get a notification and won't be able to comment." msgstr "" +msgid "People without permission will never get a notification." +msgstr "" + msgid "Perform advanced options such as changing path, transferring, or removing the group." msgstr "" @@ -10188,6 +10191,9 @@ msgstr "" msgid "Third party offers" msgstr "" +msgid "This %{issuableDisplayName} is locked. Only project members can comment." +msgstr "" + msgid "This %{issuable} is locked. Only <strong>project members</strong> can comment." msgstr "" @@ -10284,9 +10290,6 @@ msgstr "" msgid "This issue is confidential" msgstr "" -msgid "This issue is confidential and locked." -msgstr "" - msgid "This issue is locked." msgstr "" @@ -11937,9 +11940,6 @@ msgstr "" msgid "Your comment could not be updated! Please check your network connection and try again." msgstr "" -msgid "Your comment will not be visible to the public." -msgstr "" - msgid "Your deployment services will be broken, you will need to manually fix the services after renaming." msgstr "" diff --git a/spec/frontend/vue_shared/components/issue/issue_warning_spec.js b/spec/frontend/vue_shared/components/issue/issue_warning_spec.js index 4a8de5fc4f1..63880b85625 100644 --- a/spec/frontend/vue_shared/components/issue/issue_warning_spec.js +++ b/spec/frontend/vue_shared/components/issue/issue_warning_spec.js @@ -15,31 +15,37 @@ function formatWarning(string) { describe('Issue Warning Component', () => { describe('isLocked', () => { it('should render locked issue warning information', () => { - const vm = mountComponent(IssueWarning, { + const props = { isLocked: true, - }); + lockedIssueDocsPath: 'docs/issues/locked', + }; + const vm = mountComponent(IssueWarning, props); expect( vm.$el.querySelector('.icon use').getAttributeNS('http://www.w3.org/1999/xlink', 'href'), ).toMatch(/lock$/); 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', () => { it('should render confidential issue warning information', () => { - const vm = mountComponent(IssueWarning, { + const props = { isConfidential: true, - }); + confidentialIssueDocsPath: '/docs/issues/confidential', + }; + const vm = mountComponent(IssueWarning, props); expect( vm.$el.querySelector('.icon use').getAttributeNS('http://www.w3.org/1999/xlink', 'href'), ).toMatch(/eye-slash$/); 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); }); }); |