Skip to content
Snippets Groups Projects
Commit af28cb8a authored by Jacques Erasmus's avatar Jacques Erasmus
Browse files

Merge branch 'master' into 51306-fix-inaccessible-dropdown-for-codeless-projects

parents 16cd5967 28d412e5
No related branches found
No related tags found
No related merge requests found
Showing
with 302 additions and 265 deletions
<script>
import iconCycleAnalyticsSplash from 'icons/_icon_cycle_analytics_splash.svg';
import Icon from '~/vue_shared/components/icon.vue';
import iconCycleAnalyticsSplash from 'icons/_icon_cycle_analytics_splash.svg';
 
export default {
props: {
documentationLink: {
type: String,
required: true,
},
export default {
components: {
Icon,
},
props: {
documentationLink: {
type: String,
required: true,
},
computed: {
iconCycleAnalyticsSplash() {
return iconCycleAnalyticsSplash;
},
},
computed: {
iconCycleAnalyticsSplash() {
return iconCycleAnalyticsSplash;
},
methods: {
dismissOverviewDialog() {
this.$emit('dismiss-overview-dialog');
},
},
methods: {
dismissOverviewDialog() {
this.$emit('dismiss-overview-dialog');
},
};
},
};
</script>
<template>
<div class="landing content-block">
Loading
Loading
@@ -28,10 +32,9 @@
type="button"
@click="dismissOverviewDialog"
>
<i
class="fa fa-times"
aria-hidden="true">
</i>
<icon
name="close"
/>
</button>
<div
class="svg-container"
Loading
Loading
<script>
import tooltip from '../../vue_shared/directives/tooltip';
import tooltip from '../../vue_shared/directives/tooltip';
 
export default {
directives: {
tooltip,
export default {
directives: {
tooltip,
},
props: {
count: {
type: Number,
required: true,
},
props: {
count: {
type: Number,
required: true,
},
},
};
},
};
</script>
<template>
<span
Loading
Loading
<script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
 
export default {
components: {
userAvatarImage,
limitWarning,
totalTime,
export default {
components: {
userAvatarImage,
limitWarning,
totalTime,
},
props: {
items: {
type: Array,
default: () => [],
},
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
stage: {
type: Object,
default: () => ({}),
},
};
},
};
</script>
<template>
<div>
Loading
Loading
<script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
 
export default {
components: {
userAvatarImage,
limitWarning,
totalTime,
export default {
components: {
userAvatarImage,
limitWarning,
totalTime,
},
props: {
items: {
type: Array,
default: () => [],
},
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
stage: {
type: Object,
default: () => ({}),
},
};
},
};
</script>
<template>
<div>
Loading
Loading
@@ -73,4 +73,3 @@
</ul>
</div>
</template>
<script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import iconCommit from '../svg/icon_commit.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import iconCommit from '../svg/icon_commit.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
 
export default {
components: {
userAvatarImage,
totalTime,
limitWarning,
export default {
components: {
userAvatarImage,
totalTime,
limitWarning,
},
props: {
items: {
type: Array,
default: () => [],
},
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
stage: {
type: Object,
default: () => ({}),
},
computed: {
iconCommit() {
return iconCommit;
},
},
computed: {
iconCommit() {
return iconCommit;
},
};
},
};
</script>
<template>
<div>
Loading
Loading
@@ -74,4 +74,3 @@
</ul>
</div>
</template>
<script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import icon from '../../vue_shared/components/icon.vue';
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import icon from '../../vue_shared/components/icon.vue';
 
export default {
components: {
userAvatarImage,
totalTime,
limitWarning,
icon,
export default {
components: {
userAvatarImage,
totalTime,
limitWarning,
icon,
},
props: {
items: {
type: Array,
default: () => [],
},
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
stage: {
type: Object,
default: () => ({}),
},
};
},
};
</script>
<template>
<div>
Loading
Loading
<script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import iconBranch from '../svg/icon_branch.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import icon from '../../vue_shared/components/icon.vue';
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import iconBranch from '../svg/icon_branch.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import icon from '../../vue_shared/components/icon.vue';
 
export default {
components: {
userAvatarImage,
totalTime,
limitWarning,
icon,
export default {
components: {
userAvatarImage,
totalTime,
limitWarning,
icon,
},
props: {
items: {
type: Array,
default: () => [],
},
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
stage: {
type: Object,
default: () => ({}),
},
computed: {
iconBranch() {
return iconBranch;
},
},
computed: {
iconBranch() {
return iconBranch;
},
};
},
};
</script>
<template>
<div>
Loading
Loading
<script>
import iconBuildStatus from '../svg/icon_build_status.svg';
import iconBranch from '../svg/icon_branch.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import icon from '../../vue_shared/components/icon.vue';
import iconBuildStatus from '../svg/icon_build_status.svg';
import iconBranch from '../svg/icon_branch.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
import icon from '../../vue_shared/components/icon.vue';
 
export default {
components: {
totalTime,
limitWarning,
icon,
export default {
components: {
totalTime,
limitWarning,
icon,
},
props: {
items: {
type: Array,
default: () => [],
},
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
stage: {
type: Object,
default: () => ({}),
},
computed: {
iconBuildStatus() {
return iconBuildStatus;
},
iconBranch() {
return iconBranch;
},
},
computed: {
iconBuildStatus() {
return iconBuildStatus;
},
};
iconBranch() {
return iconBranch;
},
},
};
</script>
<template>
<div>
Loading
Loading
<script>
export default {
props: {
time: {
type: Object,
required: false,
default: () => ({}),
},
export default {
props: {
time: {
type: Object,
required: false,
default: () => ({}),
},
computed: {
hasData() {
return Object.keys(this.time).length;
},
},
computed: {
hasData() {
return Object.keys(this.time).length;
},
};
},
};
</script>
<template>
<span class="total-time">
Loading
Loading
Loading
Loading
@@ -18,7 +18,8 @@ Vue.use(Translate);
export default () => {
const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed';
 
new Vue({ // eslint-disable-line no-new
// eslint-disable-next-line no-new
new Vue({
el: '#cycle-analytics',
name: 'CycleAnalytics',
components: {
Loading
Loading
@@ -66,14 +67,17 @@ export default () => {
const $dropdown = $('.js-ca-dropdown');
const $label = $dropdown.find('.dropdown-label');
 
$dropdown.find('li a').off('click').on('click', (e) => {
e.preventDefault();
const $target = $(e.currentTarget);
this.startDate = $target.data('value');
$dropdown
.find('li a')
.off('click')
.on('click', e => {
e.preventDefault();
const $target = $(e.currentTarget);
this.startDate = $target.data('value');
 
$label.text($target.text().trim());
this.fetchCycleAnalyticsData({ startDate: this.startDate });
});
$label.text($target.text().trim());
this.fetchCycleAnalyticsData({ startDate: this.startDate });
});
},
fetchCycleAnalyticsData(options) {
const fetchOptions = options || { startDate: this.startDate };
Loading
Loading
@@ -82,7 +86,7 @@ export default () => {
 
this.service
.fetchCycleAnalyticsData(fetchOptions)
.then((response) => {
.then(response => {
this.store.setCycleAnalyticsData(response);
this.selectDefaultStage();
this.initDropdown();
Loading
Loading
@@ -115,7 +119,7 @@ export default () => {
stage,
startDate: this.startDate,
})
.then((response) => {
.then(response => {
this.isEmptyStage = !response.events.length;
this.store.setStageEvents(response.events, stage);
this.isLoadingStage = false;
Loading
Loading
Loading
Loading
@@ -18,10 +18,7 @@ export default class CycleAnalyticsService {
}
 
fetchStageData(options) {
const {
stage,
startDate,
} = options;
const { stage, startDate } = options;
 
return this.axios
.get(`events/${stage.name}.json`, {
Loading
Loading
Loading
Loading
@@ -5,13 +5,27 @@ import { dasherize } from '../lib/utils/text_utility';
import DEFAULT_EVENT_OBJECTS from './default_event_objects';
 
const EMPTY_STAGE_TEXTS = {
issue: __('The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.'),
plan: __('The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.'),
code: __('The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.'),
test: __('The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.'),
review: __('The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.'),
staging: __('The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.'),
production: __('The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.'),
issue: __(
'The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.',
),
plan: __(
'The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.',
),
code: __(
'The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.',
),
test: __(
'The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running.',
),
review: __(
'The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.',
),
staging: __(
'The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.',
),
production: __(
'The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.',
),
};
 
export default {
Loading
Loading
@@ -31,11 +45,11 @@ export default {
newData.stages = data.stats || [];
newData.summary = data.summary || [];
 
newData.summary.forEach((item) => {
newData.summary.forEach(item => {
item.value = item.value || '-';
});
 
newData.stages.forEach((item) => {
newData.stages.forEach(item => {
const stageSlug = dasherize(item.name.toLowerCase());
item.active = false;
item.isUserAllowed = data.permissions[stageSlug];
Loading
Loading
@@ -53,7 +67,7 @@ export default {
this.state.hasError = state;
},
deactivateAllStages() {
this.state.stages.forEach((stage) => {
this.state.stages.forEach(stage => {
stage.active = false;
});
},
Loading
Loading
@@ -67,7 +81,7 @@ export default {
decorateEvents(events, stage) {
const newEvents = [];
 
events.forEach((item) => {
events.forEach(item => {
if (!item) return;
 
const eventItem = Object.assign({}, DEFAULT_EVENT_OBJECTS[stage.slug], item);
Loading
Loading
Loading
Loading
@@ -18,52 +18,56 @@ const CommentAndResolveBtn = Vue.extend({
};
},
computed: {
showButton: function () {
showButton: function() {
if (this.discussion) {
return this.discussion.isResolvable();
} else {
return false;
}
},
isDiscussionResolved: function () {
isDiscussionResolved: function() {
return this.discussion.isResolved();
},
buttonText: function () {
buttonText: function() {
if (this.isDiscussionResolved) {
if (this.textareaIsEmpty) {
return "Unresolve discussion";
return 'Unresolve discussion';
} else {
return "Comment & unresolve discussion";
return 'Comment & unresolve discussion';
}
} else {
if (this.textareaIsEmpty) {
return "Resolve discussion";
return 'Resolve discussion';
} else {
return "Comment & resolve discussion";
return 'Comment & resolve discussion';
}
}
}
},
},
created() {
if (this.discussionId) {
this.discussion = CommentsStore.state[this.discussionId];
}
},
mounted: function () {
mounted: function() {
if (!this.discussionId) return;
 
const $textarea = $(`.js-discussion-note-form[data-discussion-id=${this.discussionId}] .note-textarea`);
const $textarea = $(
`.js-discussion-note-form[data-discussion-id=${this.discussionId}] .note-textarea`,
);
this.textareaIsEmpty = $textarea.val() === '';
 
$textarea.on('input.comment-and-resolve-btn', () => {
this.textareaIsEmpty = $textarea.val() === '';
});
},
destroyed: function () {
destroyed: function() {
if (!this.discussionId) return;
 
$(`.js-discussion-note-form[data-discussion-id=${this.discussionId}] .note-textarea`).off('input.comment-and-resolve-btn');
}
$(`.js-discussion-note-form[data-discussion-id=${this.discussionId}] .note-textarea`).off(
'input.comment-and-resolve-btn',
);
},
});
 
Vue.component('comment-and-resolve-btn', CommentAndResolveBtn);
Loading
Loading
@@ -83,7 +83,11 @@ const DiffNoteAvatars = Vue.extend({
this.addNoCommentClass();
this.setDiscussionVisible();
 
this.lineType = $(this.$el).closest('.diff-line-num').hasClass('old_line') ? 'old' : 'new';
this.lineType = $(this.$el)
.closest('.diff-line-num')
.hasClass('old_line')
? 'old'
: 'new';
});
 
$(document).on('toggle.comments', () => {
Loading
Loading
@@ -113,20 +117,30 @@ const DiffNoteAvatars = Vue.extend({
addNoCommentClass() {
const { notesCount } = this;
 
$(this.$el).closest('.js-avatar-container')
$(this.$el)
.closest('.js-avatar-container')
.toggleClass('no-comment-btn', notesCount > 0)
.nextUntil('.js-avatar-container')
.toggleClass('no-comment-btn', notesCount > 0);
},
toggleDiscussionsToggleState() {
const $notesHolders = $(this.$el).closest('.code').find('.notes_holder');
const $notesHolders = $(this.$el)
.closest('.code')
.find('.notes_holder');
const $visibleNotesHolders = $notesHolders.filter(':visible');
const $toggleDiffCommentsBtn = $(this.$el).closest('.diff-file').find('.js-toggle-diff-comments');
$toggleDiffCommentsBtn.toggleClass('active', $notesHolders.length === $visibleNotesHolders.length);
const $toggleDiffCommentsBtn = $(this.$el)
.closest('.diff-file')
.find('.js-toggle-diff-comments');
$toggleDiffCommentsBtn.toggleClass(
'active',
$notesHolders.length === $visibleNotesHolders.length,
);
},
setDiscussionVisible() {
this.isVisible = $(`.diffs .notes[data-discussion-id="${this.discussion.id}"]`).is(':visible');
this.isVisible = $(`.diffs .notes[data-discussion-id="${this.discussion.id}"]`).is(
':visible',
);
},
getTooltipText(note) {
return `${note.authorName}: ${note.noteTruncated}`;
Loading
Loading
Loading
Loading
@@ -14,24 +14,24 @@ const JumpToDiscussion = Vue.extend({
required: true,
},
},
data: function () {
data: function() {
return {
discussions: CommentsStore.state,
discussion: {},
};
},
computed: {
buttonText: function () {
buttonText: function() {
if (this.discussionId) {
return 'Jump to next unresolved discussion';
} else {
return 'Jump to first unresolved discussion';
}
},
allResolved: function () {
allResolved: function() {
return this.unresolvedDiscussionCount === 0;
},
showButton: function () {
showButton: function() {
if (this.discussionId) {
if (this.unresolvedDiscussionCount > 1) {
return true;
Loading
Loading
@@ -42,7 +42,7 @@ const JumpToDiscussion = Vue.extend({
return this.unresolvedDiscussionCount >= 1;
}
},
lastResolvedId: function () {
lastResolvedId: function() {
let lastId;
for (const discussionId in this.discussions) {
const discussion = this.discussions[discussionId];
Loading
Loading
@@ -52,13 +52,13 @@ const JumpToDiscussion = Vue.extend({
}
}
return lastId;
}
},
},
created() {
this.discussion = this.discussions[this.discussionId];
},
methods: {
jumpToNextUnresolvedDiscussion: function () {
jumpToNextUnresolvedDiscussion: function() {
let discussionsSelector;
let discussionIdsInScope;
let firstUnresolvedDiscussionId;
Loading
Loading
@@ -68,9 +68,11 @@ const JumpToDiscussion = Vue.extend({
let jumpToFirstDiscussion = !this.discussionId;
 
const discussionIdsForElements = function(elements) {
return elements.map(function() {
return $(this).attr('data-discussion-id');
}).toArray();
return elements
.map(function() {
return $(this).attr('data-discussion-id');
})
.toArray();
};
 
const { discussions } = this;
Loading
Loading
@@ -144,8 +146,7 @@ const JumpToDiscussion = Vue.extend({
if (!discussion.isResolved()) {
nextUnresolvedDiscussionId = discussionId;
break;
}
else {
} else {
continue;
}
}
Loading
Loading
@@ -175,9 +176,9 @@ const JumpToDiscussion = Vue.extend({
// Resolved discussions are hidden in the diffs tab by default.
// If they are marked unresolved on the notes tab, they will still be hidden on the diffs tab.
// When jumping between unresolved discussions on the diffs tab, we show them.
$target.closest(".content").show();
$target.closest('.content').show();
 
const $notesHolder = $target.closest("tr.notes_holder");
const $notesHolder = $target.closest('tr.notes_holder');
 
// Image diff discussions does not use notes_holder
// so we should keep original $target value in those cases
Loading
Loading
@@ -194,7 +195,7 @@ const JumpToDiscussion = Vue.extend({
prevEl = $target.prev();
 
// If the discussion doesn't have 4 lines above it, we'll have to do with fewer.
if (!prevEl.hasClass("line_holder")) {
if (!prevEl.hasClass('line_holder')) {
break;
}
 
Loading
Loading
@@ -203,9 +204,9 @@ const JumpToDiscussion = Vue.extend({
}
 
$.scrollTo($target, {
offset: -150
offset: -150,
});
}
},
},
});
 
Loading
Loading
Loading
Loading
@@ -13,17 +13,17 @@ window.ResolveCount = Vue.extend({
required: true,
},
},
data: function () {
data: function() {
return {
discussions: CommentsStore.state
discussions: CommentsStore.state,
};
},
computed: {
allResolved: function () {
allResolved: function() {
return this.resolvedDiscussionCount === this.discussionCount;
},
resolvedCountText() {
return this.discussionCount === 1 ? 'discussion' : 'discussions';
}
}
},
},
});
Loading
Loading
@@ -2,10 +2,10 @@
 
const DiscussionMixins = {
computed: {
discussionCount: function () {
discussionCount: function() {
return Object.keys(this.discussions).length;
},
resolvedDiscussionCount: function () {
resolvedDiscussionCount: function() {
let resolvedCount = 0;
 
for (const discussionId in this.discussions) {
Loading
Loading
@@ -18,7 +18,7 @@ const DiscussionMixins = {
 
return resolvedCount;
},
unresolvedDiscussionCount: function () {
unresolvedDiscussionCount: function() {
let unresolvedCount = 0;
 
for (const discussionId in this.discussions) {
Loading
Loading
@@ -30,8 +30,8 @@ const DiscussionMixins = {
}
 
return unresolvedCount;
}
}
},
},
};
 
export default DiscussionMixins;
Loading
Loading
@@ -6,22 +6,22 @@ import Vue from 'vue';
import { localTimeAgo } from '../../lib/utils/datetime_utility';
 
class DiscussionModel {
constructor (discussionId) {
constructor(discussionId) {
this.id = discussionId;
this.notes = {};
this.loading = false;
this.canResolve = false;
}
 
createNote (noteObj) {
createNote(noteObj) {
Vue.set(this.notes, noteObj.noteId, new NoteModel(this.id, noteObj));
}
 
deleteNote (noteId) {
deleteNote(noteId) {
Vue.delete(this.notes, noteId);
}
 
getNote (noteId) {
getNote(noteId) {
return this.notes[noteId];
}
 
Loading
Loading
@@ -29,7 +29,7 @@ class DiscussionModel {
return Object.keys(this.notes).length;
}
 
isResolved () {
isResolved() {
for (const noteId in this.notes) {
const note = this.notes[noteId];
 
Loading
Loading
@@ -40,7 +40,7 @@ class DiscussionModel {
return true;
}
 
resolveAllNotes (resolved_by) {
resolveAllNotes(resolved_by) {
for (const noteId in this.notes) {
const note = this.notes[noteId];
 
Loading
Loading
@@ -51,7 +51,7 @@ class DiscussionModel {
}
}
 
unResolveAllNotes () {
unResolveAllNotes() {
for (const noteId in this.notes) {
const note = this.notes[noteId];
 
Loading
Loading
@@ -62,7 +62,7 @@ class DiscussionModel {
}
}
 
updateHeadline (data) {
updateHeadline(data) {
const discussionSelector = `.discussion[data-discussion-id="${this.id}"]`;
const $discussionHeadline = $(`${discussionSelector} .js-discussion-headline`);
 
Loading
Loading
@@ -79,7 +79,7 @@ class DiscussionModel {
}
}
 
isResolvable () {
isResolvable() {
if (!this.canResolve) {
return false;
}
Loading
Loading
Loading
Loading
@@ -5,10 +5,10 @@ import Vue from 'vue';
 
window.CommentsStore = {
state: {},
get: function (discussionId, noteId) {
get: function(discussionId, noteId) {
return this.state[discussionId].getNote(noteId);
},
createDiscussion: function (discussionId, canResolve) {
createDiscussion: function(discussionId, canResolve) {
let discussion = this.state[discussionId];
if (!this.state[discussionId]) {
discussion = new DiscussionModel(discussionId);
Loading
Loading
@@ -21,18 +21,18 @@ window.CommentsStore = {
 
return discussion;
},
create: function (noteObj) {
create: function(noteObj) {
const discussion = this.createDiscussion(noteObj.discussionId);
 
discussion.createNote(noteObj);
},
update: function (discussionId, noteId, resolved, resolved_by) {
update: function(discussionId, noteId, resolved, resolved_by) {
const discussion = this.state[discussionId];
const note = discussion.getNote(noteId);
note.resolved = resolved;
note.resolved_by = resolved_by;
},
delete: function (discussionId, noteId) {
delete: function(discussionId, noteId) {
const discussion = this.state[discussionId];
discussion.deleteNote(noteId);
 
Loading
Loading
@@ -40,7 +40,7 @@ window.CommentsStore = {
Vue.delete(this.state, discussionId);
}
},
unresolvedDiscussionIds: function () {
unresolvedDiscussionIds: function() {
const ids = [];
 
for (const discussionId in this.state) {
Loading
Loading
@@ -52,5 +52,5 @@ window.CommentsStore = {
}
 
return ids;
}
},
};
Loading
Loading
@@ -43,7 +43,9 @@ export default {
return (this.commit.author && this.commit.author.name) || this.commit.authorName;
},
authorUrl() {
return (this.commit.author && this.commit.author.webUrl) || `mailto:${this.commit.authorEmail}`;
return (
(this.commit.author && this.commit.author.webUrl) || `mailto:${this.commit.authorEmail}`
);
},
authorAvatar() {
return (this.commit.author && this.commit.author.avatarUrl) || this.commit.authorGravatarUrl;
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment