Commit 82711ce5 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '283255-order-scoped-labels-first' into 'master'

Sort scoped labels first in issuable sidebar

See merge request gitlab-org/gitlab!67794
parents c6284616 622853e2
<script>
import { GlLabel } from '@gitlab/ui';
import { sortBy } from 'lodash';
import { mapState } from 'vuex';
import { isScopedLabel } from '~/lib/utils/common_utils';
......@@ -23,6 +24,9 @@ export default {
'labelsFilterBasePath',
'labelsFilterParam',
]),
sortedSelectedLabels() {
return sortBy(this.selectedLabels, (label) => (isScopedLabel(label) ? 0 : 1));
},
},
methods: {
labelFilterUrl(label) {
......@@ -47,7 +51,7 @@ export default {
<span v-if="!selectedLabels.length" class="text-secondary">
<slot></slot>
</span>
<template v-for="label in selectedLabels" v-else>
<template v-for="label in sortedSelectedLabels" v-else>
<gl-label
:key="label.id"
data-qa-selector="selected_label_content"
......
<script>
import { GlLabel } from '@gitlab/ui';
import { sortBy } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { isScopedLabel } from '~/lib/utils/common_utils';
......@@ -31,6 +32,11 @@ export default {
required: true,
},
},
computed: {
sortedSelectedLabels() {
return sortBy(this.selectedLabels, (label) => (isScopedLabel(label) ? 0 : 1));
},
},
methods: {
labelFilterUrl(label) {
return `${this.labelsFilterBasePath}?${this.labelsFilterParam}[]=${encodeURIComponent(
......@@ -60,7 +66,7 @@ export default {
</span>
<template v-else>
<gl-label
v-for="label in selectedLabels"
v-for="label in sortedSelectedLabels"
:key="label.id"
data-qa-selector="selected_label_content"
:data-qa-label-name="label.title"
......
......@@ -156,7 +156,7 @@ describe('sidebar labels', () => {
variables: {
input: {
iid: defaultProps.iid,
labelIds: [toLabelGid(27), toLabelGid(28), toLabelGid(29), toLabelGid(40)],
labelIds: [toLabelGid(29), toLabelGid(28), toLabelGid(27), toLabelGid(40)],
operationMode: MutationOperationMode.Replace,
projectPath: defaultProps.projectPath,
},
......
......@@ -124,7 +124,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('returns false when provided `label` param is not one of the selected labels', () => {
expect(wrapper.vm.isLabelSelected(mockLabels[2])).toBe(false);
expect(wrapper.vm.isLabelSelected(mockLabels[1])).toBe(false);
});
});
......@@ -203,7 +203,7 @@ describe('DropdownContentsLabelsView', () => {
it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
wrapper.setData({
currentHighlightItem: 1,
currentHighlightItem: 2,
});
wrapper.vm.handleKeyDown({
......@@ -213,7 +213,7 @@ describe('DropdownContentsLabelsView', () => {
expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([
{
...mockLabels[1],
...mockLabels[2],
set: true,
},
]);
......
......@@ -6,7 +6,7 @@ import DropdownValue from '~/vue_shared/components/sidebar/labels_select_vue/dro
import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_vue/store';
import { mockConfig, mockRegularLabel, mockScopedLabel } from './mock_data';
import { mockConfig, mockLabels, mockRegularLabel, mockScopedLabel } from './mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
......@@ -14,6 +14,9 @@ localVue.use(Vuex);
describe('DropdownValue', () => {
let wrapper;
const findAllLabels = () => wrapper.findAllComponents(GlLabel);
const findLabel = (index) => findAllLabels().at(index).props('title');
const createComponent = (initialState = {}, slots = {}) => {
const store = new Vuex.Store(labelsSelectModule());
......@@ -28,7 +31,6 @@ describe('DropdownValue', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('methods', () => {
......@@ -82,7 +84,17 @@ describe('DropdownValue', () => {
it('renders labels when `selectedLabels` is not empty', () => {
createComponent();
expect(wrapper.findAll(GlLabel).length).toBe(2);
expect(findAllLabels()).toHaveLength(2);
});
it('orders scoped labels first', () => {
createComponent({ selectedLabels: mockLabels });
expect(findAllLabels()).toHaveLength(mockLabels.length);
expect(findLabel(0)).toBe('Foo::Bar');
expect(findLabel(1)).toBe('Boog');
expect(findLabel(2)).toBe('Bug');
expect(findLabel(3)).toBe('Foo Label');
});
});
});
......@@ -15,22 +15,22 @@ export const mockScopedLabel = {
};
export const mockLabels = [
mockRegularLabel,
mockScopedLabel,
{
id: 28,
title: 'Bug',
id: 29,
title: 'Boog',
description: 'Label for bugs',
color: '#FF0000',
textColor: '#FFFFFF',
},
{
id: 29,
title: 'Boog',
id: 28,
title: 'Bug',
description: 'Label for bugs',
color: '#FF0000',
textColor: '#FFFFFF',
},
mockRegularLabel,
mockScopedLabel,
];
export const mockCollapsedLabels = [
......
......@@ -9,8 +9,8 @@ describe('DropdownValue', () => {
let wrapper;
const findAllLabels = () => wrapper.findAllComponents(GlLabel);
const findRegularLabel = () => findAllLabels().at(0);
const findScopedLabel = () => findAllLabels().at(1);
const findRegularLabel = () => findAllLabels().at(1);
const findScopedLabel = () => findAllLabels().at(0);
const findWrapper = () => wrapper.find('[data-testid="value-wrapper"]');
const findEmptyPlaceholder = () => wrapper.find('[data-testid="empty-placeholder"]');
......
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