Commit 46e3ad4b authored by Mike Greiling's avatar Mike Greiling

Prettify sidebar modules

parent 4695b311
...@@ -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')); });
});
}, },
}, },
}; };
......
<script> <script>
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
import { abbreviateTime } from '~/lib/utils/pretty_time'; import { abbreviateTime } from '~/lib/utils/pretty_time';
import icon from '~/vue_shared/components/icon.vue'; import icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
export default { export default {
name: 'TimeTrackingCollapsedState', name: 'TimeTrackingCollapsedState',
components: { components: {
icon, icon,
},
directives: {
tooltip,
},
props: {
showComparisonState: {
type: Boolean,
required: true,
}, },
directives: { showSpentOnlyState: {
tooltip, type: Boolean,
required: true,
}, },
props: { showEstimateOnlyState: {
showComparisonState: { type: Boolean,
type: Boolean, required: true,
required: true,
},
showSpentOnlyState: {
type: Boolean,
required: true,
},
showEstimateOnlyState: {
type: Boolean,
required: true,
},
showNoTimeTrackingState: {
type: Boolean,
required: true,
},
timeSpentHumanReadable: {
type: String,
required: false,
default: '',
},
timeEstimateHumanReadable: {
type: String,
required: false,
default: '',
},
}, },
computed: { showNoTimeTrackingState: {
timeSpent() { type: Boolean,
return this.abbreviateTime(this.timeSpentHumanReadable); required: true,
}, },
timeEstimate() { timeSpentHumanReadable: {
return this.abbreviateTime(this.timeEstimateHumanReadable); type: String,
}, required: false,
divClass() { default: '',
if (this.showComparisonState) { },
return 'compare'; timeEstimateHumanReadable: {
} else if (this.showEstimateOnlyState) { type: String,
return 'estimate-only'; required: false,
} else if (this.showSpentOnlyState) { default: '',
return 'spend-only'; },
} else if (this.showNoTimeTrackingState) { },
return 'no-tracking'; computed: {
} timeSpent() {
return this.abbreviateTime(this.timeSpentHumanReadable);
},
timeEstimate() {
return this.abbreviateTime(this.timeEstimateHumanReadable);
},
divClass() {
if (this.showComparisonState) {
return 'compare';
} else if (this.showEstimateOnlyState) {
return 'estimate-only';
} else if (this.showSpentOnlyState) {
return 'spend-only';
} else if (this.showNoTimeTrackingState) {
return 'no-tracking';
}
return '';
},
spanClass() {
if (this.showComparisonState) {
return ''; return '';
}, } else if (this.showEstimateOnlyState || this.showSpentOnlyState) {
spanClass() { return 'bold';
if (this.showComparisonState) { } else if (this.showNoTimeTrackingState) {
return ''; return 'no-value';
} else if (this.showEstimateOnlyState || this.showSpentOnlyState) { }
return 'bold';
} else if (this.showNoTimeTrackingState) {
return 'no-value';
}
return ''; return '';
}, },
text() { text() {
if (this.showComparisonState) { if (this.showComparisonState) {
return `${this.timeSpent} / ${this.timeEstimate}`; return `${this.timeSpent} / ${this.timeEstimate}`;
} else if (this.showEstimateOnlyState) { } else if (this.showEstimateOnlyState) {
return `-- / ${this.timeEstimate}`; return `-- / ${this.timeEstimate}`;
} else if (this.showSpentOnlyState) { } else if (this.showSpentOnlyState) {
return `${this.timeSpent} / --`; return `${this.timeSpent} / --`;
} else if (this.showNoTimeTrackingState) { } else if (this.showNoTimeTrackingState) {
return 'None'; return 'None';
} }
return ''; return '';
}, },
timeTrackedTooltipText() { timeTrackedTooltipText() {
let title; let title;
if (this.showComparisonState) { if (this.showComparisonState) {
title = __('Time remaining'); title = __('Time remaining');
} else if (this.showEstimateOnlyState) { } else if (this.showEstimateOnlyState) {
title = __('Estimated'); title = __('Estimated');
} else if (this.showSpentOnlyState) { } else if (this.showSpentOnlyState) {
title = __('Time spent'); title = __('Time spent');
} }
return sprintf('%{title}: %{text}', ({ title, text: this.text })); return sprintf('%{title}: %{text}', { title, text: this.text });
}, },
tooltipText() { tooltipText() {
return this.showNoTimeTrackingState ? __('Time tracking') : this.timeTrackedTooltipText; return this.showNoTimeTrackingState ? __('Time tracking') : this.timeTrackedTooltipText;
},
}, },
methods: { },
abbreviateTime(timeStr) { methods: {
return abbreviateTime(timeStr); abbreviateTime(timeStr) {
}, return abbreviateTime(timeStr);
}, },
}; },
};
</script> </script>
<template> <template>
......
...@@ -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