From 4143aa47931eadd3796978f08fd65f334e4e108a Mon Sep 17 00:00:00 2001 From: Kushal Pandya <kushalspandya@gmail.com> Date: Wed, 9 Feb 2022 18:32:32 +0530 Subject: [PATCH] Use copy based on issuableType Update copy usages throughout the app to determine correct text based on issuableType. --- .../components/add_issuable_form.vue | 12 ++++++-- .../components/related_issues_block.vue | 19 ++++++++++-- .../javascripts/related_issues/constants.js | 25 ++++++++++++++++ .../javascripts/related_issues/index.js | 1 + locale/gitlab.pot | 15 ++++++++++ .../components/add_issuable_form_spec.js | 25 ++++++++++++++++ .../components/related_issues_block_spec.js | 29 ++++++++++++++++--- 7 files changed, 117 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/related_issues/components/add_issuable_form.vue b/app/assets/javascripts/related_issues/components/add_issuable_form.vue index f936c03c5d37b..9ee2e7a4ffd69 100644 --- a/app/assets/javascripts/related_issues/components/add_issuable_form.vue +++ b/app/assets/javascripts/related_issues/components/add_issuable_form.vue @@ -9,6 +9,8 @@ import { linkedIssueTypesMap, addRelatedIssueErrorMap, addRelatedItemErrorMap, + issuablesFormCategoryHeaderTextMap, + issuablesFormInputTextMap, } from '../constants'; import RelatedIssuableInput from './related_issuable_input.vue'; @@ -134,6 +136,12 @@ export default { epics: mergeUrlParams({ confidential_only: true }, this.autoCompleteSources.epics), }; }, + issuableCategoryHeaderText() { + return issuablesFormCategoryHeaderTextMap[this.issuableType]; + }, + issuableInputText() { + return issuablesFormInputTextMap[this.issuableType]; + }, }, methods: { onPendingIssuableRemoveRequest(params) { @@ -162,7 +170,7 @@ export default { <form @submit.prevent="onFormSubmit"> <template v-if="showCategorizedIssues"> <gl-form-group - :label="__('The current issue')" + :label="issuableCategoryHeaderText" label-for="linked-issue-type-radio" label-class="label-bold" class="mb-2" @@ -175,7 +183,7 @@ export default { /> </gl-form-group> <p class="bold"> - {{ __('the following issue(s)') }} + {{ issuableInputText }} </p> </template> <related-issuable-input diff --git a/app/assets/javascripts/related_issues/components/related_issues_block.vue b/app/assets/javascripts/related_issues/components/related_issues_block.vue index 94535e1b8c908..bc97fab9ad23b 100644 --- a/app/assets/javascripts/related_issues/components/related_issues_block.vue +++ b/app/assets/javascripts/related_issues/components/related_issues_block.vue @@ -5,6 +5,9 @@ import { issuableQaClassMap, linkedIssueTypesMap, linkedIssueTypesTextMap, + issuablesBlockHeaderTextMap, + issuablesBlockHelpTextMap, + issuablesBlockAddButtonTextMap, } from '../constants'; import AddIssuableForm from './add_issuable_form.vue'; import RelatedIssuesList from './related_issues_list.vue'; @@ -105,6 +108,15 @@ export default { hasBody() { return this.isFormVisible || this.shouldShowTokenBody; }, + headerText() { + return issuablesBlockHeaderTextMap[this.issuableType]; + }, + helpLinkText() { + return issuablesBlockHelpTextMap[this.issuableType]; + }, + addIssuableButtonText() { + return issuablesBlockAddButtonTextMap[this.issuableType]; + }, badgeLabel() { return this.isFetching && this.relatedIssues.length === 0 ? '...' : this.relatedIssues.length; }, @@ -138,13 +150,14 @@ export default { href="#related-issues" aria-hidden="true" /> - <slot name="header-text">{{ __('Linked issues') }}</slot> + <slot name="header-text">{{ headerText }}</slot> <gl-link v-if="hasHelpPath" :href="helpPath" target="_blank" class="gl-display-flex gl-align-items-center gl-ml-2 gl-text-gray-500" - :aria-label="__('Read more about related issues')" + data-testid="help-link" + :aria-label="helpLinkText" > <gl-icon name="question" :size="12" /> </gl-link> @@ -160,7 +173,7 @@ export default { v-if="canAdmin" data-qa-selector="related_issues_plus_button" icon="plus" - :aria-label="__('Add a related issue')" + :aria-label="addIssuableButtonText" :class="qaClass" @click="$emit('toggleAddRelatedIssuesForm', $event)" /> diff --git a/app/assets/javascripts/related_issues/constants.js b/app/assets/javascripts/related_issues/constants.js index 89eae069a240e..f911468d8f19c 100644 --- a/app/assets/javascripts/related_issues/constants.js +++ b/app/assets/javascripts/related_issues/constants.js @@ -104,3 +104,28 @@ export const PathIdSeparator = { Epic: '&', Issue: '#', }; + +export const issuablesBlockHeaderTextMap = { + [issuableTypesMap.ISSUE]: __('Linked issues'), + [issuableTypesMap.EPIC]: __('Linked epics'), +}; + +export const issuablesBlockHelpTextMap = { + [issuableTypesMap.ISSUE]: __('Read more about related issues'), + [issuableTypesMap.EPIC]: __('Read more about related epics'), +}; + +export const issuablesBlockAddButtonTextMap = { + [issuableTypesMap.ISSUE]: __('Add a related issue'), + [issuableTypesMap.EPIC]: __('Add a related epic'), +}; + +export const issuablesFormCategoryHeaderTextMap = { + [issuableTypesMap.ISSUE]: __('The current issue'), + [issuableTypesMap.EPIC]: __('The current epic'), +}; + +export const issuablesFormInputTextMap = { + [issuableTypesMap.ISSUE]: __('the following issue(s)'), + [issuableTypesMap.EPIC]: __('the following epic(s)'), +}; diff --git a/app/assets/javascripts/related_issues/index.js b/app/assets/javascripts/related_issues/index.js index 0ee99df14550d..bd9845e616b1c 100644 --- a/app/assets/javascripts/related_issues/index.js +++ b/app/assets/javascripts/related_issues/index.js @@ -8,6 +8,7 @@ export default function initRelatedIssues() { // eslint-disable-next-line no-new new Vue({ el: relatedIssuesRootElement, + name: 'RelatedIssuesApp', components: { relatedIssuesRoot: RelatedIssuesRoot, }, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 76ce6fc67c975..d8c71a9eb0422 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2091,6 +2091,9 @@ msgstr "" msgid "Add a numbered list" msgstr "" +msgid "Add a related epic" +msgstr "" + msgid "Add a related issue" msgstr "" @@ -21755,6 +21758,9 @@ msgstr "" msgid "Linked emails (%{email_count})" msgstr "" +msgid "Linked epics" +msgstr "" + msgid "Linked issues" msgstr "" @@ -29685,6 +29691,9 @@ msgstr "" msgid "Read more about project permissions %{help_link_open}here%{help_link_close}" msgstr "" +msgid "Read more about related epics" +msgstr "" + msgid "Read more about related issues" msgstr "" @@ -36091,6 +36100,9 @@ msgstr "" msgid "The contents of this group, its subgroups and projects will be permanently removed after %{deletion_adjourned_period} days on %{date}. After this point, your data cannot be recovered." msgstr "" +msgid "The current epic" +msgstr "" + msgid "The current issue" msgstr "" @@ -44006,6 +44018,9 @@ msgstr "" msgid "the file" msgstr "" +msgid "the following epic(s)" +msgstr "" + msgid "the following issue(s)" msgstr "" diff --git a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js index 2ae32e8960518..ce98a16dbb707 100644 --- a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js +++ b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js @@ -1,3 +1,4 @@ +import { GlFormGroup } from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue'; @@ -153,6 +154,30 @@ describe('AddIssuableForm', () => { }); }); + describe('categorized issuables', () => { + it.each` + issuableType | pathIdSeparator | contextHeader | contextFooter + ${issuableTypesMap.ISSUE} | ${PathIdSeparator.Issue} | ${'The current issue'} | ${'the following issue(s)'} + ${issuableTypesMap.EPIC} | ${PathIdSeparator.Epic} | ${'The current epic'} | ${'the following epic(s)'} + `( + 'show header text as "$contextHeader" and footer text as "$contextFooter" issuableType is set to $issuableType', + ({ issuableType, contextHeader, contextFooter }) => { + wrapper = shallowMount(AddIssuableForm, { + propsData: { + issuableType, + inputValue: '', + showCategorizedIssues: true, + pathIdSeparator, + pendingReferences: [], + }, + }); + + expect(wrapper.findComponent(GlFormGroup).attributes('label')).toBe(contextHeader); + expect(wrapper.find('p.bold').text()).toContain(contextFooter); + }, + ); + }); + describe('when it is a Linked Issues form', () => { beforeEach(() => { wrapper = mount(AddIssuableForm, { diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js index 608fec45bbdaf..c7925034eb012 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js @@ -7,6 +7,7 @@ import { } from 'jest/issuable/components/related_issuable_mock_data'; import RelatedIssuesBlock from '~/related_issues/components/related_issues_block.vue'; import { + issuableTypesMap, linkedIssueTypesMap, linkedIssueTypesTextMap, PathIdSeparator, @@ -29,14 +30,34 @@ describe('RelatedIssuesBlock', () => { wrapper = mount(RelatedIssuesBlock, { propsData: { pathIdSeparator: PathIdSeparator.Issue, - issuableType: 'issue', + issuableType: issuableTypesMap.ISSUE, }, }); }); - it('displays "Linked issues" in the header', () => { - expect(wrapper.find('.card-title').text()).toContain('Linked issues'); - }); + it.each` + issuableType | pathIdSeparator | titleText | helpLinkText | addButtonText + ${'issue'} | ${PathIdSeparator.Issue} | ${'Linked issues'} | ${'Read more about related issues'} | ${'Add a related issue'} + ${'epic'} | ${PathIdSeparator.Epic} | ${'Linked epics'} | ${'Read more about related epics'} | ${'Add a related epic'} + `( + 'displays "$titleText" in the header, "$helpLinkText" aria-label for help link, and "$addButtonText" aria-label for add button when issuableType is set to "$issuableType"', + ({ issuableType, pathIdSeparator, titleText, helpLinkText, addButtonText }) => { + wrapper = mount(RelatedIssuesBlock, { + propsData: { + pathIdSeparator, + issuableType, + canAdmin: true, + helpPath: '/help/user/project/issues/related_issues', + }, + }); + + expect(wrapper.find('.card-title').text()).toContain(titleText); + expect(wrapper.find('[data-testid="help-link"]').attributes('aria-label')).toBe( + helpLinkText, + ); + expect(findIssueCountBadgeAddButton().attributes('aria-label')).toBe(addButtonText); + }, + ); it('unable to add new related issues', () => { expect(findIssueCountBadgeAddButton().exists()).toBe(false); -- GitLab