Commit b3d243da authored by Phil Hughes's avatar Phil Hughes

Merge branch 'ss/add-loading-to-assignees' into 'master'

Add loading state to initial load of assignees in dropdown

See merge request gitlab-org/gitlab!47848
parents ee202720 0e274436
......@@ -7,6 +7,7 @@ import {
GlAvatarLabeled,
GlAvatarLink,
GlSearchBoxByType,
GlLoadingIcon,
} from '@gitlab/ui';
import { __, n__ } from '~/locale';
import IssuableAssignees from '~/sidebar/components/assignees/issuable_assignees.vue';
......@@ -33,6 +34,7 @@ export default {
GlAvatarLabeled,
GlAvatarLink,
GlSearchBoxByType,
GlLoadingIcon,
},
data() {
return {
......@@ -144,45 +146,48 @@ export default {
<gl-search-box-by-type v-model.trim="search" />
</template>
<template #items>
<gl-dropdown-item
:is-checked="selectedIsEmpty"
data-testid="unassign"
class="mt-2"
@click="selectAssignee()"
>{{ $options.i18n.unassigned }}</gl-dropdown-item
>
<gl-dropdown-divider data-testid="unassign-divider" />
<gl-dropdown-item
v-for="item in selected"
:key="item.id"
:is-checked="isChecked(item.username)"
@click="unselect(item.username)"
>
<gl-avatar-link>
<gl-avatar-labeled
:size="32"
:label="item.name"
:sub-label="item.username"
:src="item.avatarUrl || item.avatar"
/>
</gl-avatar-link>
</gl-dropdown-item>
<gl-dropdown-divider v-if="!selectedIsEmpty" data-testid="selected-user-divider" />
<gl-dropdown-item
v-for="unselectedUser in unSelectedFiltered"
:key="unselectedUser.id"
:data-testid="`item_${unselectedUser.name}`"
@click="selectAssignee(unselectedUser)"
>
<gl-avatar-link>
<gl-avatar-labeled
:size="32"
:label="unselectedUser.name"
:sub-label="unselectedUser.username"
:src="unselectedUser.avatarUrl || unselectedUser.avatar"
/>
</gl-avatar-link>
</gl-dropdown-item>
<gl-loading-icon v-if="$apollo.queries.participants.loading" size="lg" />
<template v-else>
<gl-dropdown-item
:is-checked="selectedIsEmpty"
data-testid="unassign"
class="mt-2"
@click="selectAssignee()"
>{{ $options.i18n.unassigned }}</gl-dropdown-item
>
<gl-dropdown-divider data-testid="unassign-divider" />
<gl-dropdown-item
v-for="item in selected"
:key="item.id"
:is-checked="isChecked(item.username)"
@click="unselect(item.username)"
>
<gl-avatar-link>
<gl-avatar-labeled
:size="32"
:label="item.name"
:sub-label="item.username"
:src="item.avatarUrl || item.avatar"
/>
</gl-avatar-link>
</gl-dropdown-item>
<gl-dropdown-divider v-if="!selectedIsEmpty" data-testid="selected-user-divider" />
<gl-dropdown-item
v-for="unselectedUser in unSelectedFiltered"
:key="unselectedUser.id"
:data-testid="`item_${unselectedUser.name}`"
@click="selectAssignee(unselectedUser)"
>
<gl-avatar-link>
<gl-avatar-labeled
:size="32"
:label="unselectedUser.name"
:sub-label="unselectedUser.username"
:src="unselectedUser.avatarUrl || unselectedUser.avatar"
/>
</gl-avatar-link>
</gl-dropdown-item>
</template>
</template>
</multi-select-dropdown>
</template>
......
---
title: Add loading state to assignees dropdown
merge_request: 47848
author:
type: added
......@@ -26,6 +26,15 @@ describe('ee/BoardContentSidebar', () => {
'board-sidebar-due-date': '<div></div>',
'board-sidebar-subscription': '<div></div>',
},
mocks: {
$apollo: {
queries: {
participants: {
loading: false,
},
},
},
},
});
};
......@@ -55,7 +64,7 @@ describe('ee/BoardContentSidebar', () => {
expect(wrapper.find(IssuableTitle).text()).toContain('One');
});
it('renders IssuableAssignees', () => {
it('renders BoardAssigneeDropdown', () => {
expect(wrapper.find(BoardAssigneeDropdown).exists()).toBe(true);
});
......
import { mount, createLocalVue } from '@vue/test-utils';
import { GlDropdownItem, GlAvatarLink, GlAvatarLabeled, GlSearchBoxByType } from '@gitlab/ui';
import {
GlDropdownItem,
GlAvatarLink,
GlAvatarLabeled,
GlSearchBoxByType,
GlLoadingIcon,
} from '@gitlab/ui';
import createMockApollo from 'jest/helpers/mock_apollo_helper';
import VueApollo from 'vue-apollo';
import BoardAssigneeDropdown from '~/boards/components/board_assignee_dropdown.vue';
......@@ -26,7 +32,7 @@ describe('BoardCardAssigneeDropdown', () => {
const activeIssueName = 'test';
const anotherIssueName = 'hello';
const createComponent = (search = '') => {
const createComponent = (search = '', loading = false) => {
wrapper = mount(BoardAssigneeDropdown, {
data() {
return {
......@@ -40,6 +46,15 @@ describe('BoardCardAssigneeDropdown', () => {
canUpdate: true,
rootPath: '',
},
mocks: {
$apollo: {
queries: {
participants: {
loading,
},
},
},
},
});
};
......@@ -83,6 +98,8 @@ describe('BoardCardAssigneeDropdown', () => {
return wrapper.findAll(GlDropdownItem).wrappers.find(node => node.text().indexOf(text) === 0);
};
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
beforeEach(() => {
store.state.activeId = '1';
store.state.issues = {
......@@ -245,6 +262,30 @@ describe('BoardCardAssigneeDropdown', () => {
},
);
describe('when participants is loading', () => {
beforeEach(() => {
createComponent('', true);
});
it('finds a loading icon in the dropdown', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
});
describe('when participants is loading is false', () => {
beforeEach(() => {
createComponent();
});
it('does not find GlLoading icon in the dropdown', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
it('finds at least 1 GlDropdownItem', () => {
expect(wrapper.findAll(GlDropdownItem).length).toBeGreaterThan(0);
});
});
describe('Apollo', () => {
beforeEach(() => {
getIssueParticipantsSpy = jest.fn().mockResolvedValue({
......
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