From 9b4589cf4c16115344091c6198f56c65a51a0f73 Mon Sep 17 00:00:00 2001
From: Florie Guibert <fguibert@gitlab.com>
Date: Tue, 13 Jul 2021 11:33:24 +1000
Subject: [PATCH] Migrate Add To Do button to widget

Review feedback
---
 .../components/design_todo_button.vue         |  2 +-
 .../todo_toggle/sidebar_todo_widget.vue       | 21 ++++++++++++-------
 .../javascripts/sidebar/mount_sidebar.js      |  8 +++++--
 app/assets/javascripts/sidebar/utils.js       |  4 ----
 .../{ => todo_toggle}/todo_button.stories.js  |  2 +-
 .../sidebar/{ => todo_toggle}/todo_button.vue |  4 ++--
 .../components/sidebar/todo_toggle/utils.js   |  5 +++++
 doc/development/fe_guide/storybook.md         |  2 +-
 .../components/design_todo_button_spec.js     |  2 +-
 .../todo_toggle/sidebar_todo_widget_spec.js   |  2 +-
 .../components/sidebar/todo_button_spec.js    |  2 +-
 11 files changed, 33 insertions(+), 21 deletions(-)
 rename app/assets/javascripts/vue_shared/components/sidebar/{ => todo_toggle}/todo_button.stories.js (90%)
 rename app/assets/javascripts/vue_shared/components/sidebar/{ => todo_toggle}/todo_button.vue (92%)
 create mode 100644 app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js

diff --git a/app/assets/javascripts/design_management/components/design_todo_button.vue b/app/assets/javascripts/design_management/components/design_todo_button.vue
index c614fee17d114..013dd1d89f3ca 100644
--- a/app/assets/javascripts/design_management/components/design_todo_button.vue
+++ b/app/assets/javascripts/design_management/components/design_todo_button.vue
@@ -1,6 +1,6 @@
 <script>
 import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 import createDesignTodoMutation from '../graphql/mutations/create_design_todo.mutation.graphql';
 import getDesignQuery from '../graphql/queries/get_design.query.graphql';
 import allVersionsMixin from '../mixins/all_versions';
diff --git a/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue b/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
index f0784f2ed1066..a9c4203af22b2 100644
--- a/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
+++ b/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
@@ -1,13 +1,15 @@
 <script>
