Commit 8c74c7ec authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Kushal Pandya

Project level cycle analytics stages cant be edited

Removes the hide, edit and remove options as well
as the more options dropdown from project level
cycle analytics stage list items. This feature
only applies to group level cycle analytics which
occur under ee/.../analytics/cycle_analytics.
parent bc94b5b1
<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> <script>
import StageCardListItem from './stage_card_list_item.vue';
export default { export default {
name: 'StageNavItem', name: 'StageNavItem',
components: {
StageCardListItem,
},
props: { props: {
isDefaultStage: { isDefaultStage: {
type: Boolean, type: Boolean,
...@@ -40,16 +35,16 @@ export default { ...@@ -40,16 +35,16 @@ export default {
hasValue() { hasValue() {
return this.value && this.value.length > 0; return this.value && this.value.length > 0;
}, },
editable() {
return this.isUserAllowed && this.canEdit;
},
}, },
}; };
</script> </script>
<template> <template>
<li @click="$emit('select')"> <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 }"> <div class="stage-nav-item-cell stage-name p-0" :class="{ 'font-weight-bold': isActive }">
{{ title }} {{ title }}
</div> </div>
...@@ -62,27 +57,6 @@ export default { ...@@ -62,27 +57,6 @@ export default {
<span class="not-available">{{ __('Not available') }}</span> <span class="not-available">{{ __('Not available') }}</span>
</template> </template>
</div> </div>
<template v-slot:dropdown-options> </div>
<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>
</li> </li>
</template> </template>
<script> <script>
import Icon from '~/vue_shared/components/icon.vue';
import { GlButton } from '@gitlab/ui';
export default { export default {
name: 'StageCardListItem', name: 'StageCardListItem',
components: {
Icon,
GlButton,
},
props: { props: {
isActive: { isActive: {
type: Boolean, type: Boolean,
...@@ -34,17 +27,5 @@ export default { ...@@ -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" 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> <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> </div>
</template> </template>
<script> <script>
import { GlButton } from '@gitlab/ui';
import StageCardListItem from './stage_card_list_item.vue'; import StageCardListItem from './stage_card_list_item.vue';
import Icon from '~/vue_shared/components/icon.vue';
export default { export default {
name: 'StageNavItem', name: 'StageNavItem',
components: { components: {
StageCardListItem, StageCardListItem,
Icon,
GlButton,
}, },
props: { props: {
isDefaultStage: { isDefaultStage: {
...@@ -32,6 +36,11 @@ export default { ...@@ -32,6 +36,11 @@ export default {
required: false, required: false,
}, },
}, },
data() {
return {
isHover: false,
};
},
computed: { computed: {
hasValue() { hasValue() {
return this.value && this.value.length > 0; return this.value && this.value.length > 0;
...@@ -40,11 +49,26 @@ export default { ...@@ -40,11 +49,26 @@ export default {
return this.canEdit; 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> </script>
<template> <template>
<li @click="$emit('select')"> <li @click="handleSelectStage" @mouseover="handleHover(true)" @mouseleave="handleHover()">
<stage-card-list-item :is-active="isActive" :can-edit="editable"> <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 }"> <div class="stage-nav-item-cell stage-name p-0" :class="{ 'font-weight-bold': isActive }">
{{ title }} {{ title }}
...@@ -53,27 +77,48 @@ export default { ...@@ -53,27 +77,48 @@ export default {
<span v-if="hasValue">{{ value }}</span> <span v-if="hasValue">{{ value }}</span>
<span v-else class="stage-empty">{{ __('Not enough data') }}</span> <span v-else class="stage-empty">{{ __('Not enough data') }}</span>
</div> </div>
<template v-slot:dropdown-options> <div v-show="canEdit && isHover" ref="dropdown" class="dropdown">
<template v-if="isDefaultStage"> <gl-button
<li> :title="__('More actions')"
<button type="button" class="btn-default btn-transparent"> class="more-actions-toggle btn btn-transparent p-0"
{{ __('Hide stage') }} data-toggle="dropdown"
</button> >
</li> <icon class="icon" name="ellipsis_v" />
</template> </gl-button>
<template v-else> <ul class="more-actions-dropdown dropdown-menu dropdown-open-left">
<li> <template v-if="isDefaultStage">
<button type="button" class="btn-default btn-transparent"> <li>
{{ __('Edit stage') }} <button
</button> type="button"
</li> class="btn-default btn-transparent"
<li> @click="handleDropdownAction('hide', $event)"
<button type="button" class="btn-danger danger"> >
{{ __('Remove stage') }} {{ __('Hide stage') }}
</button> </button>
</li> </li>
</template> </template>
</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> </stage-card-list-item>
</li> </li>
</template> </template>
...@@ -133,45 +133,19 @@ describe('StageNavItem', () => { ...@@ -133,45 +133,19 @@ describe('StageNavItem', () => {
hasStageName(); hasStageName();
}); });
it('renders options menu', () => { it('does not render options menu', () => {
expect(wrapper.find('.more-actions-toggle').exists()).toBe(true); expect(wrapper.find('.more-actions-toggle').exists()).toBe(false);
}); });
describe('Default stages', () => { it('can not edit the stage', () => {
beforeEach(() => { expect(wrapper.text()).not.toContain('Edit stage');
wrapper = createComponent( });
{ canEdit: true, isUserAllowed: true, isDefaultStage: true }, it('can not remove the stage', () => {
false, expect(wrapper.text()).not.toContain('Remove stage');
);
});
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');
});
}); });
describe('Custom stages', () => { it('can not hide the stage', () => {
beforeEach(() => { expect(wrapper.text()).not.toContain('Hide stage');
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');
});
}); });
}); });
}); });
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