summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2017-12-05 13:29:41 +0100
committerKamil Trzcinski <ayufan@ayufan.eu>2017-12-05 13:29:41 +0100
commit9429514e303bdceee0621b5c4bf02ad8ca0a7add (patch)
treea7bc5cc425601c4ea73ff9a9be90eebc21a93b17 /app/assets
parentb9d8d85e20af046c7dbe11c69fd3252f0486b9b2 (diff)
parent3138fcdcd70fd30fea74deff537b9836d6c94d21 (diff)
downloadgitlab-ce-9429514e303bdceee0621b5c4bf02ad8ca0a7add.tar.gz
Merge branch '35616-move-k8-to-cluster-page' into cluster-page-with-list-clusters
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/boards/models/issue.js5
-rw-r--r--app/assets/javascripts/commons/index.js1
-rw-r--r--app/assets/javascripts/gl_dropdown.js3
-rw-r--r--app/assets/javascripts/notes/components/discussion_locked_widget.vue (renamed from app/assets/javascripts/notes/components/issue_discussion_locked_widget.vue)10
-rw-r--r--app/assets/javascripts/notes/components/issue_comment_form.vue15
-rw-r--r--app/assets/javascripts/notes/components/issue_discussion.vue22
-rw-r--r--app/assets/javascripts/notes/components/issue_note.vue12
-rw-r--r--app/assets/javascripts/notes/components/issue_note_body.vue18
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue (renamed from app/assets/javascripts/notes/components/issue_note_actions.vue)6
-rw-r--r--app/assets/javascripts/notes/components/note_attachment.vue (renamed from app/assets/javascripts/notes/components/issue_note_attachment.vue)2
-rw-r--r--app/assets/javascripts/notes/components/note_awards_list.vue (renamed from app/assets/javascripts/notes/components/issue_note_awards_list.vue)0
-rw-r--r--app/assets/javascripts/notes/components/note_edited_text.vue (renamed from app/assets/javascripts/notes/components/issue_note_edited_text.vue)0
-rw-r--r--app/assets/javascripts/notes/components/note_header.vue (renamed from app/assets/javascripts/notes/components/issue_note_header.vue)0
-rw-r--r--app/assets/javascripts/notes/components/note_signed_out_widget.vue (renamed from app/assets/javascripts/notes/components/issue_note_signed_out_widget.vue)1
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_component.vue9
-rw-r--r--app/assets/javascripts/right_sidebar.js6
-rw-r--r--app/assets/javascripts/sidebar/components/lock/edit_form.vue9
-rw-r--r--app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue9
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js104
-rw-r--r--app/assets/javascripts/sidebar/sidebar_bundle.js102
-rw-r--r--app/assets/javascripts/sidebar/sidebar_mediator.js34
-rw-r--r--app/assets/javascripts/sidebar/stores/sidebar_store.js5
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/system_note.vue8
-rw-r--r--app/assets/javascripts/vue_shared/mixins/issuable.js13
-rw-r--r--app/assets/stylesheets/framework/common.scss1
-rw-r--r--app/assets/stylesheets/framework/gfm.scss1
-rw-r--r--app/assets/stylesheets/framework/wells.scss5
-rw-r--r--app/assets/stylesheets/pages/issuable.scss13
-rw-r--r--app/assets/stylesheets/pages/notes.scss9
-rw-r--r--app/assets/stylesheets/pages/profile.scss2
-rw-r--r--app/assets/stylesheets/pages/projects.scss1
-rw-r--r--app/assets/stylesheets/pages/wiki.scss6
32 files changed, 243 insertions, 189 deletions
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index 10f85c1d676..81edd95bf2b 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -20,6 +20,7 @@ class ListIssue {
this.isFetching = {
subscriptions: true,
};
+ this.isLoading = {};
this.sidebarInfoEndpoint = obj.issue_sidebar_endpoint;
this.toggleSubscriptionEndpoint = obj.toggle_subscription_endpoint;
@@ -86,6 +87,10 @@ class ListIssue {
this.isFetching[key] = value;
}
+ setLoadingState(key, value) {
+ this.isLoading[key] = value;
+ }
+
update (url) {
const data = {
issue: {
diff --git a/app/assets/javascripts/commons/index.js b/app/assets/javascripts/commons/index.js
index 768453b28f1..0d2fe2925d8 100644
--- a/app/assets/javascripts/commons/index.js
+++ b/app/assets/javascripts/commons/index.js
@@ -3,3 +3,4 @@ import './polyfills';
import './jquery';
import './bootstrap';
import './vue';
+import '../lib/utils/axios_utils';
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index 4e7a6e54f90..7ca783d3af6 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -514,10 +514,11 @@ GitLabDropdown = (function() {
const dropdownToggle = this.dropdown.find('.dropdown-menu-toggle');
const hasFilterBulkUpdate = dropdownToggle.hasClass('js-filter-bulk-update');
+ const shouldRefreshOnOpen = dropdownToggle.hasClass('js-gl-dropdown-refresh-on-open');
const hasMultiSelect = dropdownToggle.hasClass('js-multiselect');
// Makes indeterminate items effective
- if (this.fullData && hasFilterBulkUpdate) {
+ if (this.fullData && (shouldRefreshOnOpen || hasFilterBulkUpdate)) {
this.parseData(this.fullData);
}
diff --git a/app/assets/javascripts/notes/components/issue_discussion_locked_widget.vue b/app/assets/javascripts/notes/components/discussion_locked_widget.vue
index 64466b04b40..e6f7ee56ff3 100644
--- a/app/assets/javascripts/notes/components/issue_discussion_locked_widget.vue
+++ b/app/assets/javascripts/notes/components/discussion_locked_widget.vue
@@ -1,8 +1,12 @@
<script>
- import Icon from '../../vue_shared/components/icon.vue';
+ import Icon from '~/vue_shared/components/icon.vue';
+ import Issuable from '~/vue_shared/mixins/issuable';
export default {
- component: {
+ mixins: [
+ Issuable,
+ ],
+ components: {
Icon,
},
};
@@ -16,7 +20,7 @@
:size="16"
class="icon">
</icon>
- <span>This issue is locked. Only <b>project members</b> can comment.</span>
+ <span>This {{ issuableDisplayName }} is locked. Only <b>project members</b> can comment.</span>
</span>
</div>
</template>
diff --git a/app/assets/javascripts/notes/components/issue_comment_form.vue b/app/assets/javascripts/notes/components/issue_comment_form.vue
index dbc900f4c04..78986a450c2 100644
--- a/app/assets/javascripts/notes/components/issue_comment_form.vue
+++ b/app/assets/javascripts/notes/components/issue_comment_form.vue
@@ -8,8 +8,8 @@
import * as constants from '../constants';
import eventHub from '../event_hub';
import issueWarning from '../../vue_shared/components/issue/issue_warning.vue';
- import issueNoteSignedOutWidget from './issue_note_signed_out_widget.vue';
- import issueDiscussionLockedWidget from './issue_discussion_locked_widget.vue';
+ import noteSignedOutWidget from './note_signed_out_widget.vue';
+ import discussionLockedWidget from './discussion_locked_widget.vue';
import markdownField from '../../vue_shared/components/markdown/field.vue';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import issuableStateMixin from '../mixins/issuable_state';
@@ -29,8 +29,8 @@
},
components: {
issueWarning,
- issueNoteSignedOutWidget,
- issueDiscussionLockedWidget,
+ noteSignedOutWidget,
+ discussionLockedWidget,
markdownField,
userAvatarLink,
},
@@ -240,8 +240,11 @@
<template>
<div>
- <issue-note-signed-out-widget v-if="!isLoggedIn" />
- <issue-discussion-locked-widget v-else-if="!canCreateNote" />
+ <note-signed-out-widget v-if="!isLoggedIn" />
+ <discussion-locked-widget
+ issuable-type="issue"
+ v-else-if="!canCreateNote"
+ />
<ul
v-else
class="notes notes-form timeline">
diff --git a/app/assets/javascripts/notes/components/issue_discussion.vue b/app/assets/javascripts/notes/components/issue_discussion.vue
index 26f729d8875..460fde9b62a 100644
--- a/app/assets/javascripts/notes/components/issue_discussion.vue
+++ b/app/assets/javascripts/notes/components/issue_discussion.vue
@@ -4,10 +4,9 @@
import { SYSTEM_NOTE } from '../constants';
import issueNote from './issue_note.vue';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
- import issueNoteHeader from './issue_note_header.vue';
- import issueNoteActions from './issue_note_actions.vue';
- import issueNoteSignedOutWidget from './issue_note_signed_out_widget.vue';
- import issueNoteEditedText from './issue_note_edited_text.vue';
+ import noteHeader from './note_header.vue';
+ import noteSignedOutWidget from './note_signed_out_widget.vue';
+ import noteEditedText from './note_edited_text.vue';
import issueNoteForm from './issue_note_form.vue';
import placeholderNote from '../../vue_shared/components/notes/placeholder_note.vue';
import placeholderSystemNote from '../../vue_shared/components/notes/placeholder_system_note.vue';
@@ -28,10 +27,9 @@
components: {
issueNote,
userAvatarLink,
- issueNoteHeader,
- issueNoteActions,
- issueNoteSignedOutWidget,
- issueNoteEditedText,
+ noteHeader,
+ noteSignedOutWidget,
+ noteEditedText,
issueNoteForm,
placeholderNote,
placeholderSystemNote,
@@ -171,7 +169,7 @@
<div class="timeline-content">
<div class="discussion">
<div class="discussion-header">
- <issue-note-header
+ <note-header
:author="author"
:created-at="discussion.created_at"
:note-id="discussion.id"
@@ -179,8 +177,8 @@
@toggleHandler="toggleDiscussionHandler"
action-text="started a discussion"
class="discussion"
- />
- <issue-note-edited-text
+ />
+ <note-edited-text
v-if="lastUpdatedAt"
:edited-at="lastUpdatedAt"
:edited-by="lastUpdatedBy"
@@ -220,7 +218,7 @@
@cancelFormEdition="cancelReplyForm"
ref="noteForm"
/>
- <issue-note-signed-out-widget v-if="!canReply" />
+ <note-signed-out-widget v-if="!canReply" />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/notes/components/issue_note.vue b/app/assets/javascripts/notes/components/issue_note.vue
index 40318f9a600..8c81c5d6df3 100644
--- a/app/assets/javascripts/notes/components/issue_note.vue
+++ b/app/assets/javascripts/notes/components/issue_note.vue
@@ -2,8 +2,8 @@
import { mapGetters, mapActions } from 'vuex';
import Flash from '../../flash';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
- import issueNoteHeader from './issue_note_header.vue';
- import issueNoteActions from './issue_note_actions.vue';
+ import noteHeader from './note_header.vue';
+ import noteActions from './note_actions.vue';
import issueNoteBody from './issue_note_body.vue';
import eventHub from '../event_hub';
@@ -23,8 +23,8 @@
},
components: {
userAvatarLink,
- issueNoteHeader,
- issueNoteActions,
+ noteHeader,
+ noteActions,
issueNoteBody,
},
computed: {
@@ -155,13 +155,13 @@
</div>
<div class="timeline-content">
<div class="note-header">
- <issue-note-header
+ <note-header
:author="author"
:created-at="note.created_at"
:note-id="note.id"
action-text="commented"
/>
- <issue-note-actions
+ <note-actions
:author-id="author.id"
:note-id="note.id"
:access-level="note.human_access"
diff --git a/app/assets/javascripts/notes/components/issue_note_body.vue b/app/assets/javascripts/notes/components/issue_note_body.vue
index 5f9003bfd87..a16c5f6a785 100644
--- a/app/assets/javascripts/notes/components/issue_note_body.vue
+++ b/app/assets/javascripts/notes/components/issue_note_body.vue
@@ -1,7 +1,7 @@
<script>
- import issueNoteEditedText from './issue_note_edited_text.vue';
- import issueNoteAwardsList from './issue_note_awards_list.vue';
- import issueNoteAttachment from './issue_note_attachment.vue';
+ import noteEditedText from './note_edited_text.vue';
+ import noteAwardsList from './note_awards_list.vue';
+ import noteAttachment from './note_attachment.vue';
import issueNoteForm from './issue_note_form.vue';
import TaskList from '../../task_list';
import autosave from '../mixins/autosave';
@@ -26,9 +26,9 @@
autosave,
],
components: {
- issueNoteEditedText,
- issueNoteAwardsList,
- issueNoteAttachment,
+ noteEditedText,
+ noteAwardsList,
+ noteAttachment,
issueNoteForm,
},
computed: {
@@ -101,20 +101,20 @@
v-model="note.note"
:data-update-url="note.path"
class="hidden js-task-list-field"></textarea>
- <issue-note-edited-text
+ <note-edited-text
v-if="note.last_edited_at"
:edited-at="note.last_edited_at"
:edited-by="note.last_edited_by"
action-text="Edited"
/>
- <issue-note-awards-list
+ <note-awards-list
v-if="note.award_emoji.length"
:note-id="note.id"
:note-author-id="note.author.id"
:awards="note.award_emoji"
:toggle-award-path="note.toggle_award_path"
/>
- <issue-note-attachment
+ <note-attachment
v-if="note.attachment"
:attachment="note.attachment"
/>
diff --git a/app/assets/javascripts/notes/components/issue_note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index feb3e73194b..45fc6196be4 100644
--- a/app/assets/javascripts/notes/components/issue_note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -5,11 +5,11 @@
import emojiSmiley from 'icons/_emoji_smiley.svg';
import editSvg from 'icons/_icon_pencil.svg';
import ellipsisSvg from 'icons/_ellipsis_v.svg';
- import loadingIcon from '../../vue_shared/components/loading_icon.vue';
- import tooltip from '../../vue_shared/directives/tooltip';
+ import loadingIcon from '~/vue_shared/components/loading_icon.vue';
+ import tooltip from '~/vue_shared/directives/tooltip';
export default {
- name: 'issueNoteActions',
+ name: 'noteActions',
props: {
authorId: {
type: Number,
diff --git a/app/assets/javascripts/notes/components/issue_note_attachment.vue b/app/assets/javascripts/notes/components/note_attachment.vue
index 7134a3eb47e..cd9571a4002 100644
--- a/app/assets/javascripts/notes/components/issue_note_attachment.vue
+++ b/app/assets/javascripts/notes/components/note_attachment.vue
@@ -1,6 +1,6 @@
<script>
export default {
- name: 'issueNoteAttachment',
+ name: 'noteAttachment',
props: {
attachment: {
type: Object,
diff --git a/app/assets/javascripts/notes/components/issue_note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue
index c3a340139e7..c3a340139e7 100644
--- a/app/assets/javascripts/notes/components/issue_note_awards_list.vue
+++ b/app/assets/javascripts/notes/components/note_awards_list.vue
diff --git a/app/assets/javascripts/notes/components/issue_note_edited_text.vue b/app/assets/javascripts/notes/components/note_edited_text.vue
index 49e09f0ecc5..49e09f0ecc5 100644
--- a/app/assets/javascripts/notes/components/issue_note_edited_text.vue
+++ b/app/assets/javascripts/notes/components/note_edited_text.vue
diff --git a/app/assets/javascripts/notes/components/issue_note_header.vue b/app/assets/javascripts/notes/components/note_header.vue
index 63aa3d777d0..63aa3d777d0 100644
--- a/app/assets/javascripts/notes/components/issue_note_header.vue
+++ b/app/assets/javascripts/notes/components/note_header.vue
diff --git a/app/assets/javascripts/notes/components/issue_note_signed_out_widget.vue b/app/assets/javascripts/notes/components/note_signed_out_widget.vue
index 77af3594c1c..45d3c2de355 100644
--- a/app/assets/javascripts/notes/components/issue_note_signed_out_widget.vue
+++ b/app/assets/javascripts/notes/components/note_signed_out_widget.vue
@@ -2,7 +2,6 @@
import { mapGetters } from 'vuex';
export default {
- name: 'singInLinksNotes',
computed: {
...mapGetters([
'getNotesDataByProp',
diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue
index 5dea4555515..08199b4234a 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue
@@ -78,11 +78,13 @@
<div class="ci-job-component">
<a
v-tooltip
- v-if="job.status.details_path"
+ v-if="job.status.has_details"
:href="job.status.details_path"
:title="tooltipText"
:class="cssClassJobName"
- data-container="body">
+ data-container="body"
+ class="js-pipeline-graph-job-link"
+ >
<job-name-component
:name="job.name"
@@ -95,7 +97,8 @@
v-tooltip
:title="tooltipText"
:class="cssClassJobName"
- data-container="body">
+ data-container="body"
+ >
<job-name-component
:name="job.name"
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index a41548bd694..fa7f6825d7e 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -15,7 +15,7 @@ import Cookies from 'js-cookie';
Sidebar.prototype.removeListeners = function () {
this.sidebar.off('click', '.sidebar-collapsed-icon');
- $('.dropdown').off('hidden.gl.dropdown');
+ this.sidebar.off('hidden.gl.dropdown');
$('.dropdown').off('loading.gl.dropdown');
$('.dropdown').off('loaded.gl.dropdown');
$(document).off('click', '.js-sidebar-toggle');
@@ -25,7 +25,7 @@ import Cookies from 'js-cookie';
const $document = $(document);
this.sidebar.on('click', '.sidebar-collapsed-icon', this, this.sidebarCollapseClicked);
- $('.dropdown').on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden);
+ this.sidebar.on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden);
$('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading);
$('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded);
@@ -180,7 +180,7 @@ import Cookies from 'js-cookie';
var $block, sidebar;
sidebar = e.data;
e.preventDefault();
- $block = $(this).closest('.block');
+ $block = $(e.target).closest('.block');
return sidebar.sidebarDropdownHidden($block);
};
diff --git a/app/assets/javascripts/sidebar/components/lock/edit_form.vue b/app/assets/javascripts/sidebar/components/lock/edit_form.vue
index c7a6edc7c70..242e826d471 100644
--- a/app/assets/javascripts/sidebar/components/lock/edit_form.vue
+++ b/app/assets/javascripts/sidebar/components/lock/edit_form.vue
@@ -18,11 +18,6 @@ export default {
required: true,
type: Function,
},
-
- issuableType: {
- required: true,
- type: String,
- },
},
mixins: [
@@ -39,13 +34,13 @@ export default {
<div class="dropdown open">
<div class="dropdown-menu sidebar-item-warning-message">
<p class="text" v-if="isLocked">
- Unlock this {{ issuableDisplayName(issuableType) }}?
+ Unlock this {{ issuableDisplayName }}?
<strong>Everyone</strong>
will be able to comment.
</p>
<p class="text" v-else>
- Lock this {{ issuableDisplayName(issuableType) }}?
+ Lock this {{ issuableDisplayName }}?
Only
<strong>project members</strong>
will be able to comment.
diff --git a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue
index 9aff53cf8af..04c3a96bf74 100644
--- a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue
+++ b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue
@@ -23,11 +23,6 @@ export default {
return mediatorObject.service && mediatorObject.service.update && mediatorObject.store;
},
},
-
- issuableType: {
- required: true,
- type: String,
- },
},
mixins: [
@@ -59,7 +54,7 @@ export default {
discussion_locked: locked,
})
.then(() => location.reload())
- .catch(() => Flash(this.__(`Something went wrong trying to change the locked state of this ${this.issuableDisplayName(this.issuableType)}`)));
+ .catch(() => Flash(this.__(`Something went wrong trying to change the locked state of this ${this.issuableDisplayName}`)));
},
},
};
@@ -77,7 +72,7 @@ export default {
</div>
<div class="title hide-collapsed">
- Lock {{issuableDisplayName(issuableType) }}
+ Lock {{ issuableDisplayName }}
<button
v-if="isEditable"
class="pull-right lock-edit btn btn-blank"
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
new file mode 100644
index 00000000000..4032f156b15
--- /dev/null
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -0,0 +1,104 @@
+import Vue from 'vue';
+import SidebarTimeTracking from './components/time_tracking/sidebar_time_tracking';
+import SidebarAssignees from './components/assignees/sidebar_assignees';
+import ConfidentialIssueSidebar from './components/confidential/confidential_issue_sidebar.vue';
+import SidebarMoveIssue from './lib/sidebar_move_issue';
+import LockIssueSidebar from './components/lock/lock_issue_sidebar.vue';
+import sidebarParticipants from './components/participants/sidebar_participants.vue';
+import sidebarSubscriptions from './components/subscriptions/sidebar_subscriptions.vue';
+import Translate from '../vue_shared/translate';
+
+Vue.use(Translate);
+
+function mountConfidentialComponent(mediator) {
+ const el = document.getElementById('js-confidential-entry-point');
+
+ if (!el) return;
+
+ const dataNode = document.getElementById('js-confidential-issue-data');
+ const initialData = JSON.parse(dataNode.innerHTML);
+
+ const ConfidentialComp = Vue.extend(ConfidentialIssueSidebar);
+
+ new ConfidentialComp({
+ propsData: {
+ isConfidential: initialData.is_confidential,
+ isEditable: initialData.is_editable,
+ service: mediator.service,
+ },
+ }).$mount(el);
+}
+
+function mountLockComponent(mediator) {
+ const el = document.getElementById('js-lock-entry-point');
+
+ if (!el) return;
+
+ const dataNode = document.getElementById('js-lock-issue-data');
+ const initialData = JSON.parse(dataNode.innerHTML);
+
+ const LockComp = Vue.extend(LockIssueSidebar);
+
+ new LockComp({
+ propsData: {
+ isLocked: initialData.is_locked,
+ isEditable: initialData.is_editable,
+ mediator,
+ issuableType: gl.utils.isInIssuePage() ? 'issue' : 'merge_request',
+ },
+ }).$mount(el);
+}
+
+function mountParticipantsComponent() {
+ const el = document.querySelector('.js-sidebar-participants-entry-point');
+
+ if (!el) return;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ sidebarParticipants,
+ },
+ render: createElement => createElement('sidebar-participants', {}),
+ });
+}
+
+function mountSubscriptionsComponent() {
+ const el = document.querySelector('.js-sidebar-subscriptions-entry-point');
+
+ if (!el) return;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ sidebarSubscriptions,
+ },
+ render: createElement => createElement('sidebar-subscriptions', {}),
+ });
+}
+
+function mount(mediator) {
+ const sidebarAssigneesEl = document.getElementById('js-vue-sidebar-assignees');
+ // Only create the sidebarAssignees vue app if it is found in the DOM
+ // We currently do not use sidebarAssignees for the MR page
+ if (sidebarAssigneesEl) {
+ new Vue(SidebarAssignees).$mount(sidebarAssigneesEl);
+ }
+
+ mountConfidentialComponent(mediator);
+ mountLockComponent(mediator);
+ mountParticipantsComponent();
+ mountSubscriptionsComponent();
+
+ new SidebarMoveIssue(
+ mediator,
+ $('.js-move-issue'),
+ $('.js-move-issue-confirmation-button'),
+ ).init();
+
+ new Vue(SidebarTimeTracking).$mount('#issuable-time-tracker');
+}
+
+export default mount;
diff --git a/app/assets/javascripts/sidebar/sidebar_bundle.js b/app/assets/javascripts/sidebar/sidebar_bundle.js
index 2650bb725d4..f78287e504b 100644
--- a/app/assets/javascripts/sidebar/sidebar_bundle.js
+++ b/app/assets/javascripts/sidebar/sidebar_bundle.js
@@ -1,110 +1,12 @@
-import Vue from 'vue';
-import SidebarTimeTracking from './components/time_tracking/sidebar_time_tracking';
-import SidebarAssignees from './components/assignees/sidebar_assignees';
-import ConfidentialIssueSidebar from './components/confidential/confidential_issue_sidebar.vue';
-import SidebarMoveIssue from './lib/sidebar_move_issue';
-import LockIssueSidebar from './components/lock/lock_issue_sidebar.vue';
-import sidebarParticipants from './components/participants/sidebar_participants.vue';
-import sidebarSubscriptions from './components/subscriptions/sidebar_subscriptions.vue';
-import Translate from '../vue_shared/translate';
-
import Mediator from './sidebar_mediator';
-
-Vue.use(Translate);
-
-function mountConfidentialComponent(mediator) {
- const el = document.getElementById('js-confidential-entry-point');
-
- if (!el) return;
-
- const dataNode = document.getElementById('js-confidential-issue-data');
- const initialData = JSON.parse(dataNode.innerHTML);
-
- const ConfidentialComp = Vue.extend(ConfidentialIssueSidebar);
-
- new ConfidentialComp({
- propsData: {
- isConfidential: initialData.is_confidential,
- isEditable: initialData.is_editable,
- service: mediator.service,
- },
- }).$mount(el);
-}
-
-function mountLockComponent(mediator) {
- const el = document.getElementById('js-lock-entry-point');
-
- if (!el) return;
-
- const dataNode = document.getElementById('js-lock-issue-data');
- const initialData = JSON.parse(dataNode.innerHTML);
-
- const LockComp = Vue.extend(LockIssueSidebar);
-
- new LockComp({
- propsData: {
- isLocked: initialData.is_locked,
- isEditable: initialData.is_editable,
- mediator,
- issuableType: gl.utils.isInIssuePage() ? 'issue' : 'merge_request',
- },
- }).$mount(el);
-}
-
-function mountParticipantsComponent() {
- const el = document.querySelector('.js-sidebar-participants-entry-point');
-
- if (!el) return;
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- components: {
- sidebarParticipants,
- },
- render: createElement => createElement('sidebar-participants', {}),
- });
-}
-
-function mountSubscriptionsComponent() {
- const el = document.querySelector('.js-sidebar-subscriptions-entry-point');
-
- if (!el) return;
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- components: {
- sidebarSubscriptions,
- },
- render: createElement => createElement('sidebar-subscriptions', {}),
- });
-}
+import mountSidebar from './mount_sidebar';
function domContentLoaded() {
const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
const mediator = new Mediator(sidebarOptions);
mediator.fetch();
- const sidebarAssigneesEl = document.getElementById('js-vue-sidebar-assignees');
- // Only create the sidebarAssignees vue app if it is found in the DOM
- // We currently do not use sidebarAssignees for the MR page
- if (sidebarAssigneesEl) {
- new Vue(SidebarAssignees).$mount(sidebarAssigneesEl);
- }
-
- mountConfidentialComponent(mediator);
- mountLockComponent(mediator);
- mountParticipantsComponent();
- mountSubscriptionsComponent();
-
- new SidebarMoveIssue(
- mediator,
- $('.js-move-issue'),
- $('.js-move-issue-confirmation-button'),
- ).init();
-
- new Vue(SidebarTimeTracking).$mount('#issuable-time-tracker');
+ mountSidebar(mediator);
}
document.addEventListener('DOMContentLoaded', domContentLoaded);
diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js
index 2bda5a47791..d4c07a188b3 100644
--- a/app/assets/javascripts/sidebar/sidebar_mediator.js
+++ b/app/assets/javascripts/sidebar/sidebar_mediator.js
@@ -5,19 +5,23 @@ import Store from './stores/sidebar_store';
export default class SidebarMediator {
constructor(options) {
if (!SidebarMediator.singleton) {
- this.store = new Store(options);
- this.service = new Service({
- endpoint: options.endpoint,
- toggleSubscriptionEndpoint: options.toggleSubscriptionEndpoint,
- moveIssueEndpoint: options.moveIssueEndpoint,
- projectsAutocompleteEndpoint: options.projectsAutocompleteEndpoint,
- });
- SidebarMediator.singleton = this;
+ this.initSingleton(options);
}
return SidebarMediator.singleton;
}
+ initSingleton(options) {
+ this.store = new Store(options);
+ this.service = new Service({
+ endpoint: options.endpoint,
+ toggleSubscriptionEndpoint: options.toggleSubscriptionEndpoint,
+ moveIssueEndpoint: options.moveIssueEndpoint,
+ projectsAutocompleteEndpoint: options.projectsAutocompleteEndpoint,
+ });
+ SidebarMediator.singleton = this;
+ }
+
assignYourself() {
this.store.addAssignee(this.store.currentUser);
}
@@ -35,17 +39,21 @@ export default class SidebarMediator {
}
fetch() {
- this.service.get()
+ return this.service.get()
.then(response => response.json())
.then((data) => {
- this.store.setAssigneeData(data);
- this.store.setTimeTrackingData(data);
- this.store.setParticipantsData(data);
- this.store.setSubscriptionsData(data);
+ this.processFetchedData(data);
})
.catch(() => new Flash('Error occurred when fetching sidebar data'));
}
+ processFetchedData(data) {
+ this.store.setAssigneeData(data);
+ this.store.setTimeTrackingData(data);
+ this.store.setParticipantsData(data);
+ this.store.setSubscriptionsData(data);
+ }
+
toggleSubscription() {
this.store.setFetchingState('subscriptions', true);
return this.service.toggleSubscription()
diff --git a/app/assets/javascripts/sidebar/stores/sidebar_store.js b/app/assets/javascripts/sidebar/stores/sidebar_store.js
index 3150221b685..73eb25e2333 100644
--- a/app/assets/javascripts/sidebar/stores/sidebar_store.js
+++ b/app/assets/javascripts/sidebar/stores/sidebar_store.js
@@ -15,6 +15,7 @@ export default class SidebarStore {
participants: true,
subscriptions: true,
};
+ this.isLoading = {};
this.autocompleteProjects = [];
this.moveToProjectId = 0;
this.isLockDialogOpen = false;
@@ -55,6 +56,10 @@ export default class SidebarStore {
this.isFetching[key] = value;
}
+ setLoadingState(key, value) {
+ this.isLoading[key] = value;
+ }
+
addAssignee(assignee) {
if (!this.findAssignee(assignee)) {
this.assignees.push(assignee);
diff --git a/app/assets/javascripts/vue_shared/components/notes/system_note.vue b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
index 98f8f32557d..2248699c399 100644
--- a/app/assets/javascripts/vue_shared/components/notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
@@ -17,7 +17,7 @@
* />
*/
import { mapGetters } from 'vuex';
- import issueNoteHeader from '../../../notes/components/issue_note_header.vue';
+ import noteHeader from '~/notes/components/note_header.vue';
import { spriteIcon } from '../../../lib/utils/common_utils';
export default {
@@ -29,7 +29,7 @@
},
},
components: {
- issueNoteHeader,
+ noteHeader,
},
computed: {
...mapGetters([
@@ -60,12 +60,12 @@
</div>
<div class="timeline-content">
<div class="note-header">
- <issue-note-header
+ <note-header
:author="note.author"
:created-at="note.created_at"
:note-id="note.id"
:action-text-html="note.note_html"
- />
+ />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/mixins/issuable.js b/app/assets/javascripts/vue_shared/mixins/issuable.js
index 263361587e0..fab0919d96e 100644
--- a/app/assets/javascripts/vue_shared/mixins/issuable.js
+++ b/app/assets/javascripts/vue_shared/mixins/issuable.js
@@ -1,9 +1,14 @@
export default {
- methods: {
- issuableDisplayName(issuableType) {
- const displayName = issuableType.replace(/_/, ' ');
+ props: {
+ issuableType: {
+ required: true,
+ type: String,
+ },
+ },
- return this.__ ? this.__(displayName) : displayName;
+ computed: {
+ issuableDisplayName() {
+ return this.issuableType.replace(/_/g, ' ');
},
},
};
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index cb1aad90a9c..a42fab50db5 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -39,7 +39,6 @@
color: $brand-info;
}
-.underlined-link { text-decoration: underline; }
.hint { font-style: italic; color: $hint-color; }
.light { color: $common-gray; }
diff --git a/app/assets/stylesheets/framework/gfm.scss b/app/assets/stylesheets/framework/gfm.scss
index 34a35734acc..5621505996d 100644
--- a/app/assets/stylesheets/framework/gfm.scss
+++ b/app/assets/stylesheets/framework/gfm.scss
@@ -14,6 +14,5 @@
&:hover {
background-color: $user-mention-bg-hover;
- text-decoration: none;
}
}
diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss
index 68824ff8418..735fc4babd7 100644
--- a/app/assets/stylesheets/framework/wells.scss
+++ b/app/assets/stylesheets/framework/wells.scss
@@ -20,6 +20,11 @@
.ref-name {
font-size: 12px;
+
+ &:hover {
+ text-decoration: underline;
+ color: $gl-text-color;
+ }
}
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 63c51747f92..b33825a506e 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -110,6 +110,10 @@
padding: 6px 10px;
border-radius: $label-border-radius;
}
+
+ &:hover .color-label {
+ text-decoration: underline;
+ }
}
&.has-labels {
@@ -174,6 +178,14 @@
color: $gray-darkest;
}
}
+
+ &.assignee {
+ .author_link:hover {
+ .author {
+ text-decoration: underline;
+ }
+ }
+ }
}
.block-first {
@@ -468,7 +480,6 @@
a:not(.btn-retry) {
&:hover {
color: $md-link-color;
- text-decoration: none;
.avatar {
border-color: rgba($avatar-border, .2);
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 4fe182c9fce..a6009ab328e 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -208,7 +208,6 @@ ul.notes {
a {
color: $gl-link-color;
- text-decoration: none;
}
p {
@@ -395,6 +394,10 @@ ul.notes {
&:focus,
&:hover {
text-decoration: none;
+
+ .note-header-author-name {
+ text-decoration: underline;
+ }
}
}
@@ -461,6 +464,10 @@ ul.notes {
.system-note-message {
white-space: normal;
}
+
+ a:hover {
+ text-decoration: underline;
+ }
}
/**
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 28dc71dc641..ac745019319 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -73,7 +73,7 @@
.profile-link-holder {
display: inline;
- a {
+ a:not(.text-link) {
text-decoration: none;
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 2856af37f8d..a88a650fb8f 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -724,6 +724,7 @@ a.deploy-project-label {
&:hover,
&:focus {
color: $gl-text-color;
+ text-decoration: underline;
}
}
}
diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss
index e150f96f3fa..d8fec583121 100644
--- a/app/assets/stylesheets/pages/wiki.scss
+++ b/app/assets/stylesheets/pages/wiki.scss
@@ -124,7 +124,11 @@
&:hover,
&.active {
- color: $black;
+ text-decoration: none;
+
+ span {
+ text-decoration: underline;
+ }
}
}