Commit 81ca8ce7 authored by Kushal Pandya's avatar Kushal Pandya

Fix missing create/manage label actions

- Fixes missing create/manage label actions.
- Fixes a bug which happened due to
`gon.suggested_label_colors` converted to map from
array.
parent c33eac31
...@@ -29,6 +29,10 @@ export default { ...@@ -29,6 +29,10 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
labelsWebUrl: {
type: String,
required: true,
},
scopedIssueBoardFeatureEnabled: { scopedIssueBoardFeatureEnabled: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -198,6 +202,7 @@ export default { ...@@ -198,6 +202,7 @@ export default {
:board="board" :board="board"
:can-admin-board="canAdminBoard" :can-admin-board="canAdminBoard"
:labels-path="labelsPath" :labels-path="labelsPath"
:labels-web-url="labelsWebUrl"
:enable-scoped-labels="enableScopedLabels" :enable-scoped-labels="enableScopedLabels"
:project-id="projectId" :project-id="projectId"
:group-id="groupId" :group-id="groupId"
......
...@@ -61,6 +61,10 @@ export default { ...@@ -61,6 +61,10 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
labelsWebUrl: {
type: String,
required: true,
},
projectId: { projectId: {
type: Number, type: Number,
required: true, required: true,
...@@ -332,6 +336,7 @@ export default { ...@@ -332,6 +336,7 @@ export default {
<board-form <board-form
v-if="currentPage" v-if="currentPage"
:labels-path="labelsPath" :labels-path="labelsPath"
:labels-web-url="labelsWebUrl"
:project-id="projectId" :project-id="projectId"
:group-id="groupId" :group-id="groupId"
:can-admin-board="canAdminBoard" :can-admin-board="canAdminBoard"
......
...@@ -14,7 +14,10 @@ import DropdownSearchInput from './dropdown_search_input.vue'; ...@@ -14,7 +14,10 @@ import DropdownSearchInput from './dropdown_search_input.vue';
import DropdownFooter from './dropdown_footer.vue'; import DropdownFooter from './dropdown_footer.vue';
import DropdownCreateLabel from './dropdown_create_label.vue'; import DropdownCreateLabel from './dropdown_create_label.vue';
import { DropdownVariant } from '../labels_select_vue/constants';
export default { export default {
DropdownVariant,
components: { components: {
DropdownTitle, DropdownTitle,
DropdownValue, DropdownValue,
...@@ -80,6 +83,11 @@ export default { ...@@ -80,6 +83,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
variant: {
type: String,
required: false,
default: DropdownVariant.Sidebar,
},
}, },
computed: { computed: {
hiddenInputName() { hiddenInputName() {
...@@ -123,7 +131,7 @@ export default { ...@@ -123,7 +131,7 @@ export default {
<template> <template>
<div class="block labels js-labels-block"> <div class="block labels js-labels-block">
<dropdown-value-collapsed <dropdown-value-collapsed
v-if="showCreate" v-if="showCreate && variant === $options.DropdownVariant.Sidebar"
:labels="context.labels" :labels="context.labels"
@onValueClick="handleCollapsedValueClick" @onValueClick="handleCollapsedValueClick"
/> />
...@@ -150,18 +158,21 @@ export default { ...@@ -150,18 +158,21 @@ export default {
:labels-path="labelsPath" :labels-path="labelsPath"
:namespace="namespace" :namespace="namespace"
:labels="context.labels" :labels="context.labels"
:show-extra-options="!showCreate" :show-extra-options="!showCreate || variant !== $options.DropdownVariant.Sidebar"
:enable-scoped-labels="enableScopedLabels" :enable-scoped-labels="enableScopedLabels"
/> />
<div <div
class="dropdown-menu dropdown-select dropdown-menu-paging class="dropdown-menu dropdown-select dropdown-menu-paging dropdown-menu-labels dropdown-menu-selectable"
dropdown-menu-labels dropdown-menu-selectable"
> >
<div class="dropdown-page-one"> <div class="dropdown-page-one">
<dropdown-header v-if="showCreate" /> <dropdown-header v-if="showCreate && variant === $options.DropdownVariant.Sidebar" />
<dropdown-search-input /> <dropdown-search-input />
<div class="dropdown-content" data-qa-selector="labels_dropdown_content"></div> <div class="dropdown-content" data-qa-selector="labels_dropdown_content"></div>
<div class="dropdown-loading"><gl-loading-icon /></div> <div class="dropdown-loading">
<gl-loading-icon
class="gl-display-flex gl-justify-content-center gl-align-items-center gl-h-full"
/>
</div>
<dropdown-footer <dropdown-footer
v-if="showCreate" v-if="showCreate"
:labels-web-url="labelsWebUrl" :labels-web-url="labelsWebUrl"
......
<script> <script>
import { GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
export default { export default {
directives: {
GlTooltip: GlTooltipDirective,
},
props: { props: {
headerTitle: { headerTitle: {
type: String, type: String,
...@@ -10,7 +14,11 @@ export default { ...@@ -10,7 +14,11 @@ export default {
}, },
}, },
created() { created() {
this.suggestedColors = gon.suggested_label_colors; const rawLabelsColors = gon.suggested_label_colors;
this.suggestedColors = Object.keys(rawLabelsColors).map(colorCode => ({
colorCode,
title: rawLabelsColors[colorCode],
}));
}, },
}; };
</script> </script>
...@@ -46,10 +54,12 @@ export default { ...@@ -46,10 +54,12 @@ export default {
<a <a
v-for="(color, index) in suggestedColors" v-for="(color, index) in suggestedColors"
:key="index" :key="index"
:data-color="color" v-gl-tooltip
:data-color="color.colorCode"
:style="{ :style="{
backgroundColor: color, backgroundColor: color.colorCode,
}" }"
:title="color.title"
href="#" href="#"
> >
&nbsp; &nbsp;
......
...@@ -171,6 +171,13 @@ ...@@ -171,6 +171,13 @@
} }
} }
.labels {
// Prevent double scroll-bars for labels dropdown.
.dropdown-menu-toggle.wide + .dropdown-select {
max-height: unset;
}
}
.gl-dropdown .dropdown-menu-toggle { .gl-dropdown .dropdown-menu-toggle {
padding-right: $gl-padding-8; padding-right: $gl-padding-8;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
can_admin_board: can?(current_user, :admin_board, parent).to_s, can_admin_board: can?(current_user, :admin_board, parent).to_s,
multiple_issue_boards_available: parent.multiple_issue_boards_available?.to_s, multiple_issue_boards_available: parent.multiple_issue_boards_available?.to_s,
labels_path: labels_filter_path_with_defaults(only_group_labels: true, include_descendant_groups: true), labels_path: labels_filter_path_with_defaults(only_group_labels: true, include_descendant_groups: true),
labels_web_url: parent.is_a?(Project) ? project_labels_path(@project) : group_labels_path(@group),
project_id: @project&.id, project_id: @project&.id,
group_id: @group&.id, group_id: @group&.id,
scoped_issue_board_feature_enabled: Gitlab.ee? && parent.feature_available?(:scoped_issue_board) ? 'true' : 'false', scoped_issue_board_feature_enabled: Gitlab.ee? && parent.feature_available?(:scoped_issue_board) ? 'true' : 'false',
......
---
title: Fix create & manage label actions in Labels dropdown
merge_request: 40511
author:
type: fixed
...@@ -31,6 +31,10 @@ export default { ...@@ -31,6 +31,10 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
labelsWebUrl: {
type: String,
required: true,
},
enableScopedLabels: { enableScopedLabels: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -110,13 +114,15 @@ export default { ...@@ -110,13 +114,15 @@ export default {
<board-labels-select <board-labels-select
:context="board" :context="board"
:labels-path="labelsPath" :labels-path="labelsPath"
:labels-web-url="labelsWebUrl"
:can-edit="canAdminBoard" :can-edit="canAdminBoard"
:show-create="canAdminBoard"
:enable-scoped-labels="enableScopedLabels" :enable-scoped-labels="enableScopedLabels"
variant="standalone"
ability-name="issue" ability-name="issue"
@onLabelClick="handleLabelClick" @onLabelClick="handleLabelClick"
>{{ __('Any label') }}</board-labels-select
> >
{{ __('Any label') }}
</board-labels-select>
<assignee-select <assignee-select
:board="board" :board="board"
......
...@@ -4,6 +4,7 @@ require 'spec_helper' ...@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe 'Scoped issue boards', :js do RSpec.describe 'Scoped issue boards', :js do
include FilteredSearchHelpers include FilteredSearchHelpers
include MobileHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let(:group) { create(:group, :public) } let(:group) { create(:group, :public) }
...@@ -34,10 +35,16 @@ RSpec.describe 'Scoped issue boards', :js do ...@@ -34,10 +35,16 @@ RSpec.describe 'Scoped issue boards', :js do
login_as(user) login_as(user)
# ensure there is enough vertical space for create/edit board modal
resize_window(1920, 1080)
visit project_boards_path(project) visit project_boards_path(project)
wait_for_requests wait_for_requests
end end
after do
restore_window_size
end
context 'new board' do context 'new board' do
context 'milestone' do context 'milestone' do
it 'creates board filtering by milestone' do it 'creates board filtering by milestone' do
......
...@@ -15,6 +15,7 @@ describe('BoardScope', () => { ...@@ -15,6 +15,7 @@ describe('BoardScope', () => {
assignee: {}, assignee: {},
}, },
labelsPath: `${TEST_HOST}/labels`, labelsPath: `${TEST_HOST}/labels`,
labelsWebUrl: `${TEST_HOST}/-/labels`,
}; };
wrapper = mount(BoardScope, { wrapper = mount(BoardScope, {
......
...@@ -11,6 +11,7 @@ describe('board_form.vue', () => { ...@@ -11,6 +11,7 @@ describe('board_form.vue', () => {
const propsData = { const propsData = {
canAdminBoard: false, canAdminBoard: false,
labelsPath: `${TEST_HOST}/labels/path`, labelsPath: `${TEST_HOST}/labels/path`,
labelsWebUrl: `${TEST_HOST}/-/labels`,
}; };
const findModal = () => wrapper.find(DeprecatedModal); const findModal = () => wrapper.find(DeprecatedModal);
......
...@@ -86,6 +86,7 @@ describe('BoardsSelector', () => { ...@@ -86,6 +86,7 @@ describe('BoardsSelector', () => {
canAdminBoard: true, canAdminBoard: true,
multipleIssueBoardsAvailable: true, multipleIssueBoardsAvailable: true,
labelsPath: `${TEST_HOST}/labels/path`, labelsPath: `${TEST_HOST}/labels/path`,
labelsWebUrl: `${TEST_HOST}/labels`,
projectId: 42, projectId: 42,
groupId: 19, groupId: 19,
scopedIssueBoardFeatureEnabled: true, scopedIssueBoardFeatureEnabled: true,
......
...@@ -14,6 +14,7 @@ const createComponent = headerTitle => { ...@@ -14,6 +14,7 @@ const createComponent = headerTitle => {
}; };
describe('DropdownCreateLabelComponent', () => { describe('DropdownCreateLabelComponent', () => {
const colorsCount = Object.keys(mockSuggestedColors).length;
let vm; let vm;
beforeEach(() => { beforeEach(() => {
...@@ -27,7 +28,7 @@ describe('DropdownCreateLabelComponent', () => { ...@@ -27,7 +28,7 @@ describe('DropdownCreateLabelComponent', () => {
describe('created', () => { describe('created', () => {
it('initializes `suggestedColors` prop on component from `gon.suggested_color_labels` object', () => { it('initializes `suggestedColors` prop on component from `gon.suggested_color_labels` object', () => {
expect(vm.suggestedColors.length).toBe(mockSuggestedColors.length); expect(vm.suggestedColors.length).toBe(colorsCount);
}); });
}); });
...@@ -78,11 +79,11 @@ describe('DropdownCreateLabelComponent', () => { ...@@ -78,11 +79,11 @@ describe('DropdownCreateLabelComponent', () => {
const colorsListContainerEl = vm.$el.querySelector('.suggest-colors.suggest-colors-dropdown'); const colorsListContainerEl = vm.$el.querySelector('.suggest-colors.suggest-colors-dropdown');
expect(colorsListContainerEl).not.toBe(null); expect(colorsListContainerEl).not.toBe(null);
expect(colorsListContainerEl.querySelectorAll('a').length).toBe(mockSuggestedColors.length); expect(colorsListContainerEl.querySelectorAll('a').length).toBe(colorsCount);
const colorItemEl = colorsListContainerEl.querySelectorAll('a')[0]; const colorItemEl = colorsListContainerEl.querySelectorAll('a')[0];
expect(colorItemEl.dataset.color).toBe(vm.suggestedColors[0]); expect(colorItemEl.dataset.color).toBe(vm.suggestedColors[0].colorCode);
expect(colorItemEl.getAttribute('style')).toBe('background-color: rgb(0, 51, 204);'); expect(colorItemEl.getAttribute('style')).toBe('background-color: rgb(0, 51, 204);');
}); });
......
...@@ -15,29 +15,29 @@ export const mockLabels = [ ...@@ -15,29 +15,29 @@ export const mockLabels = [
}, },
]; ];
export const mockSuggestedColors = [ export const mockSuggestedColors = {
'#0033CC', '#0033CC': 'UA blue',
'#428BCA', '#428BCA': 'Moderate blue',
'#44AD8E', '#44AD8E': 'Lime green',
'#A8D695', '#A8D695': 'Feijoa',
'#5CB85C', '#5CB85C': 'Slightly desaturated green',
'#69D100', '#69D100': 'Bright green',
'#004E00', '#004E00': 'Very dark lime green',
'#34495E', '#34495E': 'Very dark desaturated blue',
'#7F8C8D', '#7F8C8D': 'Dark grayish cyan',
'#A295D6', '#A295D6': 'Slightly desaturated blue',
'#5843AD', '#5843AD': 'Dark moderate blue',
'#8E44AD', '#8E44AD': 'Dark moderate violet',
'#FFECDB', '#FFECDB': 'Very pale orange',
'#AD4363', '#AD4363': 'Dark moderate pink',
'#D10069', '#D10069': 'Strong pink',
'#CC0033', '#CC0033': 'Strong red',
'#FF0000', '#FF0000': 'Pure red',
'#D9534F', '#D9534F': 'Soft red',
'#D1D100', '#D1D100': 'Strong yellow',
'#F0AD4E', '#F0AD4E': 'Soft orange',
'#AD8D43', '#AD8D43': 'Dark moderate orange',
]; };
export const mockConfig = { export const mockConfig = {
showCreate: true, showCreate: true,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment