diff options
Diffstat (limited to 'app')
10 files changed, 128 insertions, 92 deletions
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js b/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js index 2cb1b6a195f..9775a9119c6 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js @@ -21,7 +21,7 @@ export const DEFAULT_ITERATIONS = DEFAULT_NONE_ANY.concat([ { value: FILTER_CURRENT, text: __(FILTER_CURRENT) }, ]); -export const DEFAULT_LABELS = [{ value: 'No label', text: __('No label') }]; // eslint-disable-line @gitlab/require-i18n-strings +export const DEFAULT_LABELS = [DEFAULT_LABEL_NONE, DEFAULT_LABEL_ANY]; export const DEFAULT_MILESTONES = DEFAULT_NONE_ANY.concat([ { value: 'Upcoming', text: __('Upcoming') }, // eslint-disable-line @gitlab/require-i18n-strings diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue index 6ebc5431012..b325f846934 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue @@ -120,7 +120,7 @@ export default { }, DEBOUNCE_DELAY); }, handleTokenValueSelected(activeTokenValue) { - if (this.isRecentTokenValuesEnabled) { + if (this.isRecentTokenValuesEnabled && activeTokenValue) { setTokenValueToRecentlyUsed(this.recentTokenValuesStorageKey, activeTokenValue); } }, diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue index 76b005772ec..a8868da2dcc 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue @@ -1,27 +1,20 @@ <script> -import { - GlToken, - GlFilteredSearchToken, - GlFilteredSearchSuggestion, - GlDropdownDivider, - GlLoadingIcon, -} from '@gitlab/ui'; -import { debounce } from 'lodash'; +import { GlToken, GlFilteredSearchSuggestion } from '@gitlab/ui'; import { deprecatedCreateFlash as createFlash } from '~/flash'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { __ } from '~/locale'; -import { DEFAULT_LABELS, DEBOUNCE_DELAY } from '../constants'; +import { DEFAULT_LABELS } from '../constants'; import { stripQuotes } from '../filtered_search_utils'; +import BaseToken from './base_token.vue'; + export default { components: { + BaseToken, GlToken, - GlFilteredSearchToken, GlFilteredSearchSuggestion, - GlDropdownDivider, - GlLoadingIcon, }, props: { config: { @@ -32,43 +25,24 @@ export default { type: Object, required: true, }, + active: { + type: Boolean, + required: true, + }, }, data() { return { labels: this.config.initialLabels || [], defaultLabels: this.config.defaultLabels || DEFAULT_LABELS, - loading: true, + loading: false, }; }, - computed: { - currentValue() { - return this.value.data.toLowerCase(); - }, - activeLabel() { - return this.labels.find( - (label) => this.getLabelName(label).toLowerCase() === stripQuotes(this.currentValue), + methods: { + getActiveLabel(labels, currentValue) { + return labels.find( + (label) => this.getLabelName(label).toLowerCase() === stripQuotes(currentValue), ); }, - containerStyle() { - if (this.activeLabel) { - const { color, textColor } = convertObjectPropsToCamelCase(this.activeLabel); - - return { backgroundColor: color, color: textColor }; - } - return {}; - }, - }, - watch: { - active: { - immediate: true, - handler(newValue) { - if (!newValue && !this.labels.length) { - this.fetchLabelBySearchTerm(this.value.data); - } - }, - }, - }, - methods: { /** * There's an inconsistency between private and public API * for labels where label name is included in a different @@ -84,6 +58,16 @@ export default { getLabelName(label) { return label.name || label.title; }, + getContainerStyle(activeLabel) { + if (activeLabel) { + const { color: backgroundColor, textColor: color } = convertObjectPropsToCamelCase( + activeLabel, + ); + + return { backgroundColor, color }; + } + return {}; + }, fetchLabelBySearchTerm(searchTerm) { this.loading = true; this.config @@ -99,50 +83,47 @@ export default { this.loading = false; }); }, - searchLabels: debounce(function debouncedSearch({ data }) { - if (!this.loading) this.fetchLabelBySearchTerm(data); - }, DEBOUNCE_DELAY), }, }; </script> <template> - <gl-filtered-search-token - :config="config" - v-bind="{ ...$props, ...$attrs }" - v-on="$listeners" - @input="searchLabels" + <base-token + :token-config="config" + :token-value="value" + :token-active="active" + :tokens-list-loading="loading" + :token-values="labels" + :fn-active-token-value="getActiveLabel" + :default-token-values="defaultLabels" + :recent-token-values-storage-key="config.recentTokenValuesStorageKey" + @fetch-token-values="fetchLabelBySearchTerm" > - <template #view-token="{ inputValue, cssClasses, listeners }"> - <gl-token variant="search-value" :class="cssClasses" :style="containerStyle" v-on="listeners" - >~{{ activeLabel ? getLabelName(activeLabel) : inputValue }}</gl-token + <template + #view-token="{ viewTokenProps: { inputValue, cssClasses, listeners, activeTokenValue } }" + > + <gl-token + variant="search-value" + :class="cssClasses" + :style="getContainerStyle(activeTokenValue)" + v-on="listeners" + >~{{ activeTokenValue ? getLabelName(activeTokenValue) : inputValue }}</gl-token > </template> - <template #suggestions> + <template #token-values-list="{ tokenValues }"> <gl-filtered-search-suggestion - v-for="label in defaultLabels" - :key="label.value" - :value="label.value" + v-for="label in tokenValues" + :key="label.id" + :value="getLabelName(label)" > - {{ label.text }} + <div class="gl-display-flex gl-align-items-center"> + <span + :style="{ backgroundColor: label.color }" + class="gl-display-inline-block mr-2 p-2" + ></span> + <div>{{ getLabelName(label) }}</div> + </div> </gl-filtered-search-suggestion> - <gl-dropdown-divider v-if="defaultLabels.length" /> - <gl-loading-icon v-if="loading" /> - <template v-else> - <gl-filtered-search-suggestion - v-for="label in labels" - :key="label.id" - :value="getLabelName(label)" - > - <div class="gl-display-flex gl-align-items-center"> - <span - :style="{ backgroundColor: label.color }" - class="gl-display-inline-block mr-2 p-2" - ></span> - <div>{{ getLabelName(label) }}</div> - </div> - </gl-filtered-search-suggestion> - </template> </template> - </gl-filtered-search-token> + </base-token> </template> diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index dbe628cb43a..17af44672d9 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -92,7 +92,7 @@ class Projects::BlobController < Projects::ApplicationController @blob.load_all_data! diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true) diff_lines = diffy.diff.scan(/.*\n/)[2..-1] - diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines) + diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines).to_a @diff_lines = Gitlab::Diff::Highlight.new(diff_lines, repository: @repository).highlight render layout: false diff --git a/app/helpers/keyset_helper.rb b/app/helpers/keyset_helper.rb new file mode 100644 index 00000000000..e7f6f884091 --- /dev/null +++ b/app/helpers/keyset_helper.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module KeysetHelper + def keyset_paginate(paginator, without_first_and_last_pages: false) + page_params = params.to_unsafe_h + + render('kaminari/gitlab/keyset_paginator', { + paginator: paginator, + without_first_and_last_pages: without_first_and_last_pages, + page_params: page_params + }) + end +end diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb index a28b97e63e5..d1584a62bfb 100644 --- a/app/models/hooks/project_hook.rb +++ b/app/models/hooks/project_hook.rb @@ -39,6 +39,11 @@ class ProjectHook < WebHook def rate_limit project.actual_limits.limit_for(:web_hook_calls) end + + override :application_context + def application_context + super.merge(project: project) + end end ProjectHook.prepend_mod_with('ProjectHook') diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 02b4feb4ccc..f0c3791079a 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -80,6 +80,11 @@ class WebHook < ApplicationRecord nil end + # Custom attributes to be included in the worker context. + def application_context + { related_class: type } + end + private def web_hooks_disable_failed? diff --git a/app/services/web_hook_service.rb b/app/services/web_hook_service.rb index c24ab10ad86..82a7e8501cd 100644 --- a/app/services/web_hook_service.rb +++ b/app/services/web_hook_service.rb @@ -93,7 +93,9 @@ class WebHookService if rate_limited?(hook) log_rate_limit(hook) else - WebHookWorker.perform_async(hook.id, data, hook_name) + Gitlab::ApplicationContext.with_context(hook.application_context) do + WebHookWorker.perform_async(hook.id, data, hook_name) + end end end diff --git a/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json b/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json index 7c3720dd2e6..dc08ce9dfad 100644 --- a/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json +++ b/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json @@ -109,20 +109,6 @@ ] }, { - "name": "kubesec", - "label": "Kubesec", - "enabled" : true, - "description": "Kubernetes manifests, Helm Charts", - "variables": [] - }, - { - "name": "nodejs-scan", - "label": "Node.js Scan", - "enabled" : true, - "description": "Node.js", - "variables": [] - }, - { "name": "gosec", "label": "Gosec", "enabled" : true, @@ -140,6 +126,20 @@ ] }, { + "name": "kubesec", + "label": "Kubesec", + "enabled" : true, + "description": "Kubernetes manifests, Helm Charts", + "variables": [] + }, + { + "name": "nodejs-scan", + "label": "Node.js Scan", + "enabled" : true, + "description": "Node.js", + "variables": [] + }, + { "name": "phpcs-security-audit", "label": "PHP Security Audit", "enabled" : true, diff --git a/app/views/kaminari/gitlab/_keyset_paginator.html.haml b/app/views/kaminari/gitlab/_keyset_paginator.html.haml new file mode 100644 index 00000000000..f64c70dadfc --- /dev/null +++ b/app/views/kaminari/gitlab/_keyset_paginator.html.haml @@ -0,0 +1,30 @@ +- previous_path = url_for(page_params.merge(cursor: paginator.cursor_for_previous_page)) +- next_path = url_for(page_params.merge(cursor: paginator.cursor_for_next_page)) + +.gl-pagination.gl-mt-3 + %ul.pagination.justify-content-center + + - if paginator.has_previous_page? + - unless without_first_and_last_pages + %li.page-item + - first_page_path = url_for(page_params.merge(cursor: paginator.cursor_for_first_page)) + = link_to first_page_path, rel: 'first', class: 'page-link' do + = sprite_icon('angle-double-left', size: 8) + = s_('Pagination|First') + + %li.page-item.prev + = link_to previous_path, rel: 'prev', class: 'page-link' do + = sprite_icon('angle-left', size: 8) + = s_('Pagination|Prev') + + - if paginator.has_next_page? + %li.page-item.next + = link_to next_path, rel: 'next', class: 'page-link' do + = s_('Pagination|Next') + = sprite_icon('angle-right', size: 8) + - unless without_first_and_last_pages + %li.page-item + - last_page_path = url_for(page_params.merge(cursor: paginator.cursor_for_last_page)) + = link_to last_page_path, rel: 'last', class: 'page-link' do + = s_('Pagination|Last') + = sprite_icon('angle-double-right', size: 8) |