Commit c33245e9 authored by Filipa Lacerda's avatar Filipa Lacerda

Reuse getter

Add loading button for better UX
parent ab734240
...@@ -9,10 +9,11 @@ ...@@ -9,10 +9,11 @@
import * as constants from '../constants'; import * as constants from '../constants';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import issueWarning from '../../vue_shared/components/issue/issue_warning.vue'; import issueWarning from '../../vue_shared/components/issue/issue_warning.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
import discussionLockedWidget from './discussion_locked_widget.vue';
import markdownField from '../../vue_shared/components/markdown/field.vue'; import markdownField from '../../vue_shared/components/markdown/field.vue';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import loadingButton from '../../vue_shared/components/loading_button.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
import discussionLockedWidget from './discussion_locked_widget.vue';
import issuableStateMixin from '../mixins/issuable_state'; import issuableStateMixin from '../mixins/issuable_state';
export default { export default {
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
discussionLockedWidget, discussionLockedWidget,
markdownField, markdownField,
userAvatarLink, userAvatarLink,
loadingButton,
}, },
mixins: [ mixins: [
issuableStateMixin, issuableStateMixin,
...@@ -41,11 +43,8 @@ ...@@ -41,11 +43,8 @@
'getUserData', 'getUserData',
'getNoteableData', 'getNoteableData',
'getNotesData', 'getNotesData',
'getIssueState', 'issueState',
]), ]),
issueState() {
return this.getIssueState;
},
isLoggedIn() { isLoggedIn() {
return this.getUserData.id; return this.getUserData.id;
}, },
...@@ -131,6 +130,8 @@ ...@@ -131,6 +130,8 @@
} }
}, },
handleSave(withIssueAction) { handleSave(withIssueAction) {
this.isSubmitting = true;
if (this.note.length) { if (this.note.length) {
const noteData = { const noteData = {
endpoint: this.endpoint, endpoint: this.endpoint,
...@@ -147,7 +148,6 @@ ...@@ -147,7 +148,6 @@
if (this.noteType === constants.DISCUSSION) { if (this.noteType === constants.DISCUSSION) {
noteData.data.note.type = constants.DISCUSSION_NOTE; noteData.data.note.type = constants.DISCUSSION_NOTE;
} }
this.isSubmitting = true;
this.note = ''; // Empty textarea while being requested. Repopulate in catch this.note = ''; // Empty textarea while being requested. Repopulate in catch
this.resizeTextarea(); this.resizeTextarea();
this.stopPolling(); this.stopPolling();
...@@ -189,13 +189,24 @@ Please check your network connection and try again.`; ...@@ -189,13 +189,24 @@ Please check your network connection and try again.`;
this.toggleIssueState(); this.toggleIssueState();
} }
}, },
enableButton() {
this.isSubmitting = false;
},
toggleIssueState() { toggleIssueState() {
if (this.isIssueOpen) { if (this.isIssueOpen) {
this.closeIssue() this.closeIssue()
.catch(() => Flash(__('Something went wrong while closing the issue. Please try again later'))); .then(() => this.enableButton())
.catch(() => {
this.enableButton();
Flash(__('Something went wrong while closing the issue. Please try again later'));
});
} else { } else {
this.reopenIssue() this.reopenIssue()
.catch(() => Flash(__('Something went wrong while reopening the issue. Please try again later'))); .then(() => this.enableButton())
.catch(() => {
this.enableButton();
Flash(__('Something went wrong while reopening the issue. Please try again later'));
});
} }
}, },
discard(shouldClear = true) { discard(shouldClear = true) {
...@@ -373,15 +384,19 @@ append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown" ...@@ -373,15 +384,19 @@ append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
</li> </li>
</ul> </ul>
</div> </div>
<button
type="button" <loading-button
@click="handleSave(true)"
v-if="canUpdateIssue" v-if="canUpdateIssue"
:class="actionButtonClassNames" :loading="isSubmitting"
@click="handleSave(true)"
:container-class="[
actionButtonClassNames,
'btn btn-comment btn-comment-and-close js-action-button'
]"
:disabled="isSubmitting" :disabled="isSubmitting"
class="btn btn-comment btn-comment-and-close js-action-button"> :label="issueActionButtonTitle"
{{ issueActionButtonTitle }} />
</button>
<button <button
type="button" type="button"
v-if="note.length" v-if="note.length"
......
...@@ -77,10 +77,10 @@ export const reopenIssue = ({ commit, dispatch, state }) => service ...@@ -77,10 +77,10 @@ export const reopenIssue = ({ commit, dispatch, state }) => service
dispatch('emitStateChangedEvent', data); dispatch('emitStateChangedEvent', data);
}); });
export const emitStateChangedEvent = ({ commit }, data) => { export const emitStateChangedEvent = ({ commit, getters }, data) => {
const event = new CustomEvent('issuable_vue_app:change', { detail: { const event = new CustomEvent('issuable_vue_app:change', { detail: {
data, data,
isClosed: data.state === constants.CLOSED, isClosed: getters.issueState === constants.CLOSED,
} }); } });
document.dispatchEvent(event); document.dispatchEvent(event);
......
...@@ -8,7 +8,7 @@ export const getNotesDataByProp = state => prop => state.notesData[prop]; ...@@ -8,7 +8,7 @@ export const getNotesDataByProp = state => prop => state.notesData[prop];
export const getNoteableData = state => state.noteableData; export const getNoteableData = state => state.noteableData;
export const getNoteableDataByProp = state => prop => state.noteableData[prop]; export const getNoteableDataByProp = state => prop => state.noteableData[prop];
export const getIssueState = state => state.noteableData.state; export const issueState = state => state.noteableData.state;
export const getUserData = state => state.userData || {}; export const getUserData = state => state.userData || {};
export const getUserDataByProp = state => prop => state.userData && state.userData[prop]; export const getUserDataByProp = state => prop => state.userData && state.userData[prop];
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
required: false, required: false,
}, },
containerClass: { containerClass: {
type: String, type: [String, Array, Object],
required: false, required: false,
default: 'btn btn-align-content', default: 'btn btn-align-content',
}, },
......
...@@ -109,7 +109,7 @@ describe('Actions Notes Store', () => { ...@@ -109,7 +109,7 @@ describe('Actions Notes Store', () => {
it('emits an event on the document', () => { it('emits an event on the document', () => {
document.addEventListener('issuable_vue_app:change', (event) => { document.addEventListener('issuable_vue_app:change', (event) => {
expect(event.detail.data).toEqual({ id: '1', state: 'closed' }); expect(event.detail.data).toEqual({ id: '1', state: 'closed' });
expect(event.detail.isClosed).toEqual(true); expect(event.detail.isClosed).toEqual(false);
}); });
store.dispatch('emitStateChangedEvent', { id: '1', state: 'closed' }); store.dispatch('emitStateChangedEvent', { id: '1', state: 'closed' });
......
...@@ -55,4 +55,10 @@ describe('Getters Notes Store', () => { ...@@ -55,4 +55,10 @@ describe('Getters Notes Store', () => {
expect(getters.getCurrentUserLastNote(state)).toEqual(individualNote.notes[0]); expect(getters.getCurrentUserLastNote(state)).toEqual(individualNote.notes[0]);
}); });
}); });
describe('issueState', () => {
it('should return the issue state', () => {
expect(getters.issueState(state)).toEqual(noteableDataMock.state);
});
});
}); });
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