diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-01 15:10:48 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-01 15:10:48 +0300 |
commit | a21091270d45530468f8ac2f4f926fe1b9840b67 (patch) | |
tree | a641a030521f16e320f1d3559a49956f485c217f /app/assets | |
parent | 8700fc108e2c269a4d73530d60662a6aaff14381 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
6 files changed, 88 insertions, 18 deletions
diff --git a/app/assets/javascripts/pages/projects/find_file/ref_switcher/index.js b/app/assets/javascripts/pages/projects/find_file/ref_switcher/index.js new file mode 100644 index 00000000000..9a3bb25de70 --- /dev/null +++ b/app/assets/javascripts/pages/projects/find_file/ref_switcher/index.js @@ -0,0 +1,38 @@ +import Vue from 'vue'; +import { s__ } from '~/locale'; +import Translate from '~/vue_shared/translate'; +import RefSelector from '~/ref/components/ref_selector.vue'; +import { visitUrl } from '~/lib/utils/url_utility'; +import { generateRefDestinationPath } from './ref_switcher_utils'; + +Vue.use(Translate); + +const REF_SWITCH_HEADER = s__('FindFile|Switch branch/tag'); + +export default () => { + const el = document.getElementById('js-blob-ref-switcher'); + if (!el) return false; + + const { projectId, ref, namespace } = el.dataset; + + return new Vue({ + el, + render(createElement) { + return createElement(RefSelector, { + props: { + projectId, + value: ref, + translations: { + dropdownHeader: REF_SWITCH_HEADER, + searchPlaceholder: REF_SWITCH_HEADER, + }, + }, + on: { + input(selected) { + visitUrl(generateRefDestinationPath(selected, namespace)); + }, + }, + }); + }, + }); +}; diff --git a/app/assets/javascripts/pages/projects/find_file/ref_switcher/ref_switcher_utils.js b/app/assets/javascripts/pages/projects/find_file/ref_switcher/ref_switcher_utils.js new file mode 100644 index 00000000000..5fecd024f1a --- /dev/null +++ b/app/assets/javascripts/pages/projects/find_file/ref_switcher/ref_switcher_utils.js @@ -0,0 +1,28 @@ +import { joinPaths } from '~/lib/utils/url_utility'; + +/** + * Generates a ref destination url based on the selected ref and current url. + * @param {string} selectedRef - The selected ref from the ref dropdown. + * @param {string} namespace - The destination namespace for the path. + */ +export function generateRefDestinationPath(selectedRef, namespace) { + if (!selectedRef || !namespace) { + return window.location.href; + } + + const { pathname } = window.location; + const encodedHash = '%23'; + + const [projectRootPath] = pathname.split(namespace); + + const destinationPath = joinPaths( + projectRootPath, + namespace, + encodeURI(selectedRef).replace(/#/g, encodedHash), + ); + + const newURL = new URL(window.location); + newURL.pathname = destinationPath; + + return newURL.href; +} diff --git a/app/assets/javascripts/pages/projects/find_file/show/index.js b/app/assets/javascripts/pages/projects/find_file/show/index.js index f47888f0cb8..e207df2434b 100644 --- a/app/assets/javascripts/pages/projects/find_file/show/index.js +++ b/app/assets/javascripts/pages/projects/find_file/show/index.js @@ -1,7 +1,9 @@ import $ from 'jquery'; import ShortcutsFindFile from '~/behaviors/shortcuts/shortcuts_find_file'; import ProjectFindFile from '~/projects/project_find_file'; +import InitBlobRefSwitcher from '../ref_switcher'; +InitBlobRefSwitcher(); const findElement = document.querySelector('.js-file-finder'); const projectFindFile = new ProjectFindFile($('.file-finder-holder'), { url: findElement.dataset.fileFindUrl, diff --git a/app/assets/javascripts/work_items/components/work_item_comment_form.vue b/app/assets/javascripts/work_items/components/work_item_comment_form.vue index 9da4473cd46..a38fea01d1f 100644 --- a/app/assets/javascripts/work_items/components/work_item_comment_form.vue +++ b/app/assets/javascripts/work_items/components/work_item_comment_form.vue @@ -175,7 +175,7 @@ export default { this.isSubmitting = true; this.$emit('replying', this.commentText); - const { queryVariables, fetchByIid, sortOrder } = this; + const { queryVariables, fetchByIid } = this; try { this.track('add_work_item_comment'); @@ -193,7 +193,7 @@ export default { if (createNoteData.data?.createNote?.errors?.length) { throw new Error(createNoteData.data?.createNote?.errors[0]); } - updateCommentState(store, createNoteData, fetchByIid, queryVariables, sortOrder); + updateCommentState(store, createNoteData, fetchByIid, queryVariables); }, }); clearDraft(this.autosaveKey); diff --git a/app/assets/javascripts/work_items/components/work_item_notes.vue b/app/assets/javascripts/work_items/components/work_item_notes.vue index 474fea5cec6..457eabb5671 100644 --- a/app/assets/javascripts/work_items/components/work_item_notes.vue +++ b/app/assets/javascripts/work_items/components/work_item_notes.vue @@ -50,7 +50,6 @@ export default { }, data() { return { - notesArray: [], isLoadingMore: false, perPage: DEFAULT_PAGE_SIZE_NOTES, sortOrder: ASC, @@ -61,12 +60,12 @@ export default { initialLoading() { return this.$apollo.queries.workItemNotes.loading && !this.isLoadingMore; }, - pageInfo() { - return this.workItemNotes?.pageInfo; - }, avatarUrl() { return window.gon.current_user_avatar_url; }, + pageInfo() { + return this.workItemNotes?.pageInfo; + }, hasNextPage() { return this.pageInfo?.hasNextPage; }, @@ -95,6 +94,14 @@ export default { sortOrder: this.sortOrder, }; }, + notesArray() { + const notes = this.workItemNotes?.nodes || []; + + if (this.sortOrder === DESC) { + return [...notes].reverse(); + } + return notes; + }, }, apollo: { workItemNotes: { @@ -117,8 +124,6 @@ export default { : data.workItem?.widgets; const discussionNodes = workItemWidgets.find((widget) => widget.type === 'NOTES')?.discussions || []; - this.notesArray = discussionNodes?.nodes || []; - this.updateSortingOrderIfApplicable(); return discussionNodes; }, skip() { @@ -128,6 +133,8 @@ export default { this.$emit('error', i18n.fetchError); }, result() { + this.updateSortingOrderIfApplicable(); + if (this.hasNextPage) { this.fetchMoreNotes(); } @@ -163,7 +170,6 @@ export default { }, changeNotesSortOrder(direction) { this.sortOrder = direction; - this.notesArray = [...this.notesArray].reverse(); this.changeNotesSortOrderAfterLoading = false; }, async fetchMoreNotes() { diff --git a/app/assets/javascripts/work_items/graphql/cache_utils.js b/app/assets/javascripts/work_items/graphql/cache_utils.js index c1de9f673f2..16b892b3476 100644 --- a/app/assets/javascripts/work_items/graphql/cache_utils.js +++ b/app/assets/javascripts/work_items/graphql/cache_utils.js @@ -1,6 +1,5 @@ import { produce } from 'immer'; import { WIDGET_TYPE_NOTES } from '~/work_items/constants'; -import { ASC } from '~/notes/constants'; import { getWorkItemNotesQuery } from '~/work_items/utils'; /** @@ -12,13 +11,7 @@ import { getWorkItemNotesQuery } from '~/work_items/utils'; * @param queryVariables * @param sortOrder */ -export const updateCommentState = ( - store, - { data: { createNote } }, - fetchByIid, - queryVariables, - sortOrder, -) => { +export const updateCommentState = (store, { data: { createNote } }, fetchByIid, queryVariables) => { const notesQuery = getWorkItemNotesQuery(fetchByIid); const variables = { ...queryVariables, @@ -36,7 +29,10 @@ export const updateCommentState = ( ) : draftData.workItem.widgets.find((widget) => widget.type === WIDGET_TYPE_NOTES); - const arrayPushMethod = sortOrder === ASC ? 'push' : 'unshift'; + // as notes are currently sorted/reversed on the frontend rather than in the query + // we only ever push. + // const arrayPushMethod = sortOrder === ASC ? 'push' : 'unshift'; + const arrayPushMethod = 'push'; // manual update of cache with a completely new discussion if (createNote.note.discussion.notes.nodes.length === 1) { |