-import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlButton, GlIcon, GlTooltipDirective } from '@gitlab/ui';
 import { produce } from 'immer';
 import createFlash from '~/flash';
 import { __, sprintf } from '~/locale';
 import { todoQueries, TodoMutationTypes, todoMutations } from '~/sidebar/constants';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import { todoLabel } from '~/vue_shared/components/sidebar/todo_toggle//utils';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 
 export default {
   components: {
+    GlButton,
     GlIcon,
     TodoButton,
   },
@@ -96,7 +98,7 @@ export default {
       return this.hasTodo ? 'todo-done' : 'todo-add';
     },
     tootltipTitle() {
-      return this.hasTodo ? __('Mark as done') : __('Add a to do');
+      return todoLabel(this.hasTodo);
     },
   },
   methods: {
@@ -173,16 +175,21 @@ export default {
       class="hide-collapsed"
       @click.stop.prevent="toggleTodo"
     />
-    <div v-if="isClassicSidebar" class="sidebar-collapsed-icon sidebar-collapsed-container">
+    <gl-button
+      v-if="isClassicSidebar"
+      category="tertiary"
+      type="reset"
+      class="sidebar-collapsed-icon sidebar-collapsed-container gl-rounded-0! gl-shadow-none!"
+      @click.stop.prevent="toggleTodo"
+    >
       <gl-icon
-        v-gl-tooltip
+        v-gl-tooltip.left.viewport
         :title="tootltipTitle"
         :size="16"
         :class="{ 'todo-undone': hasTodo }"
         :name="collapsedButtonIcon"
         :aria-label="collapsedButtonIcon"
-        @click.stop.prevent="toggleTodo"
       />
-    </div>
+    </gl-button>
   </div>
 </template>
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index 380ec1f752718..dd1b439c482e3 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -2,6 +2,8 @@ import $ from 'jquery';
 import Vue from 'vue';
 import VueApollo from 'vue-apollo';
 import createFlash from '~/flash';
+import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
 import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
 import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
 import { IssuableType } from '~/issue_show/constants';
@@ -22,7 +24,6 @@ import SidebarDropdownWidget from '~/sidebar/components/sidebar_dropdown_widget.
 import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
 import { apolloProvider } from '~/sidebar/graphql';
 import trackShowInviteMemberLink from '~/sidebar/track_invite_members';
-import { toIssueGid, toMergeRequestGid } from '~/sidebar/utils';
 import Translate from '../vue_shared/translate';
 import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
 import CopyEmailToClipboard from './components/copy_email_to_clipboard.vue';
@@ -64,7 +65,10 @@ function mountSidebarToDoWidget() {
       createElement('sidebar-todo-widget', {
         props: {
           fullPath: projectPath,
-          issuableId: isInIssuePage() || isInDesignPage() ? toIssueGid(id) : toMergeRequestGid(id),
+          issuableId:
+            isInIssuePage() || isInDesignPage()
+              ? convertToGraphQLId(TYPE_ISSUE, id)
+              : convertToGraphQLId(TYPE_MERGE_REQUEST, id),
           issuableIid: iid,
           issuableType:
             isInIssuePage() || isInDesignPage() ? IssuableType.Issue : IssuableType.MergeRequest,
diff --git a/app/assets/javascripts/sidebar/utils.js b/app/assets/javascripts/sidebar/utils.js
index 06bb1ee59f173..20cd4ce9d99d7 100644
--- a/app/assets/javascripts/sidebar/utils.js
+++ b/app/assets/javascripts/sidebar/utils.js
@@ -1,5 +1 @@
 export const toLabelGid = (id) => `gid://gitlab/Label/${id}`;
-
-export const toIssueGid = (id) => `gid://gitlab/Issue/${id}`;
-
-export const toMergeRequestGid = (id) => `gid://gitlab/MergeRequest/${id}`;
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.stories.js b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.stories.js
similarity index 90%
rename from app/assets/javascripts/vue_shared/components/sidebar/todo_button.stories.js
rename to app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.stories.js
index db4d8724a0d9f..d2afc02233efc 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.stories.js
+++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.stories.js
@@ -4,7 +4,7 @@ import TodoButton from './todo_button.vue';
 
 export default {
   component: TodoButton,
-  title: 'vue_shared/components/todo_button',
+  title: 'vue_shared/components/todo_toggle/todo_button',
 };
 
 const Template = (args, { argTypes }) => ({
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue
similarity index 92%
rename from app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue
rename to app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue
index a35171835153e..e6229cf0a937a 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue
@@ -1,6 +1,6 @@
 <script>
 import { GlButton } from '@gitlab/ui';
-import { __ } from '~/locale';
+import { todoLabel } from './utils';
 
 export default {
   components: {
@@ -15,7 +15,7 @@ export default {
   },
   computed: {
     buttonLabel() {
-      return this.isTodo ? __('Mark as done') : __('Add a to do');
+      return todoLabel(this.isTodo);
     },
   },
   methods: {
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js
new file mode 100644
index 0000000000000..59e72a2ffe34c
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/utils.js
@@ -0,0 +1,5 @@
+import { __ } from '~/locale';
+
+export const todoLabel = (hasTodo) => {
+  return hasTodo ? __('Mark as done') : __('Add a to do');
+};
diff --git a/doc/development/fe_guide/storybook.md b/doc/development/fe_guide/storybook.md
index 986eafb11da45..15225cc1debbb 100644
--- a/doc/development/fe_guide/storybook.md
+++ b/doc/development/fe_guide/storybook.md
@@ -47,5 +47,5 @@ To add a story:
 
    Notes:
    - Specify the `title` field of the story as the component's file path from the `javascripts/` directory,
-     e.g. if the component is located at `app/assets/javascripts/vue_shared/components/sidebar/todo_button.vue`, specify the `title` as
+     e.g. if the component is located at `app/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue`, specify the `title` as
      `vue_shared/components/To-do Button`. This will ensure the Storybook navigation maps closely to our internal directory structure.
diff --git a/spec/frontend/design_management/components/design_todo_button_spec.js b/spec/frontend/design_management/components/design_todo_button_spec.js
index 816de32d2db68..757bf50c52783 100644
--- a/spec/frontend/design_management/components/design_todo_button_spec.js
+++ b/spec/frontend/design_management/components/design_todo_button_spec.js
@@ -2,7 +2,7 @@ import { shallowMount, mount } from '@vue/test-utils';
 import DesignTodoButton from '~/design_management/components/design_todo_button.vue';
 import createDesignTodoMutation from '~/design_management/graphql/mutations/create_design_todo.mutation.graphql';
 import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 import mockDesign from '../mock_data/design';
 
 const mockDesignWithPendingTodos = {
diff --git a/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js b/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
index 8190545f7d4dc..23f1753c4bf65 100644
--- a/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
+++ b/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
@@ -7,7 +7,7 @@ import waitForPromises from 'helpers/wait_for_promises';
 import createFlash from '~/flash';
 import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
 import epicTodoQuery from '~/sidebar/queries/epic_todo.query.graphql';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 import { todosResponse, noTodosResponse } from '../../mock_data';
 
 jest.mock('~/flash');
diff --git a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
index 123a995ad5778..de3e1ccfb0310 100644
--- a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
@@ -1,6 +1,6 @@
 import { GlButton } from '@gitlab/ui';
 import { shallowMount, mount } from '@vue/test-utils';
-import TodoButton from '~/vue_shared/components/sidebar/todo_button.vue';
+import TodoButton from '~/vue_shared/components/sidebar/todo_toggle/todo_button.vue';
 
 describe('Todo Button', () => {
   let wrapper;
-- 
GitLab