Commit b77ef97b authored by Tim Zallmann's avatar Tim Zallmann

Merge branch 'prettify-all-the-things-4' into 'master'

Prettify all the things (part 4)

See merge request gitlab-org/gitlab-ce!22253
parents e5304d52 0efbc126
...@@ -95,29 +95,20 @@ export default { ...@@ -95,29 +95,20 @@ export default {
return awardList.filter(award => award.user.id === this.getUserData.id).length; return awardList.filter(award => award.user.id === this.getUserData.id).length;
}, },
awardTitle(awardsList) { awardTitle(awardsList) {
const hasReactionByCurrentUser = this.hasReactionByCurrentUser( const hasReactionByCurrentUser = this.hasReactionByCurrentUser(awardsList);
awardsList,
);
const TOOLTIP_NAME_COUNT = hasReactionByCurrentUser ? 9 : 10; const TOOLTIP_NAME_COUNT = hasReactionByCurrentUser ? 9 : 10;
let awardList = awardsList; let awardList = awardsList;
// Filter myself from list if I am awarded. // Filter myself from list if I am awarded.
if (hasReactionByCurrentUser) { if (hasReactionByCurrentUser) {
awardList = awardList.filter( awardList = awardList.filter(award => award.user.id !== this.getUserData.id);
award => award.user.id !== this.getUserData.id,
);
} }
// Get only 9-10 usernames to show in tooltip text. // Get only 9-10 usernames to show in tooltip text.
const namesToShow = awardList const namesToShow = awardList.slice(0, TOOLTIP_NAME_COUNT).map(award => award.user.name);
.slice(0, TOOLTIP_NAME_COUNT)
.map(award => award.user.name);
// Get the remaining list to use in `and x more` text. // Get the remaining list to use in `and x more` text.
const remainingAwardList = awardList.slice( const remainingAwardList = awardList.slice(TOOLTIP_NAME_COUNT, awardList.length);
TOOLTIP_NAME_COUNT,
awardList.length,
);
// Add myself to the begining of the list so title will start with You. // Add myself to the begining of the list so title will start with You.
if (hasReactionByCurrentUser) { if (hasReactionByCurrentUser) {
...@@ -128,9 +119,7 @@ export default { ...@@ -128,9 +119,7 @@ export default {
// We have 10+ awarded user, join them with comma and add `and x more`. // We have 10+ awarded user, join them with comma and add `and x more`.
if (remainingAwardList.length) { if (remainingAwardList.length) {
title = `${namesToShow.join(', ')}, and ${ title = `${namesToShow.join(', ')}, and ${remainingAwardList.length} more.`;
remainingAwardList.length
} more.`;
} else if (namesToShow.length > 1) { } else if (namesToShow.length > 1) {
// Join all names with comma but not the last one, it will be added with and text. // Join all names with comma but not the last one, it will be added with and text.
title = namesToShow.slice(0, namesToShow.length - 1).join(', '); title = namesToShow.slice(0, namesToShow.length - 1).join(', ');
...@@ -170,9 +159,7 @@ export default { ...@@ -170,9 +159,7 @@ export default {
awardName: parsedName, awardName: parsedName,
}; };
this.toggleAwardRequest(data).catch(() => this.toggleAwardRequest(data).catch(() => Flash('Something went wrong on our end.'));
Flash('Something went wrong on our end.'),
);
}, },
}, },
}; };
......
...@@ -68,10 +68,7 @@ export const collapseSystemNotes = notes => { ...@@ -68,10 +68,7 @@ export const collapseSystemNotes = notes => {
lastDescriptionSystemNote = note; lastDescriptionSystemNote = note;
lastDescriptionSystemNoteIndex = acc.length; lastDescriptionSystemNoteIndex = acc.length;
} else if (lastDescriptionSystemNote) { } else if (lastDescriptionSystemNote) {
const timeDifferenceMinutes = getTimeDifferenceMinutes( const timeDifferenceMinutes = getTimeDifferenceMinutes(lastDescriptionSystemNote, note);
lastDescriptionSystemNote,
note,
);
// are they less than 10 minutes appart? // are they less than 10 minutes appart?
if (timeDifferenceMinutes > 10) { if (timeDifferenceMinutes > 10) {
......
...@@ -4,5 +4,4 @@ import notesModule from './modules'; ...@@ -4,5 +4,4 @@ import notesModule from './modules';
Vue.use(Vuex); Vue.use(Vuex);
export default () => export default () => new Vuex.Store(notesModule());
new Vuex.Store(notesModule());
<script> <script>
export default { export default {
props: { props: {
currentRequest: { currentRequest: {
type: Object, type: Object,
required: true, required: true,
},
metric: {
type: String,
required: true,
},
}, },
computed: { metric: {
duration() { type: String,
return ( required: true,
this.currentRequest.details[this.metric] &&
this.currentRequest.details[this.metric].duration
);
},
calls() {
return (
this.currentRequest.details[this.metric] && this.currentRequest.details[this.metric].calls
);
},
}, },
}; },
computed: {
duration() {
return (
this.currentRequest.details[this.metric] &&
this.currentRequest.details[this.metric].duration
);
},
calls() {
return (
this.currentRequest.details[this.metric] && this.currentRequest.details[this.metric].calls
);
},
},
};
</script> </script>
<template> <template>
<div <div
......
...@@ -9,8 +9,7 @@ export default ({ container }) => ...@@ -9,8 +9,7 @@ export default ({ container }) =>
performanceBarApp: () => import('./components/performance_bar_app.vue'), performanceBarApp: () => import('./components/performance_bar_app.vue'),
}, },
data() { data() {
const performanceBarData = document.querySelector(this.$options.el) const performanceBarData = document.querySelector(this.$options.el).dataset;
.dataset;
const store = new PerformanceBarStore(); const store = new PerformanceBarStore();
return { return {
......
...@@ -11,8 +11,10 @@ export default class PerformanceBarService { ...@@ -11,8 +11,10 @@ export default class PerformanceBarService {
static registerInterceptor(peekUrl, callback) { static registerInterceptor(peekUrl, callback) {
const interceptor = response => { const interceptor = response => {
const [fireCallback, requestId, requestUrl] = const [fireCallback, requestId, requestUrl] = PerformanceBarService.callbackParams(
PerformanceBarService.callbackParams(response, peekUrl); response,
peekUrl,
);
if (fireCallback) { if (fireCallback) {
callback(requestId, requestUrl); callback(requestId, requestUrl);
...@@ -30,10 +32,7 @@ export default class PerformanceBarService { ...@@ -30,10 +32,7 @@ export default class PerformanceBarService {
static removeInterceptor(interceptor) { static removeInterceptor(interceptor) {
axios.interceptors.response.eject(interceptor); axios.interceptors.response.eject(interceptor);
Vue.http.interceptors = _.without( Vue.http.interceptors = _.without(Vue.http.interceptors, vueResourceInterceptor);
Vue.http.interceptors,
vueResourceInterceptor,
);
} }
static callbackParams(response, peekUrl) { static callbackParams(response, peekUrl) {
......
...@@ -32,8 +32,6 @@ export default class PerformanceBarStore { ...@@ -32,8 +32,6 @@ export default class PerformanceBarStore {
} }
canTrackRequest(requestUrl) { canTrackRequest(requestUrl) {
return ( return this.requests.filter(request => request.url === requestUrl).length < 2;
this.requests.filter(request => request.url === requestUrl).length < 2
);
} }
} }
<script> <script>
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
import { __, s__, sprintf } from '~/locale'; import { __, s__, sprintf } from '~/locale';
import csrf from '~/lib/utils/csrf'; import csrf from '~/lib/utils/csrf';
export default { export default {
components: { components: {
DeprecatedModal, DeprecatedModal,
},
props: {
actionUrl: {
type: String,
required: true,
}, },
props: { confirmWithPassword: {
actionUrl: { type: Boolean,
type: String, required: true,
required: true,
},
confirmWithPassword: {
type: Boolean,
required: true,
},
username: {
type: String,
required: true,
},
}, },
data() { username: {
return { type: String,
enteredPassword: '', required: true,
enteredUsername: '',
};
}, },
computed: { },
csrfToken() { data() {
return csrf.token; return {
}, enteredPassword: '',
inputLabel() { enteredUsername: '',
let confirmationValue; };
if (this.confirmWithPassword) { },
confirmationValue = __('password'); computed: {
} else { csrfToken() {
confirmationValue = __('username'); return csrf.token;
} },
inputLabel() {
let confirmationValue;
if (this.confirmWithPassword) {
confirmationValue = __('password');
} else {
confirmationValue = __('username');
}
confirmationValue = `<code>${confirmationValue}</code>`; confirmationValue = `<code>${confirmationValue}</code>`;
return sprintf( return sprintf(
s__('Profiles|Type your %{confirmationValue} to confirm:'), s__('Profiles|Type your %{confirmationValue} to confirm:'),
{ confirmationValue }, { confirmationValue },
false, false,
); );
}, },
text() { text() {
return sprintf( return sprintf(
s__(`Profiles| s__(`Profiles|
You are about to permanently delete %{yourAccount}, and all of the issues, merge requests, and groups linked to your account. You are about to permanently delete %{yourAccount}, and all of the issues, merge requests, and groups linked to your account.
Once you confirm %{deleteAccount}, it cannot be undone or recovered.`), Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
{ {
yourAccount: `<strong>${s__('Profiles|your account')}</strong>`, yourAccount: `<strong>${s__('Profiles|your account')}</strong>`,
deleteAccount: `<strong>${s__('Profiles|Delete Account')}</strong>`, deleteAccount: `<strong>${s__('Profiles|Delete Account')}</strong>`,
}, },
false, false,
); );
},
}, },
methods: { },
canSubmit() { methods: {
if (this.confirmWithPassword) { canSubmit() {
return this.enteredPassword !== ''; if (this.confirmWithPassword) {
} return this.enteredPassword !== '';
}
return this.enteredUsername === this.username; return this.enteredUsername === this.username;
}, },
onSubmit() { onSubmit() {
this.$refs.form.submit(); this.$refs.form.submit();
},
}, },
}; },
};
</script> </script>
<template> <template>
......
...@@ -4,20 +4,35 @@ import $ from 'jquery'; ...@@ -4,20 +4,35 @@ import $ from 'jquery';
import 'cropper'; import 'cropper';
import _ from 'underscore'; import _ from 'underscore';
((global) => { (global => {
// Matches everything but the file name // Matches everything but the file name
const FILENAMEREGEX = /^.*[\\\/]/; const FILENAMEREGEX = /^.*[\\\/]/;
class GitLabCrop { class GitLabCrop {
constructor(input, { filename, previewImage, modalCrop, pickImageEl, uploadImageBtn, modalCropImg, constructor(
exportWidth = 200, exportHeight = 200, cropBoxWidth = 200, cropBoxHeight = 200 } = {}) { input,
{
filename,
previewImage,
modalCrop,
pickImageEl,
uploadImageBtn,
modalCropImg,
exportWidth = 200,
exportHeight = 200,
cropBoxWidth = 200,
cropBoxHeight = 200,
} = {},
) {
this.onUploadImageBtnClick = this.onUploadImageBtnClick.bind(this); this.onUploadImageBtnClick = this.onUploadImageBtnClick.bind(this);
this.onModalHide = this.onModalHide.bind(this); this.onModalHide = this.onModalHide.bind(this);
this.onModalShow = this.onModalShow.bind(this); this.onModalShow = this.onModalShow.bind(this);
this.onPickImageClick = this.onPickImageClick.bind(this); this.onPickImageClick = this.onPickImageClick.bind(this);
this.fileInput = $(input); this.fileInput = $(input);
this.modalCropImg = _.isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg; this.modalCropImg = _.isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg;
this.fileInput.attr('name', `${this.fileInput.attr('name')}-trigger`).attr('id', `${this.fileInput.attr('id')}-trigger`); this.fileInput
.attr('name', `${this.fileInput.attr('name')}-trigger`)
.attr('id', `${this.fileInput.attr('id')}-trigger`);
this.exportWidth = exportWidth; this.exportWidth = exportWidth;
this.exportHeight = exportHeight; this.exportHeight = exportHeight;
this.cropBoxWidth = cropBoxWidth; this.cropBoxWidth = cropBoxWidth;
...@@ -59,7 +74,7 @@ import _ from 'underscore'; ...@@ -59,7 +74,7 @@ import _ from 'underscore';
btn = this; btn = this;
return _this.onActionBtnClick(btn); return _this.onActionBtnClick(btn);
}); });
return this.croppedImageBlob = null; return (this.croppedImageBlob = null);
} }
onPickImageClick() { onPickImageClick() {
...@@ -94,9 +109,9 @@ import _ from 'underscore'; ...@@ -94,9 +109,9 @@ import _ from 'underscore';
width: cropBoxWidth, width: cropBoxWidth,
height: cropBoxHeight, height: cropBoxHeight,
left: (container.width - cropBoxWidth) / 2, left: (container.width - cropBoxWidth) / 2,
top: (container.height - cropBoxHeight) / 2 top: (container.height - cropBoxHeight) / 2,
}); });
} },
}); });
} }
...@@ -116,7 +131,7 @@ import _ from 'underscore'; ...@@ -116,7 +131,7 @@ import _ from 'underscore';
var data, result; var data, result;
data = $(btn).data(); data = $(btn).data();
if (this.modalCropImg.data('cropper') && data.method) { if (this.modalCropImg.data('cropper') && data.method) {
return result = this.modalCropImg.cropper(data.method, data.option); return (result = this.modalCropImg.cropper(data.method, data.option));
} }
} }
...@@ -127,7 +142,7 @@ import _ from 'underscore'; ...@@ -127,7 +142,7 @@ import _ from 'underscore';
readFile(input) { readFile(input) {
var _this, reader; var _this, reader;
_this = this; _this = this;
reader = new FileReader; reader = new FileReader();
reader.onload = () => { reader.onload = () => {
_this.modalCropImg.attr('src', reader.result); _this.modalCropImg.attr('src', reader.result);
return _this.modalCrop.modal('show'); return _this.modalCrop.modal('show');
...@@ -145,7 +160,7 @@ import _ from 'underscore'; ...@@ -145,7 +160,7 @@ import _ from 'underscore';
array.push(binary.charCodeAt(i)); array.push(binary.charCodeAt(i));
} }
return new Blob([new Uint8Array(array)], { return new Blob([new Uint8Array(array)], {
type: 'image/png' type: 'image/png',
}); });
} }
...@@ -157,11 +172,13 @@ import _ from 'underscore'; ...@@ -157,11 +172,13 @@ import _ from 'underscore';
} }
setBlob() { setBlob() {
this.dataURL = this.modalCropImg.cropper('getCroppedCanvas', { this.dataURL = this.modalCropImg
width: 200, .cropper('getCroppedCanvas', {
height: 200 width: 200,
}).toDataURL('image/png'); height: 200,
return this.croppedImageBlob = this.dataURLtoBlob(this.dataURL); })
.toDataURL('image/png');
return (this.croppedImageBlob = this.dataURLtoBlob(this.dataURL));
} }
getBlob() { getBlob() {
......
...@@ -26,11 +26,7 @@ export default class Profile { ...@@ -26,11 +26,7 @@ export default class Profile {
} }
bindEvents() { bindEvents() {
$('.js-preferences-form').on( $('.js-preferences-form').on('change.preference', 'input[type=radio]', this.submitForm);
'change.preference',
'input[type=radio]',
this.submitForm,
);
$('#user_notification_email').on('change', this.submitForm); $('#user_notification_email').on('change', this.submitForm);
$('#user_notified_of_own_activity').on('change', this.submitForm); $('#user_notified_of_own_activity').on('change', this.submitForm);
this.form.on('submit', this.onSubmitForm); this.form.on('submit', this.onSubmitForm);
......
...@@ -46,8 +46,12 @@ export default class ProtectedBranchCreate { ...@@ -46,8 +46,12 @@ export default class ProtectedBranchCreate {
onSelect() { onSelect() {
// Enable submit button // Enable submit button
const $branchInput = this.$form.find('input[name="protected_branch[name]"]'); const $branchInput = this.$form.find('input[name="protected_branch[name]"]');
const $allowedToMergeInput = this.$form.find('input[name="protected_branch[merge_access_levels_attributes][0][access_level]"]'); const $allowedToMergeInput = this.$form.find(
const $allowedToPushInput = this.$form.find('input[name="protected_branch[push_access_levels_attributes][0][access_level]"]'); 'input[name="protected_branch[merge_access_levels_attributes][0][access_level]"]',
);
const $allowedToPushInput = this.$form.find(
'input[name="protected_branch[push_access_levels_attributes][0][access_level]"]',
);
const completedForm = !( const completedForm = !(
$branchInput.val() && $branchInput.val() &&
$allowedToMergeInput.length && $allowedToMergeInput.length &&
......
...@@ -29,8 +29,12 @@ export default class ProtectedBranchEdit { ...@@ -29,8 +29,12 @@ export default class ProtectedBranchEdit {
} }
onSelect() { onSelect() {
const $allowedToMergeInput = this.$wrap.find(`input[name="${this.$allowedToMergeDropdown.data('fieldName')}"]`); const $allowedToMergeInput = this.$wrap.find(
const $allowedToPushInput = this.$wrap.find(`input[name="${this.$allowedToPushDropdown.data('fieldName')}"]`); `input[name="${this.$allowedToMergeDropdown.data('fieldName')}"]`,
);
const $allowedToPushInput = this.$wrap.find(
`input[name="${this.$allowedToPushDropdown.data('fieldName')}"]`,
);
// Do not update if one dropdown has not selected any option // Do not update if one dropdown has not selected any option
if (!($allowedToMergeInput.length && $allowedToPushInput.length)) return; if (!($allowedToMergeInput.length && $allowedToPushInput.length)) return;
...@@ -38,25 +42,36 @@ export default class ProtectedBranchEdit { ...@@ -38,25 +42,36 @@ export default class ProtectedBranchEdit {
this.$allowedToMergeDropdown.disable(); this.$allowedToMergeDropdown.disable();
this.$allowedToPushDropdown.disable(); this.$allowedToPushDropdown.disable();
axios.patch(this.$wrap.data('url'), { axios
protected_branch: { .patch(this.$wrap.data('url'), {
merge_access_levels_attributes: [{ protected_branch: {
id: this.$allowedToMergeDropdown.data('accessLevelId'), merge_access_levels_attributes: [
access_level: $allowedToMergeInput.val(), {
}], id: this.$allowedToMergeDropdown.data('accessLevelId'),
push_access_levels_attributes: [{ access_level: $allowedToMergeInput.val(),
id: this.$allowedToPushDropdown.data('accessLevelId'), },
access_level: $allowedToPushInput.val(), ],
}], push_access_levels_attributes: [
}, {
}).then(() => { id: this.$allowedToPushDropdown.data('accessLevelId'),
this.$allowedToMergeDropdown.enable(); access_level: $allowedToPushInput.val(),
this.$allowedToPushDropdown.enable(); },
}).catch(() => { ],
this.$allowedToMergeDropdown.enable(); },
this.$allowedToPushDropdown.enable(); })
.then(() => {
flash('Failed to update branch!', 'alert', document.querySelector('.js-protected-branches-list')); this.$allowedToMergeDropdown.enable();
}); this.$allowedToPushDropdown.enable();
})
.catch(() => {
this.$allowedToMergeDropdown.enable();
this.$allowedToPushDropdown.enable();
flash(
'Failed to update branch!',
'alert',
document.querySelector('.js-protected-branches-list'),
);
});
} }
} }
...@@ -40,7 +40,9 @@ export default class ProtectedTagCreate { ...@@ -40,7 +40,9 @@ export default class ProtectedTagCreate {
const $tagInput = this.$form.find('input[name="protected_tag[name]"]'); const $tagInput = this.$form.find('input[name="protected_tag[name]"]');
const $allowedToCreateInput = this.$form.find('#create_access_levels_attributes'); const $allowedToCreateInput = this.$form.find('#create_access_levels_attributes');
this.$form.find('input[type="submit"]').prop('disabled', !($tagInput.val() && $allowedToCreateInput.length)); this.$form
.find('input[type="submit"]')
.prop('disabled', !($tagInput.val() && $allowedToCreateInput.length));
} }
static getProtectedTags(term, callback) { static getProtectedTags(term, callback) {
......
...@@ -21,26 +21,33 @@ export default class ProtectedTagEdit { ...@@ -21,26 +21,33 @@ export default class ProtectedTagEdit {
} }
onSelect() { onSelect() {
const $allowedToCreateInput = this.$wrap.find(`input[name="${this.$allowedToCreateDropdownButton.data('fieldName')}"]`); const $allowedToCreateInput = this.$wrap.find(
`input[name="${this.$allowedToCreateDropdownButton.data('fieldName')}"]`,
);
// Do not update if one dropdown has not selected any option // Do not update if one dropdown has not selected any option
if (!$allowedToCreateInput.length) return; if (!$allowedToCreateInput.length) return;
this.$allowedToCreateDropdownButton.disable(); this.$allowedToCreateDropdownButton.disable();
axios.patch(this.$wrap.data('url'), { axios
protected_tag: { .patch(this.$wrap.data('url'), {
create_access_levels_attributes: [{ protected_tag: {
id: this.$allowedToCreateDropdownButton.data('accessLevelId'), create_access_levels_attributes: [
access_level: $allowedToCreateInput.val(), {
}], id: this.$allowedToCreateDropdownButton.data('accessLevelId'),
}, access_level: $allowedToCreateInput.val(),
}).then(() => { },
this.$allowedToCreateDropdownButton.enable(); ],
}).catch(() => { },
this.$allowedToCreateDropdownButton.enable(); })
.then(() => {
flash('Failed to update tag!', 'alert', document.querySelector('.js-protected-tags-list')); this.$allowedToCreateDropdownButton.enable();
}); })
.catch(() => {
this.$allowedToCreateDropdownButton.enable();
flash('Failed to update tag!', 'alert', document.querySelector('.js-protected-tags-list'));
});
} }
} }
<script> <script>
import { mapGetters, mapActions } from 'vuex'; import { mapGetters, mapActions } from 'vuex';
import Flash from '../../flash'; import Flash from '../../flash';
import store from '../stores'; import store from '../stores';
import collapsibleContainer from './collapsible_container.vue'; import collapsibleContainer from './collapsible_container.vue';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
export default { export default {
name: 'RegistryListApp', name: 'RegistryListApp',
components: { components: {
collapsibleContainer, collapsibleContainer,
},
props: {
endpoint: {
type: String,
required: true,
}, },
props: { },
endpoint: { store,
type: String, computed: {
required: true, ...mapGetters(['isLoading', 'repos']),
}, },
}, created() {
store, this.setMainEndpoint(this.endpoint);
computed: { },
...mapGetters([ mounted() {
'isLoading', this.fetchRepos().catch(() => Flash(errorMessages[errorMessagesTypes.FETCH_REPOS]));
'repos', },
]), methods: {
}, ...mapActions(['setMainEndpoint', 'fetchRepos']),
created() { },
this.setMainEndpoint(this.endpoint); };
},
mounted() {
this.fetchRepos()
.catch(() => Flash(errorMessages[errorMessagesTypes.FETCH_REPOS]));
},
methods: {
...mapActions([
'setMainEndpoint',
'fetchRepos',
]),
},
};
</script> </script>
<template> <template>
<div> <div>
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import Flash from '../../flash'; import Flash from '../../flash';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import tableRegistry from './table_registry.vue'; import tableRegistry from './table_registry.vue';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
import { __ } from '../../locale'; import { __ } from '../../locale';
export default { export default {
name: 'CollapsibeContainerRegisty', name: 'CollapsibeContainerRegisty',
components: { components: {
clipboardButton, clipboardButton,
tableRegistry, tableRegistry,
},
directives: {
tooltip,
},
props: {
repo: {
type: Object,
required: true,
}, },
directives: { },
tooltip, data() {
}, return {
props: { isOpen: false,
repo: { };
type: Object, },
required: true, methods: {
}, ...mapActions(['fetchRepos', 'fetchList', 'deleteRepo']),
},
data() {
return {
isOpen: false,
};
},
methods: {
...mapActions([
'fetchRepos',
'fetchList',
'deleteRepo',
]),
toggleRepo() { toggleRepo() {
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
if (this.isOpen) { if (this.isOpen) {
this.fetchList({ repo: this.repo }) this.fetchList({ repo: this.repo }).catch(() =>
.catch(() => this.showError(errorMessagesTypes.FETCH_REGISTRY)); this.showError(errorMessagesTypes.FETCH_REGISTRY),
} );
}, }
},
handleDeleteRepository() { handleDeleteRepository() {
this.deleteRepo(this.repo) this.deleteRepo(this.repo)
.then(() => { .then(() => {
Flash(__('This container registry has been scheduled for deletion.'), 'notice'); Flash(__('This container registry has been scheduled for deletion.'), 'notice');
this.fetchRepos(); this.fetchRepos();
}) })
.catch(() => this.showError(errorMessagesTypes.DELETE_REPO)); .catch(() => this.showError(errorMessagesTypes.DELETE_REPO));
}, },
showError(message) { showError(message) {
Flash(errorMessages[message]); Flash(errorMessages[message]);
},
}, },
}; },
};
</script> </script>
<template> <template>
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { n__ } from '../../locale'; import { n__ } from '../../locale';
import Flash from '../../flash'; import Flash from '../../flash';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import tablePagination from '../../vue_shared/components/table_pagination.vue'; import tablePagination from '../../vue_shared/components/table_pagination.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import timeagoMixin from '../../vue_shared/mixins/timeago'; import timeagoMixin from '../../vue_shared/mixins/timeago';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
import { numberToHumanSize } from '../../lib/utils/number_utils'; import { numberToHumanSize } from '../../lib/utils/number_utils';
export default { export default {
components: { components: {
clipboardButton, clipboardButton,
tablePagination, tablePagination,
},
directives: {
tooltip,
},
mixins: [timeagoMixin],
props: {
repo: {
type: Object,
required: true,
}, },
directives: { },
tooltip, computed: {
shouldRenderPagination() {
return this.repo.pagination.total > this.repo.pagination.perPage;
}, },
mixins: [ },
timeagoMixin, methods: {
], ...mapActions(['fetchList', 'deleteRegistry']),
props: {
repo: {
type: Object,
required: true,
},
},
computed: {
shouldRenderPagination() {
return this.repo.pagination.total > this.repo.pagination.perPage;
},
},
methods: {
...mapActions([
'fetchList',
'deleteRegistry',
]),
layers(item) { layers(item) {
return item.layers ? n__('%d layer', '%d layers', item.layers) : ''; return item.layers ? n__('%d layer', '%d layers', item.layers) : '';
}, },
formatSize(size) { formatSize(size) {
return numberToHumanSize(size); return numberToHumanSize(size);
}, },
handleDeleteRegistry(registry) { handleDeleteRegistry(registry) {
this.deleteRegistry(registry) this.deleteRegistry(registry)
.then(() => this.fetchList({ repo: this.repo })) .then(() => this.fetchList({ repo: this.repo }))
.catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY)); .catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY));
}, },
onPageChange(pageNumber) { onPageChange(pageNumber) {
this.fetchList({ repo: this.repo, page: pageNumber }) this.fetchList({ repo: this.repo, page: pageNumber }).catch(() =>
.catch(() => this.showError(errorMessagesTypes.FETCH_REGISTRY)); this.showError(errorMessagesTypes.FETCH_REGISTRY),
}, );
},
showError(message) { showError(message) {
Flash(errorMessages[message]); Flash(errorMessages[message]);
},
}, },
}; },
};
</script> </script>
<template> <template>
<div> <div>
......
...@@ -4,22 +4,23 @@ import Translate from '../vue_shared/translate'; ...@@ -4,22 +4,23 @@ import Translate from '../vue_shared/translate';
Vue.use(Translate); Vue.use(Translate);
export default () => new Vue({ export default () =>
el: '#js-vue-registry-images', new Vue({
components: { el: '#js-vue-registry-images',
registryApp, components: {
}, registryApp,
data() { },
const { dataset } = document.querySelector(this.$options.el); data() {
return { const { dataset } = document.querySelector(this.$options.el);
endpoint: dataset.endpoint, return {
}; endpoint: dataset.endpoint,
}, };
render(createElement) { },
return createElement('registry-app', { render(createElement) {
props: { return createElement('registry-app', {
endpoint: this.endpoint, props: {
}, endpoint: this.endpoint,
}); },
}, });
}); },
});
...@@ -2,7 +2,6 @@ import * as types from './mutation_types'; ...@@ -2,7 +2,6 @@ import * as types from './mutation_types';
import { parseIntPagination, normalizeHeaders } from '../../lib/utils/common_utils'; import { parseIntPagination, normalizeHeaders } from '../../lib/utils/common_utils';
export default { export default {
[types.SET_MAIN_ENDPOINT](state, endpoint) { [types.SET_MAIN_ENDPOINT](state, endpoint) {
Object.assign(state, { endpoint }); Object.assign(state, { endpoint });
}, },
......
<script> <script>
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { componentNames } from './issue_body'; import { componentNames } from './issue_body';
import ReportSection from './report_section.vue'; import ReportSection from './report_section.vue';
import SummaryRow from './summary_row.vue'; import SummaryRow from './summary_row.vue';
import IssuesList from './issues_list.vue'; import IssuesList from './issues_list.vue';
import Modal from './modal.vue'; import Modal from './modal.vue';
import createStore from '../store'; import createStore from '../store';
import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils'; import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils';
export default { export default {
name: 'GroupedTestReportsApp', name: 'GroupedTestReportsApp',
store: createStore(), store: createStore(),
components: { components: {
ReportSection, ReportSection,
SummaryRow, SummaryRow,
IssuesList, IssuesList,
Modal, Modal,
},
props: {
endpoint: {
type: String,
required: true,
}, },
props: { },
endpoint: { componentNames,
type: String, computed: {
required: true, ...mapState(['reports', 'isLoading', 'hasError', 'summary']),
}, ...mapState({
}, modalTitle: state => state.modal.title || '',
componentNames, modalData: state => state.modal.data || {},
computed: { }),
...mapState([ ...mapGetters(['summaryStatus']),
'reports', groupedSummaryText() {
'isLoading', if (this.isLoading) {
'hasError', return s__('Reports|Test summary results are being parsed');
'summary', }
]),
...mapState({
modalTitle: state => state.modal.title || '',
modalData: state => state.modal.data || {},
}),
...mapGetters([
'summaryStatus',
]),
groupedSummaryText() {
if (this.isLoading) {
return s__('Reports|Test summary results are being parsed');
}
if (this.hasError) { if (this.hasError) {
return s__('Reports|Test summary failed loading results'); return s__('Reports|Test summary failed loading results');
} }
return summaryTextBuilder(s__('Reports|Test summary'), this.summary); return summaryTextBuilder(s__('Reports|Test summary'), this.summary);
},
}, },
created() { },
this.setEndpoint(this.endpoint); created() {
this.setEndpoint(this.endpoint);
this.fetchReports(); this.fetchReports();
},
methods: {
...mapActions(['setEndpoint', 'fetchReports']),
reportText(report) {
const summary = report.summary || {};
return reportTextBuilder(report.name, summary);
},
getReportIcon(report) {
return statusIcon(report.status);
}, },
methods: { shouldRenderIssuesList(report) {
...mapActions(['setEndpoint', 'fetchReports']), return (
reportText(report) { report.existing_failures.length > 0 ||
const summary = report.summary || {}; report.new_failures.length > 0 ||
return reportTextBuilder(report.name, summary); report.resolved_failures.length > 0
}, );
getReportIcon(report) {
return statusIcon(report.status);
},
shouldRenderIssuesList(report) {
return (
report.existing_failures.length > 0 ||
report.new_failures.length > 0 ||
report.resolved_failures.length > 0
);
},
}, },
}; },
};
</script> </script>
<template> <template>
<report-section <report-section
......
<script> <script>
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '../constants';
STATUS_FAILED,
STATUS_NEUTRAL,
STATUS_SUCCESS,
} from '../constants';
export default { export default {
name: 'IssueStatusIcon', name: 'IssueStatusIcon',
......
<script> <script>
import IssuesBlock from '~/reports/components/report_issues.vue'; import IssuesBlock from '~/reports/components/report_issues.vue';
import { import { STATUS_SUCCESS, STATUS_FAILED, STATUS_NEUTRAL } from '~/reports/constants';
STATUS_SUCCESS,
STATUS_FAILED,
STATUS_NEUTRAL,
} from '~/reports/constants';
/** /**
* Renders block of issues * Renders block of issues
......
<script> <script>
import Modal from '~/vue_shared/components/gl_modal.vue'; import Modal from '~/vue_shared/components/gl_modal.vue';
import LoadingButton from '~/vue_shared/components/loading_button.vue'; import LoadingButton from '~/vue_shared/components/loading_button.vue';
import CodeBlock from '~/vue_shared/components/code_block.vue'; import CodeBlock from '~/vue_shared/components/code_block.vue';
import { fieldTypes } from '../constants'; import { fieldTypes } from '../constants';
export default { export default {
components: { components: {
Modal, Modal,
LoadingButton, LoadingButton,
CodeBlock, CodeBlock,
},
props: {
title: {
type: String,
required: true,
}, },
props: { modalData: {
title: { type: Object,
type: String, required: true,
required: true,
},
modalData: {
type: Object,
required: true,
},
}, },
fieldTypes, },
}; fieldTypes,
};
</script> </script>
<template> <template>
<modal <modal
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
export default { export default {
name: 'TestIssueBody', name: 'TestIssueBody',
props: { props: {
issue: { issue: {
type: Object, type: Object,
required: true, required: true,
},
// failed || success
status: {
type: String,
required: true,
},
isNew: {
type: Boolean,
required: false,
default: false,
},
}, },
methods: { // failed || success
...mapActions(['openModal']), status: {
type: String,
required: true,
}, },
}; isNew: {
type: Boolean,
required: false,
default: false,
},
},
methods: {
...mapActions(['openModal']),
},
};
</script> </script>
<template> <template>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5"> <div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
......
...@@ -43,9 +43,11 @@ export const fetchReports = ({ state, dispatch }) => { ...@@ -43,9 +43,11 @@ export const fetchReports = ({ state, dispatch }) => {
}, },
data: state.endpoint, data: state.endpoint,
method: 'getReports', method: 'getReports',
successCallback: ({ data, status }) => dispatch('receiveReportsSuccess', { successCallback: ({ data, status }) =>
data, status, dispatch('receiveReportsSuccess', {
}), data,
status,
}),
errorCallback: () => dispatch('receiveReportsError'), errorCallback: () => dispatch('receiveReportsError'),
}); });
......
...@@ -7,9 +7,10 @@ import state from './state'; ...@@ -7,9 +7,10 @@ import state from './state';
Vue.use(Vuex); Vue.use(Vuex);
export default () => new Vuex.Store({ export default () =>
actions, new Vuex.Store({
mutations, actions,
getters, mutations,
state: state(), getters,
}); state: state(),
});
...@@ -4,4 +4,3 @@ export const REQUEST_REPORTS = 'REQUEST_REPORTS'; ...@@ -4,4 +4,3 @@ export const REQUEST_REPORTS = 'REQUEST_REPORTS';
export const RECEIVE_REPORTS_SUCCESS = 'RECEIVE_REPORTS_SUCCESS'; export const RECEIVE_REPORTS_SUCCESS = 'RECEIVE_REPORTS_SUCCESS';
export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR'; export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR';
export const SET_ISSUE_MODAL_DATA = 'SET_ISSUE_MODAL_DATA'; export const SET_ISSUE_MODAL_DATA = 'SET_ISSUE_MODAL_DATA';
...@@ -19,7 +19,6 @@ export default { ...@@ -19,7 +19,6 @@ export default {
state.status = response.status; state.status = response.status;
state.reports = response.suites; state.reports = response.suites;
}, },
[types.RECEIVE_REPORTS_ERROR](state) { [types.RECEIVE_REPORTS_ERROR](state) {
state.isLoading = false; state.isLoading = false;
...@@ -36,7 +35,7 @@ export default { ...@@ -36,7 +35,7 @@ export default {
[types.SET_ISSUE_MODAL_DATA](state, payload) { [types.SET_ISSUE_MODAL_DATA](state, payload) {
state.modal.title = payload.issue.name; state.modal.title = payload.issue.name;
Object.keys(payload.issue).forEach((key) => { Object.keys(payload.issue).forEach(key => {
if (Object.prototype.hasOwnProperty.call(state.modal.data, key)) { if (Object.prototype.hasOwnProperty.call(state.modal.data, key)) {
state.modal.data[key] = { state.modal.data[key] = {
...state.modal.data[key], ...state.modal.data[key],
......
...@@ -57,5 +57,4 @@ export default () => ({ ...@@ -57,5 +57,4 @@ export default () => ({
}, },
}, },
}, },
}); });
...@@ -69,7 +69,8 @@ export default { ...@@ -69,7 +69,8 @@ export default {
this.loading = false; this.loading = false;
} }
this.mediator.saveAssignees(this.field) this.mediator
.saveAssignees(this.field)
.then(setLoadingFalse.bind(this)) .then(setLoadingFalse.bind(this))
.catch(() => { .catch(() => {
setLoadingFalse(); setLoadingFalse();
......
...@@ -56,11 +56,7 @@ export default { ...@@ -56,11 +56,7 @@ export default {
.update('issue', { confidential }) .update('issue', { confidential })
.then(() => window.location.reload()) .then(() => window.location.reload())
.catch(() => { .catch(() => {
Flash( Flash(__('Something went wrong trying to change the confidentiality of this issue'));
__(
'Something went wrong trying to change the confidentiality of this issue',
),
);
}); });
}, },
}, },
......
...@@ -34,11 +34,7 @@ export default { ...@@ -34,11 +34,7 @@ export default {
required: true, required: true,
type: Object, type: Object,
validator(mediatorObject) { validator(mediatorObject) {
return ( return mediatorObject.service && mediatorObject.service.update && mediatorObject.store;
mediatorObject.service &&
mediatorObject.service.update &&
mediatorObject.store
);
}, },
}, },
}, },
...@@ -67,8 +63,7 @@ export default { ...@@ -67,8 +63,7 @@ export default {
methods: { methods: {
toggleForm() { toggleForm() {
this.mediator.store.isLockDialogOpen = !this.mediator.store this.mediator.store.isLockDialogOpen = !this.mediator.store.isLockDialogOpen;
.isLockDialogOpen;
}, },
updateLockedAttribute(locked) { updateLockedAttribute(locked) {
...@@ -79,9 +74,14 @@ export default { ...@@ -79,9 +74,14 @@ export default {
.then(() => window.location.reload()) .then(() => window.location.reload())
.catch(() => .catch(() =>
Flash( Flash(
sprintf(__('Something went wrong trying to change the locked state of this %{issuableDisplayName}'), { sprintf(
issuableDisplayName: this.issuableDisplayName, __(
}), 'Something went wrong trying to change the locked state of this %{issuableDisplayName}',
),
{
issuableDisplayName: this.issuableDisplayName,
},
),
), ),
); );
}, },
......
<script> <script>
import { __, n__, sprintf } from '~/locale'; import { __, n__, sprintf } from '~/locale';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue'; import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
export default { export default {
directives: { directives: {
tooltip, tooltip,
},
components: {
userAvatarImage,
},
props: {
loading: {
type: Boolean,
required: false,
default: false,
}, },
components: { participants: {
userAvatarImage, type: Array,
required: false,
default: () => [],
}, },
props: { numberOfLessParticipants: {
loading: { type: Number,
type: Boolean, required: false,
required: false, default: 7,
default: false,
},
participants: {
type: Array,
required: false,
default: () => [],
},
numberOfLessParticipants: {
type: Number,
required: false,
default: 7,
},
}, },
data() { },
return { data() {
isShowingMoreParticipants: false, return {
}; isShowingMoreParticipants: false,
};
},
computed: {
lessParticipants() {
return this.participants.slice(0, this.numberOfLessParticipants);
}, },
computed: { visibleParticipants() {
lessParticipants() { return this.isShowingMoreParticipants ? this.participants : this.lessParticipants;
return this.participants.slice(0, this.numberOfLessParticipants); },
}, hasMoreParticipants() {
visibleParticipants() { return this.participants.length > this.numberOfLessParticipants;
return this.isShowingMoreParticipants ? this.participants : this.lessParticipants; },
}, toggleLabel() {
hasMoreParticipants() { let label = '';
return this.participants.length > this.numberOfLessParticipants; if (this.isShowingMoreParticipants) {
}, label = __('- show less');
toggleLabel() { } else {
let label = ''; label = sprintf(__('+ %{moreCount} more'), {
if (this.isShowingMoreParticipants) { moreCount: this.participants.length - this.numberOfLessParticipants,
label = __('- show less'); });
} else { }
label = sprintf(__('+ %{moreCount} more'), {
moreCount: this.participants.length - this.numberOfLessParticipants,
});
}
return label; return label;
}, },
participantLabel() { participantLabel() {
return sprintf( return sprintf(
n__('%{count} participant', '%{count} participants', this.participants.length), n__('%{count} participant', '%{count} participants', this.participants.length),
{ count: this.loading ? '' : this.participantCount }, { count: this.loading ? '' : this.participantCount },
); );
}, },
participantCount() { participantCount() {
return this.participants.length; return this.participants.length;
}, },
},
methods: {
toggleMoreParticipants() {
this.isShowingMoreParticipants = !this.isShowingMoreParticipants;
}, },
methods: { onClickCollapsedIcon() {
toggleMoreParticipants() { this.$emit('toggleSidebar');
this.isShowingMoreParticipants = !this.isShowingMoreParticipants;
},
onClickCollapsedIcon() {
this.$emit('toggleSidebar');
},
}, },
}; },
};
</script> </script>
<template> <template>
......
<script> <script>
import Store from '../../stores/sidebar_store'; import Store from '../../stores/sidebar_store';
import participants from './participants.vue'; import participants from './participants.vue';
export default { export default {
components: { components: {
participants, participants,
},
props: {
mediator: {
type: Object,
required: true,
}, },
props: { },
mediator: { data() {
type: Object, return {
required: true, store: new Store(),
}, };
}, },
data() { };
return {
store: new Store(),
};
},
};
</script> </script>
<template> <template>
......
...@@ -21,10 +21,9 @@ export default { ...@@ -21,10 +21,9 @@ export default {
}, },
methods: { methods: {
onToggleSubscription() { onToggleSubscription() {
this.mediator.toggleSubscription() this.mediator.toggleSubscription().catch(() => {
.catch(() => { Flash(__('Error occurred when toggling the notification subscription'));
Flash(__('Error occurred when toggling the notification subscription')); });
});
}, },
}, },
}; };
......
...@@ -15,16 +15,22 @@ export default { ...@@ -15,16 +15,22 @@ export default {
}, },
estimateText() { estimateText() {
return sprintf( return sprintf(
s__('estimateCommand|%{slash_command} will update the estimated time with the latest command.'), { s__(
'estimateCommand|%{slash_command} will update the estimated time with the latest command.',
),
{
slash_command: '<code>/estimate</code>', slash_command: '<code>/estimate</code>',
}, false, },
false,
); );
}, },
spendText() { spendText() {
return sprintf( return sprintf(
s__('spendCommand|%{slash_command} will update the sum of the time spent.'), { s__('spendCommand|%{slash_command} will update the sum of the time spent.'),
{
slash_command: '<code>/spend</code>', slash_command: '<code>/spend</code>',
}, false, },
false,
); );
}, },
}, },
......
...@@ -26,7 +26,7 @@ export default { ...@@ -26,7 +26,7 @@ export default {
methods: { methods: {
listenForQuickActions() { listenForQuickActions() {
$(document).on('ajax:success', '.gfm-form', this.quickActionListened); $(document).on('ajax:success', '.gfm-form', this.quickActionListened);
eventHub.$on('timeTrackingUpdated', (data) => { eventHub.$on('timeTrackingUpdated', data => {
this.quickActionListened(null, data); this.quickActionListened(null, data);
}); });
}, },
...@@ -34,9 +34,7 @@ export default { ...@@ -34,9 +34,7 @@ export default {
const subscribedCommands = ['spend_time', 'time_estimate']; const subscribedCommands = ['spend_time', 'time_estimate'];
let changedCommands; let changedCommands;
if (data !== undefined) { if (data !== undefined) {
changedCommands = data.commands_changes changedCommands = data.commands_changes ? Object.keys(data.commands_changes) : [];
? Object.keys(data.commands_changes)
: [];
} else { } else {
changedCommands = []; changedCommands = [];
} }
......
...@@ -41,9 +41,9 @@ export default { ...@@ -41,9 +41,9 @@ export default {
}, },
computed: { computed: {
buttonClasses() { buttonClasses() {
return this.collapsed ? return this.collapsed
'btn-blank btn-todo sidebar-collapsed-icon dont-change-state' : ? 'btn-blank btn-todo sidebar-collapsed-icon dont-change-state'
'btn btn-default btn-todo issuable-header-btn float-right'; : 'btn btn-default btn-todo issuable-header-btn float-right';
}, },
buttonLabel() { buttonLabel() {
return this.isTodo ? MARK_TEXT : TODO_TEXT; return this.isTodo ? MARK_TEXT : TODO_TEXT;
......
...@@ -37,7 +37,8 @@ class SidebarMoveIssue { ...@@ -37,7 +37,8 @@ class SidebarMoveIssue {
// Keep the dropdown open after selecting an option // Keep the dropdown open after selecting an option
shouldPropagate: false, shouldPropagate: false,
data: (searchTerm, callback) => { data: (searchTerm, callback) => {
this.mediator.fetchAutocompleteProjects(searchTerm) this.mediator
.fetchAutocompleteProjects(searchTerm)
.then(callback) .then(callback)
.catch(() => new window.Flash('An error occurred while fetching projects autocomplete.')); .catch(() => new window.Flash('An error occurred while fetching projects autocomplete.'));
}, },
...@@ -48,7 +49,7 @@ class SidebarMoveIssue { ...@@ -48,7 +49,7 @@ class SidebarMoveIssue {
</a> </a>
</li> </li>
`, `,
clicked: (options) => { clicked: options => {
const project = options.selectedObj; const project = options.selectedObj;
const selectedProjectId = options.isMarking ? project.id : 0; const selectedProjectId = options.isMarking ? project.id : 0;
this.mediator.setMoveToProjectId(selectedProjectId); this.mediator.setMoveToProjectId(selectedProjectId);
...@@ -68,17 +69,12 @@ class SidebarMoveIssue { ...@@ -68,17 +69,12 @@ class SidebarMoveIssue {
onConfirmClicked() { onConfirmClicked() {
if (isValidProjectId(this.mediator.store.moveToProjectId)) { if (isValidProjectId(this.mediator.store.moveToProjectId)) {
this.$confirmButton this.$confirmButton.disable().addClass('is-loading');
.disable()
.addClass('is-loading');
this.mediator.moveIssue() this.mediator.moveIssue().catch(() => {
.catch(() => { window.Flash('An error occurred while moving the issue.');
window.Flash('An error occurred while moving the issue.'); this.$confirmButton.enable().removeClass('is-loading');
this.$confirmButton });
.enable()
.removeClass('is-loading');
});
} }
} }
} }
......
...@@ -15,15 +15,16 @@ export default class SidebarMilestone { ...@@ -15,15 +15,16 @@ export default class SidebarMilestone {
components: { components: {
timeTracker, timeTracker,
}, },
render: createElement => createElement('timeTracker', { render: createElement =>
props: { createElement('timeTracker', {
timeEstimate: parseInt(timeEstimate, 10), props: {
timeSpent: parseInt(timeSpent, 10), timeEstimate: parseInt(timeEstimate, 10),
humanTimeEstimate, timeSpent: parseInt(timeSpent, 10),
humanTimeSpent, humanTimeEstimate,
rootPath: '/', humanTimeSpent,
}, rootPath: '/',
}), },
}),
}); });
} }
} }
...@@ -22,14 +22,15 @@ function mountAssigneesComponent(mediator) { ...@@ -22,14 +22,15 @@ function mountAssigneesComponent(mediator) {
components: { components: {
SidebarAssignees, SidebarAssignees,
}, },
render: createElement => createElement('sidebar-assignees', { render: createElement =>
props: { createElement('sidebar-assignees', {
mediator, props: {
field: el.dataset.field, mediator,
signedIn: el.hasAttribute('data-signed-in'), field: el.dataset.field,
issuableType: gl.utils.isInIssuePage() ? 'issue' : 'merge_request', signedIn: el.hasAttribute('data-signed-in'),
}, issuableType: gl.utils.isInIssuePage() ? 'issue' : 'merge_request',
}), },
}),
}); });
} }
...@@ -83,11 +84,12 @@ function mountParticipantsComponent(mediator) { ...@@ -83,11 +84,12 @@ function mountParticipantsComponent(mediator) {
components: { components: {
sidebarParticipants, sidebarParticipants,
}, },
render: createElement => createElement('sidebar-participants', { render: createElement =>
props: { createElement('sidebar-participants', {
mediator, props: {
}, mediator,
}), },
}),
}); });
} }
...@@ -102,11 +104,12 @@ function mountSubscriptionsComponent(mediator) { ...@@ -102,11 +104,12 @@ function mountSubscriptionsComponent(mediator) {
components: { components: {
sidebarSubscriptions, sidebarSubscriptions,
}, },
render: createElement => createElement('sidebar-subscriptions', { render: createElement =>
props: { createElement('sidebar-subscriptions', {
mediator, props: {
}, mediator,
}), },
}),
}); });
} }
......
...@@ -22,11 +22,15 @@ export default class SidebarService { ...@@ -22,11 +22,15 @@ export default class SidebarService {
} }
update(key, data) { update(key, data) {
return Vue.http.put(this.endpoint, { return Vue.http.put(
[key]: data, this.endpoint,
}, { {
emulateJSON: true, [key]: data,
}); },
{
emulateJSON: true,
},
);
} }
getProjectsAutocomplete(searchTerm) { getProjectsAutocomplete(searchTerm) {
......
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