Commit 4e41c7e6 authored by Florie Guibert's avatar Florie Guibert Committed by Natalia Tepluhina

Labels widget architecture polish

parent 4a57a0d5
<script>
import { GlLabel } from '@gitlab/ui';
import { GlIcon, GlLabel, GlTooltipDirective } from '@gitlab/ui';
import { sortBy } from 'lodash';
import { isScopedLabel } from '~/lib/utils/common_utils';
import { s__, sprintf } from '~/locale';
export default {
directives: {
GlTooltip: GlTooltipDirective,
},
components: {
GlIcon,
GlLabel,
},
inject: ['allowScopedLabels'],
......@@ -35,6 +40,23 @@ export default {
sortedSelectedLabels() {
return sortBy(this.selectedLabels, (label) => (isScopedLabel(label) ? 0 : 1));
},
labelsList() {
const labelsString = this.selectedLabels.length
? this.selectedLabels
.slice(0, 5)
.map((label) => label.title)
.join(', ')
: s__('LabelSelect|Labels');
if (this.selectedLabels.length > 5) {
return sprintf(s__('LabelSelect|%{labelsString}, and %{remainingLabelCount} more'), {
labelsString,
remainingLabelCount: this.selectedLabels.length - 5,
});
}
return labelsString;
},
},
methods: {
labelFilterUrl(label) {
......@@ -48,6 +70,9 @@ export default {
removeLabel(labelId) {
this.$emit('onLabelRemove', labelId);
},
handleCollapsedClick() {
this.$emit('onCollapsedValueClick');
},
},
};
</script>
......@@ -57,16 +82,30 @@ export default {
:class="{
'has-labels': selectedLabels.length,
}"
class="hide-collapsed value issuable-show-labels js-value"
class="value issuable-show-labels js-value"
data-testid="value-wrapper"
>
<span v-if="!selectedLabels.length" class="text-secondary" data-testid="empty-placeholder">
<div
v-gl-tooltip.left.viewport
:title="labelsList"
class="sidebar-collapsed-icon"
@click="handleCollapsedClick"
>
<gl-icon name="labels" />
<span class="gl-font-base gl-line-height-24">{{ selectedLabels.length }}</span>
</div>
<span
v-if="!selectedLabels.length"
class="text-secondary hide-collapsed"
data-testid="empty-placeholder"
>
<slot></slot>
</span>
<template v-else>
<gl-label
v-for="label in sortedSelectedLabels"
:key="label.id"
class="hide-collapsed"
data-qa-selector="selected_label_content"
:data-qa-label-name="label.title"
:title="label.title"
......
<script>
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
export default {
directives: {
GlTooltip: GlTooltipDirective,
},
components: {
GlIcon,
},
props: {
labels: {
type: Array,
required: true,
},
},
computed: {
labelsList() {
const labelsString = this.labels.length
? this.labels
.slice(0, 5)
.map((label) => label.title)
.join(', ')
: s__('LabelSelect|Labels');
if (this.labels.length > 5) {
return sprintf(s__('LabelSelect|%{labelsString}, and %{remainingLabelCount} more'), {
labelsString,
remainingLabelCount: this.labels.length - 5,
});
}
return labelsString;
},
},
methods: {
handleClick() {
this.$emit('onValueClick');
},
},
};
</script>
<template>
<div
v-gl-tooltip.left.viewport
:title="labelsList"
class="sidebar-collapsed-icon"
@click="handleClick"
>
<gl-icon name="labels" />
<span>{{ labels.length }}</span>
</div>
</template>
......@@ -9,7 +9,6 @@ import { issuableLabelsQueries } from '~/sidebar/constants';
import { DEBOUNCE_DROPDOWN_DELAY, DropdownVariant } from './constants';
import DropdownContents from './dropdown_contents.vue';
import DropdownValue from './dropdown_value.vue';
import DropdownValueCollapsed from './dropdown_value_collapsed.vue';
import {
isDropdownVariantSidebar,
isDropdownVariantStandalone,
......@@ -20,7 +19,6 @@ export default {
components: {
DropdownValue,
DropdownContents,
DropdownValueCollapsed,
SidebarEditableItem,
},
inject: {
......@@ -294,11 +292,6 @@ export default {
data-qa-selector="labels_block"
>
<template v-if="isDropdownVariantSidebar(variant)">
<dropdown-value-collapsed
ref="dropdownButtonCollapsed"
:labels="issuableLabels"
@onValueClick="handleCollapsedValueClick"
/>
<sidebar-editable-item
ref="editable"
:title="__('Labels')"
......@@ -314,6 +307,7 @@ export default {
:labels-filter-base-path="labelsFilterBasePath"
:labels-filter-param="labelsFilterParam"
@onLabelRemove="handleLabelRemove"
@onCollapsedValueClick="handleCollapsedValueClick"
>
<slot></slot>
</dropdown-value>
......
......@@ -95,5 +95,10 @@ describe('DropdownValue', () => {
findRegularLabel().vm.$emit('close');
expect(wrapper.emitted('onLabelRemove')).toEqual([[mockRegularLabel.id]]);
});
it('emits `onCollapsedValueClick` when clicking on collapsed value', () => {
wrapper.find('.sidebar-collapsed-icon').trigger('click');
expect(wrapper.emitted('onCollapsedValueClick')).toEqual([[]]);
});
});
});
......@@ -8,7 +8,6 @@ import { IssuableType } from '~/issues/constants';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue';
import DropdownValue from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue';
import DropdownValueCollapsed from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value_collapsed.vue';
import issueLabelsQuery from '~/vue_shared/components/sidebar/labels_select_widget/graphql/issue_labels.query.graphql';
import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
import updateMergeRequestLabelsMutation from '~/sidebar/queries/update_merge_request_labels.mutation.graphql';
......@@ -35,7 +34,6 @@ describe('LabelsSelectRoot', () => {
const findSidebarEditableItem = () => wrapper.findComponent(SidebarEditableItem);
const findDropdownValue = () => wrapper.findComponent(DropdownValue);
const findDropdownValueCollapsed = () => wrapper.findComponent(DropdownValueCollapsed);
const findDropdownContents = () => wrapper.findComponent(DropdownContents);
const createComponent = ({
......@@ -122,9 +120,6 @@ describe('LabelsSelectRoot', () => {
expect(findDropdownValue().props('selectedLabels')).toEqual(
issuableLabelsQueryResponse.data.workspace.issuable.labels.nodes,
);
expect(findDropdownValueCollapsed().props('labels')).toEqual(
issuableLabelsQueryResponse.data.workspace.issuable.labels.nodes,
);
});
it('emits `onLabelRemove` event on dropdown value label remove event', () => {
......
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