diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-04 21:08:15 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-04 21:08:15 +0300 |
commit | 23dda8d4edb3c0efeb34586969ce0c64e385f936 (patch) | |
tree | 7573726226f43c71edff707dda377ca3088d3477 /app/assets/javascripts/notes | |
parent | bf6d126a58a66a11b2e4b9de89986174a1885105 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/notes')
8 files changed, 87 insertions, 113 deletions
diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index f700802d6bc..c1824dc883c 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -9,8 +9,6 @@ import { import { mapActions } from 'vuex'; import { __, s__ } from '~/locale'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; -import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; export default { safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] }, @@ -21,13 +19,11 @@ export default { GlIcon, GlBadge, GlLoadingIcon, - UserNameWithStatus, }, directives: { SafeHtml, GlTooltip: GlTooltipDirective, }, - mixins: [glFeatureFlagsMixin()], props: { author: { type: Object, @@ -74,12 +70,15 @@ export default { required: false, default: false, }, + isSystemNote: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { isUsernameLinkHovered: false, - emojiTitle: '', - authorStatusHasTooltip: false, }; }, computed: { @@ -100,15 +99,6 @@ export default { 'js-user-link': true, }; }, - authorStatus() { - if (this.author?.show_status) { - return this.author.status_tooltip_html; - } - return false; - }, - emojiElement() { - return this.$refs?.authorStatus?.querySelector('gl-emoji'); - }, authorName() { return this.author.name; }, @@ -116,14 +106,6 @@ export default { return s__('Notes|This internal note will always remain confidential'); }, }, - mounted() { - this.emojiTitle = this.emojiElement ? this.emojiElement.getAttribute('title') : ''; - - const authorStatusTitle = this.$refs?.authorStatus - ?.querySelector('.user-status-emoji') - ?.getAttribute('title'); - this.authorStatusHasTooltip = authorStatusTitle && authorStatusTitle !== ''; - }, methods: { ...mapActions(['setTargetNoteHash']), handleToggle() { @@ -134,12 +116,6 @@ export default { this.setTargetNoteHash(this.noteTimestampLink); } }, - removeEmojiTitle() { - this.emojiElement.removeAttribute('title'); - }, - addEmojiTitle() { - this.emojiElement.setAttribute('title', this.emojiTitle); - }, handleUsernameMouseEnter() { this.$refs.authorNameLink.dispatchEvent(new Event('mouseenter')); this.isUsernameLinkHovered = true; @@ -148,9 +124,6 @@ export default { this.$refs.authorNameLink.dispatchEvent(new Event('mouseleave')); this.isUsernameLinkHovered = false; }, - userAvailability(selectedAuthor) { - return selectedAuthor?.availability || ''; - }, }, i18n: { showThread: __('Show thread'), @@ -185,35 +158,11 @@ export default { :data-user-id="author.id" :data-username="author.username" > - <span - v-if="glFeatures.removeUserAttributesProjects || glFeatures.removeUserAttributesGroups" - class="note-header-author-name gl-font-weight-bold" - > + <span class="note-header-author-name gl-font-weight-bold"> {{ authorName }} </span> - <user-name-with-status - v-else - :name="authorName" - :availability="userAvailability(author)" - container-classes="note-header-author-name gl-font-weight-bold" - /> </a> - <span - v-if=" - authorStatus && - !glFeatures.removeUserAttributesProjects && - !glFeatures.removeUserAttributesGroups - " - ref="authorStatus" - v-safe-html:[$options.safeHtmlConfig]="authorStatus" - v-on=" - authorStatusHasTooltip ? { mouseenter: removeEmojiTitle, mouseleave: addEmojiTitle } : {} - " - ></span> - <span - v-if="!glFeatures.removeUserAttributesProjects && !glFeatures.removeUserAttributesGroups" - class="text-nowrap author-username" - > + <span v-if="!isSystemNote" class="text-nowrap author-username"> <a ref="authorUsernameLink" class="author-username-link" diff --git a/app/assets/javascripts/notes/components/notes_activity_header.vue b/app/assets/javascripts/notes/components/notes_activity_header.vue new file mode 100644 index 00000000000..e4f88962731 --- /dev/null +++ b/app/assets/javascripts/notes/components/notes_activity_header.vue @@ -0,0 +1,38 @@ +<script> +import DiscussionFilter from './discussion_filter.vue'; + +export default { + components: { + TimelineToggle: () => import('./timeline_toggle.vue'), + DiscussionFilter, + }, + inject: { + showTimelineViewToggle: { + default: false, + }, + }, + props: { + notesFilters: { + type: Array, + required: true, + }, + notesFilterValue: { + type: Number, + default: undefined, + required: false, + }, + }, +}; +</script> + +<template> + <div + class="gl-display-flex gl-sm-align-items-center gl-flex-direction-column gl-sm-flex-direction-row gl-justify-content-space-between gl-pt-5 gl-mt-5 gl-border-t" + > + <h2 class="gl-font-size-h1 gl-m-0">{{ __('Activity') }}</h2> + <div class="gl-display-flex gl-gap-3 gl-w-full gl-sm-w-auto gl-mt-3 gl-sm-mt-0"> + <timeline-toggle v-if="showTimelineViewToggle" /> + <discussion-filter :filters="notesFilters" :selected-value="notesFilterValue" /> + </div> + </div> +</template> diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue index 3e29e438063..9c2ff2c3e7f 100644 --- a/app/assets/javascripts/notes/components/notes_app.vue +++ b/app/assets/javascripts/notes/components/notes_app.vue @@ -19,10 +19,12 @@ import DiscussionFilterNote from './discussion_filter_note.vue'; import NoteableDiscussion from './noteable_discussion.vue'; import NoteableNote from './noteable_note.vue'; import SidebarSubscription from './sidebar_subscription.vue'; +import NotesActivityHeader from './notes_activity_header.vue'; export default { name: 'NotesApp', components: { + NotesActivityHeader, NoteableNote, NoteableDiscussion, SystemNote, @@ -46,6 +48,15 @@ export default { type: Object, required: true, }, + notesFilters: { + type: Array, + required: true, + }, + notesFilterValue: { + type: Number, + default: undefined, + required: false, + }, userData: { type: Object, required: false, @@ -281,6 +292,7 @@ export default { <template> <div v-show="shouldShow" id="notes"> <sidebar-subscription :iid="noteableData.iid" :noteable-data="noteableData" /> + <notes-activity-header :notes-filters="notesFilters" :notes-filter-value="notesFilterValue" /> <ordered-layout :slot-keys="slotKeys"> <template #form> <comment-form diff --git a/app/assets/javascripts/notes/components/timeline_toggle.vue b/app/assets/javascripts/notes/components/timeline_toggle.vue index 8632eea5d8e..59a3cc2d306 100644 --- a/app/assets/javascripts/notes/components/timeline_toggle.vue +++ b/app/assets/javascripts/notes/components/timeline_toggle.vue @@ -53,6 +53,7 @@ export default { :selected="timelineEnabled" :title="tooltip" :aria-label="tooltip" + data-testid="timeline-toggle-button" @click="toggleTimeline" /> </template> diff --git a/app/assets/javascripts/notes/discussion_filters.js b/app/assets/javascripts/notes/discussion_filters.js deleted file mode 100644 index 104e9d4183a..00000000000 --- a/app/assets/javascripts/notes/discussion_filters.js +++ /dev/null @@ -1,34 +0,0 @@ -import Vue from 'vue'; -import DiscussionFilter from './components/discussion_filter.vue'; - -export default (store) => { - const discussionFilterEl = document.getElementById('js-vue-discussion-filter'); - - if (discussionFilterEl) { - const { defaultFilter, notesFilters } = discussionFilterEl.dataset; - const filterValues = notesFilters ? JSON.parse(notesFilters) : {}; - const filters = Object.keys(filterValues).map((entry) => ({ - title: entry, - value: filterValues[entry], - })); - const props = { filters }; - - if (defaultFilter) { - props.selectedValue = parseInt(defaultFilter, 10); - } - - return new Vue({ - el: discussionFilterEl, - name: 'DiscussionFilterRoot', - components: { - DiscussionFilter, - }, - store, - render(createElement) { - return createElement('discussion-filter', { props }); - }, - }); - } - - return null; -}; diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js index 054a5bd36e2..defcb0533b7 100644 --- a/app/assets/javascripts/notes/index.js +++ b/app/assets/javascripts/notes/index.js @@ -1,9 +1,8 @@ import Vue from 'vue'; import { parseBoolean } from '~/lib/utils/common_utils'; import NotesApp from './components/notes_app.vue'; -import initDiscussionFilters from './discussion_filters'; import { store } from './stores'; -import initTimelineToggle from './timeline'; +import { getNotesFilterData } from './utils/get_notes_filter_data'; export default () => { const el = document.getElementById('js-vue-notes'); @@ -11,6 +10,9 @@ export default () => { return; } + const notesFilterProps = getNotesFilterData(el); + const showTimelineViewToggle = parseBoolean(el.dataset.showTimelineViewToggle); + // eslint-disable-next-line no-new new Vue({ el, @@ -19,6 +21,9 @@ export default () => { NotesApp, }, store, + provide: { + showTimelineViewToggle, + }, data() { const notesDataset = el.dataset; const parsedUserData = JSON.parse(notesDataset.currentUserData); @@ -56,11 +61,9 @@ export default () => { noteableData: this.noteableData, notesData: this.notesData, userData: this.currentUserData, + ...notesFilterProps, }, }); }, }); - - initDiscussionFilters(store); - initTimelineToggle(store); }; diff --git a/app/assets/javascripts/notes/timeline.js b/app/assets/javascripts/notes/timeline.js deleted file mode 100644 index df6d1b21400..00000000000 --- a/app/assets/javascripts/notes/timeline.js +++ /dev/null @@ -1,16 +0,0 @@ -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); - }, - }); -} diff --git a/app/assets/javascripts/notes/utils/get_notes_filter_data.js b/app/assets/javascripts/notes/utils/get_notes_filter_data.js new file mode 100644 index 00000000000..6d62ab5e91b --- /dev/null +++ b/app/assets/javascripts/notes/utils/get_notes_filter_data.js @@ -0,0 +1,21 @@ +/** + * Returns parsed notes filter data from a given element's dataset + * + * @param {Element} el containing info in the dataset + */ +export const getNotesFilterData = (el) => { + const { notesFilterValue: valueData, notesFilters: filtersData } = el.dataset; + + const filtersParsed = filtersData ? JSON.parse(filtersData) : {}; + const filters = Object.keys(filtersParsed).map((key) => ({ + title: key, + value: filtersParsed[key], + })); + + const value = valueData ? Number(valueData) : undefined; + + return { + notesFilters: filters, + notesFilterValue: value, + }; +}; |