diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-02 21:10:41 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-02 21:10:41 +0300 |
commit | 93fdeb5a619e45cb64ff346c127ff4d68c619ffe (patch) | |
tree | 93a645322b77bec56bec7b7ecbed56a7f866cea0 /app | |
parent | b3432e3b6d3ad4baf73847907c4fea91b59288a5 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
16 files changed, 152 insertions, 86 deletions
diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue index 69021dde0e9..771ecb1a0d4 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue @@ -163,7 +163,7 @@ export default { " > <template #link="{ content }"> - <gl-link data-testid="runner-install-link" @click="toggleDrawer">{{ content }}</gl-link> + <gl-link @click="toggleDrawer">{{ content }}</gl-link> </template> </gl-sprintf> </p> diff --git a/app/assets/javascripts/ci/runner/components/runner_details.vue b/app/assets/javascripts/ci/runner/components/runner_details.vue index 8c1280cffb9..fac90fb0370 100644 --- a/app/assets/javascripts/ci/runner/components/runner_details.vue +++ b/app/assets/javascripts/ci/runner/components/runner_details.vue @@ -94,10 +94,7 @@ export default { <div> <runner-upgrade-status-alert class="gl-my-4" :runner="runner" /> <div class="gl-pt-4"> - <dl - class="gl-mb-0 gl-display-grid runner-details-grid-template" - data-testid="runner-details-list" - > + <dl class="gl-mb-0 gl-display-grid runner-details-grid-template"> <runner-detail :label="s__('Runners|Description')" :value="runner.description" /> <runner-detail :label="s__('Runners|Last contact')" diff --git a/app/assets/javascripts/comment_templates/components/form.vue b/app/assets/javascripts/comment_templates/components/form.vue index fd305ac537c..334c67ca339 100644 --- a/app/assets/javascripts/comment_templates/components/form.vue +++ b/app/assets/javascripts/comment_templates/components/form.vue @@ -61,6 +61,13 @@ export default { }, }, methods: { + onCancel() { + if (this.id) { + this.$router.push({ path: '/' }); + } else { + this.$emit('cancel'); + } + }, onSubmit() { this.showValidation = true; @@ -178,6 +185,6 @@ export default { > {{ __('Save') }} </gl-button> - <gl-button v-if="id" :to="{ path: '/' }">{{ __('Cancel') }}</gl-button> + <gl-button @click="onCancel">{{ __('Cancel') }}</gl-button> </gl-form> </template> diff --git a/app/assets/javascripts/comment_templates/components/list.vue b/app/assets/javascripts/comment_templates/components/list.vue index 76a5b231d81..9c460297335 100644 --- a/app/assets/javascripts/comment_templates/components/list.vue +++ b/app/assets/javascripts/comment_templates/components/list.vue @@ -1,21 +1,14 @@ <!-- eslint-disable vue/multi-word-component-names --> <script> -import { GlKeysetPagination, GlLoadingIcon, GlSprintf } from '@gitlab/ui'; +import { GlKeysetPagination } from '@gitlab/ui'; import ListItem from './list_item.vue'; export default { components: { - GlLoadingIcon, GlKeysetPagination, - GlSprintf, ListItem, }, props: { - loading: { - type: Boolean, - required: false, - default: false, - }, savedReplies: { type: Array, required: true, @@ -24,10 +17,6 @@ export default { type: Object, required: true, }, - count: { - type: Number, - required: true, - }, }, methods: { prevPage() { @@ -45,28 +34,16 @@ export default { </script> <template> - <div class="settings-section"> - <gl-loading-icon v-if="loading" size="lg" /> - <template v-else> - <div class="settings-sticky-header"> - <div class="settings-sticky-header-inner"> - <h4 class="gl-my-0" data-testid="title"> - <gl-sprintf :message="__('My comment templates (%{count})')"> - <template #count>{{ count }}</template> - </gl-sprintf> - </h4> - </div> - </div> - <ul class="gl-list-style-none gl-p-0 gl-m-0"> - <list-item v-for="template in savedReplies" :key="template.id" :template="template" /> - </ul> - <gl-keyset-pagination - v-if="pageInfo.hasPreviousPage || pageInfo.hasNextPage" - v-bind="pageInfo" - class="gl-mt-4" - @prev="prevPage" - @next="nextPage" - /> - </template> + <div class="gl-new-card-content gl-p-0"> + <ul class="content-list"> + <list-item v-for="template in savedReplies" :key="template.id" :template="template" /> + </ul> + <gl-keyset-pagination + v-if="pageInfo.hasPreviousPage || pageInfo.hasNextPage" + v-bind="pageInfo" + class="gl-mt-4" + @prev="prevPage" + @next="nextPage" + /> </div> </template> diff --git a/app/assets/javascripts/comment_templates/components/list_item.vue b/app/assets/javascripts/comment_templates/components/list_item.vue index 70ba449113b..0619201e346 100644 --- a/app/assets/javascripts/comment_templates/components/list_item.vue +++ b/app/assets/javascripts/comment_templates/components/list_item.vue @@ -74,8 +74,8 @@ export default { </script> <template> - <li class="gl-pt-4 gl-pb-5 gl-border-b"> - <div class="gl-display-flex gl-align-items-center"> + <li class="gl-px-5! gl-py-4!"> + <div class="gl-display-flex"> <h6 class="gl-mr-3 gl-my-0" data-testid="comment-template-name">{{ template.name }}</h6> <div class="gl-ml-auto"> <gl-disclosure-dropdown @@ -94,7 +94,9 @@ export default { </gl-tooltip> </div> </div> - <div class="gl-mt-3 gl-font-monospace gl-white-space-pre-wrap">{{ template.content }}</div> + <div class="gl-font-monospace gl-white-space-pre-line gl-font-sm gl-mt-n5"> + {{ template.content }} + </div> <gl-modal ref="delete-modal" :title="__('Delete comment template')" diff --git a/app/assets/javascripts/comment_templates/pages/index.vue b/app/assets/javascripts/comment_templates/pages/index.vue index bbd6cf935f5..58fbe3574bc 100644 --- a/app/assets/javascripts/comment_templates/pages/index.vue +++ b/app/assets/javascripts/comment_templates/pages/index.vue @@ -1,5 +1,6 @@ <!-- eslint-disable vue/multi-word-component-names --> <script> +import { GlCard, GlLoadingIcon, GlIcon, GlButton } from '@gitlab/ui'; import { fetchPolicies } from '~/lib/graphql'; import CreateForm from '../components/form.vue'; import savedRepliesQuery from '../queries/saved_replies.query.graphql'; @@ -28,6 +29,10 @@ export default { }, }, components: { + GlCard, + GlButton, + GlLoadingIcon, + GlIcon, CreateForm, List, }, @@ -37,34 +42,58 @@ export default { count: 0, pageInfo: {}, pagination: {}, + showForm: false, }; }, methods: { refetchSavedReplies() { this.pagination = {}; this.$apollo.queries.savedReplies.refetch(); + this.toggleShowForm(); }, changePage(pageInfo) { this.pagination = pageInfo; }, + toggleShowForm() { + this.showForm = !this.showForm; + }, }, }; </script> <template> - <div> - <div class="settings-section"> - <h5 class="gl-mt-0 gl-font-lg"> - {{ __('Add new comment template') }} - </h5> - <create-form @saved="refetchSavedReplies" /> + <gl-card + class="gl-new-card gl-overflow-hidden" + header-class="gl-new-card-header" + body-class="gl-new-card-body gl-px-0" + > + <template #header> + <div class="gl-new-card-title-wrapper" data-testid="title"> + <h3 class="gl-new-card-title"> + {{ __('My comment templates') }} + </h3> + <div class="gl-new-card-count"> + <gl-icon name="comment-lines" class="gl-mr-2" /> + {{ count }} + </div> + </div> + <gl-button v-if="!showForm" size="small" class="gl-ml-3" @click="toggleShowForm"> + {{ __('Add new') }} + </gl-button> + </template> + <div v-if="showForm" class="gl-new-card-add-form gl-m-3 gl-mb-4"> + <h4 class="gl-mt-0">{{ __('Add new comment template') }}</h4> + <create-form @saved="refetchSavedReplies" @cancel="toggleShowForm" /> </div> + <gl-loading-icon v-if="$apollo.queries.savedReplies.loading" size="sm" class="gl-my-5" /> <list - :loading="$apollo.queries.savedReplies.loading" + v-else-if="savedReplies" :saved-replies="savedReplies" :page-info="pageInfo" - :count="count" @input="changePage" /> - </div> + <div v-else class="gl-new-card-empty gl-px-5 gl-py-4"> + {{ __('You have no saved replies yet.') }} + </div> + </gl-card> </template> diff --git a/app/assets/javascripts/super_sidebar/components/global_search/components/global_search.vue b/app/assets/javascripts/super_sidebar/components/global_search/components/global_search.vue index a91e41585a8..d3bc8f44725 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/components/global_search.vue +++ b/app/assets/javascripts/super_sidebar/components/global_search/components/global_search.vue @@ -200,17 +200,21 @@ export default { const isSearchInput = target.matches(SEARCH_INPUT_SELECTOR); if (code === HOME_KEY) { + if (isSearchInput) return; + this.focusItem(0, elements); } else if (code === END_KEY) { + if (isSearchInput) return; + this.focusItem(elements.length - 1, elements); } else if (code === ARROW_UP_KEY) { if (isSearchInput) return; if (elements.indexOf(target) === 0) { this.focusSearchInput(); - return; + } else { + this.focusNextItem(event, elements, -1); } - this.focusNextItem(event, elements, -1); } else if (code === ARROW_DOWN_KEY) { this.focusNextItem(event, elements, 1); } else if (code === ESC_KEY) { diff --git a/app/assets/javascripts/super_sidebar/components/global_search/constants.js b/app/assets/javascripts/super_sidebar/components/global_search/constants.js index 5a860fcd1ab..dc8fc4d2452 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/constants.js +++ b/app/assets/javascripts/super_sidebar/components/global_search/constants.js @@ -21,6 +21,6 @@ export const INPUT_FIELD_PADDING = 84; export const FETCH_TYPES = ['generic', 'search']; export const SEARCH_MODAL_ID = 'super-sidebar-search-modal'; -export const SEARCH_INPUT_SELECTOR = '.gl-search-box-by-type-input-borderless'; +export const SEARCH_INPUT_SELECTOR = 'input[role="searchbox"]'; export const SEARCH_RESULTS_ITEM_SELECTOR = '.gl-new-dropdown-item'; diff --git a/app/controllers/organizations/application_controller.rb b/app/controllers/organizations/application_controller.rb index cce76395cbd..bd2dcfacabe 100644 --- a/app/controllers/organizations/application_controller.rb +++ b/app/controllers/organizations/application_controller.rb @@ -16,8 +16,10 @@ module Organizations strong_memoize_attr :organization def authorize_action!(action) - access_denied! if Feature.disabled?(:ui_for_organizations, current_user) - access_denied! unless can?(current_user, action, organization) + return if Feature.enabled?(:ui_for_organizations, current_user) && + can?(current_user, action, organization) + + access_denied! end end end diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index 6cfbb61fbb2..02579cd4283 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -65,15 +65,7 @@ class Projects::PagesController < Projects::ApplicationController end def project_params_attributes - attributes = %i[pages_https_only] - - return attributes unless Feature.enabled?(:pages_unique_domain, @project) - - attributes + [ - project_setting_attributes: [ - :pages_unique_domain_enabled - ] - ] + [:pages_https_only, { project_setting_attributes: [:pages_unique_domain_enabled] }] end end diff --git a/app/models/work_items/type.rb b/app/models/work_items/type.rb index 6a619dbab21..88ab3d6bab0 100644 --- a/app/models/work_items/type.rb +++ b/app/models/work_items/type.rb @@ -19,7 +19,8 @@ module WorkItems requirement: 'Requirement', task: 'Task', objective: 'Objective', - key_result: 'Key Result' + key_result: 'Key Result', + epic: 'Epic' }.freeze # Base types need to exist on the DB on app startup @@ -32,7 +33,8 @@ module WorkItems requirement: { name: TYPE_NAMES[:requirement], icon_name: 'issue-type-requirements', enum_value: 3 }, ## EE-only task: { name: TYPE_NAMES[:task], icon_name: 'issue-type-task', enum_value: 4 }, objective: { name: TYPE_NAMES[:objective], icon_name: 'issue-type-objective', enum_value: 5 }, ## EE-only - key_result: { name: TYPE_NAMES[:key_result], icon_name: 'issue-type-keyresult', enum_value: 6 } ## EE-only + key_result: { name: TYPE_NAMES[:key_result], icon_name: 'issue-type-keyresult', enum_value: 6 }, ## EE-only + epic: { name: TYPE_NAMES[:epic], icon_name: 'issue-type-epic', enum_value: 7 } ## EE-only }.freeze # A list of types user can change between - both original and new @@ -79,7 +81,7 @@ module WorkItems end def self.allowed_types_for_issues - base_types.keys.excluding('task', 'objective', 'key_result') + base_types.keys.excluding('task', 'objective', 'key_result', 'epic') end def default? diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index c470cedf0b8..8639e2f833f 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -51,12 +51,6 @@ module Projects private def add_pages_unique_domain - if Feature.disabled?(:pages_unique_domain, project) - params[:project_setting_attributes]&.delete(:pages_unique_domain_enabled) - - return - end - return unless params.dig(:project_setting_attributes, :pages_unique_domain_enabled) # If the project used a unique domain once, it'll always use the same diff --git a/app/views/projects/pages/_pages_settings.html.haml b/app/views/projects/pages/_pages_settings.html.haml index 914292eea02..b1ec7a362b7 100644 --- a/app/views/projects/pages/_pages_settings.html.haml +++ b/app/views/projects/pages/_pages_settings.html.haml @@ -1,8 +1,6 @@ - can_edit_max_page_size = can?(current_user, :update_max_pages_size) - can_enforce_https_only = Gitlab.config.pages.external_http || Gitlab.config.pages.external_https -- can_edit_unique_domain = Feature.enabled?(:pages_unique_domain, @project) -- return unless can_edit_max_page_size || can_enforce_https_only || can_edit_unique_domain = gitlab_ui_form_for @project, url: project_pages_path(@project), html: { class: 'inline', title: pages_https_only_title } do |f| - if can_edit_max_page_size = render_if_exists 'shared/pages/max_pages_size_input', form: f @@ -18,14 +16,13 @@ %p.gl-pl-6 = s_("GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}").html_safe % { docs_link_start: docs_link_start, link_end: link_end } - - if can_edit_unique_domain - .form-group - = f.fields_for :project_setting do |settings| - = settings.gitlab_ui_checkbox_component :pages_unique_domain_enabled, - s_('GitLabPages|Use unique domain'), - label_options: { class: 'label-bold' } - %p.gl-pl-6 - = s_("GitLabPages|When enabled, a unique domain is generated to access pages.").html_safe + .form-group + = f.fields_for :project_setting do |settings| + = settings.gitlab_ui_checkbox_component :pages_unique_domain_enabled, + s_('GitLabPages|Use unique domain'), + label_options: { class: 'label-bold' } + %p.gl-pl-6 + = s_("GitLabPages|When enabled, a unique domain is generated to access pages.").html_safe .gl-mt-3 = f.submit s_('GitLabPages|Save changes'), pajamas_button: true diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 89bb1d11d1d..ee57646d4bd 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -678,6 +678,15 @@ :weight: 1 :idempotent: true :tags: [] +- :name: cronjob:pause_control_resume + :worker_name: PauseControl::ResumeWorker + :feature_category: :global_search + :has_external_dependencies: false + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: cronjob:personal_access_tokens_expired_notification :worker_name: PersonalAccessTokens::ExpiredNotificationWorker :feature_category: :system_access diff --git a/app/workers/concerns/worker_attributes.rb b/app/workers/concerns/worker_attributes.rb index c260e06607c..cc8d77e91f1 100644 --- a/app/workers/concerns/worker_attributes.rb +++ b/app/workers/concerns/worker_attributes.rb @@ -151,6 +151,10 @@ module WorkerAttributes set_class_attribute(:weight, value) end + def pause_control(value) + ::Gitlab::SidekiqMiddleware::PauseControl::WorkersMap.set_strategy_for(strategy: value, worker: self) + end + def get_weight get_class_attribute(:weight) || NAMESPACE_WEIGHTS[queue_namespace] || diff --git a/app/workers/pause_control/resume_worker.rb b/app/workers/pause_control/resume_worker.rb new file mode 100644 index 00000000000..98725c0b6f2 --- /dev/null +++ b/app/workers/pause_control/resume_worker.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module PauseControl + class ResumeWorker + include ApplicationWorker + # There is no onward scheduling and this cron handles work from across the + # application, so there's no useful context to add. + include CronjobQueue # rubocop:disable Scalability/CronWorkerContext + + RESCHEDULE_DELAY = 1.second + + feature_category :global_search + data_consistency :sticky + idempotent! + urgency :low + + def perform + reschedule_job = false + + pause_strategies_workers.each do |strategy, workers| + strategy_klass = Gitlab::SidekiqMiddleware::PauseControl.for(strategy) + + next if strategy_klass.should_pause? + + workers.each do |worker| + next unless jobs_in_the_queue?(worker) + + queue_size = resume_processing!(worker) + reschedule_job = true if queue_size.to_i > 0 + end + end + + self.class.perform_in(RESCHEDULE_DELAY) if reschedule_job + end + + private + + def jobs_in_the_queue?(worker) + Gitlab::SidekiqMiddleware::PauseControl::PauseControlService.has_jobs_in_waiting_queue?(worker.to_s) + end + + def resume_processing!(worker) + Gitlab::SidekiqMiddleware::PauseControl::PauseControlService.resume_processing!(worker.to_s) + end + + def pause_strategies_workers + Gitlab::SidekiqMiddleware::PauseControl::WorkersMap.workers || [] + end + end +end |