Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-05 18:08:56 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-05 18:08:56 +0300
commit61265b9f01c7db3d4f6e1266d165b1c85be7b9e7 (patch)
treeb6589df984e18e3b008a155c8d9ffcae75cf7c91 /app/assets/javascripts/notes
parent5460c19548d3d3d2ff764ceff05c2b72aa2d3a32 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/notes')
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter.vue14
-rw-r--r--app/assets/javascripts/notes/components/notes_app.vue5
-rw-r--r--app/assets/javascripts/notes/components/sort_discussion.vue7
-rw-r--r--app/assets/javascripts/notes/components/timeline_toggle.vue55
-rw-r--r--app/assets/javascripts/notes/constants.js3
-rw-r--r--app/assets/javascripts/notes/index.js2
-rw-r--r--app/assets/javascripts/notes/stores/actions.js8
-rw-r--r--app/assets/javascripts/notes/stores/getters.js21
-rw-r--r--app/assets/javascripts/notes/stores/modules/index.js2
-rw-r--r--app/assets/javascripts/notes/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/notes/stores/mutations.js9
-rw-r--r--app/assets/javascripts/notes/timeline.js16
12 files changed, 131 insertions, 12 deletions
diff --git a/app/assets/javascripts/notes/components/discussion_filter.vue b/app/assets/javascripts/notes/components/discussion_filter.vue
index 0e7ed854032..e4b191b55a7 100644
--- a/app/assets/javascripts/notes/components/discussion_filter.vue
+++ b/app/assets/javascripts/notes/components/discussion_filter.vue
@@ -5,6 +5,7 @@ import { getLocationHash, doesHashExistInUrl } from '../../lib/utils/url_utility
import {
DISCUSSION_FILTERS_DEFAULT_VALUE,
HISTORY_ONLY_FILTER_VALUE,
+ COMMENTS_ONLY_FILTER_VALUE,
DISCUSSION_TAB_LABEL,
DISCUSSION_FILTER_TYPES,
NOTE_UNDERSCORE,
@@ -38,7 +39,7 @@ export default {
};
},
computed: {
- ...mapGetters(['getNotesDataByProp']),
+ ...mapGetters(['getNotesDataByProp', 'timelineEnabled']),
currentFilter() {
if (!this.currentValue) return this.filters[0];
return this.filters.find(filter => filter.value === this.currentValue);
@@ -63,11 +64,20 @@ export default {
window.removeEventListener('hashchange', this.handleLocationHash);
},
methods: {
- ...mapActions(['filterDiscussion', 'setCommentsDisabled', 'setTargetNoteHash']),
+ ...mapActions([
+ 'filterDiscussion',
+ 'setCommentsDisabled',
+ 'setTargetNoteHash',
+ 'setTimelineView',
+ ]),
selectFilter(value, persistFilter = true) {
const filter = parseInt(value, 10);
if (filter === this.currentValue) return;
+
+ if (this.timelineEnabled && filter !== COMMENTS_ONLY_FILTER_VALUE) {
+ this.setTimelineView(false);
+ }
this.currentValue = filter;
this.filterDiscussion({
path: this.getNotesDataByProp('discussionsPath'),
diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue
index fb18be9386e..9eaa4e422d5 100644
--- a/app/assets/javascripts/notes/components/notes_app.vue
+++ b/app/assets/javascripts/notes/components/notes_app.vue
@@ -73,6 +73,7 @@ export default {
'userCanReply',
'discussionTabCounter',
'sortDirection',
+ 'timelineEnabled',
]),
sortDirDesc() {
return this.sortDirection === constants.DESC;
@@ -95,7 +96,7 @@ export default {
return this.discussions;
},
canReply() {
- return this.userCanReply && !this.commentsDisabled;
+ return this.userCanReply && !this.commentsDisabled && !this.timelineEnabled;
},
slotKeys() {
return this.sortDirDesc ? ['form', 'comments'] : ['comments', 'form'];
@@ -252,7 +253,7 @@ export default {
<ordered-layout :slot-keys="slotKeys">
<template #form>
<comment-form
- v-if="!commentsDisabled"
+ v-if="!(commentsDisabled || timelineEnabled)"
class="js-comment-form"
:noteable-type="noteableType"
/>
diff --git a/app/assets/javascripts/notes/components/sort_discussion.vue b/app/assets/javascripts/notes/components/sort_discussion.vue
index 113c00ffe8e..c279a7107c7 100644
--- a/app/assets/javascripts/notes/components/sort_discussion.vue
+++ b/app/assets/javascripts/notes/components/sort_discussion.vue
@@ -20,7 +20,7 @@ export default {
},
mixins: [Tracking.mixin()],
computed: {
- ...mapGetters(['sortDirection', 'noteableType']),
+ ...mapGetters(['sortDirection', 'persistSortOrder', 'noteableType']),
selectedOption() {
return SORT_OPTIONS.find(({ key }) => this.sortDirection === key);
},
@@ -38,7 +38,7 @@ export default {
return;
}
- this.setDiscussionSortDirection(direction);
+ this.setDiscussionSortDirection({ direction });
this.track('change_discussion_sort_direction', { property: direction });
},
isDropdownItemActive(sortDir) {
@@ -53,7 +53,8 @@ export default {
<local-storage-sync
:value="sortDirection"
:storage-key="storageKey"
- @input="setDiscussionSortDirection"
+ :persist="persistSortOrder"
+ @input="setDiscussionSortDirection({ direction: $event })"
/>
<gl-dropdown
:text="dropdownText"
diff --git a/app/assets/javascripts/notes/components/timeline_toggle.vue b/app/assets/javascripts/notes/components/timeline_toggle.vue
new file mode 100644
index 00000000000..735dc5ff2a8
--- /dev/null
+++ b/app/assets/javascripts/notes/components/timeline_toggle.vue
@@ -0,0 +1,55 @@
+<script>
+import { GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { mapActions, mapGetters } from 'vuex';
+import { s__ } from '~/locale';
+import { COMMENTS_ONLY_FILTER_VALUE, DESC } from '../constants';
+import notesEventHub from '../event_hub';
+
+export const timelineEnabledTooltip = s__('Timeline|Turn timeline view off');
+export const timelineDisabledTooltip = s__('Timeline|Turn timeline view on');
+
+export default {
+ components: {
+ GlButton,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ computed: {
+ ...mapGetters(['timelineEnabled', 'sortDirection']),
+ tooltip() {
+ return this.timelineEnabled ? timelineEnabledTooltip : timelineDisabledTooltip;
+ },
+ },
+ methods: {
+ ...mapActions(['setTimelineView', 'setDiscussionSortDirection']),
+ setSort() {
+ if (this.timelineEnabled && this.sortDirection !== DESC) {
+ this.setDiscussionSortDirection({ direction: DESC, persist: false });
+ }
+ },
+ setFilter() {
+ notesEventHub.$emit('dropdownSelect', COMMENTS_ONLY_FILTER_VALUE, false);
+ },
+ toggleTimeline(event) {
+ event.currentTarget.blur();
+ this.setTimelineView(!this.timelineEnabled);
+ this.setSort();
+ this.setFilter();
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-button
+ v-gl-tooltip
+ icon="comments"
+ size="small"
+ :selected="timelineEnabled"
+ :title="tooltip"
+ :aria-label="tooltip"
+ class="gl-mr-3"
+ @click="toggleTimeline"
+ />
+</template>
diff --git a/app/assets/javascripts/notes/constants.js b/app/assets/javascripts/notes/constants.js
index b81aae7c257..7acf2ad57c8 100644
--- a/app/assets/javascripts/notes/constants.js
+++ b/app/assets/javascripts/notes/constants.js
@@ -14,8 +14,9 @@ export const MERGE_REQUEST_NOTEABLE_TYPE = 'MergeRequest';
export const UNRESOLVE_NOTE_METHOD_NAME = 'delete';
export const RESOLVE_NOTE_METHOD_NAME = 'post';
export const DESCRIPTION_TYPE = 'changed the description';
-export const HISTORY_ONLY_FILTER_VALUE = 2;
export const DISCUSSION_FILTERS_DEFAULT_VALUE = 0;
+export const COMMENTS_ONLY_FILTER_VALUE = 1;
+export const HISTORY_ONLY_FILTER_VALUE = 2;
export const DISCUSSION_TAB_LABEL = 'show';
export const NOTE_UNDERSCORE = 'note_';
export const TIME_DIFFERENCE_VALUE = 10;
diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js
index ca186123a83..3247a93f0a0 100644
--- a/app/assets/javascripts/notes/index.js
+++ b/app/assets/javascripts/notes/index.js
@@ -2,6 +2,7 @@ import Vue from 'vue';
import notesApp from './components/notes_app.vue';
import initDiscussionFilters from './discussion_filters';
import initSortDiscussions from './sort_discussions';
+import initTimelineToggle from './timeline';
import { store } from './stores';
document.addEventListener('DOMContentLoaded', () => {
@@ -59,4 +60,5 @@ document.addEventListener('DOMContentLoaded', () => {
initDiscussionFilters(store);
initSortDiscussions(store);
+ initTimelineToggle(store);
});
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 9c63a7e3cd4..37986c8a02d 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -99,8 +99,12 @@ export const updateDiscussion = ({ commit, state }, discussion) => {
return utils.findNoteObjectById(state.discussions, discussion.id);
};
-export const setDiscussionSortDirection = ({ commit }, direction) => {
- commit(types.SET_DISCUSSIONS_SORT, direction);
+export const setDiscussionSortDirection = ({ commit }, { direction, persist = true }) => {
+ commit(types.SET_DISCUSSIONS_SORT, { direction, persist });
+};
+
+export const setTimelineView = ({ commit }, enabled) => {
+ commit(types.SET_TIMELINE_VIEW, enabled);
};
export const setSelectedCommentPosition = ({ commit }, position) => {
diff --git a/app/assets/javascripts/notes/stores/getters.js b/app/assets/javascripts/notes/stores/getters.js
index fbdb71925ea..5b3ffa425a0 100644
--- a/app/assets/javascripts/notes/stores/getters.js
+++ b/app/assets/javascripts/notes/stores/getters.js
@@ -5,6 +5,23 @@ import { collapseSystemNotes } from './collapse_utils';
export const discussions = state => {
let discussionsInState = clone(state.discussions);
// NOTE: not testing bc will be removed when backend is finished.
+
+ if (state.isTimelineEnabled) {
+ discussionsInState = discussionsInState
+ .reduce((acc, discussion) => {
+ const transformedToIndividualNotes = discussion.notes.map(note => ({
+ ...discussion,
+ id: note.id,
+ created_at: note.created_at,
+ individual_note: true,
+ notes: [note],
+ }));
+
+ return acc.concat(transformedToIndividualNotes);
+ }, [])
+ .sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
+ }
+
if (state.discussionSortOrder === constants.DESC) {
discussionsInState = discussionsInState.reverse();
}
@@ -27,6 +44,10 @@ export const isNotesFetched = state => state.isNotesFetched;
export const sortDirection = state => state.discussionSortOrder;
+export const persistSortOrder = state => state.persistSortOrder;
+
+export const timelineEnabled = state => state.isTimelineEnabled;
+
export const isLoading = state => state.isLoading;
export const getNotesDataByProp = state => prop => state.notesData[prop];
diff --git a/app/assets/javascripts/notes/stores/modules/index.js b/app/assets/javascripts/notes/stores/modules/index.js
index 161c9b8b1b5..a8738fa7c5f 100644
--- a/app/assets/javascripts/notes/stores/modules/index.js
+++ b/app/assets/javascripts/notes/stores/modules/index.js
@@ -7,6 +7,7 @@ export default () => ({
state: {
discussions: [],
discussionSortOrder: ASC,
+ persistSortOrder: true,
convertedDisscussionIds: [],
targetNoteHash: null,
lastFetchedAt: null,
@@ -45,6 +46,7 @@ export default () => ({
resolvableDiscussionsCount: 0,
unresolvedDiscussionsCount: 0,
descriptionVersions: {},
+ isTimelineEnabled: false,
},
actions,
getters,
diff --git a/app/assets/javascripts/notes/stores/mutation_types.js b/app/assets/javascripts/notes/stores/mutation_types.js
index 23515cdd9e3..7496dd630f6 100644
--- a/app/assets/javascripts/notes/stores/mutation_types.js
+++ b/app/assets/javascripts/notes/stores/mutation_types.js
@@ -34,6 +34,7 @@ export const SET_EXPAND_DISCUSSIONS = 'SET_EXPAND_DISCUSSIONS';
export const UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS = 'UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS';
export const SET_CURRENT_DISCUSSION_ID = 'SET_CURRENT_DISCUSSION_ID';
export const SET_DISCUSSIONS_SORT = 'SET_DISCUSSIONS_SORT';
+export const SET_TIMELINE_VIEW = 'SET_TIMELINE_VIEW';
export const SET_SELECTED_COMMENT_POSITION = 'SET_SELECTED_COMMENT_POSITION';
export const SET_SELECTED_COMMENT_POSITION_HOVER = 'SET_SELECTED_COMMENT_POSITION_HOVER';
export const SET_FETCHING_DISCUSSIONS = 'SET_FETCHING_DISCUSSIONS';
diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js
index a8bd94cc763..6c11d53dba3 100644
--- a/app/assets/javascripts/notes/stores/mutations.js
+++ b/app/assets/javascripts/notes/stores/mutations.js
@@ -313,8 +313,13 @@ export default {
discussion.truncated_diff_lines = utils.prepareDiffLines(diffLines);
},
- [types.SET_DISCUSSIONS_SORT](state, sort) {
- state.discussionSortOrder = sort;
+ [types.SET_DISCUSSIONS_SORT](state, { direction, persist }) {
+ state.discussionSortOrder = direction;
+ state.persistSortOrder = persist;
+ },
+
+ [types.SET_TIMELINE_VIEW](state, value) {
+ state.isTimelineEnabled = value;
},
[types.SET_SELECTED_COMMENT_POSITION](state, position) {
diff --git a/app/assets/javascripts/notes/timeline.js b/app/assets/javascripts/notes/timeline.js
new file mode 100644
index 00000000000..df6d1b21400
--- /dev/null
+++ b/app/assets/javascripts/notes/timeline.js
@@ -0,0 +1,16 @@
+import Vue from 'vue';
+import TimelineToggle from './components/timeline_toggle.vue';
+
+export default function initTimelineToggle(store) {
+ const el = document.getElementById('js-incidents-timeline-toggle');
+
+ if (!el) return null;
+
+ return new Vue({
+ el,
+ store,
+ render(createElement) {
+ return createElement(TimelineToggle);
+ },
+ });
+}