diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-08 15:13:04 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-08 15:13:04 +0300 |
commit | 886ecba0bd2d964504b43303a39cfa2386f0feed (patch) | |
tree | e814b9f24f3df16bc1a8c8725a168fac3844d719 /app/assets/javascripts/work_items | |
parent | cb09086128f2923126d009a88b478ff3919c8309 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/work_items')
6 files changed, 164 insertions, 14 deletions
diff --git a/app/assets/javascripts/work_items/components/item_title.vue b/app/assets/javascripts/work_items/components/item_title.vue new file mode 100644 index 00000000000..5e9e50a94f0 --- /dev/null +++ b/app/assets/javascripts/work_items/components/item_title.vue @@ -0,0 +1,71 @@ +<script> +import { escape } from 'lodash'; +import { __ } from '~/locale'; + +export default { + props: { + initialTitle: { + type: String, + required: false, + default: '', + }, + placeholder: { + type: String, + required: false, + default: __('Add a title...'), + }, + disabled: { + type: Boolean, + required: false, + default: false, + }, + }, + data() { + return { + title: this.initialTitle, + }; + }, + methods: { + getSanitizedTitle(inputEl) { + const { innerText } = inputEl; + return escape(innerText); + }, + handleBlur({ target }) { + this.$emit('title-changed', this.getSanitizedTitle(target)); + }, + handleInput({ target }) { + this.$emit('title-input', this.getSanitizedTitle(target)); + }, + handleSubmit() { + this.$refs.titleEl.blur(); + }, + }, +}; +</script> + +<template> + <h2 + class="gl-font-weight-normal gl-sm-font-weight-bold gl-my-5 gl-display-inline-block" + :class="{ 'gl-cursor-not-allowed': disabled }" + data-testid="title" + aria-labelledby="item-title" + > + <span + id="item-title" + ref="titleEl" + role="textbox" + :aria-label="__('Title')" + :data-placeholder="placeholder" + :contenteditable="!disabled" + class="gl-pseudo-placeholder" + @blur="handleBlur" + @keyup="handleInput" + @keydown.enter.exact="handleSubmit" + @keydown.ctrl.u.prevent + @keydown.meta.u.prevent + @keydown.ctrl.b.prevent + @keydown.meta.b.prevent + >{{ title }}</span + > + </h2> +</template> diff --git a/app/assets/javascripts/work_items/graphql/resolvers.js b/app/assets/javascripts/work_items/graphql/resolvers.js index bab0147f4b8..8005f334314 100644 --- a/app/assets/javascripts/work_items/graphql/resolvers.js +++ b/app/assets/javascripts/work_items/graphql/resolvers.js @@ -29,5 +29,30 @@ export const resolvers = { workItem, }; }, + + updateWorkItem(_, { input }, { cache }) { + const workItemTitle = { + __typename: 'TitleWidget', + type: 'TITLE', + enabled: true, + contentText: input.title, + }; + const workItem = { + __typename: 'WorkItem', + type: 'FEATURE', + id: input.id, + widgets: { + __typename: 'WorkItemWidgetConnection', + nodes: [workItemTitle], + }, + }; + + cache.writeQuery({ query: workItemQuery, variables: { id: input.id }, data: { workItem } }); + + return { + __typename: 'UpdateWorkItemPayload', + workItem, + }; + }, }, }; diff --git a/app/assets/javascripts/work_items/graphql/typedefs.graphql b/app/assets/javascripts/work_items/graphql/typedefs.graphql index 2a9cd52c18e..dd7ea7c26cc 100644 --- a/app/assets/javascripts/work_items/graphql/typedefs.graphql +++ b/app/assets/javascripts/work_items/graphql/typedefs.graphql @@ -37,14 +37,24 @@ type CreateWorkItemInput { title: String! } +type UpdateWorkItemInput { + id: ID! + title: String +} + type CreateWorkItemPayload { workItem: WorkItem! } +type UpdateWorkItemPayload { + workItem: WorkItem! +} + extend type Query { workItem(id: ID!): WorkItem! } extend type Mutation { createWorkItem(input: CreateWorkItemInput!): CreateWorkItemPayload! + updateWorkItem(input: UpdateWorkItemInput!): UpdateWorkItemPayload! } diff --git a/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql b/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql new file mode 100644 index 00000000000..fc140954fbe --- /dev/null +++ b/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql @@ -0,0 +1,18 @@ +#import './widget.fragment.graphql' + +mutation updateWorkItem($input: UpdateWorkItemInput) { + updateWorkItem(input: $input) @client { + workItem { + id + type + widgets { + nodes { + ...WidgetBase + ... on TitleWidget { + contentText + } + } + } + } + } +} diff --git a/app/assets/javascripts/work_items/pages/create_work_item.vue b/app/assets/javascripts/work_items/pages/create_work_item.vue index 190e50f903c..43cbee019c1 100644 --- a/app/assets/javascripts/work_items/pages/create_work_item.vue +++ b/app/assets/javascripts/work_items/pages/create_work_item.vue @@ -2,10 +2,13 @@ import { GlButton, GlAlert } from '@gitlab/ui'; import createWorkItemMutation from '../graphql/create_work_item.mutation.graphql'; +import ItemTitle from '../components/item_title.vue'; + export default { components: { GlButton, GlAlert, + ItemTitle, }, data() { return { @@ -37,6 +40,9 @@ export default { this.error = true; } }, + handleTitleInput(title) { + this.title = title; + }, }, }; </script> @@ -46,15 +52,7 @@ export default { <gl-alert v-if="error" variant="danger" @dismiss="error = false">{{ __('Something went wrong when creating a work item. Please try again') }}</gl-alert> - <label for="title" class="gl-sr-only">{{ __('Title') }}</label> - <input - id="title" - v-model.trim="title" - type="text" - class="gl-font-size-h-display gl-font-weight-bold gl-my-5 gl-border-none gl-w-full gl-pl-2" - data-testid="title-input" - :placeholder="__('Add a titleā¦')" - /> + <item-title data-testid="title-input" @title-input="handleTitleInput" /> <div class="gl-bg-gray-10 gl-py-5 gl-px-6"> <gl-button variant="confirm" diff --git a/app/assets/javascripts/work_items/pages/work_item_root.vue b/app/assets/javascripts/work_items/pages/work_item_root.vue index 493ee0aba01..479274baf3a 100644 --- a/app/assets/javascripts/work_items/pages/work_item_root.vue +++ b/app/assets/javascripts/work_items/pages/work_item_root.vue @@ -1,8 +1,16 @@ <script> +import { GlAlert } from '@gitlab/ui'; import workItemQuery from '../graphql/work_item.query.graphql'; +import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql'; import { widgetTypes } from '../constants'; +import ItemTitle from '../components/item_title.vue'; + export default { + components: { + ItemTitle, + GlAlert, + }, props: { id: { type: String, @@ -12,6 +20,7 @@ export default { data() { return { workItem: null, + error: false, }; }, apollo: { @@ -29,20 +38,39 @@ export default { return this.workItem?.widgets?.nodes?.find((widget) => widget.type === widgetTypes.title); }, }, + methods: { + async updateWorkItem(title) { + try { + await this.$apollo.mutate({ + mutation: updateWorkItemMutation, + variables: { + input: { + id: this.id, + title, + }, + }, + }); + } catch { + this.error = true; + } + }, + }, }; </script> <template> <section> + <gl-alert v-if="error" variant="danger" @dismiss="error = false">{{ + __('Something went wrong while updating work item. Please try again') + }}</gl-alert> <!-- Title widget placeholder --> <div> - <h2 + <item-title v-if="titleWidgetData" - class="gl-font-weight-normal gl-sm-font-weight-bold gl-my-5" + :initial-title="titleWidgetData.contentText" data-testid="title" - > - {{ titleWidgetData.contentText }} - </h2> + @title-changed="updateWorkItem" + /> </div> </section> </template> |