Commit 7f7a6d2d authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '13076-fix-over-triggering-cycle-analytics-stage-select-event' into 'master'

Fix select event triggering from cycle analytics stage

See merge request gitlab-org/gitlab!19729
parents bc94b5b1 8c74c7ec
<script>
import Icon from '~/vue_shared/components/icon.vue';
import { GlButton } from '@gitlab/ui';
export default {
name: 'StageCardListItem',
components: {
Icon,
GlButton,
},
props: {
isActive: {
type: Boolean,
required: true,
},
canEdit: {
type: Boolean,
default: false,
required: false,
},
},
};
</script>
<template>
<div
:class="{ active: isActive }"
class="stage-nav-item d-flex pl-4 pr-4 m-0 mb-1 ml-2 rounded border-color-default border-style-solid border-width-1px"
>
<slot></slot>
<div v-if="canEdit" class="dropdown">
<gl-button
:title="__('More actions')"
class="more-actions-toggle btn btn-transparent p-0"
data-toggle="dropdown"
>
<icon class="icon" name="ellipsis_v" />
</gl-button>
<ul class="more-actions-dropdown dropdown-menu dropdown-open-left">
<slot name="dropdown-options"></slot>
</ul>
</div>
</div>
</template>
<script>
import StageCardListItem from './stage_card_list_item.vue';
export default {
name: 'StageNavItem',
components: {
StageCardListItem,
},
props: {
isDefaultStage: {
type: Boolean,
......@@ -40,16 +35,16 @@ export default {
hasValue() {
return this.value && this.value.length > 0;
},
editable() {
return this.isUserAllowed && this.canEdit;
},
},
};
</script>
<template>
<li @click="$emit('select')">
<stage-card-list-item :is-active="isActive" :can-edit="editable">
<div
:class="{ active: isActive }"
class="stage-nav-item d-flex pl-4 pr-4 m-0 mb-1 ml-2 rounded border-color-default border-style-solid border-width-1px"
>
<div class="stage-nav-item-cell stage-name p-0" :class="{ 'font-weight-bold': isActive }">
{{ title }}
</div>
......@@ -62,27 +57,6 @@ export default {
<span class="not-available">{{ __('Not available') }}</span>
</template>
</div>
<template v-slot:dropdown-options>
<template v-if="isDefaultStage">
<li>
<button type="button" class="btn-default btn-transparent">
{{ __('Hide stage') }}
</button>
</li>
</template>
<template v-else>
<li>
<button type="button" class="btn-default btn-transparent">
{{ __('Edit stage') }}
</button>
</li>
<li>
<button type="button" class="btn-danger danger">
{{ __('Remove stage') }}
</button>
</li>
</template>
</template>
</stage-card-list-item>
</div>
</li>
</template>
<script>
import Icon from '~/vue_shared/components/icon.vue';
import { GlButton } from '@gitlab/ui';
export default {
name: 'StageCardListItem',
components: {
Icon,
GlButton,
},
props: {
isActive: {
type: Boolean,
......@@ -34,17 +27,5 @@ export default {
class="stage-nav-item d-flex pl-4 pr-4 m-0 mb-1 ml-2 rounded border-width-1px border-style-solid"
>
<slot></slot>
<div v-if="canEdit" class="dropdown">
<gl-button
:title="__('More actions')"
class="more-actions-toggle btn btn-transparent p-0"
data-toggle="dropdown"
>
<icon class="icon" name="ellipsis_v" />
</gl-button>
<ul class="more-actions-dropdown dropdown-menu dropdown-open-left">
<slot name="dropdown-options"></slot>
</ul>
</div>
</div>
</template>
<script>
import { GlButton } from '@gitlab/ui';
import StageCardListItem from './stage_card_list_item.vue';
import Icon from '~/vue_shared/components/icon.vue';
export default {
name: 'StageNavItem',
components: {
StageCardListItem,
Icon,
GlButton,
},
props: {
isDefaultStage: {
......@@ -32,6 +36,11 @@ export default {
required: false,
},
},
data() {
return {
isHover: false,
};
},
computed: {
hasValue() {
return this.value && this.value.length > 0;
......@@ -40,11 +49,26 @@ export default {
return this.canEdit;
},
},
methods: {
handleDropdownAction(action) {
this.$emit(action);
},
handleSelectStage(e) {
// we don't want to emit the select event when we click the more actions dropdown
// But we should still trigger the event if we click anywhere else in the list item
if (!this.$refs.dropdown.contains(e.target)) {
this.$emit('select');
}
},
handleHover(hoverState = false) {
this.isHover = hoverState;
},
},
};
</script>
<template>
<li @click="$emit('select')">
<li @click="handleSelectStage" @mouseover="handleHover(true)" @mouseleave="handleHover()">
<stage-card-list-item :is-active="isActive" :can-edit="editable">
<div class="stage-nav-item-cell stage-name p-0" :class="{ 'font-weight-bold': isActive }">
{{ title }}
......@@ -53,27 +77,48 @@ export default {
<span v-if="hasValue">{{ value }}</span>
<span v-else class="stage-empty">{{ __('Not enough data') }}</span>
</div>
<template v-slot:dropdown-options>
<template v-if="isDefaultStage">
<li>
<button type="button" class="btn-default btn-transparent">
{{ __('Hide stage') }}
</button>
</li>
</template>
<template v-else>
<li>
<button type="button" class="btn-default btn-transparent">
{{ __('Edit stage') }}
</button>
</li>
<li>
<button type="button" class="btn-danger danger">
{{ __('Remove stage') }}
</button>
</li>
</template>
</template>
<div v-show="canEdit && isHover" ref="dropdown" class="dropdown">
<gl-button
:title="__('More actions')"
class="more-actions-toggle btn btn-transparent p-0"
data-toggle="dropdown"
>
<icon class="icon" name="ellipsis_v" />
</gl-button>
<ul class="more-actions-dropdown dropdown-menu dropdown-open-left">
<template v-if="isDefaultStage">
<li>
<button
type="button"
class="btn-default btn-transparent"
@click="handleDropdownAction('hide', $event)"
>
{{ __('Hide stage') }}
</button>
</li>
</template>
<template v-else>
<li>
<button
type="button"
class="btn-default btn-transparent"
@click="handleDropdownAction('edit', $event)"
>
{{ __('Edit stage') }}
</button>
</li>
<li>
<button
type="button"
class="btn-danger danger"
@click="handleDropdownAction('remove', $event)"
>
{{ __('Remove stage') }}
</button>
</li>
</template>
</ul>
</div>
</stage-card-list-item>
</li>
</template>
......@@ -133,45 +133,19 @@ describe('StageNavItem', () => {
hasStageName();
});
it('renders options menu', () => {
expect(wrapper.find('.more-actions-toggle').exists()).toBe(true);
it('does not render options menu', () => {
expect(wrapper.find('.more-actions-toggle').exists()).toBe(false);
});
describe('Default stages', () => {
beforeEach(() => {
wrapper = createComponent(
{ canEdit: true, isUserAllowed: true, isDefaultStage: true },
false,
);
});
it('can hide the stage', () => {
expect(wrapper.text()).toContain('Hide stage');
});
it('can not edit the stage', () => {
expect(wrapper.text()).not.toContain('Edit stage');
});
it('can not remove the stage', () => {
expect(wrapper.text()).not.toContain('Remove stage');
});
it('can not edit the stage', () => {
expect(wrapper.text()).not.toContain('Edit stage');
});
it('can not remove the stage', () => {
expect(wrapper.text()).not.toContain('Remove stage');
});
describe('Custom stages', () => {
beforeEach(() => {
wrapper = createComponent(
{ canEdit: true, isUserAllowed: true, isDefaultStage: false },
false,
);
});
it('can edit the stage', () => {
expect(wrapper.text()).toContain('Edit stage');
});
it('can remove the stage', () => {
expect(wrapper.text()).toContain('Remove stage');
});
it('can not hide the stage', () => {
expect(wrapper.text()).not.toContain('Hide stage');
});
it('can not hide the stage', () => {
expect(wrapper.text()).not.toContain('Hide stage');
});
});
});
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