diff options
Diffstat (limited to 'app/assets/javascripts/sidebar')
8 files changed, 143 insertions, 59 deletions
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue index 4ff12824008..0ac6208c7d3 100644 --- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue +++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue @@ -6,6 +6,7 @@ import { TYPE_ALERT, TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/issues/constants'; import { __, n__ } from '~/locale'; import UserSelect from '~/vue_shared/components/user_select/user_select.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { ISSUE_MR_CHANGE_ASSIGNEE } from '~/behaviors/shortcuts/keybindings'; import { assigneesQueries } from '../../queries/constants'; import SidebarEditableItem from '../sidebar_editable_item.vue'; import SidebarAssigneesRealtime from './assignees_realtime.vue'; @@ -156,6 +157,12 @@ export default { issuableAuthor() { return this.issuable?.author; }, + assigneeShortcutDescription() { + return ISSUE_MR_CHANGE_ASSIGNEE.description; + }, + assigneeShortcutKey() { + return ISSUE_MR_CHANGE_ASSIGNEE.defaultKeys[0]; + }, }, watch: { iid(_, oldIid) { @@ -246,6 +253,9 @@ export default { :loading="isSettingAssignees" :initial-loading="isAssigneesLoading" :title="assigneeText" + :edit-tooltip="`${assigneeShortcutDescription} <kbd class='flat ml-1' aria-hidden=true>${assigneeShortcutKey}</kbd>`" + :edit-aria-label="assigneeShortcutDescription" + :edit-keyshortcuts="assigneeShortcutKey" :is-dirty="isDirty" @open="showDropdown" @close="saveAssignees" diff --git a/app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue b/app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue index 93e3cfba309..f3209d1a02f 100644 --- a/app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue +++ b/app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue @@ -1,17 +1,11 @@ <script> import { get } from 'lodash'; -import { - GlAlert, - GlTooltipDirective, - GlButton, - GlFormInput, - GlLink, - GlLoadingIcon, -} from '@gitlab/ui'; +import { GlAlert, GlTooltipDirective, GlButton, GlFormInput, GlLoadingIcon } from '@gitlab/ui'; import produce from 'immer'; import { createAlert } from '~/alert'; import { WORKSPACE_GROUP } from '~/issues/constants'; import { __ } from '~/locale'; +import SidebarColorPicker from '../../sidebar_color_picker.vue'; import { workspaceLabelsQueries, workspaceCreateLabelMutation } from '../../../queries/constants'; import { DEFAULT_LABEL_COLOR } from './constants'; @@ -22,8 +16,8 @@ export default { GlAlert, GlButton, GlFormInput, - GlLink, GlLoadingIcon, + SidebarColorPicker, }, directives: { GlTooltip: GlTooltipDirective, @@ -84,15 +78,6 @@ export default { }, }, methods: { - getColorCode(color) { - return Object.keys(color).pop(); - }, - getColorName(color) { - return Object.values(color).pop(); - }, - handleColorClick(color) { - this.selectedColor = this.getColorCode(color); - }, updateLabelsInCache(store, label) { const { query, dataPath } = workspaceLabelsQueries[this.workspaceType]; @@ -163,34 +148,7 @@ export default { data-testid="label-title-input" /> </div> - <div class="dropdown-content gl-px-3"> - <div class="suggest-colors suggest-colors-dropdown gl-mt-0! gl-mb-3! gl-mb-0"> - <gl-link - v-for="(color, index) in suggestedColors" - :key="index" - v-gl-tooltip:tooltipcontainer - :style="{ backgroundColor: getColorCode(color) }" - :title="getColorName(color)" - @click.prevent="handleColorClick(color)" - /> - </div> - <div class="color-input-container gl-display-flex"> - <gl-form-input - v-model.trim="selectedColor" - class="gl-rounded-top-right-none gl-rounded-bottom-right-none gl-mr-n1 gl-mb-2 gl-w-8" - type="color" - :value="selectedColor" - :placeholder="__('Select color')" - data-testid="selected-color" - /> - <gl-form-input - v-model.trim="selectedColor" - class="gl-rounded-top-left-none gl-rounded-bottom-left-none gl-mb-2" - :placeholder="__('Use custom color #FF0000')" - data-testid="selected-color-text" - /> - </div> - </div> + <sidebar-color-picker v-model.trim="selectedColor" /> <div class="dropdown-actions gl-display-flex gl-justify-content-space-between gl-pt-3 gl-px-3"> <gl-button :disabled="disableCreate" diff --git a/app/assets/javascripts/sidebar/components/labels/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/sidebar/components/labels/labels_select_widget/labels_select_root.vue index e0d7400f7a6..cbaa8a59813 100644 --- a/app/assets/javascripts/sidebar/components/labels/labels_select_widget/labels_select_root.vue +++ b/app/assets/javascripts/sidebar/components/labels/labels_select_widget/labels_select_root.vue @@ -1,12 +1,13 @@ <script> import { debounce } from 'lodash'; import issuableLabelsSubscription from 'ee_else_ce/sidebar/queries/issuable_labels.subscription.graphql'; -import { MutationOperationMode, getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { mutationOperationMode, getIdFromGraphQLId } from '~/graphql_shared/utils'; import { createAlert } from '~/alert'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { TYPE_EPIC, TYPE_ISSUE, TYPE_MERGE_REQUEST, TYPE_TEST_CASE } from '~/issues/constants'; import { __ } from '~/locale'; +import { ISSUABLE_CHANGE_LABEL } from '~/behaviors/shortcuts/keybindings'; import { issuableLabelsQueries } from '../../../queries/constants'; import SidebarEditableItem from '../../sidebar_editable_item.vue'; import { DEBOUNCE_DROPDOWN_DELAY, VARIANT_SIDEBAR } from './constants'; @@ -159,6 +160,12 @@ export default { isLockOnMergeSupported() { return this.issuableSupportsLockOnMerge || this.issuable?.supportsLockOnMerge; }, + labelShortcutDescription() { + return ISSUABLE_CHANGE_LABEL.description; + }, + labelShortcutKey() { + return ISSUABLE_CHANGE_LABEL.defaultKeys[0]; + }, }, apollo: { issuable: { @@ -275,7 +282,7 @@ export default { case TYPE_MERGE_REQUEST: return { ...updateVariables, - operationMode: MutationOperationMode.Replace, + operationMode: mutationOperationMode.replace, }; case TYPE_EPIC: return { @@ -336,7 +343,7 @@ export default { return { ...removeVariables, labelIds: [labelId], - operationMode: MutationOperationMode.Remove, + operationMode: mutationOperationMode.remove, }; case TYPE_EPIC: return { @@ -375,6 +382,9 @@ export default { <sidebar-editable-item ref="editable" :title="__('Labels')" + :edit-tooltip="`${labelShortcutDescription} <kbd class='flat ml-1' aria-hidden=true>${labelShortcutKey}</kbd>`" + :edit-aria-label="labelShortcutDescription" + :edit-keyshortcuts="labelShortcutKey" :loading="isLoading" :can-edit="allowLabelEdit" @open="oldIid = null" diff --git a/app/assets/javascripts/sidebar/components/sidebar_color_picker.vue b/app/assets/javascripts/sidebar/components/sidebar_color_picker.vue new file mode 100644 index 00000000000..95b1febb575 --- /dev/null +++ b/app/assets/javascripts/sidebar/components/sidebar_color_picker.vue @@ -0,0 +1,75 @@ +<script> +import { GlFormInput, GlLink, GlTooltipDirective } from '@gitlab/ui'; + +export default { + components: { + GlFormInput, + GlLink, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + value: { + type: String, + required: false, + default: '', + }, + }, + computed: { + suggestedColors() { + const colorsMap = gon.suggested_label_colors; + return Object.keys(colorsMap).map((color) => ({ [color]: colorsMap[color] })); + }, + selectedColor: { + get() { + return this.value; + }, + set(color) { + this.handleColorClick(color); + }, + }, + }, + methods: { + handleColorClick(color) { + this.$emit('input', color); + }, + getColorCode(color) { + return Object.keys(color).pop(); + }, + getColorName(color) { + return Object.values(color).pop(); + }, + }, +}; +</script> +<template> + <div class="dropdown-content gl-px-3"> + <div class="suggest-colors suggest-colors-dropdown gl-mt-0!"> + <gl-link + v-for="(color, index) in suggestedColors" + :key="index" + v-gl-tooltip:tooltipcontainer + :style="{ backgroundColor: getColorCode(color) }" + :title="getColorName(color)" + @click.prevent="handleColorClick(getColorCode(color))" + /> + </div> + <div class="color-input-container gl-display-flex"> + <gl-form-input + v-model.trim="selectedColor" + class="gl-rounded-top-right-none gl-rounded-bottom-right-none gl-mr-n1 gl-mb-2 gl-w-8" + type="color" + :value="selectedColor" + :placeholder="__('Select color')" + data-testid="selected-color" + /> + <gl-form-input + v-model.trim="selectedColor" + class="gl-rounded-top-left-none gl-rounded-bottom-left-none gl-mb-2" + :placeholder="__('Use custom color #FF0000')" + data-testid="selected-color-text" + /> + </div> + </div> +</template> diff --git a/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue b/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue index ad83866ceb2..c887d5d292e 100644 --- a/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue +++ b/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue @@ -1,5 +1,5 @@ <script> -import { GlButton, GlLoadingIcon } from '@gitlab/ui'; +import { GlButton, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; import { __ } from '~/locale'; export default { @@ -7,6 +7,9 @@ export default { unassigned: __('Unassigned'), }, components: { GlButton, GlLoadingIcon }, + directives: { + GlTooltip: GlTooltipDirective, + }, inject: { canUpdate: {}, isClassicSidebar: { @@ -58,6 +61,21 @@ export default { required: false, default: false, }, + editTooltip: { + type: String, + required: false, + default: '', + }, + editAriaLabel: { + type: String, + required: false, + default: '', + }, + editKeyshortcuts: { + type: String, + required: false, + default: '', + }, }, data() { return { @@ -68,6 +86,15 @@ export default { editButtonText() { return this.isDirty ? __('Apply') : __('Edit'); }, + editTooltipText() { + return this.isDirty ? '' : this.editTooltip; + }, + editAriaLabelText() { + return this.isDirty ? this.editButtonText : this.editAriaLabel; + }, + editKeyshortcutsText() { + return this.isDirty ? __('Escape') : this.editKeyshortcuts; + }, }, destroyed() { window.removeEventListener('click', this.collapseWhenOffClick); @@ -150,9 +177,13 @@ export default { <gl-button v-if="canUpdate && !initialLoading && canEdit" :id="buttonId" + v-gl-tooltip.viewport.html category="tertiary" size="small" class="gl-text-gray-900! gl-ml-auto hide-collapsed gl-mr-n2 shortcut-sidebar-dropdown-toggle" + :title="editTooltipText" + :aria-label="editAriaLabelText" + :aria-keyshortcuts="editKeyshortcutsText" data-testid="edit-button" :data-track-action="tracking.event" :data-track-label="tracking.label" 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 f2257adb79c..3dfe5b6cc15 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 @@ -6,7 +6,7 @@ import { TYPE_MERGE_REQUEST } from '~/issues/constants'; import { __, sprintf } from '~/locale'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import Tracking from '~/tracking'; -import { TodoMutationTypes } from '../../constants'; +import { todoMutationTypes } from '../../constants'; import { todoQueries, todoMutations } from '../../queries/constants'; import { todoLabel } from '../../utils'; import TodoButton from './todo_button.vue'; @@ -104,9 +104,9 @@ export default { }, todoMutationType() { if (this.hasTodo) { - return TodoMutationTypes.MarkDone; + return todoMutationTypes.markDone; } - return TodoMutationTypes.Create; + return todoMutationTypes.create; }, collapsedButtonIcon() { return this.hasTodo ? 'todo-done' : 'todo-add'; diff --git a/app/assets/javascripts/sidebar/constants.js b/app/assets/javascripts/sidebar/constants.js index f13f613733b..953684b5c93 100644 --- a/app/assets/javascripts/sidebar/constants.js +++ b/app/assets/javascripts/sidebar/constants.js @@ -44,9 +44,9 @@ export const IssuableAttributeState = { [IssuableAttributeType.Milestone]: 'active', }; -export const TodoMutationTypes = { - Create: 'create', - MarkDone: 'mark-done', +export const todoMutationTypes = { + create: 'create', + markDone: 'mark-done', }; export function dropdowni18nText(issuableAttribute, issuableType) { diff --git a/app/assets/javascripts/sidebar/queries/constants.js b/app/assets/javascripts/sidebar/queries/constants.js index 6bcdc01a003..dbb2f14880a 100644 --- a/app/assets/javascripts/sidebar/queries/constants.js +++ b/app/assets/javascripts/sidebar/queries/constants.js @@ -22,7 +22,7 @@ import groupLabelsQuery from '../components/labels/labels_select_widget/graphql/ import issueLabelsQuery from '../components/labels/labels_select_widget/graphql/issue_labels.query.graphql'; import mergeRequestLabelsQuery from '../components/labels/labels_select_widget/graphql/merge_request_labels.query.graphql'; import projectLabelsQuery from '../components/labels/labels_select_widget/graphql/project_labels.query.graphql'; -import { IssuableAttributeType, TodoMutationTypes } from '../constants'; +import { IssuableAttributeType, todoMutationTypes } from '../constants'; import epicConfidentialQuery from './epic_confidential.query.graphql'; import epicDueDateQuery from './epic_due_date.query.graphql'; import epicParticipantsQuery from './epic_participants.query.graphql'; @@ -282,8 +282,8 @@ export const todoQueries = { }; export const todoMutations = { - [TodoMutationTypes.Create]: todoCreateMutation, - [TodoMutationTypes.MarkDone]: todoMarkDoneMutation, + [todoMutationTypes.create]: todoCreateMutation, + [todoMutationTypes.markDone]: todoMarkDoneMutation, }; export const escalationStatusQuery = getEscalationStatusQuery; |