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">
<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"> <template v-if="isDefaultStage">
<li> <li>
<button type="button" class="btn-default btn-transparent"> <button
type="button"
class="btn-default btn-transparent"
@click="handleDropdownAction('hide', $event)"
>
{{ __('Hide stage') }} {{ __('Hide stage') }}
</button> </button>
</li> </li>
</template> </template>
<template v-else> <template v-else>
<li> <li>
<button type="button" class="btn-default btn-transparent"> <button
type="button"
class="btn-default btn-transparent"
@click="handleDropdownAction('edit', $event)"
>
{{ __('Edit stage') }} {{ __('Edit stage') }}
</button> </button>
</li> </li>
<li> <li>
<button type="button" class="btn-danger danger"> <button
type="button"
class="btn-danger danger"
@click="handleDropdownAction('remove', $event)"
>
{{ __('Remove stage') }} {{ __('Remove stage') }}
</button> </button>
</li> </li>
</template> </template>
</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', () => {
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', () => { it('can not edit the stage', () => {
expect(wrapper.text()).not.toContain('Edit stage'); expect(wrapper.text()).not.toContain('Edit stage');
}); });
it('can not remove the stage', () => { it('can not remove the stage', () => {
expect(wrapper.text()).not.toContain('Remove 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', () => { it('can not hide the stage', () => {
expect(wrapper.text()).not.toContain('Hide 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