From 9885b7e33ece32ac3bfbf077bb2dc53c459dbc0e Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 8 Mar 2023 18:08:14 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/package-and-test/main.gitlab-ci.yml | 2 + .rubocop.yml | 4 + Gemfile | 2 +- Gemfile.checksum | 18 +-- Gemfile.lock | 4 +- app/assets/javascripts/search/store/actions.js | 5 +- app/assets/javascripts/search/store/utils.js | 29 +++- .../work_items/components/notes/work_item_note.vue | 6 + .../components/notes/work_item_note_actions.vue | 61 +++++++- ...work_item_note_add_award_emoji.mutation.graphql | 17 +++ app/models/note.rb | 5 +- .../user_search_simple_query_string.yml | 8 - doc/user/search/advanced_search.md | 6 - locale/gitlab.pot | 6 + package.json | 2 +- .../api/1_manage/import/import_github_repo_spec.rb | 7 +- .../1_manage/import/import_github_repo_spec.rb | 5 +- spec/frontend/blob/components/blob_header_spec.js | 170 ++++++++++----------- spec/frontend/search/mock_data.js | 7 + spec/frontend/search/store/utils_spec.js | 22 +++ .../notes/work_item_note_actions_spec.js | 98 +++++++++--- yarn.lock | 10 +- 22 files changed, 350 insertions(+), 144 deletions(-) create mode 100644 app/assets/javascripts/work_items/graphql/notes/work_item_note_add_award_emoji.mutation.graphql delete mode 100644 config/feature_flags/development/user_search_simple_query_string.yml diff --git a/.gitlab/ci/package-and-test/main.gitlab-ci.yml b/.gitlab/ci/package-and-test/main.gitlab-ci.yml index 41b15e2edd3..62907acfd57 100644 --- a/.gitlab/ci/package-and-test/main.gitlab-ci.yml +++ b/.gitlab/ci/package-and-test/main.gitlab-ci.yml @@ -227,6 +227,8 @@ _ee:super-sidebar-nav: QA_SUPER_SIDEBAR_ENABLED: "true" QA_ALLURE_RESULTS_DIRECTORY: tmp/allure-results-super-sidebar GITLAB_QA_OPTS: --set-feature-flags super_sidebar_nav=enabled + RSPEC_REPORT_OPTS: "--format documentation" + SKIP_REPORT_IN_ISSUES: "true" allow_failure: true rules: - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH diff --git a/.rubocop.yml b/.rubocop.yml index 3489c2e2534..8f9a02bbadd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -30,6 +30,7 @@ inherit_mode: merge: - Include - Exclude + - AllowedPatterns AllCops: # Target the current Ruby version. For example, "2.7" or "3.0". @@ -97,6 +98,9 @@ InternalAffairs/DeprecateCopHelper: Include: - spec/rubocop/**/*.rb +Layout/LineLength: + AllowedPatterns: ['^RSpec\.describe\s.*\sdo'] + Lint/LastKeywordArgument: Safe: false diff --git a/Gemfile b/Gemfile index dd8f0245d88..a87cf586a1a 100644 --- a/Gemfile +++ b/Gemfile @@ -514,7 +514,7 @@ gem 'kas-grpc', '~> 0.0.2' gem 'grpc', '~> 1.42.0' -gem 'google-protobuf', '~> 3.22' +gem 'google-protobuf', '~> 3.22', '>= 3.22.1' gem 'toml-rb', '~> 2.2.0' diff --git a/Gemfile.checksum b/Gemfile.checksum index 9bb151adb66..579849182bc 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -235,15 +235,15 @@ {"name":"google-cloud-env","version":"1.6.0","platform":"ruby","checksum":"6179acb946975892c7908748df5722a4ebadfc8cf5bb7b0d8d933ca67183fa15"}, {"name":"google-cloud-errors","version":"1.3.0","platform":"ruby","checksum":"450b681e24c089a20721a01acc4408bb4a7b0df28c175aaab488da917480d64b"}, {"name":"google-cloud-storage","version":"1.44.0","platform":"ruby","checksum":"299a1e055c9277c8120f7c10d21d37e4d8c17c7b963350c0e0bff7e9d9a570ea"}, -{"name":"google-protobuf","version":"3.22.0","platform":"arm64-darwin","checksum":"e47680f8cf46d5e0bf573052047276260d785caf7b586719af407767e96e535c"}, -{"name":"google-protobuf","version":"3.22.0","platform":"java","checksum":"24e55a0665113f60af35e27dd4c1fcc9b08d16f9da7605456634e505c95890b3"}, -{"name":"google-protobuf","version":"3.22.0","platform":"ruby","checksum":"58db86f65c686ef4b9389569faa176bada384850751675f0c3736ef76cdcae90"}, -{"name":"google-protobuf","version":"3.22.0","platform":"x64-mingw-ucrt","checksum":"43ce8f98fdfa06a81397577bb502230d545178afd592ef5e7d2daddacdda8eb6"}, -{"name":"google-protobuf","version":"3.22.0","platform":"x64-mingw32","checksum":"8255654f5a4a7fff0d430357fa9fe2f23db16eb17ed1067b46a1aab7fd9fcbab"}, -{"name":"google-protobuf","version":"3.22.0","platform":"x86-linux","checksum":"2794f32ecfbeec0fd7baa4a61292fa220f5aad07b656ba656ecf134b1f7e8425"}, -{"name":"google-protobuf","version":"3.22.0","platform":"x86-mingw32","checksum":"a037a5ed2d0a1faa556466c34f7177fee1f3aee8282c2195aed804fead65c65d"}, -{"name":"google-protobuf","version":"3.22.0","platform":"x86_64-darwin","checksum":"bff2987e4bf1a934a4555aea2020df18b557393b188c849fb9deacec9ed0f3d9"}, -{"name":"google-protobuf","version":"3.22.0","platform":"x86_64-linux","checksum":"a0ea6aa03602e9e4f11c1506a114777204aade2e04adc2051945536c35d88bfe"}, +{"name":"google-protobuf","version":"3.22.1","platform":"arm64-darwin","checksum":"bd904af849bd1f143c4d9eb74e0622f9efca7ed20719b00baa77fcb1a5fc2aa7"}, +{"name":"google-protobuf","version":"3.22.1","platform":"java","checksum":"268359af055709c5796b1c726f839ef0fe356702c7abdb136367eb37cf9662e3"}, +{"name":"google-protobuf","version":"3.22.1","platform":"ruby","checksum":"2fc99aa4f0c2fdd33baf7c7fafb045118d1775893ca8823254658429a23ba0f2"}, +{"name":"google-protobuf","version":"3.22.1","platform":"x64-mingw-ucrt","checksum":"351cb7743ea748156fea56ace3f5613ce5a5f1c4c59b18ff28930ef7c53de5f6"}, +{"name":"google-protobuf","version":"3.22.1","platform":"x64-mingw32","checksum":"3808b954ee3240ef97d019037149dde2afa877585420b30f7ac7be37cee7bb4e"}, +{"name":"google-protobuf","version":"3.22.1","platform":"x86-linux","checksum":"6d8ee9928dbe564916b37ede264b1b3492915b818a0daf9c8b4b572eda7baa30"}, +{"name":"google-protobuf","version":"3.22.1","platform":"x86-mingw32","checksum":"a8ab1fda2a208dc238f16b2796d5a3383e6a273f8ef88a23ca90e0c2846594ee"}, +{"name":"google-protobuf","version":"3.22.1","platform":"x86_64-darwin","checksum":"a425ce701b8c4f9aeb7cac0e7f1b36496ff8f6bf86dc7fe9d06af534d25e45d8"}, +{"name":"google-protobuf","version":"3.22.1","platform":"x86_64-linux","checksum":"a62f7d472c346cea6c6141c70b1caba5b7e75319c56cf44a24b62bad6c1adf10"}, {"name":"googleapis-common-protos-types","version":"1.3.0","platform":"ruby","checksum":"c5411f3197cc3e02547ded1858303b1f830b4dc89c588c142ad6c8a231050671"}, {"name":"googleauth","version":"1.3.0","platform":"ruby","checksum":"51dd7362353cf1e90a2d01e1fb94321ae3926c776d4dc4a79db65230217ffcc2"}, {"name":"gpgme","version":"2.0.22","platform":"ruby","checksum":"7c6904952afdd0bf2c7c3ed6de98a5143f86c6b7390dbcd9d7012bddfa3ec862"}, diff --git a/Gemfile.lock b/Gemfile.lock index dd8b77c40cc..89c13820b12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -664,7 +664,7 @@ GEM google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - google-protobuf (3.22.0) + google-protobuf (3.22.1) googleapis-common-protos-types (1.3.0) google-protobuf (~> 3.14) googleauth (1.3.0) @@ -1704,7 +1704,7 @@ DEPENDENCIES google-apis-serviceusage_v1 (~> 0.28.0) google-apis-sqladmin_v1beta4 (~> 0.41.0) google-cloud-storage (~> 1.44.0) - google-protobuf (~> 3.22) + google-protobuf (~> 3.22, >= 3.22.1) gpgme (~> 2.0.22) grape (~> 1.5.2) grape-entity (~> 0.10.0) diff --git a/app/assets/javascripts/search/store/actions.js b/app/assets/javascripts/search/store/actions.js index 3af2b7892be..cd89234a231 100644 --- a/app/assets/javascripts/search/store/actions.js +++ b/app/assets/javascripts/search/store/actions.js @@ -13,6 +13,7 @@ import { mergeById, isSidebarDirty, getAggregationsUrl, + prepareSearchAggregations, } from './utils'; export const fetchGroups = ({ commit }, search) => { @@ -135,12 +136,12 @@ export const fetchSidebarCount = ({ commit, state }) => { return Promise.all(promises); }; -export const fetchLanguageAggregation = ({ commit }) => { +export const fetchLanguageAggregation = ({ commit, state }) => { commit(types.REQUEST_AGGREGATIONS); return axios .get(getAggregationsUrl()) .then(({ data }) => { - commit(types.RECEIVE_AGGREGATIONS_SUCCESS, data); + commit(types.RECEIVE_AGGREGATIONS_SUCCESS, prepareSearchAggregations(state, data)); }) .catch((e) => { logError(e); diff --git a/app/assets/javascripts/search/store/utils.js b/app/assets/javascripts/search/store/utils.js index 1e6619ca6d5..8e484e69646 100644 --- a/app/assets/javascripts/search/store/utils.js +++ b/app/assets/javascripts/search/store/utils.js @@ -1,7 +1,8 @@ -import { isEqual } from 'lodash'; +import { isEqual, orderBy } from 'lodash'; import AccessorUtilities from '~/lib/utils/accessor'; import { formatNumber } from '~/locale'; import { joinPaths } from '~/lib/utils/url_utility'; +import { languageFilterData } from '~/search/sidebar/constants/language_filter_data'; import { MAX_FREQUENT_ITEMS, MAX_FREQUENCY, @@ -9,6 +10,8 @@ import { NUMBER_FORMATING_OPTIONS, } from './constants'; +const LANGUAGE_AGGREGATION_NAME = languageFilterData.filterParam; + function extractKeys(object, keyList) { return Object.fromEntries(keyList.map((key) => [key, object[key]])); } @@ -117,3 +120,27 @@ export const getAggregationsUrl = () => { currentUrl.pathname = joinPaths('/search', 'aggregations'); return currentUrl.toString(); }; + +const sortLanguages = (state, entries) => { + const queriedLanguages = state.query?.[LANGUAGE_AGGREGATION_NAME] || []; + + if (!Array.isArray(queriedLanguages) || !queriedLanguages.length) { + return entries; + } + + const queriedLanguagesSet = new Set(queriedLanguages); + + return orderBy(entries, [({ key }) => queriedLanguagesSet.has(key), 'count'], ['desc', 'desc']); +}; + +export const prepareSearchAggregations = (state, aggregationData) => + aggregationData.map((item) => { + if (item?.name === LANGUAGE_AGGREGATION_NAME) { + return { + ...item, + buckets: sortLanguages(state, item.buckets), + }; + } + + return item; + }); diff --git a/app/assets/javascripts/work_items/components/notes/work_item_note.vue b/app/assets/javascripts/work_items/components/notes/work_item_note.vue index 3225d3f6e49..1d3319dbc90 100644 --- a/app/assets/javascripts/work_items/components/notes/work_item_note.vue +++ b/app/assets/javascripts/work_items/components/notes/work_item_note.vue @@ -87,6 +87,9 @@ export default { hasAdminPermission() { return this.note.userPermissions.adminNote; }, + hasAwardEmojiPermission() { + return this.note.userPermissions.awardEmoji; + }, }, methods: { showReplyForm() { @@ -159,10 +162,13 @@ export default {
-import { GlButton, GlTooltipDirective } from '@gitlab/ui'; -import { __ } from '~/locale'; +import { GlButton, GlIcon, GlTooltipDirective } from '@gitlab/ui'; +import * as Sentry from '@sentry/browser'; +import { __, s__ } from '~/locale'; import ReplyButton from '~/notes/components/note_actions/reply_button.vue'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import addAwardEmojiMutation from '../../graphql/notes/work_item_note_add_award_emoji.mutation.graphql'; export default { name: 'WorkItemNoteActions', @@ -10,11 +13,14 @@ export default { }, components: { GlButton, + GlIcon, ReplyButton, + EmojiPicker: () => import('~/emoji/components/picker.vue'), }, directives: { GlTooltip: GlTooltipDirective, }, + mixins: [glFeatureFlagsMixin()], props: { showReply: { type: Boolean, @@ -24,12 +30,63 @@ export default { type: Boolean, required: true, }, + noteId: { + type: String, + required: true, + }, + showAwardEmoji: { + type: Boolean, + required: false, + default: false, + }, + }, + methods: { + async setAwardEmoji(name) { + try { + const { + data: { + awardEmojiAdd: { errors = [] }, + }, + } = await this.$apollo.mutate({ + mutation: addAwardEmojiMutation, + variables: { + awardableId: this.noteId, + name, + }, + }); + + if (errors.length > 0) { + throw new Error(errors[0].message); + } + } catch (error) { + this.$emit('error', s__('WorkItem|Failed to award emoji')); + Sentry.captureException(error); + } + }, }, };