Resolve "Clicking confidential and lock icons on sidebar should also activate dropdown"
This commit is contained in:
parent
b0e1749363
commit
91a4eb1cb1
10 changed files with 300 additions and 166 deletions
|
@ -1,59 +1,73 @@
|
|||
<script>
|
||||
import Flash from '../../../flash';
|
||||
import editForm from './edit_form.vue';
|
||||
import Icon from '../../../vue_shared/components/icon.vue';
|
||||
import { __ } from '../../../locale';
|
||||
import Flash from '../../../flash';
|
||||
import editForm from './edit_form.vue';
|
||||
import Icon from '../../../vue_shared/components/icon.vue';
|
||||
import { __ } from '../../../locale';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
editForm,
|
||||
Icon,
|
||||
export default {
|
||||
components: {
|
||||
editForm,
|
||||
Icon,
|
||||
},
|
||||
props: {
|
||||
isConfidential: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
props: {
|
||||
isConfidential: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
isEditable: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
service: {
|
||||
required: true,
|
||||
type: Object,
|
||||
},
|
||||
isEditable: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
edit: false,
|
||||
};
|
||||
service: {
|
||||
required: true,
|
||||
type: Object,
|
||||
},
|
||||
computed: {
|
||||
confidentialityIcon() {
|
||||
return this.isConfidential ? 'eye-slash' : 'eye';
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
edit: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
confidentialityIcon() {
|
||||
return this.isConfidential ? 'eye-slash' : 'eye';
|
||||
},
|
||||
methods: {
|
||||
toggleForm() {
|
||||
this.edit = !this.edit;
|
||||
},
|
||||
updateConfidentialAttribute(confidential) {
|
||||
this.service.update('issue', { confidential })
|
||||
.then(() => location.reload())
|
||||
.catch(() => {
|
||||
Flash(__('Something went wrong trying to change the confidentiality of this issue'));
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
eventHub.$on('closeConfidentialityForm', this.toggleForm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('closeConfidentialityForm', this.toggleForm);
|
||||
},
|
||||
methods: {
|
||||
toggleForm() {
|
||||
this.edit = !this.edit;
|
||||
},
|
||||
};
|
||||
updateConfidentialAttribute(confidential) {
|
||||
this.service
|
||||
.update('issue', { confidential })
|
||||
.then(() => location.reload())
|
||||
.catch(() => {
|
||||
Flash(
|
||||
__(
|
||||
'Something went wrong trying to change the confidentiality of this issue',
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="block issuable-sidebar-item confidentiality">
|
||||
<div class="sidebar-collapsed-icon">
|
||||
<div
|
||||
class="sidebar-collapsed-icon"
|
||||
@click="toggleForm"
|
||||
>
|
||||
<icon
|
||||
:name="confidentialityIcon"
|
||||
:size="16"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
|
@ -71,7 +85,6 @@
|
|||
<div class="value sidebar-item-value hide-collapsed">
|
||||
<editForm
|
||||
v-if="edit"
|
||||
:toggle-form="toggleForm"
|
||||
:is-confidential="isConfidential"
|
||||
:update-confidential-attribute="updateConfidentialAttribute"
|
||||
/>
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
<script>
|
||||
import editFormButtons from './edit_form_buttons.vue';
|
||||
import { s__ } from '../../../locale';
|
||||
import editFormButtons from './edit_form_buttons.vue';
|
||||
import { s__ } from '../../../locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
editFormButtons,
|
||||
export default {
|
||||
components: {
|
||||
editFormButtons,
|
||||
},
|
||||
props: {
|
||||
isConfidential: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
props: {
|
||||
isConfidential: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
toggleForm: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
updateConfidentialAttribute: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
updateConfidentialAttribute: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
computed: {
|
||||
confidentialityOnWarning() {
|
||||
return s__('confidentiality|You are going to turn on the confidentiality. This means that only team members with <strong>at least Reporter access</strong> are able to see and leave comments on the issue.');
|
||||
},
|
||||
confidentialityOffWarning() {
|
||||
return s__('confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue.');
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
confidentialityOnWarning() {
|
||||
return s__(
|
||||
'confidentiality|You are going to turn on the confidentiality. This means that only team members with <strong>at least Reporter access</strong> are able to see and leave comments on the issue.',
|
||||
);
|
||||
},
|
||||
};
|
||||
confidentialityOffWarning() {
|
||||
return s__(
|
||||
'confidentiality|You are going to turn off the confidentiality. This means <strong>everyone</strong> will be able to see and leave a comment on this issue.',
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -45,7 +45,6 @@
|
|||
</p>
|
||||
<edit-form-buttons
|
||||
:is-confidential="isConfidential"
|
||||
:toggle-form="toggleForm"
|
||||
:update-confidential-attribute="updateConfidentialAttribute"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
<script>
|
||||
import $ from 'jquery';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
isConfidential: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
toggleForm: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
updateConfidentialAttribute: {
|
||||
required: true,
|
||||
type: Function,
|
||||
|
@ -22,6 +21,16 @@ export default {
|
|||
return !this.isConfidential;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
closeForm() {
|
||||
eventHub.$emit('closeConfidentialityForm');
|
||||
$(this.$el).trigger('hidden.gl.dropdown');
|
||||
},
|
||||
submitForm() {
|
||||
this.closeForm();
|
||||
this.updateConfidentialAttribute(this.updateConfidentialBool);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -30,14 +39,14 @@ export default {
|
|||
<button
|
||||
type="button"
|
||||
class="btn btn-default append-right-10"
|
||||
@click="toggleForm"
|
||||
@click="closeForm"
|
||||
>
|
||||
{{ __('Cancel') }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-close"
|
||||
@click.prevent="updateConfidentialAttribute(updateConfidentialBool)"
|
||||
@click.prevent="submitForm"
|
||||
>
|
||||
{{ toggleButtonText }}
|
||||
</button>
|
||||
|
|
|
@ -1,40 +1,43 @@
|
|||
<script>
|
||||
import editFormButtons from './edit_form_buttons.vue';
|
||||
import issuableMixin from '../../../vue_shared/mixins/issuable';
|
||||
import { __, sprintf } from '../../../locale';
|
||||
import editFormButtons from './edit_form_buttons.vue';
|
||||
import issuableMixin from '../../../vue_shared/mixins/issuable';
|
||||
import { __, sprintf } from '../../../locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
editFormButtons,
|
||||
export default {
|
||||
components: {
|
||||
editFormButtons,
|
||||
},
|
||||
mixins: [issuableMixin],
|
||||
props: {
|
||||
isLocked: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
mixins: [
|
||||
issuableMixin,
|
||||
],
|
||||
props: {
|
||||
isLocked: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
toggleForm: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
|
||||
updateLockedAttribute: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
updateLockedAttribute: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
computed: {
|
||||
lockWarning() {
|
||||
return sprintf(__('Lock this %{issuableDisplayName}? Only <strong>project members</strong> will be able to comment.'), { issuableDisplayName: this.issuableDisplayName });
|
||||
},
|
||||
unlockWarning() {
|
||||
return sprintf(__('Unlock this %{issuableDisplayName}? <strong>Everyone</strong> will be able to comment.'), { issuableDisplayName: this.issuableDisplayName });
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
lockWarning() {
|
||||
return sprintf(
|
||||
__(
|
||||
'Lock this %{issuableDisplayName}? Only <strong>project members</strong> will be able to comment.',
|
||||
),
|
||||
{ issuableDisplayName: this.issuableDisplayName },
|
||||
);
|
||||
},
|
||||
};
|
||||
unlockWarning() {
|
||||
return sprintf(
|
||||
__(
|
||||
'Unlock this %{issuableDisplayName}? <strong>Everyone</strong> will be able to comment.',
|
||||
),
|
||||
{ issuableDisplayName: this.issuableDisplayName },
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -54,7 +57,6 @@
|
|||
|
||||
<edit-form-buttons
|
||||
:is-locked="isLocked"
|
||||
:toggle-form="toggleForm"
|
||||
:update-locked-attribute="updateLockedAttribute"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<script>
|
||||
import $ from 'jquery';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
isLocked: {
|
||||
|
@ -6,11 +9,6 @@ export default {
|
|||
type: Boolean,
|
||||
},
|
||||
|
||||
toggleForm: {
|
||||
required: true,
|
||||
type: Function,
|
||||
},
|
||||
|
||||
updateLockedAttribute: {
|
||||
required: true,
|
||||
type: Function,
|
||||
|
@ -26,6 +24,17 @@ export default {
|
|||
return !this.isLocked;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
closeForm() {
|
||||
eventHub.$emit('closeLockForm');
|
||||
$(this.$el).trigger('hidden.gl.dropdown');
|
||||
},
|
||||
submitForm() {
|
||||
this.closeForm();
|
||||
this.updateLockedAttribute(this.toggleLock);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -34,7 +43,7 @@ export default {
|
|||
<button
|
||||
type="button"
|
||||
class="btn btn-default append-right-10"
|
||||
@click="toggleForm"
|
||||
@click="closeForm"
|
||||
>
|
||||
{{ __('Cancel') }}
|
||||
</button>
|
||||
|
@ -42,7 +51,7 @@ export default {
|
|||
<button
|
||||
type="button"
|
||||
class="btn btn-close"
|
||||
@click.prevent="updateLockedAttribute(toggleLock)"
|
||||
@click.prevent="submitForm"
|
||||
>
|
||||
{{ buttonText }}
|
||||
</button>
|
||||
|
|
|
@ -1,70 +1,93 @@
|
|||
<script>
|
||||
import Flash from '~/flash';
|
||||
import editForm from './edit_form.vue';
|
||||
import issuableMixin from '../../../vue_shared/mixins/issuable';
|
||||
import Icon from '../../../vue_shared/components/icon.vue';
|
||||
import Flash from '~/flash';
|
||||
import editForm from './edit_form.vue';
|
||||
import issuableMixin from '../../../vue_shared/mixins/issuable';
|
||||
import Icon from '../../../vue_shared/components/icon.vue';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
editForm,
|
||||
Icon,
|
||||
},
|
||||
mixins: [
|
||||
issuableMixin,
|
||||
],
|
||||
export default {
|
||||
components: {
|
||||
editForm,
|
||||
Icon,
|
||||
},
|
||||
mixins: [issuableMixin],
|
||||
|
||||
props: {
|
||||
isLocked: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
isEditable: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
mediator: {
|
||||
required: true,
|
||||
type: Object,
|
||||
validator(mediatorObject) {
|
||||
return mediatorObject.service && mediatorObject.service.update && mediatorObject.store;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
isLocked: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
computed: {
|
||||
lockIcon() {
|
||||
return this.isLocked ? 'lock' : 'lock-open';
|
||||
},
|
||||
|
||||
isLockDialogOpen() {
|
||||
return this.mediator.store.isLockDialogOpen;
|
||||
},
|
||||
isEditable: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleForm() {
|
||||
this.mediator.store.isLockDialogOpen = !this.mediator.store.isLockDialogOpen;
|
||||
mediator: {
|
||||
required: true,
|
||||
type: Object,
|
||||
validator(mediatorObject) {
|
||||
return (
|
||||
mediatorObject.service &&
|
||||
mediatorObject.service.update &&
|
||||
mediatorObject.store
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
updateLockedAttribute(locked) {
|
||||
this.mediator.service.update(this.issuableType, {
|
||||
computed: {
|
||||
lockIcon() {
|
||||
return this.isLocked ? 'lock' : 'lock-open';
|
||||
},
|
||||
|
||||
isLockDialogOpen() {
|
||||
return this.mediator.store.isLockDialogOpen;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
eventHub.$on('closeLockForm', this.toggleForm);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
eventHub.$off('closeLockForm', this.toggleForm);
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleForm() {
|
||||
this.mediator.store.isLockDialogOpen = !this.mediator.store
|
||||
.isLockDialogOpen;
|
||||
},
|
||||
|
||||
updateLockedAttribute(locked) {
|
||||
this.mediator.service
|
||||
.update(this.issuableType, {
|
||||
discussion_locked: locked,
|
||||
})
|
||||
.then(() => location.reload())
|
||||
.catch(() => Flash(this.__(`Something went wrong trying to change the locked state of this ${this.issuableDisplayName}`)));
|
||||
},
|
||||
.catch(() =>
|
||||
Flash(
|
||||
this.__(
|
||||
`Something went wrong trying to change the locked state of this ${
|
||||
this.issuableDisplayName
|
||||
}`,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="block issuable-sidebar-item lock">
|
||||
<div class="sidebar-collapsed-icon">
|
||||
<div
|
||||
class="sidebar-collapsed-icon"
|
||||
@click="toggleForm"
|
||||
>
|
||||
<icon
|
||||
:name="lockIcon"
|
||||
:size="16"
|
||||
aria-hidden="true"
|
||||
class="sidebar-item-icon is-active"
|
||||
/>
|
||||
|
@ -85,7 +108,6 @@
|
|||
<div class="value sidebar-item-value hide-collapsed">
|
||||
<edit-form
|
||||
v-if="isLockDialogOpen"
|
||||
:toggle-form="toggleForm"
|
||||
:is-locked="isLocked"
|
||||
:update-locked-attribute="updateLockedAttribute"
|
||||
:issuable-type="issuableType"
|
||||
|
|
|
@ -14,7 +14,7 @@ describe 'Discussion Lock', :js do
|
|||
project.add_developer(user)
|
||||
end
|
||||
|
||||
context 'when the discussion is unlocked' do
|
||||
context 'when the discussion is unlocked' do
|
||||
it 'the user can lock the issue' do
|
||||
visit project_issue_path(project, issue)
|
||||
|
||||
|
|
|
@ -161,6 +161,50 @@ feature 'Issue Sidebar' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'interacting with collapsed sidebar', :js do
|
||||
collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
|
||||
expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
|
||||
confidentiality_sidebar_block = '.block.confidentiality'
|
||||
lock_sidebar_block = '.block.lock'
|
||||
collapsed_sidebar_block_icon = '.sidebar-collapsed-icon'
|
||||
|
||||
before do
|
||||
resize_screen_sm
|
||||
end
|
||||
|
||||
it 'confidentiality block expands then collapses sidebar' do
|
||||
expect(page).to have_css(collapsed_sidebar_selector)
|
||||
|
||||
page.within(confidentiality_sidebar_block) do
|
||||
find(collapsed_sidebar_block_icon).click
|
||||
end
|
||||
|
||||
expect(page).to have_css(expanded_sidebar_selector)
|
||||
|
||||
page.within(confidentiality_sidebar_block) do
|
||||
page.find('button', text: 'Cancel').click
|
||||
end
|
||||
|
||||
expect(page).to have_css(collapsed_sidebar_selector)
|
||||
end
|
||||
|
||||
it 'lock block expands then collapses sidebar' do
|
||||
expect(page).to have_css(collapsed_sidebar_selector)
|
||||
|
||||
page.within(lock_sidebar_block) do
|
||||
find(collapsed_sidebar_block_icon).click
|
||||
end
|
||||
|
||||
expect(page).to have_css(expanded_sidebar_selector)
|
||||
|
||||
page.within(lock_sidebar_block) do
|
||||
page.find('button', text: 'Cancel').click
|
||||
end
|
||||
|
||||
expect(page).to have_css(collapsed_sidebar_selector)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'as a guest' do
|
||||
|
|
|
@ -62,4 +62,22 @@ describe('Confidential Issue Sidebar Block', () => {
|
|||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the edit form when opened from collapsed state', (done) => {
|
||||
expect(vm1.edit).toBe(false);
|
||||
|
||||
vm1.$el.querySelector('.sidebar-collapsed-icon').click();
|
||||
|
||||
expect(vm1.edit).toBe(true);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(
|
||||
vm1.$el
|
||||
.innerHTML
|
||||
.includes('You are going to turn off the confidentiality.'),
|
||||
).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -68,4 +68,22 @@ describe('LockIssueSidebar', () => {
|
|||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the edit form when opened from collapsed state', (done) => {
|
||||
expect(vm1.isLockDialogOpen).toBe(false);
|
||||
|
||||
vm1.$el.querySelector('.sidebar-collapsed-icon').click();
|
||||
|
||||
expect(vm1.isLockDialogOpen).toBe(true);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(
|
||||
vm1.$el
|
||||
.innerHTML
|
||||
.includes('Unlock this issue?'),
|
||||
).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue