Commit a97e599a authored by Tim Zallmann's avatar Tim Zallmann

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

Prettify all the things (part 3)

See merge request gitlab-org/gitlab-ce!22251
parents 982276c3 d2ee2eab
...@@ -31,7 +31,7 @@ export default class AbuseReports { ...@@ -31,7 +31,7 @@ export default class AbuseReports {
$messageCellElement.text(originalMessage); $messageCellElement.text(originalMessage);
} else { } else {
$messageCellElement.data('messageTruncated', 'true'); $messageCellElement.data('messageTruncated', 'true');
$messageCellElement.text(`${originalMessage.substr(0, (MAX_MESSAGE_LENGTH - 3))}...`); $messageCellElement.text(`${originalMessage.substr(0, MAX_MESSAGE_LENGTH - 3)}...`);
} }
} }
} }
...@@ -23,7 +23,7 @@ export default function adminInit() { ...@@ -23,7 +23,7 @@ export default function adminInit() {
} }
}); });
$('body').on('click', '.js-toggle-colors-link', (e) => { $('body').on('click', '.js-toggle-colors-link', e => {
e.preventDefault(); e.preventDefault();
$('.js-toggle-colors-container').toggleClass('hide'); $('.js-toggle-colors-container').toggleClass('hide');
}); });
...@@ -33,12 +33,15 @@ export default function adminInit() { ...@@ -33,12 +33,15 @@ export default function adminInit() {
$(this).tab('show'); $(this).tab('show');
}); });
$('.log-bottom').on('click', (e) => { $('.log-bottom').on('click', e => {
e.preventDefault(); e.preventDefault();
const $visibleLog = $('.file-content:visible'); const $visibleLog = $('.file-content:visible');
$visibleLog.animate({ $visibleLog.animate(
scrollTop: $visibleLog.find('ol').height(), {
}, 'fast'); scrollTop: $visibleLog.find('ol').height(),
},
'fast',
);
}); });
$('.change-owner-link').on('click', function changeOwnerLinkClick(e) { $('.change-owner-link').on('click', function changeOwnerLinkClick(e) {
...@@ -47,7 +50,7 @@ export default function adminInit() { ...@@ -47,7 +50,7 @@ export default function adminInit() {
modal.show(); modal.show();
}); });
$('.change-owner-cancel-link').on('click', (e) => { $('.change-owner-cancel-link').on('click', e => {
e.preventDefault(); e.preventDefault();
modal.hide(); modal.hide();
$('.change-owner-link').show(); $('.change-owner-link').show();
......
import { __ } from '~/locale'; import { __ } from '~/locale';
export const PLACEHOLDER_USER_EXTERNAL_DEFAULT_TRUE = __('Regex pattern'); export const PLACEHOLDER_USER_EXTERNAL_DEFAULT_TRUE = __('Regex pattern');
export const PLACEHOLDER_USER_EXTERNAL_DEFAULT_FALSE = __('To define internal users, first enable new users set to external'); export const PLACEHOLDER_USER_EXTERNAL_DEFAULT_FALSE = __(
'To define internal users, first enable new users set to external',
);
function setUserInternalRegexPlaceholder(checkbox) { function setUserInternalRegexPlaceholder(checkbox) {
const userInternalRegex = document.getElementById('application_setting_user_default_internal_regex'); const userInternalRegex = document.getElementById(
'application_setting_user_default_internal_regex',
);
if (checkbox && userInternalRegex) { if (checkbox && userInternalRegex) {
if (checkbox.checked) { if (checkbox.checked) {
userInternalRegex.readOnly = false; userInternalRegex.readOnly = false;
......
...@@ -17,20 +17,24 @@ export default () => { ...@@ -17,20 +17,24 @@ export default () => {
const previewPath = $('textarea#broadcast_message_message').data('previewPath'); const previewPath = $('textarea#broadcast_message_message').data('previewPath');
$('textarea#broadcast_message_message').on('input', _.debounce(function onMessageInput() { $('textarea#broadcast_message_message').on(
const message = $(this).val(); 'input',
if (message === '') { _.debounce(function onMessageInput() {
$('.js-broadcast-message-preview').text('Your message here'); const message = $(this).val();
} else { if (message === '') {
axios.post(previewPath, { $('.js-broadcast-message-preview').text('Your message here');
broadcast_message: { } else {
message, axios
}, .post(previewPath, {
}) broadcast_message: {
.then(({ data }) => { message,
$('.js-broadcast-message-preview').html(data.message); },
}) })
.catch(() => flash(__('An error occurred while rendering preview broadcast message'))); .then(({ data }) => {
} $('.js-broadcast-message-preview').html(data.message);
}, 250)); })
.catch(() => flash(__('An error occurred while rendering preview broadcast message')));
}
}, 250),
);
}; };
<script> <script>
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash'; import createFlash from '~/flash';
import GlModal from '~/vue_shared/components/gl_modal.vue'; import GlModal from '~/vue_shared/components/gl_modal.vue';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export default { export default {
components: { components: {
GlModal, GlModal,
},
props: {
url: {
type: String,
required: true,
}, },
props: { },
url: { computed: {
type: String, text() {
required: true, return s__(
}, 'AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running.',
);
}, },
computed: { },
text() { methods: {
return s__('AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running.'); onSubmit() {
}, return axios
.post(this.url)
.then(response => {
// follow the rediect to refresh the page
redirectTo(response.request.responseURL);
})
.catch(error => {
createFlash(s__('AdminArea|Stopping jobs failed'));
throw error;
});
}, },
methods: { },
onSubmit() { };
return axios.post(this.url)
.then((response) => {
// follow the rediect to refresh the page
redirectTo(response.request.responseURL);
})
.catch((error) => {
createFlash(s__('AdminArea|Stopping jobs failed'));
throw error;
});
},
},
};
</script> </script>
<template> <template>
......
...@@ -4,6 +4,7 @@ import NamespaceSelect from '../../../namespace_select'; ...@@ -4,6 +4,7 @@ import NamespaceSelect from '../../../namespace_select';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
new ProjectsList(); // eslint-disable-line no-new new ProjectsList(); // eslint-disable-line no-new
document.querySelectorAll('.js-namespace-select') document
.querySelectorAll('.js-namespace-select')
.forEach(dropdown => new NamespaceSelect({ dropdown })); .forEach(dropdown => new NamespaceSelect({ dropdown }));
}); });
<script> <script>
import _ from 'underscore'; import _ from 'underscore';
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';
export default { export default {
components: { components: {
DeprecatedModal, DeprecatedModal,
},
props: {
deleteProjectUrl: {
type: String,
required: false,
default: '',
}, },
props: { projectName: {
deleteProjectUrl: { type: String,
type: String, required: false,
required: false, default: '',
default: '',
},
projectName: {
type: String,
required: false,
default: '',
},
csrfToken: {
type: String,
required: false,
default: '',
},
}, },
data() { csrfToken: {
return { type: String,
enteredProjectName: '', required: false,
}; default: '',
}, },
computed: { },
title() { data() {
return sprintf(s__('AdminProjects|Delete Project %{projectName}?'), return {
{ enteredProjectName: '',
projectName: `'${_.escape(this.projectName)}'`, };
}, },
false, computed: {
); title() {
}, return sprintf(
text() { s__('AdminProjects|Delete Project %{projectName}?'),
return sprintf(s__(`AdminProjects| {
projectName: `'${_.escape(this.projectName)}'`,
},
false,
);
},
text() {
return sprintf(
s__(`AdminProjects|
You’re about to permanently delete the project %{projectName}, its repository, You’re about to permanently delete the project %{projectName}, its repository,
and all related resources including issues, merge requests, etc.. Once you confirm and press and all related resources including issues, merge requests, etc.. Once you confirm and press
%{strong_start}Delete project%{strong_end}, it cannot be undone or recovered.`), %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered.`),
{ {
projectName: `<strong>${_.escape(this.projectName)}</strong>`, projectName: `<strong>${_.escape(this.projectName)}</strong>`,
strong_start: '<strong>', strong_start: '<strong>',
strong_end: '</strong>', strong_end: '</strong>',
}, },
false, false,
); );
}, },
confirmationTextLabel() { confirmationTextLabel() {
return sprintf(s__('AdminUsers|To confirm, type %{projectName}'), return sprintf(
{ s__('AdminUsers|To confirm, type %{projectName}'),
projectName: `<code>${_.escape(this.projectName)}</code>`, {
}, projectName: `<code>${_.escape(this.projectName)}</code>`,
false, },
); false,
}, );
primaryButtonLabel() { },
return s__('AdminProjects|Delete project'); primaryButtonLabel() {
}, return s__('AdminProjects|Delete project');
canSubmit() { },
return this.enteredProjectName === this.projectName; canSubmit() {
}, return this.enteredProjectName === this.projectName;
},
},
methods: {
onCancel() {
this.enteredProjectName = '';
}, },
methods: { onSubmit() {
onCancel() { this.$refs.form.submit();
this.enteredProjectName = ''; this.enteredProjectName = '';
},
onSubmit() {
this.$refs.form.submit();
this.enteredProjectName = '';
},
}, },
}; },
};
</script> </script>
<template> <template>
......
...@@ -28,7 +28,7 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -28,7 +28,7 @@ document.addEventListener('DOMContentLoaded', () => {
}, },
}); });
$(document).on('shown.bs.modal', (event) => { $(document).on('shown.bs.modal', event => {
if (event.relatedTarget.classList.contains('delete-project-button')) { if (event.relatedTarget.classList.contains('delete-project-button')) {
const buttonProps = event.relatedTarget.dataset; const buttonProps = event.relatedTarget.dataset;
deleteModal.deleteProjectUrl = buttonProps.deleteProjectUrl; deleteModal.deleteProjectUrl = buttonProps.deleteProjectUrl;
......
<script> <script>
import _ from 'underscore'; import _ from 'underscore';
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';
export default { export default {
components: { components: {
DeprecatedModal, DeprecatedModal,
},
props: {
deleteUserUrl: {
type: String,
required: false,
default: '',
}, },
props: { blockUserUrl: {
deleteUserUrl: { type: String,
type: String, required: false,
required: false, default: '',
default: '',
},
blockUserUrl: {
type: String,
required: false,
default: '',
},
deleteContributions: {
type: Boolean,
required: false,
default: false,
},
username: {
type: String,
required: false,
default: '',
},
csrfToken: {
type: String,
required: false,
default: '',
},
}, },
data() { deleteContributions: {
return { type: Boolean,
enteredUsername: '', required: false,
}; default: false,
}, },
computed: { username: {
title() { type: String,
const keepContributionsTitle = s__('AdminUsers|Delete User %{username}?'); required: false,
const deleteContributionsTitle = s__('AdminUsers|Delete User %{username} and contributions?'); default: '',
},
csrfToken: {
type: String,
required: false,
default: '',
},
},
data() {
return {
enteredUsername: '',
};
},
computed: {
title() {
const keepContributionsTitle = s__('AdminUsers|Delete User %{username}?');
const deleteContributionsTitle = s__('AdminUsers|Delete User %{username} and contributions?');
return sprintf( return sprintf(
this.deleteContributions ? deleteContributionsTitle : keepContributionsTitle, { this.deleteContributions ? deleteContributionsTitle : keepContributionsTitle,
username: `'${_.escape(this.username)}'`, {
}, false); username: `'${_.escape(this.username)}'`,
}, },
text() { false,
const keepContributionsText = s__(`AdminArea| );
},
text() {
const keepContributionsText = s__(`AdminArea|
You are about to permanently delete the user %{username}. You are about to permanently delete the user %{username}.
Issues, merge requests, and groups linked to them will be transferred to a system-wide "Ghost-user". Issues, merge requests, and groups linked to them will be transferred to a system-wide "Ghost-user".
To avoid data loss, consider using the %{strong_start}block user%{strong_end} feature instead. To avoid data loss, consider using the %{strong_start}block user%{strong_end} feature instead.
Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered.`); Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered.`);
const deleteContributionsText = s__(`AdminArea| const deleteContributionsText = s__(`AdminArea|
You are about to permanently delete the user %{username}. You are about to permanently delete the user %{username}.
This will delete all of the issues, merge requests, and groups linked to them. This will delete all of the issues, merge requests, and groups linked to them.
To avoid data loss, consider using the %{strong_start}block user%{strong_end} feature instead. To avoid data loss, consider using the %{strong_start}block user%{strong_end} feature instead.
Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered.`); Once you %{strong_start}Delete user%{strong_end}, it cannot be undone or recovered.`);
return sprintf(this.deleteContributions ? deleteContributionsText : keepContributionsText, return sprintf(
{ this.deleteContributions ? deleteContributionsText : keepContributionsText,
username: `<strong>${_.escape(this.username)}</strong>`, {
strong_start: '<strong>', username: `<strong>${_.escape(this.username)}</strong>`,
strong_end: '</strong>', strong_start: '<strong>',
}, strong_end: '</strong>',
false, },
); false,
}, );
confirmationTextLabel() { },
return sprintf(s__('AdminUsers|To confirm, type %{username}'), confirmationTextLabel() {
{ return sprintf(
username: `<code>${_.escape(this.username)}</code>`, s__('AdminUsers|To confirm, type %{username}'),
}, {
false, username: `<code>${_.escape(this.username)}</code>`,
); },
}, false,
primaryButtonLabel() { );
const keepContributionsLabel = s__('AdminUsers|Delete user'); },
const deleteContributionsLabel = s__('AdminUsers|Delete user and contributions'); primaryButtonLabel() {
const keepContributionsLabel = s__('AdminUsers|Delete user');
const deleteContributionsLabel = s__('AdminUsers|Delete user and contributions');
return this.deleteContributions ? deleteContributionsLabel : keepContributionsLabel; return this.deleteContributions ? deleteContributionsLabel : keepContributionsLabel;
},
secondaryButtonLabel() {
return s__('AdminUsers|Block user');
},
canSubmit() {
return this.enteredUsername === this.username;
},
}, },
methods: { secondaryButtonLabel() {
onCancel() { return s__('AdminUsers|Block user');
this.enteredUsername = ''; },
}, canSubmit() {
onSecondaryAction() { return this.enteredUsername === this.username;
const { form } = this.$refs; },
},
methods: {
onCancel() {
this.enteredUsername = '';
},
onSecondaryAction() {
const { form } = this.$refs;
form.action = this.blockUserUrl; form.action = this.blockUserUrl;
this.$refs.method.value = 'put'; this.$refs.method.value = 'put';
form.submit(); form.submit();
}, },
onSubmit() { onSubmit() {
this.$refs.form.submit(); this.$refs.form.submit();
this.enteredUsername = ''; this.enteredUsername = '';
},
}, },
}; },
};
</script> </script>
<template> <template>
......
...@@ -32,12 +32,14 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -32,12 +32,14 @@ document.addEventListener('DOMContentLoaded', () => {
}, },
}); });
$(document).on('shown.bs.modal', (event) => { $(document).on('shown.bs.modal', event => {
if (event.relatedTarget.classList.contains('delete-user-button')) { if (event.relatedTarget.classList.contains('delete-user-button')) {
const buttonProps = event.relatedTarget.dataset; const buttonProps = event.relatedTarget.dataset;
deleteModal.deleteUserUrl = buttonProps.deleteUserUrl; deleteModal.deleteUserUrl = buttonProps.deleteUserUrl;
deleteModal.blockUserUrl = buttonProps.blockUserUrl; deleteModal.blockUserUrl = buttonProps.blockUserUrl;
deleteModal.deleteContributions = event.relatedTarget.hasAttribute('data-delete-contributions'); deleteModal.deleteContributions = event.relatedTarget.hasAttribute(
'data-delete-contributions',
);
deleteModal.username = buttonProps.username; deleteModal.username = buttonProps.username;
} }
}); });
......
...@@ -4,7 +4,9 @@ export default class UserInternalRegexHandler { ...@@ -4,7 +4,9 @@ export default class UserInternalRegexHandler {
constructor() { constructor() {
this.regexPattern = $('[data-user-internal-regex-pattern]').data('user-internal-regex-pattern'); this.regexPattern = $('[data-user-internal-regex-pattern]').data('user-internal-regex-pattern');
if (this.regexPattern && this.regexPattern !== '') { if (this.regexPattern && this.regexPattern !== '') {
this.regexOptions = $('[data-user-internal-regex-options]').data('user-internal-regex-options'); this.regexOptions = $('[data-user-internal-regex-options]').data(
'user-internal-regex-options',
);
this.external = $('#user_external'); this.external = $('#user_external');
this.warningMessage = $('#warning_external_automatically_set'); this.warningMessage = $('#warning_external_automatically_set');
this.addListenerToEmailField(); this.addListenerToEmailField();
...@@ -13,7 +15,7 @@ export default class UserInternalRegexHandler { ...@@ -13,7 +15,7 @@ export default class UserInternalRegexHandler {
} }
addListenerToEmailField() { addListenerToEmailField() {
$('#user_email').on('input', (event) => { $('#user_email').on('input', event => {
this.setExternalCheckbox(event.currentTarget.value); this.setExternalCheckbox(event.currentTarget.value);
}); });
} }
......
...@@ -79,7 +79,8 @@ export default class Todos { ...@@ -79,7 +79,8 @@ export default class Todos {
.then(({ data }) => { .then(({ data }) => {
this.updateRowState(target); this.updateRowState(target);
this.updateBadges(data); this.updateBadges(data);
}).catch(() => { })
.catch(() => {
this.updateRowState(target, true); this.updateRowState(target, true);
return flash(__('Error updating todo status.')); return flash(__('Error updating todo status.'));
}); });
...@@ -118,10 +119,12 @@ export default class Todos { ...@@ -118,10 +119,12 @@ export default class Todos {
axios[target.dataset.method](target.dataset.href, { axios[target.dataset.method](target.dataset.href, {
ids: this.todo_ids, ids: this.todo_ids,
}).then(({ data }) => { })
this.updateAllState(target, data); .then(({ data }) => {
this.updateBadges(data); this.updateAllState(target, data);
}).catch(() => flash(__('Error updating status for all todos.'))); this.updateBadges(data);
})
.catch(() => flash(__('Error updating status for all todos.')));
} }
updateAllState(target, data) { updateAllState(target, data) {
...@@ -133,7 +136,7 @@ export default class Todos { ...@@ -133,7 +136,7 @@ export default class Todos {
target.removeAttribute('disabled'); target.removeAttribute('disabled');
target.classList.remove('disabled'); target.classList.remove('disabled');
this.todo_ids = (target === markAllDoneBtn) ? data.updated_ids : []; this.todo_ids = target === markAllDoneBtn ? data.updated_ids : [];
undoAllBtn.classList.toggle('hidden'); undoAllBtn.classList.toggle('hidden');
markAllDoneBtn.classList.toggle('hidden'); markAllDoneBtn.classList.toggle('hidden');
todoListContainer.classList.toggle('hidden'); todoListContainer.classList.toggle('hidden');
......
<script> <script>
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import Flash from '~/flash'; import Flash from '~/flash';
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
import { n__, s__, sprintf } from '~/locale'; import { n__, s__, sprintf } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
export default { export default {
components: { components: {
DeprecatedModal, DeprecatedModal,
},
props: {
issueCount: {
type: Number,
required: true,
}, },
props: { mergeRequestCount: {
issueCount: { type: Number,
type: Number, required: true,
required: true,
},
mergeRequestCount: {
type: Number,
required: true,
},
milestoneId: {
type: Number,
required: true,
},
milestoneTitle: {
type: String,
required: true,
},
milestoneUrl: {
type: String,
required: true,
},
}, },
computed: { milestoneId: {
text() { type: Number,
const milestoneTitle = sprintf('<strong>%{milestoneTitle}</strong>', { milestoneTitle: this.milestoneTitle }); required: true,
},
if (this.issueCount === 0 && this.mergeRequestCount === 0) { milestoneTitle: {
return sprintf( type: String,
s__(`Milestones| required: true,
You’re about to permanently delete the milestone %{milestoneTitle}. },
This milestone is not currently used in any issues or merge requests.`), milestoneUrl: {
{ type: String,
milestoneTitle, required: true,
}, },
false, },
); computed: {
} text() {
const milestoneTitle = sprintf('<strong>%{milestoneTitle}</strong>', {
milestoneTitle: this.milestoneTitle,
});
if (this.issueCount === 0 && this.mergeRequestCount === 0) {
return sprintf( return sprintf(
s__(`Milestones| s__(`Milestones|
You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. You’re about to permanently delete the milestone %{milestoneTitle}.
Once deleted, it cannot be undone or recovered.`), This milestone is not currently used in any issues or merge requests.`),
{ {
milestoneTitle, milestoneTitle,
issuesWithCount: n__('%d issue', '%d issues', this.issueCount),
mergeRequestsWithCount: n__('%d merge request', '%d merge requests', this.mergeRequestCount),
}, },
false, false,
); );
}, }
title() {
return sprintf(s__('Milestones|Delete milestone %{milestoneTitle}?'), { milestoneTitle: this.milestoneTitle });
},
},
methods: {
onSubmit() {
eventHub.$emit('deleteMilestoneModal.requestStarted', this.milestoneUrl);
return axios.delete(this.milestoneUrl) return sprintf(
.then((response) => { s__(`Milestones|
eventHub.$emit('deleteMilestoneModal.requestFinished', { milestoneUrl: this.milestoneUrl, successful: true }); You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}.
Once deleted, it cannot be undone or recovered.`),
{
milestoneTitle,
issuesWithCount: n__('%d issue', '%d issues', this.issueCount),
mergeRequestsWithCount: n__(
'%d merge request',
'%d merge requests',
this.mergeRequestCount,
),
},
false,
);
},
title() {
return sprintf(s__('Milestones|Delete milestone %{milestoneTitle}?'), {
milestoneTitle: this.milestoneTitle,
});
},
},
methods: {
onSubmit() {
eventHub.$emit('deleteMilestoneModal.requestStarted', this.milestoneUrl);
// follow the rediect to milestones overview page return axios
redirectTo(response.request.responseURL); .delete(this.milestoneUrl)
}) .then(response => {
.catch((error) => { eventHub.$emit('deleteMilestoneModal.requestFinished', {
eventHub.$emit('deleteMilestoneModal.requestFinished', { milestoneUrl: this.milestoneUrl, successful: false }); milestoneUrl: this.milestoneUrl,
successful: true,
});
if (error.response && error.response.status === 404) { // follow the rediect to milestones overview page
Flash(sprintf(s__('Milestones|Milestone %{milestoneTitle} was not found'), { milestoneTitle: this.milestoneTitle })); redirectTo(response.request.responseURL);
} else { })
Flash(sprintf(s__('Milestones|Failed to delete milestone %{milestoneTitle}'), { milestoneTitle: this.milestoneTitle })); .catch(error => {
} eventHub.$emit('deleteMilestoneModal.requestFinished', {
throw error; milestoneUrl: this.milestoneUrl,
successful: false,
}); });
},
if (error.response && error.response.status === 404) {
Flash(
sprintf(s__('Milestones|Milestone %{milestoneTitle} was not found'), {
milestoneTitle: this.milestoneTitle,
}),
);
} else {
Flash(
sprintf(s__('Milestones|Failed to delete milestone %{milestoneTitle}'), {
milestoneTitle: this.milestoneTitle,
}),
);
}
throw error;
});
}, },
}; },
};
</script> </script>
<template> <template>
......
...@@ -7,7 +7,9 @@ export default () => { ...@@ -7,7 +7,9 @@ export default () => {
Vue.use(Translate); Vue.use(Translate);
const onRequestFinished = ({ milestoneUrl, successful }) => { const onRequestFinished = ({ milestoneUrl, successful }) => {
const button = document.querySelector(`.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`); const button = document.querySelector(
`.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`,
);
if (!successful) { if (!successful) {
button.removeAttribute('disabled'); button.removeAttribute('disabled');
...@@ -16,14 +18,16 @@ export default () => { ...@@ -16,14 +18,16 @@ export default () => {
button.querySelector('.js-loading-icon').classList.add('hidden'); button.querySelector('.js-loading-icon').classList.add('hidden');
}; };
const onRequestStarted = (milestoneUrl) => { const onRequestStarted = milestoneUrl => {
const button = document.querySelector(`.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`); const button = document.querySelector(
`.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`,
);
button.setAttribute('disabled', ''); button.setAttribute('disabled', '');
button.querySelector('.js-loading-icon').classList.remove('hidden'); button.querySelector('.js-loading-icon').classList.remove('hidden');
eventHub.$once('deleteMilestoneModal.requestFinished', onRequestFinished); eventHub.$once('deleteMilestoneModal.requestFinished', onRequestFinished);
}; };
const onDeleteButtonClick = (event) => { const onDeleteButtonClick = event => {
const button = event.currentTarget; const button = event.currentTarget;
const modalProps = { const modalProps = {
milestoneId: parseInt(button.dataset.milestoneId, 10), milestoneId: parseInt(button.dataset.milestoneId, 10),
...@@ -37,12 +41,12 @@ export default () => { ...@@ -37,12 +41,12 @@ export default () => {
}; };
const deleteMilestoneButtons = document.querySelectorAll('.js-delete-milestone-button'); const deleteMilestoneButtons = document.querySelectorAll('.js-delete-milestone-button');
deleteMilestoneButtons.forEach((button) => { deleteMilestoneButtons.forEach(button => {
button.addEventListener('click', onDeleteButtonClick); button.addEventListener('click', onDeleteButtonClick);
}); });
eventHub.$once('deleteMilestoneModal.mounted', () => { eventHub.$once('deleteMilestoneModal.mounted', () => {
deleteMilestoneButtons.forEach((button) => { deleteMilestoneButtons.forEach(button => {
button.removeAttribute('disabled'); button.removeAttribute('disabled');
}); });
}); });
......
...@@ -7,20 +7,24 @@ Vue.use(Translate); ...@@ -7,20 +7,24 @@ Vue.use(Translate);
export default () => { export default () => {
const onRequestFinished = ({ milestoneUrl, successful }) => { const onRequestFinished = ({ milestoneUrl, successful }) => {
const button = document.querySelector(`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`); const button = document.querySelector(
`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`,
);
if (!successful) { if (!successful) {
button.removeAttribute('disabled'); button.removeAttribute('disabled');
} }
}; };
const onRequestStarted = (milestoneUrl) => { const onRequestStarted = milestoneUrl => {
const button = document.querySelector(`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`); const button = document.querySelector(
`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`,
);
button.setAttribute('disabled', ''); button.setAttribute('disabled', '');
eventHub.$once('promoteMilestoneModal.requestFinished', onRequestFinished); eventHub.$once('promoteMilestoneModal.requestFinished', onRequestFinished);
}; };
const onDeleteButtonClick = (event) => { const onDeleteButtonClick = event => {
const button = event.currentTarget; const button = event.currentTarget;
const modalProps = { const modalProps = {
milestoneTitle: button.dataset.milestoneTitle, milestoneTitle: button.dataset.milestoneTitle,
...@@ -32,12 +36,12 @@ export default () => { ...@@ -32,12 +36,12 @@ export default () => {
}; };
const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone-button'); const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone-button');
promoteMilestoneButtons.forEach((button) => { promoteMilestoneButtons.forEach(button => {
button.addEventListener('click', onDeleteButtonClick); button.addEventListener('click', onDeleteButtonClick);
}); });
eventHub.$once('promoteMilestoneModal.mounted', () => { eventHub.$once('promoteMilestoneModal.mounted', () => {
promoteMilestoneButtons.forEach((button) => { promoteMilestoneButtons.forEach(button => {
button.removeAttribute('disabled'); button.removeAttribute('disabled');
}); });
}); });
......
...@@ -3,9 +3,12 @@ import '~/profile/gl_crop'; ...@@ -3,9 +3,12 @@ import '~/profile/gl_crop';
import Profile from '~/profile/profile'; import Profile from '~/profile/profile';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
$(document).on('input.ssh_key', '#key_key', function () { // eslint-disable-line func-names // eslint-disable-next-line func-names
$(document).on('input.ssh_key', '#key_key', function() {
const $title = $('#key_title'); const $title = $('#key_title');
const comment = $(this).val().match(/^\S+ \S+ (.+)\n?$/); const comment = $(this)
.val()
.match(/^\S+ \S+ (.+)\n?$/);
// Extract the SSH Key title from its comment // Extract the SSH Key title from its comment
if (comment && comment.length > 1) { if (comment && comment.length > 1) {
......
...@@ -5,7 +5,9 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -5,7 +5,9 @@ document.addEventListener('DOMContentLoaded', () => {
const twoFactorNode = document.querySelector('.js-two-factor-auth'); const twoFactorNode = document.querySelector('.js-two-factor-auth');
const skippable = twoFactorNode.dataset.twoFactorSkippable === 'true'; const skippable = twoFactorNode.dataset.twoFactorSkippable === 'true';
if (skippable) { if (skippable) {
const button = `<a class="btn btn-sm btn-warning float-right" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`; const button = `<a class="btn btn-sm btn-warning float-right" data-method="patch" href="${
twoFactorNode.dataset.two_factor_skip_url
}">Configure it later</a>`;
const flashAlert = document.querySelector('.flash-alert .container-fluid'); const flashAlert = document.querySelector('.flash-alert .container-fluid');
if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button); if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button);
} }
......
import $ from 'jquery'; import $ from 'jquery';
import NewBranchForm from '~/new_branch_form'; import NewBranchForm from '~/new_branch_form';
document.addEventListener('DOMContentLoaded', () => ( document.addEventListener(
new NewBranchForm($('.js-create-branch-form'), JSON.parse(document.getElementById('availableRefs').innerHTML)) 'DOMContentLoaded',
)); () =>
new NewBranchForm(
$('.js-create-branch-form'),
JSON.parse(document.getElementById('availableRefs').innerHTML),
),
);
...@@ -31,14 +31,16 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -31,14 +31,16 @@ document.addEventListener('DOMContentLoaded', () => {
const chartData = data => ({ const chartData = data => ({
labels: Object.keys(data), labels: Object.keys(data),
datasets: [{ datasets: [
fillColor: 'rgba(220,220,220,0.5)', {
strokeColor: 'rgba(220,220,220,1)', fillColor: 'rgba(220,220,220,0.5)',
barStrokeWidth: 1, strokeColor: 'rgba(220,220,220,1)',
barValueSpacing: 1, barStrokeWidth: 1,
barDatasetSpacing: 1, barValueSpacing: 1,
data: _.values(data), barDatasetSpacing: 1,
}], data: _.values(data),
},
],
}); });
const hourData = chartData(projectChartData.hour); const hourData = chartData(projectChartData.hour);
...@@ -51,7 +53,9 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -51,7 +53,9 @@ document.addEventListener('DOMContentLoaded', () => {
responsiveChart($('#month-chart'), monthData); responsiveChart($('#month-chart'), monthData);
const data = projectChartData.languages; const data = projectChartData.languages;
const ctx = $('#languages-chart').get(0).getContext('2d'); const ctx = $('#languages-chart')
.get(0)
.getContext('2d');
const options = { const options = {
scaleOverlay: true, scaleOverlay: true,
responsive: true, responsive: true,
......
...@@ -7,7 +7,8 @@ import ContributorsStatGraph from './stat_graph_contributors'; ...@@ -7,7 +7,8 @@ import ContributorsStatGraph from './stat_graph_contributors';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const url = document.querySelector('.js-graphs-show').dataset.projectGraphPath; const url = document.querySelector('.js-graphs-show').dataset.projectGraphPath;
axios.get(url) axios
.get(url)
.then(({ data }) => { .then(({ data }) => {
const graph = new ContributorsStatGraph(); const graph = new ContributorsStatGraph();
graph.init(data); graph.init(data);
......
...@@ -3,7 +3,11 @@ ...@@ -3,7 +3,11 @@
import $ from 'jquery'; import $ from 'jquery';
import _ from 'underscore'; import _ from 'underscore';
import { n__, s__, createDateTimeFormat, sprintf } from '~/locale'; import { n__, s__, createDateTimeFormat, sprintf } from '~/locale';
import { ContributorsGraph, ContributorsAuthorGraph, ContributorsMasterGraph } from './stat_graph_contributors_graph'; import {
ContributorsGraph,
ContributorsAuthorGraph,
ContributorsMasterGraph,
} from './stat_graph_contributors_graph';
import ContributorsStatGraphUtil from './stat_graph_contributors_util'; import ContributorsStatGraphUtil from './stat_graph_contributors_util';
export default (function() { export default (function() {
...@@ -14,7 +18,7 @@ export default (function() { ...@@ -14,7 +18,7 @@ export default (function() {
ContributorsStatGraph.prototype.init = function(log) { ContributorsStatGraph.prototype.init = function(log) {
var author_commits, total_commits; var author_commits, total_commits;
this.parsed_log = ContributorsStatGraphUtil.parse_log(log); this.parsed_log = ContributorsStatGraphUtil.parse_log(log);
this.set_current_field("commits"); this.set_current_field('commits');
total_commits = ContributorsStatGraphUtil.get_total_data(this.parsed_log, this.field); total_commits = ContributorsStatGraphUtil.get_total_data(this.parsed_log, this.field);
author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field); author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field);
this.add_master_graph(total_commits); this.add_master_graph(total_commits);
...@@ -31,23 +35,26 @@ export default (function() { ...@@ -31,23 +35,26 @@ export default (function() {
var limited_author_data; var limited_author_data;
this.authors = []; this.authors = [];
limited_author_data = author_data.slice(0, 100); limited_author_data = author_data.slice(0, 100);
return _.each(limited_author_data, (function(_this) { return _.each(
return function(d) { limited_author_data,
var author_graph, author_header; (function(_this) {
author_header = _this.create_author_header(d); return function(d) {
$(".contributors-list").append(author_header); var author_graph, author_header;
author_header = _this.create_author_header(d);
author_graph = new ContributorsAuthorGraph(d.dates); $('.contributors-list').append(author_header);
_this.authors[d.author_name] = author_graph;
return author_graph.draw(); author_graph = new ContributorsAuthorGraph(d.dates);
}; _this.authors[d.author_name] = author_graph;
})(this)); return author_graph.draw();
};
})(this),
);
}; };
ContributorsStatGraph.prototype.format_author_commit_info = function(author) { ContributorsStatGraph.prototype.format_author_commit_info = function(author) {
var commits; var commits;
commits = $('<span/>', { commits = $('<span/>', {
"class": 'graph-author-commits-count' class: 'graph-author-commits-count',
}); });
commits.text(n__('%d commit', '%d commits', author.commits)); commits.text(n__('%d commit', '%d commits', author.commits));
return $('<span/>').append(commits); return $('<span/>').append(commits);
...@@ -56,13 +63,13 @@ export default (function() { ...@@ -56,13 +63,13 @@ export default (function() {
ContributorsStatGraph.prototype.create_author_header = function(author) { ContributorsStatGraph.prototype.create_author_header = function(author) {
var author_commit_info, author_commit_info_span, author_email, author_name, list_item; var author_commit_info, author_commit_info_span, author_email, author_name, list_item;
list_item = $('<li/>', { list_item = $('<li/>', {
"class": 'person', class: 'person',
style: 'display: block;' style: 'display: block;',
}); });
author_name = $('<h4>' + author.author_name + '</h4>'); author_name = $('<h4>' + author.author_name + '</h4>');
author_email = $('<p class="graph-author-email">' + author.author_email + '</p>'); author_email = $('<p class="graph-author-email">' + author.author_email + '</p>');
author_commit_info_span = $('<span/>', { author_commit_info_span = $('<span/>', {
"class": 'commits' class: 'commits',
}); });
author_commit_info = this.format_author_commit_info(author); author_commit_info = this.format_author_commit_info(author);
author_commit_info_span.html(author_commit_info); author_commit_info_span.html(author_commit_info);
...@@ -80,37 +87,41 @@ export default (function() { ...@@ -80,37 +87,41 @@ export default (function() {
}; };
ContributorsStatGraph.prototype.redraw_authors = function() { ContributorsStatGraph.prototype.redraw_authors = function() {
$("ol").html(""); $('ol').html('');
const { x_domain } = ContributorsGraph.prototype; const { x_domain } = ContributorsGraph.prototype;
const author_commits = ContributorsStatGraphUtil.get_author_data(this.parsed_log, this.field, x_domain); const author_commits = ContributorsStatGraphUtil.get_author_data(
this.parsed_log,
return _.each(author_commits, (function(_this) { this.field,
return function(d) { x_domain,
_this.redraw_author_commit_info(d); );
if (_this.authors[d.author_name] != null) {
$(_this.authors[d.author_name].list_item).appendTo("ol"); return _.each(
_this.authors[d.author_name].set_data(d.dates); author_commits,
return _this.authors[d.author_name].redraw(); (function(_this) {
} return function(d) {
return ''; _this.redraw_author_commit_info(d);
}; if (_this.authors[d.author_name] != null) {
})(this)); $(_this.authors[d.author_name].list_item).appendTo('ol');
_this.authors[d.author_name].set_data(d.dates);
return _this.authors[d.author_name].redraw();
}
return '';
};
})(this),
);
}; };
ContributorsStatGraph.prototype.set_current_field = function(field) { ContributorsStatGraph.prototype.set_current_field = function(field) {
return this.field = field; return (this.field = field);
}; };
ContributorsStatGraph.prototype.change_date_header = function() { ContributorsStatGraph.prototype.change_date_header = function() {
const { x_domain } = ContributorsGraph.prototype; const { x_domain } = ContributorsGraph.prototype;
const formattedDateRange = sprintf( const formattedDateRange = sprintf(s__('ContributorsPage|%{startDate} – %{endDate}'), {
s__('ContributorsPage|%{startDate} – %{endDate}'), startDate: this.dateFormat.format(new Date(x_domain[0])),
{ endDate: this.dateFormat.format(new Date(x_domain[1])),
startDate: this.dateFormat.format(new Date(x_domain[0])), });
endDate: this.dateFormat.format(new Date(x_domain[1])),
},
);
return $('#date_header').text(formattedDateRange); return $('#date_header').text(formattedDateRange);
}; };
...@@ -120,7 +131,7 @@ export default (function() { ...@@ -120,7 +131,7 @@ export default (function() {
if ($author != null) { if ($author != null) {
author_list_item = $(this.authors[author.author_name].list_item); author_list_item = $(this.authors[author.author_name].list_item);
author_commit_info = this.format_author_commit_info(author); author_commit_info = this.format_author_commit_info(author);
return author_list_item.find("span").html(author_commit_info); return author_list_item.find('span').html(author_commit_info);
} }
return ''; return '';
}; };
......
...@@ -11,10 +11,32 @@ import { brushX } from 'd3-brush'; ...@@ -11,10 +11,32 @@ import { brushX } from 'd3-brush';
import { timeParse } from 'd3-time-format'; import { timeParse } from 'd3-time-format';
import { dateTickFormat } from '~/lib/utils/tick_formats'; import { dateTickFormat } from '~/lib/utils/tick_formats';
const d3 = { extent, max, select, scaleTime, scaleLinear, axisLeft, axisBottom, area, brushX, timeParse }; const d3 = {
extent,
max,
select,
scaleTime,
scaleLinear,
axisLeft,
axisBottom,
area,
brushX,
timeParse,
};
const hasProp = {}.hasOwnProperty; const hasProp = {}.hasOwnProperty;
const extend = function(child, parent) { for (const key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; const extend = function(child, parent) {
for (const key in parent) {
if (hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
};
export const ContributorsGraph = (function() { export const ContributorsGraph = (function() {
function ContributorsGraph() {} function ContributorsGraph() {}
...@@ -23,7 +45,7 @@ export const ContributorsGraph = (function() { ...@@ -23,7 +45,7 @@ export const ContributorsGraph = (function() {
top: 20, top: 20,
right: 10, right: 10,
bottom: 30, bottom: 30,
left: 40 left: 40,
}; };
ContributorsGraph.prototype.x_domain = null; ContributorsGraph.prototype.x_domain = null;
...@@ -33,35 +55,39 @@ export const ContributorsGraph = (function() { ...@@ -33,35 +55,39 @@ export const ContributorsGraph = (function() {
ContributorsGraph.prototype.dates = []; ContributorsGraph.prototype.dates = [];
ContributorsGraph.prototype.determine_width = function(baseWidth, $parentElement) { ContributorsGraph.prototype.determine_width = function(baseWidth, $parentElement) {
const parentPaddingWidth = parseFloat($parentElement.css('padding-left')) + parseFloat($parentElement.css('padding-right')); const parentPaddingWidth =
parseFloat($parentElement.css('padding-left')) +
parseFloat($parentElement.css('padding-right'));
const marginWidth = this.MARGIN.left + this.MARGIN.right; const marginWidth = this.MARGIN.left + this.MARGIN.right;
return baseWidth - parentPaddingWidth - marginWidth; return baseWidth - parentPaddingWidth - marginWidth;
}; };
ContributorsGraph.set_x_domain = function(data) { ContributorsGraph.set_x_domain = function(data) {
return ContributorsGraph.prototype.x_domain = data; return (ContributorsGraph.prototype.x_domain = data);
}; };
ContributorsGraph.set_y_domain = function(data) { ContributorsGraph.set_y_domain = function(data) {
return ContributorsGraph.prototype.y_domain = [ return (ContributorsGraph.prototype.y_domain = [
0, d3.max(data, function(d) { 0,
return d.commits = d.commits || d.additions || d.deletions; d3.max(data, function(d) {
}) return (d.commits = d.commits || d.additions || d.deletions);
]; }),
]);
}; };
ContributorsGraph.init_x_domain = function(data) { ContributorsGraph.init_x_domain = function(data) {
return ContributorsGraph.prototype.x_domain = d3.extent(data, function(d) { return (ContributorsGraph.prototype.x_domain = d3.extent(data, function(d) {
return d.date; return d.date;
}); }));
}; };
ContributorsGraph.init_y_domain = function(data) { ContributorsGraph.init_y_domain = function(data) {
return ContributorsGraph.prototype.y_domain = [ return (ContributorsGraph.prototype.y_domain = [
0, d3.max(data, function(d) { 0,
return d.commits = d.commits || d.additions || d.deletions; d3.max(data, function(d) {
}) return (d.commits = d.commits || d.additions || d.deletions);
]; }),
]);
}; };
ContributorsGraph.init_domain = function(data) { ContributorsGraph.init_domain = function(data) {
...@@ -70,7 +96,7 @@ export const ContributorsGraph = (function() { ...@@ -70,7 +96,7 @@ export const ContributorsGraph = (function() {
}; };
ContributorsGraph.set_dates = function(data) { ContributorsGraph.set_dates = function(data) {
return ContributorsGraph.prototype.dates = data; return (ContributorsGraph.prototype.dates = data);
}; };
ContributorsGraph.prototype.set_x_domain = function() { ContributorsGraph.prototype.set_x_domain = function() {
...@@ -87,20 +113,33 @@ export const ContributorsGraph = (function() { ...@@ -87,20 +113,33 @@ export const ContributorsGraph = (function() {
}; };
ContributorsGraph.prototype.create_scale = function(width, height) { ContributorsGraph.prototype.create_scale = function(width, height) {
this.x = d3.scaleTime().range([0, width]).clamp(true); this.x = d3
return this.y = d3.scaleLinear().range([height, 0]).nice(); .scaleTime()
.range([0, width])
.clamp(true);
return (this.y = d3
.scaleLinear()
.range([height, 0])
.nice());
}; };
ContributorsGraph.prototype.draw_x_axis = function() { ContributorsGraph.prototype.draw_x_axis = function() {
return this.svg.append("g").attr("class", "x axis").attr("transform", "translate(0, " + this.height + ")").call(this.x_axis); return this.svg
.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, ' + this.height + ')')
.call(this.x_axis);
}; };
ContributorsGraph.prototype.draw_y_axis = function() { ContributorsGraph.prototype.draw_y_axis = function() {
return this.svg.append("g").attr("class", "y axis").call(this.y_axis); return this.svg
.append('g')
.attr('class', 'y axis')
.call(this.y_axis);
}; };
ContributorsGraph.prototype.set_data = function(data) { ContributorsGraph.prototype.set_data = function(data) {
return this.data = data; return (this.data = data);
}; };
return ContributorsGraph; return ContributorsGraph;
...@@ -137,9 +176,9 @@ export const ContributorsMasterGraph = (function(superClass) { ...@@ -137,9 +176,9 @@ export const ContributorsMasterGraph = (function(superClass) {
}; };
ContributorsMasterGraph.prototype.parse_dates = function(data) { ContributorsMasterGraph.prototype.parse_dates = function(data) {
const parseDate = d3.timeParse("%Y-%m-%d"); const parseDate = d3.timeParse('%Y-%m-%d');
return data.forEach(function(d) { return data.forEach(function(d) {
return d.date = parseDate(d.date); return (d.date = parseDate(d.date));
}); });
}; };
...@@ -148,42 +187,63 @@ export const ContributorsMasterGraph = (function(superClass) { ...@@ -148,42 +187,63 @@ export const ContributorsMasterGraph = (function(superClass) {
}; };
ContributorsMasterGraph.prototype.create_axes = function() { ContributorsMasterGraph.prototype.create_axes = function() {
this.x_axis = d3.axisBottom() this.x_axis = d3
.axisBottom()
.scale(this.x) .scale(this.x)
.tickFormat(dateTickFormat); .tickFormat(dateTickFormat);
return this.y_axis = d3.axisLeft().scale(this.y).ticks(5); return (this.y_axis = d3
.axisLeft()
.scale(this.y)
.ticks(5));
}; };
ContributorsMasterGraph.prototype.create_svg = function() { ContributorsMasterGraph.prototype.create_svg = function() {
this.svg = d3.select("#contributors-master") this.svg = d3
.append("svg") .select('#contributors-master')
.attr("width", this.width + this.MARGIN.left + this.MARGIN.right) .append('svg')
.attr("height", this.height + this.MARGIN.top + this.MARGIN.bottom) .attr('width', this.width + this.MARGIN.left + this.MARGIN.right)
.attr("class", "tint-box") .attr('height', this.height + this.MARGIN.top + this.MARGIN.bottom)
.append("g") .attr('class', 'tint-box')
.attr("transform", "translate(" + this.MARGIN.left + "," + this.MARGIN.top + ")"); .append('g')
.attr('transform', 'translate(' + this.MARGIN.left + ',' + this.MARGIN.top + ')');
return this.svg; return this.svg;
}; };
ContributorsMasterGraph.prototype.create_area = function(x, y) { ContributorsMasterGraph.prototype.create_area = function(x, y) {
return this.area = d3.area().x(function(d) { return (this.area = d3
return x(d.date); .area()
}).y0(this.height).y1(function(d) { .x(function(d) {
d.commits = d.commits || d.additions || d.deletions; return x(d.date);
return y(d.commits); })
}); .y0(this.height)
.y1(function(d) {
d.commits = d.commits || d.additions || d.deletions;
return y(d.commits);
}));
}; };
ContributorsMasterGraph.prototype.create_brush = function() { ContributorsMasterGraph.prototype.create_brush = function() {
return this.brush = d3.brushX(this.x).extent([[this.x.range()[0], 0], [this.x.range()[1], this.height]]).on("end", this.update_content); return (this.brush = d3
.brushX(this.x)
.extent([[this.x.range()[0], 0], [this.x.range()[1], this.height]])
.on('end', this.update_content));
}; };
ContributorsMasterGraph.prototype.draw_path = function(data) { ContributorsMasterGraph.prototype.draw_path = function(data) {
return this.svg.append("path").datum(data).attr("class", "area").attr("d", this.area); return this.svg
.append('path')
.datum(data)
.attr('class', 'area')
.attr('d', this.area);
}; };
ContributorsMasterGraph.prototype.add_brush = function() { ContributorsMasterGraph.prototype.add_brush = function() {
return this.svg.append("g").attr("class", "selection").call(this.brush).selectAll("rect").attr("height", this.height); return this.svg
.append('g')
.attr('class', 'selection')
.call(this.brush)
.selectAll('rect')
.attr('height', this.height);
}; };
ContributorsMasterGraph.prototype.update_content = function() { ContributorsMasterGraph.prototype.update_content = function() {
...@@ -193,7 +253,7 @@ export const ContributorsMasterGraph = (function(superClass) { ...@@ -193,7 +253,7 @@ export const ContributorsMasterGraph = (function(superClass) {
} else { } else {
ContributorsGraph.set_x_domain(this.x_max_domain); ContributorsGraph.set_x_domain(this.x_max_domain);
} }
return $("#brush_change").trigger('change'); return $('#brush_change').trigger('change');
}; };
ContributorsMasterGraph.prototype.draw = function() { ContributorsMasterGraph.prototype.draw = function() {
...@@ -216,9 +276,9 @@ export const ContributorsMasterGraph = (function(superClass) { ...@@ -216,9 +276,9 @@ export const ContributorsMasterGraph = (function(superClass) {
this.process_dates(this.data); this.process_dates(this.data);
ContributorsGraph.set_y_domain(this.data); ContributorsGraph.set_y_domain(this.data);
this.set_y_domain(); this.set_y_domain();
this.svg.select("path").datum(this.data); this.svg.select('path').datum(this.data);
this.svg.select("path").attr("d", this.area); this.svg.select('path').attr('d', this.area);
return this.svg.select(".y.axis").call(this.y_axis); return this.svg.select('.y.axis').call(this.y_axis);
}; };
return ContributorsMasterGraph; return ContributorsMasterGraph;
...@@ -252,43 +312,58 @@ export const ContributorsAuthorGraph = (function(superClass) { ...@@ -252,43 +312,58 @@ export const ContributorsAuthorGraph = (function(superClass) {
}; };
ContributorsAuthorGraph.prototype.create_axes = function() { ContributorsAuthorGraph.prototype.create_axes = function() {
this.x_axis = d3.axisBottom() this.x_axis = d3
.axisBottom()
.scale(this.x) .scale(this.x)
.ticks(8) .ticks(8)
.tickFormat(dateTickFormat); .tickFormat(dateTickFormat);
return this.y_axis = d3.axisLeft().scale(this.y).ticks(5); return (this.y_axis = d3
.axisLeft()
.scale(this.y)
.ticks(5));
}; };
ContributorsAuthorGraph.prototype.create_area = function(x, y) { ContributorsAuthorGraph.prototype.create_area = function(x, y) {
return this.area = d3.area().x(function(d) { return (this.area = d3
const parseDate = d3.timeParse("%Y-%m-%d"); .area()
return x(parseDate(d)); .x(function(d) {
}).y0(this.height).y1((function(_this) { const parseDate = d3.timeParse('%Y-%m-%d');
return function(d) { return x(parseDate(d));
if (_this.data[d] != null) { })
return y(_this.data[d]); .y0(this.height)
} else { .y1(
return y(0); (function(_this) {
} return function(d) {
}; if (_this.data[d] != null) {
})(this)); return y(_this.data[d]);
} else {
return y(0);
}
};
})(this),
));
}; };
ContributorsAuthorGraph.prototype.create_svg = function() { ContributorsAuthorGraph.prototype.create_svg = function() {
const persons = document.querySelectorAll('.person'); const persons = document.querySelectorAll('.person');
this.list_item = persons[persons.length - 1]; this.list_item = persons[persons.length - 1];
this.svg = d3.select(this.list_item) this.svg = d3
.append("svg") .select(this.list_item)
.attr("width", this.width + this.MARGIN.left + this.MARGIN.right) .append('svg')
.attr("height", this.height + this.MARGIN.top + this.MARGIN.bottom) .attr('width', this.width + this.MARGIN.left + this.MARGIN.right)
.attr("class", "spark") .attr('height', this.height + this.MARGIN.top + this.MARGIN.bottom)
.append("g") .attr('class', 'spark')
.attr("transform", "translate(" + this.MARGIN.left + "," + this.MARGIN.top + ")"); .append('g')
.attr('transform', 'translate(' + this.MARGIN.left + ',' + this.MARGIN.top + ')');
return this.svg; return this.svg;
}; };
ContributorsAuthorGraph.prototype.draw_path = function(data) { ContributorsAuthorGraph.prototype.draw_path = function(data) {
return this.svg.append("path").datum(data).attr("class", "area-contributor").attr("d", this.area); return this.svg
.append('path')
.datum(data)
.attr('class', 'area-contributor')
.attr('d', this.area);
}; };
ContributorsAuthorGraph.prototype.draw = function() { ContributorsAuthorGraph.prototype.draw = function() {
...@@ -304,10 +379,10 @@ export const ContributorsAuthorGraph = (function(superClass) { ...@@ -304,10 +379,10 @@ export const ContributorsAuthorGraph = (function(superClass) {
ContributorsAuthorGraph.prototype.redraw = function() { ContributorsAuthorGraph.prototype.redraw = function() {
this.set_domain(); this.set_domain();
this.svg.select("path").datum(this.dates); this.svg.select('path').datum(this.dates);
this.svg.select("path").attr("d", this.area); this.svg.select('path').attr('d', this.area);
this.svg.select(".x.axis").call(this.x_axis); this.svg.select('.x.axis').call(this.x_axis);
return this.svg.select(".y.axis").call(this.y_axis); return this.svg.select('.y.axis').call(this.y_axis);
}; };
return ContributorsAuthorGraph; return ContributorsAuthorGraph;
......
...@@ -26,12 +26,12 @@ export default { ...@@ -26,12 +26,12 @@ export default {
by_author = _.toArray(by_author); by_author = _.toArray(by_author);
return { return {
total: total, total: total,
by_author: by_author by_author: by_author,
}; };
}, },
add_date: function(date, collection) { add_date: function(date, collection) {
collection[date] = {}; collection[date] = {};
return collection[date].date = date; return (collection[date].date = date);
}, },
add_author: function(author, by_author, by_email) { add_author: function(author, by_author, by_email) {
var data, normalized_email; var data, normalized_email;
...@@ -49,28 +49,28 @@ export default { ...@@ -49,28 +49,28 @@ export default {
return this.store_deletions(entry, total, by_author); return this.store_deletions(entry, total, by_author);
}, },
store_commits: function(total, by_author) { store_commits: function(total, by_author) {
this.add(total, "commits", 1); this.add(total, 'commits', 1);
return this.add(by_author, "commits", 1); return this.add(by_author, 'commits', 1);
}, },
add: function(collection, field, value) { add: function(collection, field, value) {
if (collection[field] == null) { if (collection[field] == null) {
collection[field] = 0; collection[field] = 0;
} }
return collection[field] += value; return (collection[field] += value);
}, },
store_additions: function(entry, total, by_author) { store_additions: function(entry, total, by_author) {
if (entry.additions == null) { if (entry.additions == null) {
entry.additions = 0; entry.additions = 0;
} }
this.add(total, "additions", entry.additions); this.add(total, 'additions', entry.additions);
return this.add(by_author, "additions", entry.additions); return this.add(by_author, 'additions', entry.additions);
}, },
store_deletions: function(entry, total, by_author) { store_deletions: function(entry, total, by_author) {
if (entry.deletions == null) { if (entry.deletions == null) {
entry.deletions = 0; entry.deletions = 0;
} }
this.add(total, "deletions", entry.deletions); this.add(total, 'deletions', entry.deletions);
return this.add(by_author, "deletions", entry.deletions); return this.add(by_author, 'deletions', entry.deletions);
}, },
get_total_data: function(parsed_log, field) { get_total_data: function(parsed_log, field) {
var log, total_data; var log, total_data;
...@@ -95,15 +95,18 @@ export default { ...@@ -95,15 +95,18 @@ export default {
} }
log = parsed_log.by_author; log = parsed_log.by_author;
author_data = []; author_data = [];
_.each(log, (function(_this) { _.each(
return function(log_entry) { log,
var parsed_log_entry; (function(_this) {
parsed_log_entry = _this.parse_log_entry(log_entry, field, date_range); return function(log_entry) {
if (!_.isEmpty(parsed_log_entry.dates)) { var parsed_log_entry;
return author_data.push(parsed_log_entry); parsed_log_entry = _this.parse_log_entry(log_entry, field, date_range);
} if (!_.isEmpty(parsed_log_entry.dates)) {
}; return author_data.push(parsed_log_entry);
})(this)); }
};
})(this),
);
return _.sortBy(author_data, function(d) { return _.sortBy(author_data, function(d) {
return d[field]; return d[field];
}).reverse(); }).reverse();
...@@ -120,16 +123,19 @@ export default { ...@@ -120,16 +123,19 @@ export default {
parsed_entry.additions = 0; parsed_entry.additions = 0;
parsed_entry.deletions = 0; parsed_entry.deletions = 0;
_.each(_.omit(log_entry, 'author_name', 'author_email'), (function(_this) { _.each(
return function(value, key) { _.omit(log_entry, 'author_name', 'author_email'),
if (_this.in_range(value.date, date_range)) { (function(_this) {
parsed_entry.dates[value.date] = value[field]; return function(value, key) {
parsed_entry.commits += value.commits; if (_this.in_range(value.date, date_range)) {
parsed_entry.additions += value.additions; parsed_entry.dates[value.date] = value[field];
return parsed_entry.deletions += value.deletions; parsed_entry.commits += value.commits;
} parsed_entry.additions += value.additions;
}; return (parsed_entry.deletions += value.deletions);
})(this)); }
};
})(this),
);
return parsed_entry; return parsed_entry;
}, },
in_range: function(date, date_range) { in_range: function(date, date_range) {
...@@ -139,5 +145,5 @@ export default { ...@@ -139,5 +145,5 @@ export default {
} else { } else {
return false; return false;
} }
} },
}; };
...@@ -16,7 +16,8 @@ export default () => { ...@@ -16,7 +16,8 @@ export default () => {
); );
const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url'); const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url');
const fileBlobPermalinkUrl = fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href'); const fileBlobPermalinkUrl =
fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href');
new ShortcutsNavigation(); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new
......
import ZenMode from '~/zen_mode'; import ZenMode from '~/zen_mode';
import GLForm from '~/gl_form'; import GLForm from '~/gl_form';
export default function ($formEl) { export default function($formEl) {
new ZenMode(); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new
new GLForm($formEl); // eslint-disable-line no-new new GLForm($formEl); // eslint-disable-line no-new
} }
...@@ -5,7 +5,7 @@ import ZenMode from '~/zen_mode'; ...@@ -5,7 +5,7 @@ import ZenMode from '~/zen_mode';
import '~/notes/index'; import '~/notes/index';
import initIssueableApp from '~/issue_show'; import initIssueableApp from '~/issue_show';
export default function () { export default function() {
initIssueableApp(); initIssueableApp();
new Issue(); // eslint-disable-line no-new new Issue(); // eslint-disable-line no-new
new ShortcutsIssuable(); // eslint-disable-line no-new new ShortcutsIssuable(); // eslint-disable-line no-new
......
<script> <script>
import _ from 'underscore'; import _ from 'underscore';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash'; import createFlash from '~/flash';
import GlModal from '~/vue_shared/components/gl_modal.vue'; import GlModal from '~/vue_shared/components/gl_modal.vue';
import { s__, sprintf } from '~/locale'; import { s__, sprintf } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
export default { export default {
components: { components: {
GlModal, GlModal,
},
props: {
url: {
type: String,
required: true,
}, },
props: { labelTitle: {
url: { type: String,
type: String, required: true,
required: true,
},
labelTitle: {
type: String,
required: true,
},
labelColor: {
type: String,
required: true,
},
labelTextColor: {
type: String,
required: true,
},
groupName: {
type: String,
required: true,
},
}, },
computed: { labelColor: {
text() { type: String,
return sprintf(s__(`Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}. required: true,
Existing project labels with the same title will be merged. This action cannot be reversed.`), { },
labelTextColor: {
type: String,
required: true,
},
groupName: {
type: String,
required: true,
},
},
computed: {
text() {
return sprintf(
s__(`Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}.
Existing project labels with the same title will be merged. This action cannot be reversed.`),
{
labelTitle: this.labelTitle, labelTitle: this.labelTitle,
groupName: this.groupName, groupName: this.groupName,
}); },
}, );
title() { },
const label = `<span title() {
const label = `<span
class="label color-label" class="label color-label"
style="background-color: ${this.labelColor}; color: ${this.labelTextColor};" style="background-color: ${this.labelColor}; color: ${this.labelTextColor};"
>${_.escape(this.labelTitle)}</span>`; >${_.escape(this.labelTitle)}</span>`;
return sprintf(s__('Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>'), { return sprintf(
s__('Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>'),
{
labelTitle: label, labelTitle: label,
}, false); },
}, false,
);
}, },
methods: { },
onSubmit() { methods: {
eventHub.$emit('promoteLabelModal.requestStarted', this.url); onSubmit() {
return axios.post(this.url, { params: { format: 'json' } }) eventHub.$emit('promoteLabelModal.requestStarted', this.url);
.then((response) => { return axios
eventHub.$emit('promoteLabelModal.requestFinished', { labelUrl: this.url, successful: true }); .post(this.url, { params: { format: 'json' } })
visitUrl(response.data.url); .then(response => {
}) eventHub.$emit('promoteLabelModal.requestFinished', {
.catch((error) => { labelUrl: this.url,
eventHub.$emit('promoteLabelModal.requestFinished', { labelUrl: this.url, successful: false }); successful: true,
createFlash(error); });
visitUrl(response.data.url);
})
.catch(error => {
eventHub.$emit('promoteLabelModal.requestFinished', {
labelUrl: this.url,
successful: false,
}); });
}, createFlash(error);
});
}, },
}; },
};
</script> </script>
<template> <template>
<gl-modal <gl-modal
......
...@@ -10,20 +10,24 @@ const initLabelIndex = () => { ...@@ -10,20 +10,24 @@ const initLabelIndex = () => {
initLabels(); initLabels();
const onRequestFinished = ({ labelUrl, successful }) => { const onRequestFinished = ({ labelUrl, successful }) => {
const button = document.querySelector(`.js-promote-project-label-button[data-url="${labelUrl}"]`); const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
if (!successful) { if (!successful) {
button.removeAttribute('disabled'); button.removeAttribute('disabled');
} }
}; };
const onRequestStarted = (labelUrl) => { const onRequestStarted = labelUrl => {
const button = document.querySelector(`.js-promote-project-label-button[data-url="${labelUrl}"]`); const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
button.setAttribute('disabled', ''); button.setAttribute('disabled', '');
eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished); eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished);
}; };
const onDeleteButtonClick = (event) => { const onDeleteButtonClick = event => {
const button = event.currentTarget; const button = event.currentTarget;
const modalProps = { const modalProps = {
labelTitle: button.dataset.labelTitle, labelTitle: button.dataset.labelTitle,
...@@ -37,12 +41,12 @@ const initLabelIndex = () => { ...@@ -37,12 +41,12 @@ const initLabelIndex = () => {
}; };
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button'); const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button');
promoteLabelButtons.forEach((button) => { promoteLabelButtons.forEach(button => {
button.addEventListener('click', onDeleteButtonClick); button.addEventListener('click', onDeleteButtonClick);
}); });
eventHub.$once('promoteLabelModal.mounted', () => { eventHub.$once('promoteLabelModal.mounted', () => {
promoteLabelButtons.forEach((button) => { promoteLabelButtons.forEach(button => {
button.removeAttribute('disabled'); button.removeAttribute('disabled');
}); });
}); });
......
...@@ -6,13 +6,15 @@ import BranchGraph from '../../../network/branch_graph'; ...@@ -6,13 +6,15 @@ import BranchGraph from '../../../network/branch_graph';
export default (function() { export default (function() {
function Network(opts) { function Network(opts) {
var vph; var vph;
$("#filter_ref").click(function() { $('#filter_ref').click(function() {
return $(this).closest('form').submit(); return $(this)
.closest('form')
.submit();
}); });
this.branch_graph = new BranchGraph($(".network-graph"), opts); this.branch_graph = new BranchGraph($('.network-graph'), opts);
vph = $(window).height() - 250; vph = $(window).height() - 250;
$('.network-graph').css({ $('.network-graph').css({
'height': vph + 'px' height: vph + 'px',
}); });
} }
......
import Vue from 'vue'; import Vue from 'vue';
import PipelineSchedulesCallout from '../shared/components/pipeline_schedules_callout.vue'; import PipelineSchedulesCallout from '../shared/components/pipeline_schedules_callout.vue';
document.addEventListener('DOMContentLoaded', () => new Vue({ document.addEventListener(
el: '#pipeline-schedules-callout', 'DOMContentLoaded',
components: { () =>
'pipeline-schedules-callout': PipelineSchedulesCallout, new Vue({
}, el: '#pipeline-schedules-callout',
render(createElement) { components: {
return createElement('pipeline-schedules-callout'); 'pipeline-schedules-callout': PipelineSchedulesCallout,
}, },
})); render(createElement) {
return createElement('pipeline-schedules-callout');
},
}),
);
<script> <script>
import _ from 'underscore'; import _ from 'underscore';
export default { export default {
props: { props: {
initialCronInterval: { initialCronInterval: {
type: String, type: String,
required: false, required: false,
default: '', default: '',
},
},
data() {
return {
inputNameAttribute: 'schedule[cron]',
cronInterval: this.initialCronInterval,
cronIntervalPresets: {
everyDay: '0 4 * * *',
everyWeek: '0 4 * * 0',
everyMonth: '0 4 1 * *',
},
cronSyntaxUrl: 'https://en.wikipedia.org/wiki/Cron',
customInputEnabled: false,
};
}, },
computed: { },
intervalIsPreset() { data() {
return _.contains(this.cronIntervalPresets, this.cronInterval); return {
}, inputNameAttribute: 'schedule[cron]',
// The text input is editable when there's a custom interval, or when it's cronInterval: this.initialCronInterval,
// a preset interval and the user clicks the 'custom' radio button cronIntervalPresets: {
isEditable() { everyDay: '0 4 * * *',
return !!(this.customInputEnabled || !this.intervalIsPreset); everyWeek: '0 4 * * 0',
everyMonth: '0 4 1 * *',
}, },
cronSyntaxUrl: 'https://en.wikipedia.org/wiki/Cron',
customInputEnabled: false,
};
},
computed: {
intervalIsPreset() {
return _.contains(this.cronIntervalPresets, this.cronInterval);
}, },
watch: { // The text input is editable when there's a custom interval, or when it's
cronInterval() { // a preset interval and the user clicks the 'custom' radio button
// updates field validation state when model changes, as isEditable() {
// glFieldError only updates on input. return !!(this.customInputEnabled || !this.intervalIsPreset);
this.$nextTick(() => {
gl.pipelineScheduleFieldErrors.updateFormValidityState();
});
},
}, },
created() { },
if (this.intervalIsPreset) { watch: {
this.enableCustomInput = false; cronInterval() {
} // updates field validation state when model changes, as
// glFieldError only updates on input.
this.$nextTick(() => {
gl.pipelineScheduleFieldErrors.updateFormValidityState();
});
}, },
methods: { },
toggleCustomInput(shouldEnable) { created() {
this.customInputEnabled = shouldEnable; if (this.intervalIsPreset) {
this.enableCustomInput = false;
}
},
methods: {
toggleCustomInput(shouldEnable) {
this.customInputEnabled = shouldEnable;
if (shouldEnable) { if (shouldEnable) {
// We need to change the value so other radios don't remain selected // We need to change the value so other radios don't remain selected
// because the model (cronInterval) hasn't changed. The server trims it. // because the model (cronInterval) hasn't changed. The server trims it.
this.cronInterval = `${this.cronInterval} `; this.cronInterval = `${this.cronInterval} `;
} }
},
}, },
}; },
};
</script> </script>
<template> <template>
......
<script> <script>
import Vue from 'vue'; import Vue from 'vue';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import Translate from '../../../../../vue_shared/translate'; import Translate from '../../../../../vue_shared/translate';
import illustrationSvg from '../icons/intro_illustration.svg'; import illustrationSvg from '../icons/intro_illustration.svg';
Vue.use(Translate); Vue.use(Translate);
const cookieKey = 'pipeline_schedules_callout_dismissed'; const cookieKey = 'pipeline_schedules_callout_dismissed';
export default { export default {
name: 'PipelineSchedulesCallout', name: 'PipelineSchedulesCallout',
data() { data() {
return { return {
docsUrl: document.getElementById('pipeline-schedules-callout').dataset.docsUrl, docsUrl: document.getElementById('pipeline-schedules-callout').dataset.docsUrl,
calloutDismissed: Cookies.get(cookieKey) === 'true', calloutDismissed: Cookies.get(cookieKey) === 'true',
}; };
},
created() {
this.illustrationSvg = illustrationSvg;
},
methods: {
dismissCallout() {
this.calloutDismissed = true;
Cookies.set(cookieKey, this.calloutDismissed, { expires: 365 });
}, },
created() { },
this.illustrationSvg = illustrationSvg; };
},
methods: {
dismissCallout() {
this.calloutDismissed = true;
Cookies.set(cookieKey, this.calloutDismissed, { expires: 365 });
},
},
};
</script> </script>
<template> <template>
<div <div
......
...@@ -26,8 +26,7 @@ export default class TargetBranchDropdown { ...@@ -26,8 +26,7 @@ export default class TargetBranchDropdown {
} }
formatBranchesList() { formatBranchesList() {
return this.$dropdown.data('data') return this.$dropdown.data('data').map(val => ({ name: val }));
.map(val => ({ name: val }));
} }
setDropdownToggle() { setDropdownToggle() {
......
...@@ -11,7 +11,9 @@ Vue.use(Translate); ...@@ -11,7 +11,9 @@ Vue.use(Translate);
function initIntervalPatternInput() { function initIntervalPatternInput() {
const intervalPatternMount = document.getElementById('interval-pattern-input'); const intervalPatternMount = document.getElementById('interval-pattern-input');
const initialCronInterval = intervalPatternMount ? intervalPatternMount.dataset.initialInterval : ''; const initialCronInterval = intervalPatternMount
? intervalPatternMount.dataset.initialInterval
: '';
return new Vue({ return new Vue({
el: intervalPatternMount, el: intervalPatternMount,
......
...@@ -7,26 +7,29 @@ const options = { ...@@ -7,26 +7,29 @@ const options = {
maintainAspectRatio: false, maintainAspectRatio: false,
}; };
const buildChart = (chartScope) => { const buildChart = chartScope => {
const data = { const data = {
labels: chartScope.labels, labels: chartScope.labels,
datasets: [{ datasets: [
fillColor: '#707070', {
strokeColor: '#707070', fillColor: '#707070',
pointColor: '#707070', strokeColor: '#707070',
pointStrokeColor: '#EEE', pointColor: '#707070',
data: chartScope.totalValues, pointStrokeColor: '#EEE',
}, data: chartScope.totalValues,
{ },
fillColor: '#1aaa55', {
strokeColor: '#1aaa55', fillColor: '#1aaa55',
pointColor: '#1aaa55', strokeColor: '#1aaa55',
pointStrokeColor: '#fff', pointColor: '#1aaa55',
data: chartScope.successValues, pointStrokeColor: '#fff',
}, data: chartScope.successValues,
},
], ],
}; };
const ctx = $(`#${chartScope.scope}Chart`).get(0).getContext('2d'); const ctx = $(`#${chartScope.scope}Chart`)
.get(0)
.getContext('2d');
new Chart(ctx).Line(data, options); new Chart(ctx).Line(data, options);
}; };
...@@ -36,14 +39,16 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -36,14 +39,16 @@ document.addEventListener('DOMContentLoaded', () => {
const chartsData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML); const chartsData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML);
const data = { const data = {
labels: chartTimesData.labels, labels: chartTimesData.labels,
datasets: [{ datasets: [
fillColor: 'rgba(220,220,220,0.5)', {
strokeColor: 'rgba(220,220,220,1)', fillColor: 'rgba(220,220,220,0.5)',
barStrokeWidth: 1, strokeColor: 'rgba(220,220,220,1)',
barValueSpacing: 1, barStrokeWidth: 1,
barDatasetSpacing: 1, barValueSpacing: 1,
data: chartTimesData.values, barDatasetSpacing: 1,
}], data: chartTimesData.values,
},
],
}; };
if (window.innerWidth < 768) { if (window.innerWidth < 768) {
...@@ -51,7 +56,11 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -51,7 +56,11 @@ document.addEventListener('DOMContentLoaded', () => {
options.scaleFontSize = 8; options.scaleFontSize = 8;
} }
new Chart($('#build_timesChart').get(0).getContext('2d')).Bar(data, options); new Chart(
$('#build_timesChart')
.get(0)
.getContext('2d'),
).Bar(data, options);
chartsData.forEach(scope => buildChart(scope)); chartsData.forEach(scope => buildChart(scope));
}); });
...@@ -6,35 +6,39 @@ import { convertPermissionToBoolean } from '../../../../lib/utils/common_utils'; ...@@ -6,35 +6,39 @@ import { convertPermissionToBoolean } from '../../../../lib/utils/common_utils';
Vue.use(Translate); Vue.use(Translate);
document.addEventListener('DOMContentLoaded', () => new Vue({ document.addEventListener(
el: '#pipelines-list-vue', 'DOMContentLoaded',
components: { () =>
pipelinesComponent, new Vue({
}, el: '#pipelines-list-vue',
data() { components: {
return { pipelinesComponent,
store: new PipelinesStore(),
};
},
created() {
this.dataset = document.querySelector(this.$options.el).dataset;
},
render(createElement) {
return createElement('pipelines-component', {
props: {
store: this.store,
endpoint: this.dataset.endpoint,
helpPagePath: this.dataset.helpPagePath,
emptyStateSvgPath: this.dataset.emptyStateSvgPath,
errorStateSvgPath: this.dataset.errorStateSvgPath,
noPipelinesSvgPath: this.dataset.noPipelinesSvgPath,
autoDevopsPath: this.dataset.helpAutoDevopsPath,
newPipelinePath: this.dataset.newPipelinePath,
canCreatePipeline: convertPermissionToBoolean(this.dataset.canCreatePipeline),
hasGitlabCi: convertPermissionToBoolean(this.dataset.hasGitlabCi),
ciLintPath: this.dataset.ciLintPath,
resetCachePath: this.dataset.resetCachePath,
}, },
}); data() {
}, return {
})); store: new PipelinesStore(),
};
},
created() {
this.dataset = document.querySelector(this.$options.el).dataset;
},
render(createElement) {
return createElement('pipelines-component', {
props: {
store: this.store,
endpoint: this.dataset.endpoint,
helpPagePath: this.dataset.helpPagePath,
emptyStateSvgPath: this.dataset.emptyStateSvgPath,
errorStateSvgPath: this.dataset.errorStateSvgPath,
noPipelinesSvgPath: this.dataset.noPipelinesSvgPath,
autoDevopsPath: this.dataset.helpAutoDevopsPath,
newPipelinePath: this.dataset.newPipelinePath,
canCreatePipeline: convertPermissionToBoolean(this.dataset.canCreatePipeline),
hasGitlabCi: convertPermissionToBoolean(this.dataset.hasGitlabCi),
ciLintPath: this.dataset.ciLintPath,
resetCachePath: this.dataset.resetCachePath,
},
});
},
}),
);
...@@ -2,9 +2,12 @@ import Pipelines from '~/pipelines'; ...@@ -2,9 +2,12 @@ import Pipelines from '~/pipelines';
export default () => { export default () => {
const { controllerAction } = document.querySelector('.js-pipeline-container').dataset; const { controllerAction } = document.querySelector('.js-pipeline-container').dataset;
const pipelineStatusUrl = `${document.querySelector('.js-pipeline-tab-link a').getAttribute('href')}/status.json`; const pipelineStatusUrl = `${document
.querySelector('.js-pipeline-tab-link a')
.getAttribute('href')}/status.json`;
new Pipelines({ // eslint-disable-line no-new // eslint-disable-next-line no-new
new Pipelines({
initTabs: true, initTabs: true,
pipelineStatusUrl, pipelineStatusUrl,
tabsOptions: { tabsOptions: {
......
<script> <script>
import projectFeatureToggle from '../../../../../vue_shared/components/toggle_button.vue'; import projectFeatureToggle from '../../../../../vue_shared/components/toggle_button.vue';
export default { export default {
components: { components: {
projectFeatureToggle, projectFeatureToggle,
}, },
model: { model: {
prop: 'value', prop: 'value',
event: 'change', event: 'change',
}, },
props: { props: {
name: { name: {
type: String, type: String,
required: false, required: false,
default: '', default: '',
}, },
options: { options: {
type: Array, type: Array,
required: false, required: false,
default: () => [], default: () => [],
}, },
value: { value: {
type: Number, type: Number,
required: false, required: false,
default: 0, default: 0,
},
disabledInput: {
type: Boolean,
required: false,
default: false,
},
}, },
disabledInput: {
type: Boolean,
required: false,
default: false,
},
},
computed: { computed: {
featureEnabled() { featureEnabled() {
return this.value !== 0; return this.value !== 0;
}, },
displayOptions() { displayOptions() {
if (this.featureEnabled) { if (this.featureEnabled) {
return this.options; return this.options;
} }
return [ return [[0, 'Enable feature to choose access level']];
[0, 'Enable feature to choose access level'], },
];
},
displaySelectInput() { displaySelectInput() {
return this.disabledInput || !this.featureEnabled || this.displayOptions.length < 2; return this.disabledInput || !this.featureEnabled || this.displayOptions.length < 2;
},
}, },
},
methods: { methods: {
toggleFeature(featureEnabled) { toggleFeature(featureEnabled) {
if (featureEnabled === false || this.options.length < 1) { if (featureEnabled === false || this.options.length < 1) {
this.$emit('change', 0); this.$emit('change', 0);
} else { } else {
const [firstOptionValue] = this.options[this.options.length - 1]; const [firstOptionValue] = this.options[this.options.length - 1];
this.$emit('change', firstOptionValue); this.$emit('change', firstOptionValue);
} }
}, },
selectOption(e) { selectOption(e) {
this.$emit('change', Number(e.target.value)); this.$emit('change', Number(e.target.value));
},
}, },
}; },
};
</script> </script>
<template> <template>
......
<script> <script>
export default { export default {
props: { props: {
label: { label: {
type: String, type: String,
required: false, required: false,
default: null, default: null,
},
helpPath: {
type: String,
required: false,
default: null,
},
helpText: {
type: String,
required: false,
default: null,
},
}, },
}; helpPath: {
type: String,
required: false,
default: null,
},
helpText: {
type: String,
required: false,
default: null,
},
},
};
</script> </script>
<template> <template>
......
...@@ -5,7 +5,9 @@ export const visibilityOptions = { ...@@ -5,7 +5,9 @@ export const visibilityOptions = {
}; };
export const visibilityLevelDescriptions = { export const visibilityLevelDescriptions = {
[visibilityOptions.PRIVATE]: 'The project is accessible only by members of the project. Access must be granted explicitly to each user.', [visibilityOptions.PRIVATE]:
'The project is accessible only by members of the project. Access must be granted explicitly to each user.',
[visibilityOptions.INTERNAL]: 'The project can be accessed by any user who is logged in.', [visibilityOptions.INTERNAL]: 'The project can be accessed by any user who is logged in.',
[visibilityOptions.PUBLIC]: 'The project can be accessed by anyone, regardless of authentication.', [visibilityOptions.PUBLIC]:
'The project can be accessed by anyone, regardless of authentication.',
}; };
...@@ -8,8 +8,9 @@ export default function projectAvatar() { ...@@ -8,8 +8,9 @@ export default function projectAvatar() {
$('.js-project-avatar-input').bind('change', function onClickAvatarInput() { $('.js-project-avatar-input').bind('change', function onClickAvatarInput() {
const form = $(this).closest('form'); const form = $(this).closest('form');
// eslint-disable-next-line no-useless-escape const filename = $(this)
const filename = $(this).val().replace(/^.*[\\\/]/, ''); .val()
.replace(/^.*[\\\/]/, ''); // eslint-disable-line no-useless-escape
return form.find('.js-avatar-filename').text(filename); return form.find('.js-avatar-filename').text(filename);
}); });
} }
...@@ -21,7 +21,8 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -21,7 +21,8 @@ document.addEventListener('DOMContentLoaded', () => {
const { deleteWikiUrl, pageTitle } = deleteWikiModalWrapperEl.dataset; const { deleteWikiUrl, pageTitle } = deleteWikiModalWrapperEl.dataset;
new Vue({ // eslint-disable-line no-new // eslint-disable-next-line no-new
new Vue({
el: deleteWikiModalWrapperEl, el: deleteWikiModalWrapperEl,
data: { data: {
deleteWikiUrl: '', deleteWikiUrl: '',
......
...@@ -22,7 +22,7 @@ export default class Search { ...@@ -22,7 +22,7 @@ export default class Search {
fields: ['full_name'], fields: ['full_name'],
}, },
data(term, callback) { data(term, callback) {
return Api.groups(term, {}, (data) => { return Api.groups(term, {}, data => {
data.unshift({ data.unshift({
full_name: 'Any', full_name: 'Any',
}); });
...@@ -37,7 +37,7 @@ export default class Search { ...@@ -37,7 +37,7 @@ export default class Search {
return obj.full_name; return obj.full_name;
}, },
toggleLabel(obj) { toggleLabel(obj) {
return `${($groupDropdown.data('defaultLabel'))} ${obj.full_name}`; return `${$groupDropdown.data('defaultLabel')} ${obj.full_name}`;
}, },
clicked: () => Search.submitSearch(), clicked: () => Search.submitSearch(),
}); });
...@@ -52,7 +52,7 @@ export default class Search { ...@@ -52,7 +52,7 @@ export default class Search {
}, },
data: (term, callback) => { data: (term, callback) => {
this.getProjectsData(term) this.getProjectsData(term)
.then((data) => { .then(data => {
data.unshift({ data.unshift({
name_with_namespace: 'Any', name_with_namespace: 'Any',
}); });
...@@ -70,7 +70,7 @@ export default class Search { ...@@ -70,7 +70,7 @@ export default class Search {
return obj.name_with_namespace; return obj.name_with_namespace;
}, },
toggleLabel(obj) { toggleLabel(obj) {
return `${($projectDropdown.data('defaultLabel'))} ${obj.name_with_namespace}`; return `${$projectDropdown.data('defaultLabel')} ${obj.name_with_namespace}`;
}, },
clicked: () => Search.submitSearch(), clicked: () => Search.submitSearch(),
}); });
...@@ -99,17 +99,24 @@ export default class Search { ...@@ -99,17 +99,24 @@ export default class Search {
} }
clearSearchField() { clearSearchField() {
return $(this.searchInput).val('').trigger('keyup').focus(); return $(this.searchInput)
.val('')
.trigger('keyup')
.focus();
} }
getProjectsData(term) { getProjectsData(term) {
return new Promise((resolve) => { return new Promise(resolve => {
if (this.groupId) { if (this.groupId) {
Api.groupProjects(this.groupId, term, {}, resolve); Api.groupProjects(this.groupId, term, {}, resolve);
} else { } else {
Api.projects(term, { Api.projects(
order_by: 'id', term,
}, resolve); {
order_by: 'id',
},
resolve,
);
} }
}); });
} }
......
...@@ -20,7 +20,7 @@ export default class SigninTabsMemoizer { ...@@ -20,7 +20,7 @@ export default class SigninTabsMemoizer {
bootstrap() { bootstrap() {
const tabs = document.querySelectorAll(this.tabSelector); const tabs = document.querySelectorAll(this.tabSelector);
if (tabs.length > 0) { if (tabs.length > 0) {
tabs[0].addEventListener('click', (e) => { tabs[0].addEventListener('click', e => {
if (e.target && e.target.nodeName === 'A') { if (e.target && e.target.nodeName === 'A') {
const anchorName = e.target.getAttribute('href'); const anchorName = e.target.getAttribute('href');
this.saveData(anchorName); this.saveData(anchorName);
......
...@@ -22,10 +22,10 @@ export default class UsernameValidator { ...@@ -22,10 +22,10 @@ export default class UsernameValidator {
available: false, available: false,
valid: false, valid: false,
pending: false, pending: false,
empty: true empty: true,
}; };
const debounceTimeout = _.debounce((username) => { const debounceTimeout = _.debounce(username => {
this.validateUsername(username); this.validateUsername(username);
}, debounceTimeoutDuration); }, debounceTimeoutDuration);
...@@ -81,7 +81,8 @@ export default class UsernameValidator { ...@@ -81,7 +81,8 @@ export default class UsernameValidator {
this.state.pending = true; this.state.pending = true;
this.state.available = false; this.state.available = false;
this.renderState(); this.renderState();
axios.get(`${gon.relative_url_root}/users/${username}/exists`) axios
.get(`${gon.relative_url_root}/users/${username}/exists`)
.then(({ data }) => this.setAvailabilityState(data.exists)) .then(({ data }) => this.setAvailabilityState(data.exists))
.catch(() => flash(__('An error occurred while validating username'))); .catch(() => flash(__('An error occurred while validating username')));
} }
...@@ -100,8 +101,7 @@ export default class UsernameValidator { ...@@ -100,8 +101,7 @@ export default class UsernameValidator {
clearFieldValidationState() { clearFieldValidationState() {
this.inputElement.siblings('p').hide(); this.inputElement.siblings('p').hide();
this.inputElement.removeClass(invalidInputClass) this.inputElement.removeClass(invalidInputClass).removeClass(successInputClass);
.removeClass(successInputClass);
} }
setUnavailableState() { setUnavailableState() {
......
...@@ -13,10 +13,12 @@ function initUserProfile(action) { ...@@ -13,10 +13,12 @@ function initUserProfile(action) {
new UserTabs({ parentEl: '.user-profile', action }); new UserTabs({ parentEl: '.user-profile', action });
// hide project limit message // hide project limit message
$('.hide-project-limit-message').on('click', (e) => { $('.hide-project-limit-message').on('click', e => {
e.preventDefault(); e.preventDefault();
Cookies.set('hide_project_limit_message', 'false'); Cookies.set('hide_project_limit_message', 'false');
$(this).parents('.project-limit-message').remove(); $(this)
.parents('.project-limit-message')
.remove();
}); });
} }
......
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