diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-14 00:14:32 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-14 00:14:32 +0300 |
commit | f163fc8ce6d7661ccf0ff9aa4561f6e5a708b71b (patch) | |
tree | d2d1b57de3428ee1efaf7db74e651cd19543e75d /app | |
parent | 999cc13e0a77fad7322fbbe559013565355c2bfb (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/header_search/components/app.vue | 15 | ||||
-rw-r--r-- | app/assets/javascripts/header_search/store/actions.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/header_search/store/mutation_types.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/header_search/store/mutations.js | 3 | ||||
-rw-r--r-- | app/controllers/projects/jobs_controller.rb | 4 | ||||
-rw-r--r-- | app/mailers/emails/in_product_marketing.rb | 8 | ||||
-rw-r--r-- | app/serializers/build_details_entity.rb | 4 | ||||
-rw-r--r-- | app/serializers/build_serializer.rb | 10 | ||||
-rw-r--r-- | app/serializers/ci/job_entity.rb | 96 | ||||
-rw-r--r-- | app/serializers/ci/job_serializer.rb | 12 | ||||
-rw-r--r-- | app/serializers/ci/pipeline_entity.rb | 2 | ||||
-rw-r--r-- | app/serializers/deployment_entity.rb | 8 | ||||
-rw-r--r-- | app/serializers/job_entity.rb | 94 | ||||
-rw-r--r-- | app/serializers/job_group_entity.rb | 2 | ||||
-rw-r--r-- | app/serializers/stage_entity.rb | 4 |
15 files changed, 139 insertions, 128 deletions
diff --git a/app/assets/javascripts/header_search/components/app.vue b/app/assets/javascripts/header_search/components/app.vue index 67e3998bc97..c22f532d7ac 100644 --- a/app/assets/javascripts/header_search/components/app.vue +++ b/app/assets/javascripts/header_search/components/app.vue @@ -1,7 +1,9 @@ <script> import { GlSearchBoxByType, GlOutsideDirective as Outside } from '@gitlab/ui'; import { mapState, mapActions, mapGetters } from 'vuex'; +import { debounce } from 'lodash'; import { visitUrl } from '~/lib/utils/url_utility'; +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { s__, sprintf } from '~/locale'; import DropdownKeyboardNavigation from '~/vue_shared/components/dropdown_keyboard_navigation.vue'; import { @@ -106,7 +108,7 @@ export default { }, }, methods: { - ...mapActions(['setSearch', 'fetchAutocompleteOptions']), + ...mapActions(['setSearch', 'fetchAutocompleteOptions', 'clearAutocomplete']), openDropdown() { this.showDropdown = true; }, @@ -116,13 +118,13 @@ export default { submitSearch() { return visitUrl(this.currentFocusedOption?.url || this.searchQuery); }, - getAutocompleteOptions(searchTerm) { + getAutocompleteOptions: debounce(function debouncedSearch(searchTerm) { if (!searchTerm) { - return; + this.clearAutocomplete(); + } else { + this.fetchAutocompleteOptions(); } - - this.fetchAutocompleteOptions(); - }, + }, DEFAULT_DEBOUNCE_AND_THROTTLE_MS), }, SEARCH_BOX_INDEX, SEARCH_INPUT_DESCRIPTION, @@ -141,7 +143,6 @@ export default { v-model="searchText" role="searchbox" class="gl-z-index-1" - :debounce="500" autocomplete="off" :placeholder="$options.i18n.searchPlaceholder" :aria-activedescendant="currentFocusedId" diff --git a/app/assets/javascripts/header_search/store/actions.js b/app/assets/javascripts/header_search/store/actions.js index 2c3b1bd4c0f..0ba956f3ed1 100644 --- a/app/assets/javascripts/header_search/store/actions.js +++ b/app/assets/javascripts/header_search/store/actions.js @@ -14,6 +14,10 @@ export const fetchAutocompleteOptions = ({ commit, getters }) => { }); }; +export const clearAutocomplete = ({ commit }) => { + commit(types.CLEAR_AUTOCOMPLETE); +}; + export const setSearch = ({ commit }, value) => { commit(types.SET_SEARCH, value); }; diff --git a/app/assets/javascripts/header_search/store/mutation_types.js b/app/assets/javascripts/header_search/store/mutation_types.js index a2358621ce6..6e65345757f 100644 --- a/app/assets/javascripts/header_search/store/mutation_types.js +++ b/app/assets/javascripts/header_search/store/mutation_types.js @@ -1,5 +1,6 @@ export const REQUEST_AUTOCOMPLETE = 'REQUEST_AUTOCOMPLETE'; export const RECEIVE_AUTOCOMPLETE_SUCCESS = 'RECEIVE_AUTOCOMPLETE_SUCCESS'; export const RECEIVE_AUTOCOMPLETE_ERROR = 'RECEIVE_AUTOCOMPLETE_ERROR'; +export const CLEAR_AUTOCOMPLETE = 'CLEAR_AUTOCOMPLETE'; export const SET_SEARCH = 'SET_SEARCH'; diff --git a/app/assets/javascripts/header_search/store/mutations.js b/app/assets/javascripts/header_search/store/mutations.js index 7fe13600ac9..26b4a8854fe 100644 --- a/app/assets/javascripts/header_search/store/mutations.js +++ b/app/assets/javascripts/header_search/store/mutations.js @@ -15,6 +15,9 @@ export default { state.loading = false; state.autocompleteOptions = []; }, + [types.CLEAR_AUTOCOMPLETE](state) { + state.autocompleteOptions = []; + }, [types.SET_SEARCH](state, value) { state.search = value; }, diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 32a192192bd..fa7c62c34dd 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -42,7 +42,7 @@ class Projects::JobsController < Projects::ApplicationController format.json do Gitlab::PollingInterval.set_header(response, interval: 10_000) - render json: BuildSerializer + render json: Ci::JobSerializer .new(project: @project, current_user: @current_user) .represent(@build.present(current_user: current_user), {}, BuildDetailsEntity) end @@ -118,7 +118,7 @@ class Projects::JobsController < Projects::ApplicationController end def status - render json: BuildSerializer + render json: Ci::JobSerializer .new(project: @project, current_user: @current_user) .represent_status(@build.present(current_user: current_user)) end diff --git a/app/mailers/emails/in_product_marketing.rb b/app/mailers/emails/in_product_marketing.rb index ba94c0c8cac..317e1545350 100644 --- a/app/mailers/emails/in_product_marketing.rb +++ b/app/mailers/emails/in_product_marketing.rb @@ -21,12 +21,6 @@ module Emails mail_to(to: email, subject: @message.subject_line) end - def account_validation_email(pipeline, recipient_email) - @message = Gitlab::Email::Message::AccountValidation.new(pipeline) - - mail_to(to: recipient_email, subject: @message.subject_line) - end - private def mail_to(to:, subject:) @@ -47,3 +41,5 @@ module Emails end end end + +Emails::InProductMarketing.prepend_mod diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb index 4615f471639..5f07306aada 100644 --- a/app/serializers/build_details_entity.rb +++ b/app/serializers/build_details_entity.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildDetailsEntity < JobEntity +class BuildDetailsEntity < Ci::JobEntity expose :coverage, :erased_at, :duration expose :tag_list, as: :tags expose :has_trace?, as: :has_trace @@ -109,6 +109,8 @@ class BuildDetailsEntity < JobEntity private + alias_method :build, :object + def build_failed_issue_options { title: "Job Failed ##{build.id}", description: "Job [##{build.id}](#{project_job_url(project, build)}) failed for #{build.sha}:\n" } diff --git a/app/serializers/build_serializer.rb b/app/serializers/build_serializer.rb deleted file mode 100644 index 0649fdad6a8..00000000000 --- a/app/serializers/build_serializer.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -class BuildSerializer < BaseSerializer - entity JobEntity - - def represent_status(resource) - data = represent(resource, { only: [:status] }) - data.fetch(:status, {}) - end -end diff --git a/app/serializers/ci/job_entity.rb b/app/serializers/ci/job_entity.rb new file mode 100644 index 00000000000..fca3dec74d4 --- /dev/null +++ b/app/serializers/ci/job_entity.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +module Ci + class JobEntity < Grape::Entity + include RequestAwareEntity + + expose :id + expose :name + + expose :started?, as: :started + expose :complete?, as: :complete + expose :archived?, as: :archived + + # bridge jobs don't have build details pages + expose :build_path, if: ->(job) { !job.is_a?(Ci::Bridge) } do |job| + job_path(job) + end + + expose :retry_path, if: -> (*) { retryable? } do |job| + path_to(:retry_namespace_project_job, job) + end + + expose :cancel_path, if: -> (*) { cancelable? } do |job| + path_to( + :cancel_namespace_project_job, + job, + { continue: { to: job_path(job) } } + ) + end + + expose :play_path, if: -> (*) { playable? } do |job| + path_to(:play_namespace_project_job, job) + end + + expose :unschedule_path, if: -> (*) { scheduled? } do |job| + path_to(:unschedule_namespace_project_job, job) + end + + expose :playable?, as: :playable + expose :scheduled?, as: :scheduled + expose :scheduled_at, if: -> (*) { scheduled? } + expose :created_at + expose :updated_at + expose :detailed_status, as: :status, with: DetailedStatusEntity + expose :callout_message, if: -> (*) { failed? && !job.script_failure? } + expose :recoverable, if: -> (*) { failed? } + + private + + alias_method :job, :object + + def cancelable? + job.cancelable? && can?(request.current_user, :update_build, job) + end + + def retryable? + job.retryable? && can?(request.current_user, :update_build, job) + end + + def playable? + job.playable? && can?(request.current_user, :update_build, job) + end + + def scheduled? + job.scheduled? + end + + def detailed_status + job.detailed_status(request.current_user) + end + + def path_to(route, job, params = {}) + send("#{route}_path", job.project.namespace, job.project, job, params) # rubocop:disable GitlabSecurity/PublicSend + end + + def job_path(job) + job.target_url || path_to(:namespace_project_job, job) + end + + def failed? + job.failed? + end + + def callout_message + job_presenter.callout_failure_message + end + + def recoverable + job_presenter.recoverable? + end + + def job_presenter + @job_presenter ||= job.present + end + end +end diff --git a/app/serializers/ci/job_serializer.rb b/app/serializers/ci/job_serializer.rb new file mode 100644 index 00000000000..01f9e223943 --- /dev/null +++ b/app/serializers/ci/job_serializer.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Ci + class JobSerializer < BaseSerializer + entity Ci::JobEntity + + def represent_status(resource) + data = represent(resource, { only: [:status] }) + data.fetch(:status, {}) + end + end +end diff --git a/app/serializers/ci/pipeline_entity.rb b/app/serializers/ci/pipeline_entity.rb index d97c92ce993..20aeb978520 100644 --- a/app/serializers/ci/pipeline_entity.rb +++ b/app/serializers/ci/pipeline_entity.rb @@ -82,7 +82,7 @@ class Ci::PipelineEntity < Grape::Entity project_pipeline_path(pipeline.project, pipeline) end - expose :failed_builds, if: -> (*) { can_retry? }, using: JobEntity do |pipeline| + expose :failed_builds, if: -> (*) { can_retry? }, using: Ci::JobEntity do |pipeline| pipeline.failed_builds.each do |build| build.project = pipeline.project end diff --git a/app/serializers/deployment_entity.rb b/app/serializers/deployment_entity.rb index 08a939e86c5..ffb32a8d603 100644 --- a/app/serializers/deployment_entity.rb +++ b/app/serializers/deployment_entity.rb @@ -27,7 +27,7 @@ class DeploymentEntity < Grape::Entity expose :deployable, if: -> (deployment) { deployment.deployable.present? } do |deployment, opts| deployment.deployable.yield_self do |deployable| if include_details? - JobEntity.represent(deployable, opts) + Ci::JobEntity.represent(deployable, opts) elsif can_read_deployables? { name: deployable.name, build_path: project_job_path(deployable.project, deployable) } @@ -36,10 +36,10 @@ class DeploymentEntity < Grape::Entity end expose :commit, using: CommitEntity, if: -> (*) { include_details? } - expose :manual_actions, using: JobEntity, if: -> (*) { include_details? && can_create_deployment? } - expose :scheduled_actions, using: JobEntity, if: -> (*) { include_details? && can_create_deployment? } + expose :manual_actions, using: Ci::JobEntity, if: -> (*) { include_details? && can_create_deployment? } + expose :scheduled_actions, using: Ci::JobEntity, if: -> (*) { include_details? && can_create_deployment? } expose :playable_build, if: -> (deployment) { include_details? && can_create_deployment? && deployment.playable_build } do |deployment, options| - JobEntity.represent(deployment.playable_build, options.merge(only: [:play_path, :retry_path])) + Ci::JobEntity.represent(deployment.playable_build, options.merge(only: [:play_path, :retry_path])) end expose :cluster do |deployment, options| diff --git a/app/serializers/job_entity.rb b/app/serializers/job_entity.rb deleted file mode 100644 index eb8622edb38..00000000000 --- a/app/serializers/job_entity.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: true - -class JobEntity < Grape::Entity - include RequestAwareEntity - - expose :id - expose :name - - expose :started?, as: :started - expose :complete?, as: :complete - expose :archived?, as: :archived - - # bridge jobs don't have build detail pages - expose :build_path, if: ->(build) { !build.is_a?(Ci::Bridge) } do |build| - build_path(build) - end - - expose :retry_path, if: -> (*) { retryable? } do |build| - path_to(:retry_namespace_project_job, build) - end - - expose :cancel_path, if: -> (*) { cancelable? } do |build| - path_to( - :cancel_namespace_project_job, - build, - { continue: { to: build_path(build) } } - ) - end - - expose :play_path, if: -> (*) { playable? } do |build| - path_to(:play_namespace_project_job, build) - end - - expose :unschedule_path, if: -> (*) { scheduled? } do |build| - path_to(:unschedule_namespace_project_job, build) - end - - expose :playable?, as: :playable - expose :scheduled?, as: :scheduled - expose :scheduled_at, if: -> (*) { scheduled? } - expose :created_at - expose :updated_at - expose :detailed_status, as: :status, with: DetailedStatusEntity - expose :callout_message, if: -> (*) { failed? && !build.script_failure? } - expose :recoverable, if: -> (*) { failed? } - - private - - alias_method :build, :object - - def cancelable? - build.cancelable? && can?(request.current_user, :update_build, build) - end - - def retryable? - build.retryable? && can?(request.current_user, :update_build, build) - end - - def playable? - build.playable? && can?(request.current_user, :update_build, build) - end - - def scheduled? - build.scheduled? - end - - def detailed_status - build.detailed_status(request.current_user) - end - - def path_to(route, build, params = {}) - send("#{route}_path", build.project.namespace, build.project, build, params) # rubocop:disable GitlabSecurity/PublicSend - end - - def build_path(build) - build.target_url || path_to(:namespace_project_job, build) - end - - def failed? - build.failed? - end - - def callout_message - build_presenter.callout_failure_message - end - - def recoverable - build_presenter.recoverable? - end - - def build_presenter - @build_presenter ||= build.present - end -end diff --git a/app/serializers/job_group_entity.rb b/app/serializers/job_group_entity.rb index 0db7624b3f7..3597d5531fa 100644 --- a/app/serializers/job_group_entity.rb +++ b/app/serializers/job_group_entity.rb @@ -6,7 +6,7 @@ class JobGroupEntity < Grape::Entity expose :name expose :size expose :detailed_status, as: :status, with: DetailedStatusEntity - expose :jobs, with: JobEntity + expose :jobs, with: Ci::JobEntity private diff --git a/app/serializers/stage_entity.rb b/app/serializers/stage_entity.rb index 0aadcd01a43..548ff577863 100644 --- a/app/serializers/stage_entity.rb +++ b/app/serializers/stage_entity.rb @@ -15,13 +15,13 @@ class StageEntity < Grape::Entity expose :latest_statuses, if: -> (_, opts) { opts[:details] }, - with: JobEntity do |stage| + with: Ci::JobEntity do |stage| latest_statuses end expose :retried, if: -> (_, opts) { opts[:retried] }, - with: JobEntity do |stage| + with: Ci::JobEntity do |stage| retried_statuses end |