From 49cd88b785851a0e46e90260c3ed278ad3bd85f1 Mon Sep 17 00:00:00 2001 From: Jack Chapman Date: Tue, 3 Dec 2024 16:20:10 +0000 Subject: [PATCH 1/8] Add description template listbox to description widget --- .../components/work_item_description.vue | 39 ++++++++++++++++++- ...work_item_description_template_listbox.vue | 2 +- ...rk_item_description_template.query.graphql | 11 ++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue index 22c74b390ad8e7..be40ab6a72f0f9 100644 --- a/app/assets/javascripts/work_items/components/work_item_description.vue +++ b/app/assets/javascripts/work_items/components/work_item_description.vue @@ -1,6 +1,7 @@ @@ -309,9 +340,15 @@ export default { +
+ +
Date: Tue, 3 Dec 2024 16:21:02 +0000 Subject: [PATCH 2/8] Update locale file --- locale/gitlab.pot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8bcf68a7b1090e..a1c3d486035a2d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -58651,6 +58651,9 @@ msgstr "" msgid "Unable to find comment template" msgstr "" +msgid "Unable to find selected template" +msgstr "" + msgid "Unable to fully load the default commit message. You can still apply this suggestion and the commit message will be correct." msgstr "" -- GitLab From 0e9b1ca1a7e558c491c8b34a8417259344018cf6 Mon Sep 17 00:00:00 2001 From: Jack Chapman Date: Wed, 4 Dec 2024 14:28:08 +0000 Subject: [PATCH 3/8] allow applying templates --- .../components/work_item_description.vue | 32 ++++++++++++ app/assets/javascripts/work_items/index.js | 49 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue index be40ab6a72f0f9..d29fabd2038fb2 100644 --- a/app/assets/javascripts/work_items/components/work_item_description.vue +++ b/app/assets/javascripts/work_items/components/work_item_description.vue @@ -109,6 +109,7 @@ export default { }, descriptionTemplateName: '', descriptionTemplate: null, + showTemplateApplyWarning: false, }; }, apollo: { @@ -255,6 +256,9 @@ export default { this.startEditing(); } }, + descriptionTemplateName(newName, oldName) { + this.showTemplateApplyWarning = newName !== '' && oldName !== newName; + }, }, methods: { checkForConflicts() { @@ -330,6 +334,15 @@ export default { handleSelectTemplate(templateName) { this.descriptionTemplateName = templateName; }, + applyTemplate() { + this.descriptionText = this.descriptionTemplateContent; + this.onInput(); + this.showTemplateApplyWarning = false; + }, + cancelApplyTemplate() { + this.descriptionTemplateName = ''; + this.descriptionTemplate = null; + }, }, }; @@ -348,6 +361,25 @@ export default { :template="descriptionTemplateName" @selectTemplate="handleSelectTemplate" /> +
+

+ {{ + __( + 'Applying a template will replace the existing description. Any changes you have made will be lost.', + ) + }} +

+ {{ s__('WorkItem|Apply template') }} + + {{ s__('WorkItem|Cancel') }} + +
{ }, }); + /* eslint-disable @gitlab/require-i18n-strings */ + apolloProvider.clients.defaultClient.cache.writeQuery({ + query: workItemDescriptionTemplatesListQuery, + variables: { fullPath, search: '' }, + data: { + namespace: { + id: 'gid://gitlab/Group/33', + workItemDescriptionTemplates: { + nodes: [{ name: 'template 1' }, { name: 'template 2' }], + __typename: 'WorkItemDescriptionTemplateConnection', + }, + __typename: 'Namespace', + }, + }, + }); + + apolloProvider.clients.defaultClient.cache.writeQuery({ + query: workItemDescriptionTemplateQuery, + variables: { fullPath, name: 'template 1' }, + data: { + namespace: { + id: 'gid://gitlab/Group/33', + workItemDescriptionTemplates: { + nodes: [{ name: 'template 1', content: 'Some example template content' }], + __typename: 'WorkItemDescriptionTemplateConnection', + }, + __typename: 'Namespace', + }, + }, + }); + + apolloProvider.clients.defaultClient.cache.writeQuery({ + query: workItemDescriptionTemplateQuery, + variables: { fullPath, name: 'template 2' }, + data: { + namespace: { + id: 'gid://gitlab/Group/33', + workItemDescriptionTemplates: { + nodes: [{ name: 'template 2', content: 'Some other example template content' }], + __typename: 'WorkItemDescriptionTemplateConnection', + }, + __typename: 'Namespace', + }, + }, + }); + /* eslint-enable @gitlab/require-i18n-strings */ + if (workItemType === 'issue' && gon.features.workItemsViewPreference && !isGroup) { import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback') .then(({ initWorkItemsFeedback }) => { -- GitLab From 7bee227ae66ecc516d2b183b2006b684bdaf5cc6 Mon Sep 17 00:00:00 2001 From: Jack Chapman Date: Wed, 4 Dec 2024 14:32:39 +0000 Subject: [PATCH 4/8] Replace div with alert element --- .../components/work_item_description.vue | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue index d29fabd2038fb2..c71efdc0d3407c 100644 --- a/app/assets/javascripts/work_items/components/work_item_description.vue +++ b/app/assets/javascripts/work_items/components/work_item_description.vue @@ -361,7 +361,12 @@ export default { :template="descriptionTemplateName" @selectTemplate="handleSelectTemplate" /> -
+

{{ __( @@ -369,17 +374,19 @@ export default { ) }}

- {{ s__('WorkItem|Apply template') }} - - {{ s__('WorkItem|Cancel') }} - -
+ + Date: Wed, 4 Dec 2024 14:42:26 +0000 Subject: [PATCH 5/8] update locale file --- locale/gitlab.pot | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a1c3d486035a2d..b27a709cbfc270 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -7043,6 +7043,9 @@ msgstr "" msgid "Applying a template will replace the existing content. Any changes you have made will be lost." msgstr "" +msgid "Applying a template will replace the existing description. Any changes you have made will be lost." +msgstr "" + msgid "Applying a template will replace the existing issue description. Any changes you have made will be lost." msgstr "" @@ -62553,6 +62556,9 @@ msgstr "" msgid "WorkItem|Ancestor not available" msgstr "" +msgid "WorkItem|Apply template" +msgstr "" + msgid "WorkItem|Apricot" msgstr "" -- GitLab From b0cebd20da96119b5c68ecfd7496dfbf3d757f36 Mon Sep 17 00:00:00 2001 From: Jack Chapman Date: Wed, 4 Dec 2024 16:43:29 +0000 Subject: [PATCH 6/8] Replace cache fill with mock resolver --- .../graphql_shared/issuable_client.js | 23 +++++++++ ...rk_item_description_template.query.graphql | 2 +- ...m_description_templates_list.query.graphql | 2 +- app/assets/javascripts/work_items/index.js | 49 ------------------- 4 files changed, 25 insertions(+), 51 deletions(-) diff --git a/app/assets/javascripts/graphql_shared/issuable_client.js b/app/assets/javascripts/graphql_shared/issuable_client.js index 1f13392539007c..0fc283d46691ba 100644 --- a/app/assets/javascripts/graphql_shared/issuable_client.js +++ b/app/assets/javascripts/graphql_shared/issuable_client.js @@ -45,6 +45,29 @@ export const config = { toReference({ __typename: 'LocalWorkItemChildIsExpanded', id: variables.id }), }, }, + WorkItemDescriptionTemplateConnection: { + fields: { + nodes: { + read(_, { variables }) { + const templates = [ + /* eslint-disable @gitlab/require-i18n-strings */ + { name: 'template 1', content: 'A template' }, + { name: 'template 2', content: 'Another template' }, + { name: 'template 3', content: 'Secret template omg wow' }, + { name: 'template 4', content: 'Another another template' }, + /* eslint-enable @gitlab/require-i18n-strings */ + ]; + if (variables.search) { + return templates.filter(({ name }) => name.includes(variables.search)); + } + if (variables.name) { + return templates.filter(({ name }) => name === variables.name); + } + return templates; + }, + }, + }, + }, Project: { fields: { projectMembers: { diff --git a/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql b/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql index 8ed0e092fb0eee..a276c88f4ef13f 100644 --- a/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql +++ b/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql @@ -2,7 +2,7 @@ query workItemDescriptionTemplate($fullPath: ID!, $name: String!) { namespace(fullPath: $fullPath) { id workItemDescriptionTemplates(name: $name) { - nodes { + nodes @client { name content } diff --git a/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql b/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql index 50518ff262e4a3..0cf6f6ee4a9962 100644 --- a/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql +++ b/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql @@ -2,7 +2,7 @@ query workItemDescriptionTemplatesList($fullPath: ID!, $search: String) { namespace(fullPath: $fullPath) { id workItemDescriptionTemplates(search: $search) { - nodes { + nodes @client { name } } diff --git a/app/assets/javascripts/work_items/index.js b/app/assets/javascripts/work_items/index.js index d2ddaa550a70f6..cf1d23f3ccf57d 100644 --- a/app/assets/javascripts/work_items/index.js +++ b/app/assets/javascripts/work_items/index.js @@ -12,8 +12,6 @@ import { apolloProvider } from '~/graphql_shared/issuable_client'; import App from './components/app.vue'; import WorkItemBreadcrumb from './components/work_item_breadcrumb.vue'; import activeDiscussionQuery from './components/design_management/graphql/client/active_design_discussion.query.graphql'; -import workItemDescriptionTemplatesListQuery from './graphql/work_item_description_templates_list.query.graphql'; -import workItemDescriptionTemplateQuery from './graphql/work_item_description_template.query.graphql'; import { createRouter } from './router'; Vue.use(VueApollo); @@ -87,53 +85,6 @@ export const initWorkItemsRoot = ({ workItemType, workspaceType } = {}) => { }, }); - /* eslint-disable @gitlab/require-i18n-strings */ - apolloProvider.clients.defaultClient.cache.writeQuery({ - query: workItemDescriptionTemplatesListQuery, - variables: { fullPath, search: '' }, - data: { - namespace: { - id: 'gid://gitlab/Group/33', - workItemDescriptionTemplates: { - nodes: [{ name: 'template 1' }, { name: 'template 2' }], - __typename: 'WorkItemDescriptionTemplateConnection', - }, - __typename: 'Namespace', - }, - }, - }); - - apolloProvider.clients.defaultClient.cache.writeQuery({ - query: workItemDescriptionTemplateQuery, - variables: { fullPath, name: 'template 1' }, - data: { - namespace: { - id: 'gid://gitlab/Group/33', - workItemDescriptionTemplates: { - nodes: [{ name: 'template 1', content: 'Some example template content' }], - __typename: 'WorkItemDescriptionTemplateConnection', - }, - __typename: 'Namespace', - }, - }, - }); - - apolloProvider.clients.defaultClient.cache.writeQuery({ - query: workItemDescriptionTemplateQuery, - variables: { fullPath, name: 'template 2' }, - data: { - namespace: { - id: 'gid://gitlab/Group/33', - workItemDescriptionTemplates: { - nodes: [{ name: 'template 2', content: 'Some other example template content' }], - __typename: 'WorkItemDescriptionTemplateConnection', - }, - __typename: 'Namespace', - }, - }, - }); - /* eslint-enable @gitlab/require-i18n-strings */ - if (workItemType === 'issue' && gon.features.workItemsViewPreference && !isGroup) { import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback') .then(({ initWorkItemsFeedback }) => { -- GitLab From beade2edcc140750235687338a43a34e65c7bc74 Mon Sep 17 00:00:00 2001 From: Jack Chapman Date: Wed, 4 Dec 2024 17:14:15 +0000 Subject: [PATCH 7/8] Add fields to pass gql lint --- .../graphql/work_item_description_template.query.graphql | 1 + .../graphql/work_item_description_templates_list.query.graphql | 1 + 2 files changed, 2 insertions(+) diff --git a/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql b/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql index a276c88f4ef13f..1abc534286fd57 100644 --- a/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql +++ b/app/assets/javascripts/work_items/graphql/work_item_description_template.query.graphql @@ -2,6 +2,7 @@ query workItemDescriptionTemplate($fullPath: ID!, $name: String!) { namespace(fullPath: $fullPath) { id workItemDescriptionTemplates(name: $name) { + __typename nodes @client { name content diff --git a/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql b/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql index 0cf6f6ee4a9962..531b2832147284 100644 --- a/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql +++ b/app/assets/javascripts/work_items/graphql/work_item_description_templates_list.query.graphql @@ -2,6 +2,7 @@ query workItemDescriptionTemplatesList($fullPath: ID!, $search: String) { namespace(fullPath: $fullPath) { id workItemDescriptionTemplates(search: $search) { + __typename nodes @client { name } -- GitLab From bff1fcb4dc1713b5223e0cda5d4f1b24b308a6f2 Mon Sep 17 00:00:00 2001 From: Jack Chapman Date: Thu, 5 Dec 2024 19:41:16 +0000 Subject: [PATCH 8/8] Add specs for new code --- .../components/work_item_description.vue | 11 ++- .../components/work_item_description_spec.js | 72 +++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue index c71efdc0d3407c..c3b7a5b1a87922 100644 --- a/app/assets/javascripts/work_items/components/work_item_description.vue +++ b/app/assets/javascripts/work_items/components/work_item_description.vue @@ -335,7 +335,7 @@ export default { this.descriptionTemplateName = templateName; }, applyTemplate() { - this.descriptionText = this.descriptionTemplateContent; + this.setDescriptionText(this.descriptionTemplateContent); this.onInput(); this.showTemplateApplyWarning = false; }, @@ -366,6 +366,7 @@ export default { :dismissible="false" variant="warning" class="mt-2" + data-testid="description-template-warning" >

{{ @@ -375,13 +376,17 @@ export default { }}