Commit e3d071a2 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '300647-refactor-weight-sidebar-component-to-use-vue-apollo' into 'master'

Sidebar weight widget [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!65223
parents e2ad397f bc8ead52
...@@ -25,8 +25,8 @@ export default { ...@@ -25,8 +25,8 @@ export default {
SidebarSubscriptionsWidget, SidebarSubscriptionsWidget,
SidebarDropdownWidget, SidebarDropdownWidget,
MountingPortal, MountingPortal,
BoardSidebarWeightInput: () => SidebarWeightWidget: () =>
import('ee_component/boards/components/sidebar/board_sidebar_weight_input.vue'), import('ee_component/sidebar/components/weight/sidebar_weight_widget.vue'),
IterationSidebarDropdownWidget: () => IterationSidebarDropdownWidget: () =>
import('ee_component/sidebar/components/iteration_sidebar_dropdown_widget.vue'), import('ee_component/sidebar/components/iteration_sidebar_dropdown_widget.vue'),
}, },
...@@ -65,7 +65,12 @@ export default { ...@@ -65,7 +65,12 @@ export default {
}, },
}, },
methods: { methods: {
...mapActions(['toggleBoardItem', 'setAssignees', 'setActiveItemConfidential']), ...mapActions([
'toggleBoardItem',
'setAssignees',
'setActiveItemConfidential',
'setActiveItemWeight',
]),
handleClose() { handleClose() {
this.toggleBoardItem({ boardItem: this.activeBoardItem, sidebarType: this.sidebarType }); this.toggleBoardItem({ boardItem: this.activeBoardItem, sidebarType: this.sidebarType });
}, },
...@@ -144,7 +149,13 @@ export default { ...@@ -144,7 +149,13 @@ export default {
data-testid="sidebar-due-date" data-testid="sidebar-due-date"
/> />
<board-sidebar-labels-select class="labels" /> <board-sidebar-labels-select class="labels" />
<board-sidebar-weight-input v-if="weightFeatureAvailable" class="weight" /> <sidebar-weight-widget
v-if="weightFeatureAvailable"
:iid="activeBoardItem.iid"
:full-path="fullPath"
:issuable-type="issuableType"
@weightUpdated="setActiveItemWeight($event)"
/>
<sidebar-confidentiality-widget <sidebar-confidentiality-widget
:iid="activeBoardItem.iid" :iid="activeBoardItem.iid"
:full-path="fullPath" :full-path="fullPath"
......
...@@ -704,4 +704,7 @@ export default { ...@@ -704,4 +704,7 @@ export default {
unsetError: ({ commit }) => { unsetError: ({ commit }) => {
commit(types.SET_ERROR, undefined); commit(types.SET_ERROR, undefined);
}, },
// EE action needs CE empty equivalent
setActiveItemWeight: () => {},
}; };
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
.js-sidebar-labels{ data: sidebar_labels_data(issuable_sidebar, @project) } .js-sidebar-labels{ data: sidebar_labels_data(issuable_sidebar, @project) }
= render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar = render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar, can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid]
- if issuable_sidebar[:supports_severity] - if issuable_sidebar[:supports_severity]
#js-severity #js-severity
......
...@@ -36,7 +36,7 @@ export default { ...@@ -36,7 +36,7 @@ export default {
}, },
}, },
methods: { methods: {
...mapActions(['setActiveIssueWeight', 'setError']), ...mapActions(['setActiveItemWeight', 'setError']),
handleFormSubmit() { handleFormSubmit() {
this.$refs.sidebarItem.collapse({ emitEvent: false }); this.$refs.sidebarItem.collapse({ emitEvent: false });
this.setWeight(); this.setWeight();
...@@ -51,7 +51,7 @@ export default { ...@@ -51,7 +51,7 @@ export default {
this.loading = true; this.loading = true;
try { try {
await this.setActiveIssueWeight({ weight, projectPath: this.projectPathForActiveIssue }); await this.setActiveItemWeight({ weight, projectPath: this.projectPathForActiveIssue });
this.weight = weight; this.weight = weight;
} catch (e) { } catch (e) {
this.weight = this.activeBoardItem.weight; this.weight = this.activeBoardItem.weight;
......
...@@ -35,7 +35,6 @@ import epicMoveListMutation from '../graphql/epic_move_list.mutation.graphql'; ...@@ -35,7 +35,6 @@ import epicMoveListMutation from '../graphql/epic_move_list.mutation.graphql';
import epicsSwimlanesQuery from '../graphql/epics_swimlanes.query.graphql'; import epicsSwimlanesQuery from '../graphql/epics_swimlanes.query.graphql';
import groupBoardIterationsQuery from '../graphql/group_board_iterations.query.graphql'; import groupBoardIterationsQuery from '../graphql/group_board_iterations.query.graphql';
import groupBoardMilestonesQuery from '../graphql/group_board_milestones.query.graphql'; import groupBoardMilestonesQuery from '../graphql/group_board_milestones.query.graphql';
import issueSetWeightMutation from '../graphql/issue_set_weight.mutation.graphql';
import listUpdateLimitMetricsMutation from '../graphql/list_update_limit_metrics.mutation.graphql'; import listUpdateLimitMetricsMutation from '../graphql/list_update_limit_metrics.mutation.graphql';
import listsEpicsQuery from '../graphql/lists_epics.query.graphql'; import listsEpicsQuery from '../graphql/lists_epics.query.graphql';
import projectBoardIterationsQuery from '../graphql/project_board_iterations.query.graphql'; import projectBoardIterationsQuery from '../graphql/project_board_iterations.query.graphql';
...@@ -326,26 +325,11 @@ export default { ...@@ -326,26 +325,11 @@ export default {
commit(types.RESET_EPICS); commit(types.RESET_EPICS);
}, },
setActiveIssueWeight: async ({ commit, getters }, input) => { setActiveItemWeight: async ({ commit, getters }, weight) => {
const { data } = await gqlClient.mutate({
mutation: issueSetWeightMutation,
variables: {
input: {
iid: String(getters.activeBoardItem.iid),
weight: input.weight,
projectPath: input.projectPath,
},
},
});
if (!data.issueSetWeight || data.issueSetWeight?.errors?.length > 0) {
throw new Error(data.issueSetWeight?.errors);
}
commit(typesCE.UPDATE_BOARD_ITEM_BY_ID, { commit(typesCE.UPDATE_BOARD_ITEM_BY_ID, {
itemId: getters.activeBoardItem.id, itemId: getters.activeBoardItem.id,
prop: 'weight', prop: 'weight',
value: data.issueSetWeight.issue.weight, value: weight,
}); });
}, },
......
<script>
import {
GlButton,
GlForm,
GlFormInput,
GlLoadingIcon,
GlIcon,
GlTooltipDirective,
} from '@gitlab/ui';
import createFlash from '~/flash';
import { __, sprintf } from '~/locale';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import { weightQueries, MAX_DISPLAY_WEIGHT } from '../../constants';
export default {
tracking: {
event: 'click_edit_button',
label: 'right_sidebar',
property: 'weight',
},
components: {
GlButton,
GlForm,
GlFormInput,
GlIcon,
GlLoadingIcon,
SidebarEditableItem,
},
directives: {
autofocusonshow,
GlTooltip: GlTooltipDirective,
},
inject: ['canUpdate'],
props: {
iid: {
type: String,
required: true,
},
fullPath: {
type: String,
required: true,
},
issuableType: {
required: true,
type: String,
},
},
data() {
return {
weight: null,
loading: false,
};
},
apollo: {
weight: {
query() {
return weightQueries[this.issuableType].query;
},
variables() {
return {
fullPath: this.fullPath,
iid: String(this.iid),
};
},
update(data) {
return data.workspace?.issuable?.weight || null;
},
result({ data }) {
this.$emit('weightUpdated', data.workspace?.issuable?.weight || null);
},
error() {
createFlash({
message: sprintf(__('Something went wrong while setting %{issuableType} weight.'), {
issuableType: this.issuableType,
}),
});
},
},
},
computed: {
isLoading() {
return this.$apollo.queries?.weight?.loading || this.loading;
},
hasWeight() {
return this.weight !== null;
},
weightLabel() {
return this.hasWeight ? this.weight : this.$options.i18n.noWeightLabel;
},
tooltipTitle() {
let tooltipTitle = this.$options.i18n.weight;
if (this.hasWeight) {
tooltipTitle += ` ${this.weight}`;
}
return tooltipTitle;
},
collapsedWeightLabel() {
return this.hasWeight
? this.weight.toString().substr(0, 5)
: this.$options.i18n.noWeightLabel;
},
},
methods: {
setWeight(remove) {
const weight = remove ? null : this.weight;
this.loading = true;
this.$apollo
.mutate({
mutation: weightQueries[this.issuableType].mutation,
variables: {
input: {
projectPath: this.fullPath,
iid: this.iid,
weight,
},
},
})
.then(
({
data: {
issuableSetWeight: { errors },
},
}) => {
if (errors.length) {
createFlash({
message: errors[0],
});
}
},
)
.catch(() => {
createFlash({
message: sprintf(__('Something went wrong while setting %{issuableType} weight.'), {
issuableType: this.issuableType,
}),
});
})
.finally(() => {
this.loading = false;
});
},
expandSidebar() {
this.$refs.editable.expand();
this.$emit('expandSidebar');
},
handleFormSubmit() {
this.$refs.editable.collapse({ emitEvent: false });
this.setWeight();
},
},
i18n: {
weight: __('Weight'),
noWeightLabel: __('None'),
removeWeight: __('remove weight'),
inputPlaceholder: __('Enter a number'),
},
maxDisplayWeight: MAX_DISPLAY_WEIGHT,
};
</script>
<template>
<sidebar-editable-item
ref="editable"
:title="$options.i18n.weight"
:tracking="$options.tracking"
:loading="isLoading"
class="block weight"
data-testid="sidebar-weight"
@close="setWeight()"
>
<template #collapsed>
<div class="gl-display-flex gl-align-items-center hide-collapsed">
<span
:class="hasWeight ? 'gl-text-gray-900 gl-font-weight-bold' : 'gl-text-gray-500'"
data-testid="sidebar-weight-value"
data-qa-selector="weight_label_value"
>
{{ weightLabel }}
</span>
<div v-if="hasWeight && canUpdate" class="gl-display-flex">
<span class="gl-mx-2">-</span>
<gl-button
variant="link"
class="gl-text-gray-500!"
:disabled="loading"
@click="setWeight(true)"
>
{{ $options.i18n.removeWeight }}
</gl-button>
</div>
</div>
<div
v-gl-tooltip.left.viewport
:title="tooltipTitle"
class="sidebar-collapsed-icon js-weight-collapsed-block"
@click="expandSidebar"
>
<gl-icon :size="16" name="weight" />
<gl-loading-icon v-if="isLoading" class="js-weight-collapsed-loading-icon" />
<span v-else class="js-weight-collapsed-weight-label">
{{ collapsedWeightLabel }}
<template v-if="weight > $options.maxDisplayWeight">&hellip;</template>
</span>
</div>
</template>
<template #default>
<gl-form @submit.prevent="handleFormSubmit()">
<gl-form-input
v-model.number="weight"
v-autofocusonshow
type="number"
min="0"
:placeholder="$options.i18n.inputPlaceholder"
/>
</gl-form>
</template>
</sidebar-editable-item>
</template>
...@@ -8,10 +8,12 @@ import { ...@@ -8,10 +8,12 @@ import {
import epicAncestorsQuery from './queries/epic_ancestors.query.graphql'; import epicAncestorsQuery from './queries/epic_ancestors.query.graphql';
import groupEpicsQuery from './queries/group_epics.query.graphql'; import groupEpicsQuery from './queries/group_epics.query.graphql';
import groupIterationsQuery from './queries/group_iterations.query.graphql'; import groupIterationsQuery from './queries/group_iterations.query.graphql';
import issueWeightQuery from './queries/issue_weight.query.graphql';
import projectIssueEpicMutation from './queries/project_issue_epic.mutation.graphql'; import projectIssueEpicMutation from './queries/project_issue_epic.mutation.graphql';
import projectIssueEpicQuery from './queries/project_issue_epic.query.graphql'; import projectIssueEpicQuery from './queries/project_issue_epic.query.graphql';
import projectIssueIterationMutation from './queries/project_issue_iteration.mutation.graphql'; import projectIssueIterationMutation from './queries/project_issue_iteration.mutation.graphql';
import projectIssueIterationQuery from './queries/project_issue_iteration.query.graphql'; import projectIssueIterationQuery from './queries/project_issue_iteration.query.graphql';
import updateIssueWeightMutation from './queries/update_issue_weight.mutation.graphql';
export const healthStatus = { export const healthStatus = {
ON_TRACK: 'onTrack', ON_TRACK: 'onTrack',
...@@ -128,3 +130,10 @@ export const ancestorsQueries = { ...@@ -128,3 +130,10 @@ export const ancestorsQueries = {
query: epicAncestorsQuery, query: epicAncestorsQuery,
}, },
}; };
export const weightQueries = {
[IssuableType.Issue]: {
query: issueWeightQuery,
mutation: updateIssueWeightMutation,
},
};
...@@ -9,7 +9,7 @@ import CveIdRequest from './components/cve_id_request/cve_id_request_sidebar.vue ...@@ -9,7 +9,7 @@ import CveIdRequest from './components/cve_id_request/cve_id_request_sidebar.vue
import IterationSidebarDropdownWidget from './components/iteration_sidebar_dropdown_widget.vue'; import IterationSidebarDropdownWidget from './components/iteration_sidebar_dropdown_widget.vue';
import SidebarDropdownWidget from './components/sidebar_dropdown_widget.vue'; import SidebarDropdownWidget from './components/sidebar_dropdown_widget.vue';
import SidebarStatus from './components/status/sidebar_status.vue'; import SidebarStatus from './components/status/sidebar_status.vue';
import SidebarWeight from './components/weight/sidebar_weight.vue'; import SidebarWeightWidget from './components/weight/sidebar_weight_widget.vue';
import { IssuableAttributeType } from './constants'; import { IssuableAttributeType } from './constants';
Vue.use(VueApollo); Vue.use(VueApollo);
...@@ -19,12 +19,26 @@ const mountWeightComponent = () => { ...@@ -19,12 +19,26 @@ const mountWeightComponent = () => {
if (!el) return false; if (!el) return false;
const { canEdit, projectPath, issueIid } = el.dataset;
return new Vue({ return new Vue({
el, el,
apolloProvider,
components: { components: {
SidebarWeight, SidebarWeightWidget,
},
provide: {
canUpdate: parseBoolean(canEdit),
isClassicSidebar: true,
}, },
render: (createElement) => createElement('sidebar-weight'), render: (createElement) =>
createElement('sidebar-weight-widget', {
props: {
fullPath: projectPath,
iid: issueIid,
issuableType: IssuableType.Issue,
},
}),
}); });
}; };
......
query issueWeight($fullPath: ID!, $iid: String) {
workspace: project(fullPath: $fullPath) {
__typename
issuable: issue(iid: $iid) {
__typename
id
weight
}
}
}
mutation issueSetWeight($input: IssueSetWeightInput!) {
issuableSetWeight: issueSetWeight(input: $input) {
issuable: issue {
id
weight
}
errors
}
}
- if issuable_sidebar[:supports_weight] - if issuable_sidebar[:supports_weight]
- if issuable_sidebar[:features_available][:issue_weights] - if issuable_sidebar[:features_available][:issue_weights]
.js-sidebar-weight-entry-point .js-sidebar-weight-entry-point{ data: { can_edit: can_edit, project_path: project_path, issue_iid: issue_iid } }
- else - else
= render 'shared/promotions/promote_issue_weights' = render 'shared/promotions/promote_issue_weights'
...@@ -222,7 +222,7 @@ RSpec.describe 'Issue Boards', :js do ...@@ -222,7 +222,7 @@ RSpec.describe 'Issue Boards', :js do
context 'weight' do context 'weight' do
let(:weight_widget) { find('[data-testid="sidebar-weight"]') } let(:weight_widget) { find('[data-testid="sidebar-weight"]') }
let(:weight_value) { find('[data-testid="sidebar-weight"] .value') } let(:weight_value) { find('[data-testid="sidebar-weight-value"]') }
it 'displays weight async' do it 'displays weight async' do
click_card(card1) click_card(card1)
......
...@@ -41,10 +41,10 @@ RSpec.describe 'Issue Sidebar' do ...@@ -41,10 +41,10 @@ RSpec.describe 'Issue Sidebar' do
it 'updates weight in sidebar to 1' do it 'updates weight in sidebar to 1' do
page.within '.weight' do page.within '.weight' do
click_link 'Edit' click_button 'Edit'
find('input').send_keys 1, :enter find('input').send_keys 1, :enter
page.within '.value' do page.within '[data-testid="sidebar-weight-value"]' do
expect(page).to have_content '1' expect(page).to have_content '1'
end end
end end
...@@ -52,16 +52,16 @@ RSpec.describe 'Issue Sidebar' do ...@@ -52,16 +52,16 @@ RSpec.describe 'Issue Sidebar' do
it 'updates weight in sidebar to no weight' do it 'updates weight in sidebar to no weight' do
page.within '.weight' do page.within '.weight' do
click_link 'Edit' click_button 'Edit'
find('input').send_keys 1, :enter find('input').send_keys 1, :enter
page.within '.value' do page.within '[data-testid="sidebar-weight-value"]' do
expect(page).to have_content '1' expect(page).to have_content '1'
end end
click_link 'remove weight' click_button 'remove weight'
page.within '.value' do page.within '[data-testid="sidebar-weight-value"]' do
expect(page).to have_content 'None' expect(page).to have_content 'None'
end end
end end
......
...@@ -19,11 +19,11 @@ RSpec.describe 'Issue weight', :js do ...@@ -19,11 +19,11 @@ RSpec.describe 'Issue weight', :js do
page.within('.weight') do page.within('.weight') do
expect(page).to have_content "None" expect(page).to have_content "None"
click_link 'Edit' click_button 'Edit'
find('.block.weight input').send_keys 1, :enter find('.block.weight input').send_keys 1, :enter
page.within('.value') do page.within('[data-testid="sidebar-weight-value"]') do
expect(page).to have_content "1" expect(page).to have_content "1"
end end
end end
...@@ -37,11 +37,11 @@ RSpec.describe 'Issue weight', :js do ...@@ -37,11 +37,11 @@ RSpec.describe 'Issue weight', :js do
page.within('.weight') do page.within('.weight') do
expect(page).to have_content "2" expect(page).to have_content "2"
click_link 'Edit' click_button 'Edit'
find('.block.weight input').send_keys 3, :enter find('.block.weight input').send_keys 3, :enter
page.within('.value') do page.within('[data-testid="sidebar-weight-value"]') do
expect(page).to have_content "3" expect(page).to have_content "3"
end end
end end
...@@ -55,9 +55,9 @@ RSpec.describe 'Issue weight', :js do ...@@ -55,9 +55,9 @@ RSpec.describe 'Issue weight', :js do
page.within('.weight') do page.within('.weight') do
expect(page).to have_content "5" expect(page).to have_content "5"
click_link 'remove weight' click_button 'remove weight'
page.within('.value') do page.within('[data-testid="sidebar-weight-value"]') do
expect(page).to have_content "None" expect(page).to have_content "None"
end end
end end
......
...@@ -64,8 +64,10 @@ exports[`ee/BoardContentSidebar matches the snapshot 1`] = ` ...@@ -64,8 +64,10 @@ exports[`ee/BoardContentSidebar matches the snapshot 1`] = `
class="labels" class="labels"
/> />
<boardsidebarweightinput-stub <sidebarweightwidget-stub
class="weight" full-path="gitlab-org/gitlab-test"
iid="27"
issuable-type="issue"
/> />
<sidebarconfidentialitywidget-stub <sidebarconfidentialitywidget-stub
......
...@@ -69,7 +69,7 @@ describe('ee/BoardContentSidebar', () => { ...@@ -69,7 +69,7 @@ describe('ee/BoardContentSidebar', () => {
SidebarConfidentialityWidget: true, SidebarConfidentialityWidget: true,
SidebarDateWidget: true, SidebarDateWidget: true,
SidebarSubscriptionsWidget: true, SidebarSubscriptionsWidget: true,
BoardSidebarWeightInput: true, SidebarWeightWidget: true,
SidebarDropdownWidget: true, SidebarDropdownWidget: true,
MountingPortal: true, MountingPortal: true,
}, },
......
...@@ -52,7 +52,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => { ...@@ -52,7 +52,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => {
describe('when weight is submitted', () => { describe('when weight is submitted', () => {
beforeEach(async () => { beforeEach(async () => {
createWrapper(); createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueWeight'); jest.spyOn(wrapper.vm, 'setActiveItemWeight');
findWeightInput().vm.$emit('input', TEST_WEIGHT); findWeightInput().vm.$emit('input', TEST_WEIGHT);
findWeightForm().vm.$emit('submit', { preventDefault: () => {} }); findWeightForm().vm.$emit('submit', { preventDefault: () => {} });
store.state.boardItems[TEST_ISSUE.id].weight = TEST_WEIGHT; store.state.boardItems[TEST_ISSUE.id].weight = TEST_WEIGHT;
...@@ -66,7 +66,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => { ...@@ -66,7 +66,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => {
}); });
it('commits change to the server', () => { it('commits change to the server', () => {
expect(wrapper.vm.setActiveIssueWeight).toHaveBeenCalledWith({ expect(wrapper.vm.setActiveItemWeight).toHaveBeenCalledWith({
weight: TEST_WEIGHT, weight: TEST_WEIGHT,
projectPath: 'h/b', projectPath: 'h/b',
}); });
...@@ -76,7 +76,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => { ...@@ -76,7 +76,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => {
describe('when weight is set to 0', () => { describe('when weight is set to 0', () => {
beforeEach(async () => { beforeEach(async () => {
createWrapper({ weight: TEST_WEIGHT }); createWrapper({ weight: TEST_WEIGHT });
jest.spyOn(wrapper.vm, 'setActiveIssueWeight'); jest.spyOn(wrapper.vm, 'setActiveItemWeight');
findWeightInput().vm.$emit('input', 0); findWeightInput().vm.$emit('input', 0);
findWeightForm().vm.$emit('submit', { preventDefault: () => {} }); findWeightForm().vm.$emit('submit', { preventDefault: () => {} });
store.state.boardItems[TEST_ISSUE.id].weight = 0; store.state.boardItems[TEST_ISSUE.id].weight = 0;
...@@ -84,7 +84,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => { ...@@ -84,7 +84,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => {
}); });
it('collapses sidebar and renders "None"', () => { it('collapses sidebar and renders "None"', () => {
expect(wrapper.vm.setActiveIssueWeight).toHaveBeenCalled(); expect(wrapper.vm.setActiveItemWeight).toHaveBeenCalled();
expect(findCollapsed().isVisible()).toBe(true); expect(findCollapsed().isVisible()).toBe(true);
expect(findCollapsed().text()).toBe('None'); expect(findCollapsed().text()).toBe('None');
}); });
...@@ -93,14 +93,14 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => { ...@@ -93,14 +93,14 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => {
describe('when weight is resetted', () => { describe('when weight is resetted', () => {
beforeEach(async () => { beforeEach(async () => {
createWrapper({ weight: TEST_WEIGHT }); createWrapper({ weight: TEST_WEIGHT });
jest.spyOn(wrapper.vm, 'setActiveIssueWeight'); jest.spyOn(wrapper.vm, 'setActiveItemWeight');
findResetButton().vm.$emit('click'); findResetButton().vm.$emit('click');
store.state.boardItems[TEST_ISSUE.id].weight = 0; store.state.boardItems[TEST_ISSUE.id].weight = 0;
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
}); });
it('collapses sidebar and renders "None"', () => { it('collapses sidebar and renders "None"', () => {
expect(wrapper.vm.setActiveIssueWeight).toHaveBeenCalled(); expect(wrapper.vm.setActiveItemWeight).toHaveBeenCalled();
expect(findCollapsed().isVisible()).toBe(true); expect(findCollapsed().isVisible()).toBe(true);
expect(findCollapsed().text()).toBe('None'); expect(findCollapsed().text()).toBe('None');
}); });
...@@ -109,7 +109,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => { ...@@ -109,7 +109,7 @@ describe('ee/boards/components/sidebar/board_sidebar_weight_input.vue', () => {
describe('when the mutation fails', () => { describe('when the mutation fails', () => {
beforeEach(async () => { beforeEach(async () => {
createWrapper({ weight: TEST_WEIGHT }); createWrapper({ weight: TEST_WEIGHT });
jest.spyOn(wrapper.vm, 'setActiveIssueWeight').mockImplementation(() => { jest.spyOn(wrapper.vm, 'setActiveItemWeight').mockImplementation(() => {
throw new Error(['failed mutation']); throw new Error(['failed mutation']);
}); });
jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
......
...@@ -608,27 +608,13 @@ describe('resetEpics', () => { ...@@ -608,27 +608,13 @@ describe('resetEpics', () => {
}); });
}); });
describe('setActiveIssueWeight', () => { describe('setActiveItemWeight', () => {
const state = { boardItems: { [mockIssue.id]: mockIssue } }; const state = { boardItems: { [mockIssue.id]: mockIssue } };
const getters = { activeBoardItem: mockIssue }; const getters = { activeBoardItem: mockIssue };
const testWeight = mockIssue.weight + 1; const testWeight = mockIssue.weight + 1;
const input = { const input = testWeight;
weight: testWeight,
projectPath: 'h/b',
};
it('should commit weight after setting the issue', (done) => {
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
issueSetWeight: {
issue: {
weight: testWeight,
},
errors: [],
},
},
});
it('should commit weight', (done) => {
const payload = { const payload = {
itemId: getters.activeBoardItem.id, itemId: getters.activeBoardItem.id,
prop: 'weight', prop: 'weight',
...@@ -636,7 +622,7 @@ describe('setActiveIssueWeight', () => { ...@@ -636,7 +622,7 @@ describe('setActiveIssueWeight', () => {
}; };
testAction( testAction(
actions.setActiveIssueWeight, actions.setActiveItemWeight,
input, input,
{ ...state, ...getters }, { ...state, ...getters },
[ [
...@@ -655,7 +641,7 @@ describe('setActiveIssueWeight', () => { ...@@ -655,7 +641,7 @@ describe('setActiveIssueWeight', () => {
.spyOn(gqlClient, 'mutate') .spyOn(gqlClient, 'mutate')
.mockResolvedValue({ data: { issueSetWeight: { errors: ['failed mutation'] } } }); .mockResolvedValue({ data: { issueSetWeight: { errors: ['failed mutation'] } } });
await expect(actions.setActiveIssueWeight({ getters }, input)).rejects.toThrow(Error); await expect(actions.setActiveItemWeight({ getters }, input)).rejects.toThrow(Error);
}); });
}); });
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import SidebarWeightWidget from 'ee_component/sidebar/components/weight/sidebar_weight_widget.vue';
import issueWeightQuery from 'ee_component/sidebar/queries/issue_weight.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import { issueNoWeightResponse, issueWeightResponse } from '../../mock_data';
jest.mock('~/flash');
Vue.use(VueApollo);
describe('Sidebar Weight Widget', () => {
let wrapper;
let fakeApollo;
const findEditableItem = () => wrapper.findComponent(SidebarEditableItem);
const findWeightValue = () => wrapper.findByTestId('sidebar-weight-value');
const createComponent = ({
weightQueryHandler = jest.fn().mockResolvedValue(issueNoWeightResponse()),
} = {}) => {
fakeApollo = createMockApollo([[issueWeightQuery, weightQueryHandler]]);
wrapper = extendedWrapper(
shallowMount(SidebarWeightWidget, {
apolloProvider: fakeApollo,
provide: {
canUpdate: true,
},
propsData: {
fullPath: 'group/project',
iid: '1',
issuableType: 'issue',
},
stubs: {
SidebarEditableItem,
},
}),
);
};
afterEach(() => {
wrapper.destroy();
fakeApollo = null;
});
it('passes a `loading` prop as true to editable item when query is loading', () => {
createComponent();
expect(findEditableItem().props('loading')).toBe(true);
});
describe('when issue has no weight', () => {
beforeEach(() => {
createComponent();
return waitForPromises();
});
it('passes a `loading` prop as false to editable item', () => {
expect(findEditableItem().props('loading')).toBe(false);
});
it('toggle is unchecked', () => {
expect(findWeightValue().text()).toBe('None');
});
it('emits `weightUpdated` event with a `null` payload', () => {
expect(wrapper.emitted('weightUpdated')).toEqual([[null]]);
});
});
describe('when issue has weight', () => {
beforeEach(() => {
createComponent({
weightQueryHandler: jest.fn().mockResolvedValue(issueWeightResponse(true)),
});
return waitForPromises();
});
it('passes a `loading` prop as false to editable item', () => {
expect(findEditableItem().props('loading')).toBe(false);
});
it('toggle is checked', () => {
expect(findWeightValue().text()).toBe('1');
});
it('emits `weightUpdated` event with a `true` payload', () => {
expect(wrapper.emitted('weightUpdated')).toEqual([[1]]);
});
});
it('displays a flash message when query is rejected', async () => {
createComponent({
weightQueryHandler: jest.fn().mockRejectedValue('Houston, we have a problem'),
});
await waitForPromises();
expect(createFlash).toHaveBeenCalled();
});
});
...@@ -166,3 +166,21 @@ export const epicAncestorsResponse = () => ({ ...@@ -166,3 +166,21 @@ export const epicAncestorsResponse = () => ({
}, },
}, },
}); });
export const issueNoWeightResponse = () => ({
data: {
workspace: {
issuable: { id: mockIssueId, weight: null, __typename: 'Issue' },
__typename: 'Project',
},
},
});
export const issueWeightResponse = () => ({
data: {
workspace: {
issuable: { id: mockIssueId, weight: 1, __typename: 'Issue' },
__typename: 'Project',
},
},
});
...@@ -30491,6 +30491,9 @@ msgstr "" ...@@ -30491,6 +30491,9 @@ msgstr ""
msgid "Something went wrong while setting %{issuableType} to-do item." msgid "Something went wrong while setting %{issuableType} to-do item."
msgstr "" msgstr ""
msgid "Something went wrong while setting %{issuableType} weight."
msgstr ""
msgid "Something went wrong while stopping this environment. Please try again." msgid "Something went wrong while stopping this environment. Please try again."
msgstr "" msgstr ""
......
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