summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-03-18 00:10:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-03-18 00:10:36 +0000
commit4eee0fe3f55ecdd5d607202d93508259239b590f (patch)
tree87bfbb30e6e98ae4135221d562515888e919ec10 /app
parent0ad8135c1feeefa23ec883e409fb65b8b52882a1 (diff)
downloadgitlab-ce-4eee0fe3f55ecdd5d607202d93508259239b590f.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js36
-rw-r--r--app/assets/javascripts/filtered_search/available_dropdown_mappings.js5
-rw-r--r--app/assets/javascripts/pages/users/show/index.js19
-rw-r--r--app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql21
-rw-r--r--app/assets/javascripts/profile/components/user_achievements.vue100
-rw-r--r--app/assets/javascripts/profile/index.js28
-rw-r--r--app/assets/stylesheets/page_bundles/profile.scss1
-rw-r--r--app/assets/stylesheets/page_bundles/settings.scss22
-rw-r--r--app/finders/merge_requests_finder.rb15
-rw-r--r--app/graphql/resolvers/achievements/user_achievements_resolver.rb2
-rw-r--r--app/helpers/application_settings_helper.rb1
-rw-r--r--app/models/achievements/user_achievement.rb2
-rw-r--r--app/models/application_setting.rb7
-rw-r--r--app/models/ci/runner.rb2
-rw-r--r--app/models/ci/runner_machine.rb2
-rw-r--r--app/services/ci/runners/process_runner_version_update_service.rb5
-rw-r--r--app/views/admin/application_settings/_runner_registrars_form.html.haml11
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml2
-rw-r--r--app/views/shared/integrations/prometheus/_custom_metrics.html.haml8
-rw-r--r--app/views/shared/integrations/prometheus/_metrics.html.haml35
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml8
-rw-r--r--app/views/users/show.html.haml1
22 files changed, 272 insertions, 61 deletions
diff --git a/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js b/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js
index 397ba879866..50fca995c81 100644
--- a/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js
+++ b/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js
@@ -72,6 +72,38 @@ export default (IssuableTokenKeys, disableTargetBranchFilter = false) => {
IssuableTokenKeys.tokenKeysWithAlternative.push(targetBranchToken);
}
+ const approvedToken = {
+ token: {
+ formattedKey: __('Approved'),
+ key: 'approved',
+ type: 'string',
+ param: '',
+ symbol: '',
+ icon: 'approval',
+ tag: __('Yes or No'),
+ lowercaseValueOnSubmit: true,
+ capitalizeTokenValue: true,
+ hideNotEqual: true,
+ },
+ conditions: [
+ {
+ url: 'approved=yes',
+ tokenKey: 'approved',
+ value: __('Yes'),
+ operator: '=',
+ },
+ {
+ url: 'approved=no',
+ tokenKey: 'approved',
+ value: __('No'),
+ operator: '=',
+ },
+ ],
+ };
+
+ IssuableTokenKeys.tokenKeys.splice(3, 0, approvedToken.token);
+ IssuableTokenKeys.conditions.push(...approvedToken.conditions);
+
const approvedBy = {
token: {
formattedKey: TOKEN_TITLE_APPROVED_BY,
@@ -117,8 +149,8 @@ export default (IssuableTokenKeys, disableTargetBranchFilter = false) => {
],
};
- const tokenPosition = 3;
- IssuableTokenKeys.tokenKeys.splice(tokenPosition, 0, ...[approvedBy.token]);
+ const tokenPosition = 4;
+ IssuableTokenKeys.tokenKeys.splice(tokenPosition, 0, approvedBy.token);
IssuableTokenKeys.tokenKeysWithAlternative.splice(
tokenPosition,
0,
diff --git a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js
index 1f8baa470d8..892e9130fe8 100644
--- a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js
+++ b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js
@@ -138,6 +138,11 @@ export default class AvailableDropdownMappings {
gl: DropdownNonUser,
element: this.container.querySelector('#js-dropdown-wip'),
},
+ approved: {
+ reference: null,
+ gl: DropdownNonUser,
+ element: this.container.querySelector('#js-dropdown-approved'),
+ },
[TOKEN_TYPE_CONFIDENTIAL]: {
reference: null,
gl: DropdownNonUser,
diff --git a/app/assets/javascripts/pages/users/show/index.js b/app/assets/javascripts/pages/users/show/index.js
index dd47baf06ec..c213753257d 100644
--- a/app/assets/javascripts/pages/users/show/index.js
+++ b/app/assets/javascripts/pages/users/show/index.js
@@ -1,16 +1,7 @@
-import { s__ } from '~/locale';
-import { createAlert } from '~/alert';
+import { initProfileTabs, initUserAchievements } from '~/profile';
-if (window.gon.features?.profileTabsVue) {
- import('~/profile')
- .then(({ initProfileTabs }) => {
- initProfileTabs();
- })
- .catch(() => {
- createAlert({
- message: s__(
- 'UserProfile|An error occurred loading the profile. Please refresh the page to try again.',
- ),
- });
- });
+if (gon.features?.profileTabsVue) {
+ initProfileTabs();
}
+
+initUserAchievements();
diff --git a/app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql b/app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql
new file mode 100644
index 00000000000..e60f383ad1c
--- /dev/null
+++ b/app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql
@@ -0,0 +1,21 @@
+query getUserAchievements($id: UserID!) {
+ user(id: $id) {
+ id
+ userAchievements {
+ nodes {
+ id
+ createdAt
+ achievement {
+ id
+ name
+ description
+ avatarUrl
+ namespace {
+ id
+ fullPath
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/profile/components/user_achievements.vue b/app/assets/javascripts/profile/components/user_achievements.vue
new file mode 100644
index 00000000000..790b0e9f303
--- /dev/null
+++ b/app/assets/javascripts/profile/components/user_achievements.vue
@@ -0,0 +1,100 @@
+<script>
+import { GlPopover, GlSprintf } from '@gitlab/ui';
+import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { s__ } from '~/locale';
+import { TYPENAME_USER } from '~/graphql_shared/constants';
+import timeagoMixin from '~/vue_shared/mixins/timeago';
+import getUserAchievements from './graphql/get_user_achievements.query.graphql';
+
+export default {
+ name: 'UserAchievements',
+ components: { GlPopover, GlSprintf },
+ mixins: [timeagoMixin],
+ inject: ['rootUrl', 'userId'],
+ apollo: {
+ userAchievements: {
+ query: getUserAchievements,
+ variables() {
+ return {
+ id: convertToGraphQLId(TYPENAME_USER, this.userId),
+ };
+ },
+ update(data) {
+ return this.processNodes(data.user.userAchievements.nodes);
+ },
+ error() {
+ return [];
+ },
+ },
+ },
+ methods: {
+ processNodes(nodes) {
+ return nodes.slice(0, 3).map(
+ ({
+ achievement,
+ createdAt,
+ achievement: {
+ namespace: { fullPath },
+ },
+ }) => {
+ return {
+ id: `user-achievement-${getIdFromGraphQLId(achievement.id)}`,
+ name: achievement.name,
+ timeAgo: this.timeFormatted(createdAt),
+ avatarUrl: achievement.avatarUrl || gon.gitlab_logo,
+ description: achievement.description,
+ namespace: {
+ fullPath,
+ webUrl: this.rootUrl + fullPath,
+ },
+ };
+ },
+ );
+ },
+ },
+ i18n: {
+ awardedBy: s__('Achievements|Awarded %{timeAgo} by %{namespace}'),
+ },
+};
+</script>
+
+<template>
+ <div class="gl-mb-3">
+ <div
+ v-for="userAchievement in userAchievements"
+ :key="userAchievement.id"
+ class="gl-display-inline-block"
+ data-testid="user-achievement"
+ >
+ <img
+ :id="userAchievement.id"
+ :src="userAchievement.avatarUrl"
+ :alt="''"
+ tabindex="0"
+ class="gl-avatar gl-avatar-s32 gl-mx-2"
+ />
+ <gl-popover triggers="hover focus" placement="top" :target="userAchievement.id">
+ <div class="gl-font-weight-bold">{{ userAchievement.name }}</div>
+ <div>
+ <gl-sprintf :message="$options.i18n.awardedBy">
+ <template #timeAgo>
+ <span>{{ userAchievement.timeAgo }}</span>
+ </template>
+ <template #namespace>
+ <a :href="userAchievement.namespace.webUrl">{{
+ userAchievement.namespace.fullPath
+ }}</a>
+ </template>
+ </gl-sprintf>
+ </div>
+ <div
+ v-if="userAchievement.description"
+ class="gl-mt-5"
+ data-testid="achievement-description"
+ >
+ {{ userAchievement.description }}
+ </div>
+ </gl-popover>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/profile/index.js b/app/assets/javascripts/profile/index.js
index fe430ccca98..fbe0e3534d8 100644
--- a/app/assets/javascripts/profile/index.js
+++ b/app/assets/javascripts/profile/index.js
@@ -1,6 +1,12 @@
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+
+import createDefaultClient from '~/lib/graphql';
import ProfileTabs from './components/profile_tabs.vue';
+import UserAchievements from './components/user_achievements.vue';
+
+Vue.use(VueApollo);
export const initProfileTabs = () => {
const el = document.getElementById('js-profile-tabs');
@@ -22,3 +28,25 @@ export const initProfileTabs = () => {
},
});
};
+
+export const initUserAchievements = () => {
+ const el = document.getElementById('js-user-achievements');
+
+ if (!el) return false;
+
+ const { rootUrl, userId } = el.dataset;
+
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
+
+ return new Vue({
+ el,
+ apolloProvider,
+ name: 'UserAchievements',
+ provide: { rootUrl, userId: parseInt(userId, 10) },
+ render(createElement) {
+ return createElement(UserAchievements);
+ },
+ });
+};
diff --git a/app/assets/stylesheets/page_bundles/profile.scss b/app/assets/stylesheets/page_bundles/profile.scss
index 36a53c2ad7d..dfc86a73635 100644
--- a/app/assets/stylesheets/page_bundles/profile.scss
+++ b/app/assets/stylesheets/page_bundles/profile.scss
@@ -171,7 +171,6 @@
}
.avatar-holder {
- width: 90px;
margin: 0 auto 10px;
}
}
diff --git a/app/assets/stylesheets/page_bundles/settings.scss b/app/assets/stylesheets/page_bundles/settings.scss
index 8978b8d798b..9a0d7880734 100644
--- a/app/assets/stylesheets/page_bundles/settings.scss
+++ b/app/assets/stylesheets/page_bundles/settings.scss
@@ -138,42 +138,32 @@
border-radius: $gl-border-radius-base;
}
-.prometheus-metrics-monitoring {
- .card {
- .card-toggle {
- width: 14px;
- }
+.prometheus-metrics-monitoring {
+ .gl-card {
.badge.badge-pill {
font-size: 12px;
line-height: 12px;
}
- .card-header .label-count {
+ .gl-card-header .label-count {
color: var(--white, $white);
background: var(--gray-800, $gray-800);
}
- .card-body {
- padding: 0;
- }
-
.flash-container {
margin-bottom: 0;
cursor: default;
- .flash-notice {
+ .flash-notice,
+ .flash-warning {
+ margin-top: 0;
border-radius: 0;
}
}
}
.custom-monitored-metrics {
- .card-header {
- display: flex;
- align-items: center;
- }
-
.custom-metric {
display: flex;
align-items: center;
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index ffa912afd1e..0ce2d52f168 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -36,6 +36,7 @@ class MergeRequestsFinder < IssuableFinder
def self.scalar_params
@scalar_params ||= super + [
+ :approved,
:approved_by_ids,
:deployed_after,
:deployed_before,
@@ -71,8 +72,9 @@ class MergeRequestsFinder < IssuableFinder
items = by_approvals(items)
items = by_deployments(items)
items = by_reviewer(items)
+ items = by_source_project_id(items)
- by_source_project_id(items)
+ by_approved(items)
end
def filter_negated_items(items)
@@ -183,6 +185,17 @@ class MergeRequestsFinder < IssuableFinder
end
# rubocop: enable CodeReuse/Finder
+ def by_approved(items)
+ approved_param = Gitlab::Utils.to_boolean(params.fetch(:approved, nil))
+ return items if approved_param.nil?
+
+ if approved_param
+ items.with_approvals
+ else
+ items.without_approvals
+ end
+ end
+
def by_deployments(items)
env = params[:environment]
before = parse_datetime(params[:deployed_before])
diff --git a/app/graphql/resolvers/achievements/user_achievements_resolver.rb b/app/graphql/resolvers/achievements/user_achievements_resolver.rb
index 594fb3419d6..bf09d80afc1 100644
--- a/app/graphql/resolvers/achievements/user_achievements_resolver.rb
+++ b/app/graphql/resolvers/achievements/user_achievements_resolver.rb
@@ -8,7 +8,7 @@ module Resolvers
type ::Types::Achievements::UserAchievementType.connection_type, null: true
def resolve_with_lookahead
- user_achievements = object.user_achievements
+ user_achievements = object.user_achievements.not_revoked
apply_lookahead(user_achievements)
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index e9656cc029b..fd684ee5ecb 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -403,6 +403,7 @@ module ApplicationSettingsHelper
:protected_paths_raw,
:time_tracking_limit_to_hours,
:two_factor_grace_period,
+ :update_runner_versions_enabled,
:unique_ips_limit_enabled,
:unique_ips_limit_per_user,
:unique_ips_limit_time_window,
diff --git a/app/models/achievements/user_achievement.rb b/app/models/achievements/user_achievement.rb
index e3f810f8846..bc5d10923d7 100644
--- a/app/models/achievements/user_achievement.rb
+++ b/app/models/achievements/user_achievement.rb
@@ -14,6 +14,8 @@ module Achievements
inverse_of: :revoked_user_achievements,
optional: true
+ scope :not_revoked, -> { where(revoked_by_user_id: nil) }
+
def revoked?
revoked_by_user_id.present?
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 2e6c4a53f00..71434931d8c 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -638,7 +638,12 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
length: { maximum: 100, message: N_('is too long (maximum is 100 entries)') },
allow_nil: false
- validates :public_runner_releases_url, addressable_url: ADDRESSABLE_URL_VALIDATION_OPTIONS, presence: true
+ validates :update_runner_versions_enabled,
+ inclusion: { in: [true, false], message: N_('must be a boolean value') }
+ validates :public_runner_releases_url,
+ addressable_url: ADDRESSABLE_URL_VALIDATION_OPTIONS,
+ presence: true,
+ if: :update_runner_versions_enabled?
validates :inactive_projects_min_size_mb,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index eacb3ab8cd6..6fefe95769b 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -604,7 +604,7 @@ module Ci
# For now, heartbeats with version updates might result in two Sidekiq jobs being queued if a runner has a system_id
# This is not a problem since the jobs are deduplicated on the version
def schedule_runner_version_update(new_version)
- return unless new_version
+ return unless new_version && Gitlab::Ci::RunnerReleases.instance.enabled?
Ci::Runners::ProcessRunnerVersionUpdateWorker.perform_async(new_version)
end
diff --git a/app/models/ci/runner_machine.rb b/app/models/ci/runner_machine.rb
index 384d716cf2d..8cf395aadb4 100644
--- a/app/models/ci/runner_machine.rb
+++ b/app/models/ci/runner_machine.rb
@@ -101,7 +101,7 @@ module Ci
end
def schedule_runner_version_update(new_version)
- return unless new_version
+ return unless new_version && Gitlab::Ci::RunnerReleases.instance.enabled?
Ci::Runners::ProcessRunnerVersionUpdateWorker.perform_async(new_version)
end
diff --git a/app/services/ci/runners/process_runner_version_update_service.rb b/app/services/ci/runners/process_runner_version_update_service.rb
index c8a5e42ccab..5c42a2ab018 100644
--- a/app/services/ci/runners/process_runner_version_update_service.rb
+++ b/app/services/ci/runners/process_runner_version_update_service.rb
@@ -8,6 +8,7 @@ module Ci
end
def execute
+ return ServiceResponse.error(message: 'version update disabled') unless enabled?
return ServiceResponse.error(message: 'version not present') unless @version
_, status = upgrade_check_service.check_runner_upgrade_suggestion(@version)
@@ -22,6 +23,10 @@ module Ci
def upgrade_check_service
@runner_upgrade_check ||= Gitlab::Ci::RunnerUpgradeCheck.new(::Gitlab::VERSION)
end
+
+ def enabled?
+ Gitlab::Ci::RunnerReleases.instance.enabled?
+ end
end
end
end
diff --git a/app/views/admin/application_settings/_runner_registrars_form.html.haml b/app/views/admin/application_settings/_runner_registrars_form.html.haml
index baf7c5de7b9..53832e93ed2 100644
--- a/app/views/admin/application_settings/_runner_registrars_form.html.haml
+++ b/app/views/admin/application_settings/_runner_registrars_form.html.haml
@@ -2,7 +2,18 @@
= form_errors(@application_setting)
%fieldset
+ .form-group
+ %h5
+ = s_('Runners|Runner version management')
+ %span.form-text.gl-mb-3.gl-mt-0
+ - help_text = s_('Runners|Official runner version data is periodically fetched from GitLab.com to determine whether the runners need upgrades.')
+ - learn_more_link = link_to _('Learn more.'), help_page_path('ci/runners/configure_runners.md', anchor: 'determine-which-runners-need-to-be-upgraded'), target: '_blank', rel: 'noopener noreferrer'
+ = f.gitlab_ui_checkbox_component :update_runner_versions_enabled,
+ s_('Runners|Fetch GitLab Runner release version data from GitLab.com'),
+ help_text: '%{help_text} %{learn_more_link}'.html_safe % { help_text: help_text, learn_more_link: learn_more_link }
.gl-form-group
+ %h5
+ = s_('Runners|Runner registration')
%span.form-text.gl-mb-3.gl-mt-0
= s_('Runners|If both settings are disabled, new runners cannot be registered.')
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'restrict-runner-registration-by-all-users-in-an-instance'), target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
index a7119af7ece..c2dc3c3707e 100644
--- a/app/views/admin/application_settings/ci_cd.html.haml
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -41,7 +41,7 @@
%section.settings.as-runner.no-animate#js-runner-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
- = s_('Runners|Runner registration')
+ = s_('Runners|Runners')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? 'Collapse' : 'Expand'
.settings-content
diff --git a/app/views/shared/integrations/prometheus/_custom_metrics.html.haml b/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
index dda84e0fb9e..e5ddc055aef 100644
--- a/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
+++ b/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
@@ -6,13 +6,13 @@
= link_to s_('PrometheusService|More information'), help_page_path('operations/metrics/index.md', anchor: 'adding-custom-metrics'), target: '_blank', rel: "noopener noreferrer"
.col-lg-9
- .card.custom-monitored-metrics.js-panel-custom-monitored-metrics{ data: { active_custom_metrics: project_prometheus_metrics_path(project), environments_data: environments_list_data, service_active: "#{integration.active}" } }
- .card-header
+ = render Pajamas::CardComponent.new(header_options: { class: 'gl-display-flex gl-align-items-center' }, body_options: { class: 'gl-p-0' }, card_options: { class: 'gl-mb-5 custom-monitored-metrics js-panel-custom-monitored-metrics', data: { active_custom_metrics: project_prometheus_metrics_path(project), environments_data: environments_list_data, service_active: "#{integration.active}" } }) do |c|
+ - c.header do
%strong
= s_('PrometheusService|Custom metrics')
- = gl_badge_tag 0, nil, class: 'js-custom-monitored-count'
+ = gl_badge_tag 0, nil, class: 'gl-ml-2 js-custom-monitored-count'
= link_to s_('PrometheusService|New metric'), new_project_prometheus_metric_path(project), class: 'btn gl-button btn-confirm gl-ml-auto js-new-metric-button hidden'
- .card-body
+ - c.body do
.flash-container.hidden
.flash-warning
.flash-text
diff --git a/app/views/shared/integrations/prometheus/_metrics.html.haml b/app/views/shared/integrations/prometheus/_metrics.html.haml
index a8de6b001bd..a8125c3e3ec 100644
--- a/app/views/shared/integrations/prometheus/_metrics.html.haml
+++ b/app/views/shared/integrations/prometheus/_metrics.html.haml
@@ -8,29 +8,28 @@
= link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus'), target: '_blank', rel: "noopener noreferrer"
.col-lg-9
- .card.js-panel-monitored-metrics{ data: { active_metrics: active_common_project_prometheus_metrics_path(project, :json), metrics_help_path: help_page_path('user/project/integrations/prometheus_library/index') } }
- = render Pajamas::CardComponent.new(body_options: { class: 'gl-p-0' }) do |c|
- - c.header do
- %strong
- = s_('PrometheusService|Common metrics')
- = gl_badge_tag 0, nil, class: 'js-monitored-count'
- - c.body do
- .loading-metrics.js-loading-metrics
- %p.m-3
- = gl_loading_icon(inline: true, css_class: 'metrics-load-spinner')
- = s_('PrometheusService|Finding and configuring metrics...')
- .empty-metrics.hidden.js-empty-metrics
- %p.text-tertiary.m-3
- = s_('PrometheusService|Waiting for your first deployment to an environment to find common metrics')
- %ul.list-unstyled.metrics-list.hidden.js-metrics-list
+ = render Pajamas::CardComponent.new(body_options: { class: 'gl-p-0' }, card_options: { class: 'gl-mb-5 js-panel-monitored-metrics', data: { active_metrics: active_common_project_prometheus_metrics_path(project, :json), metrics_help_path: help_page_path('user/project/integrations/prometheus_library/index') }}) do |c|
+ - c.header do
+ %strong
+ = s_('PrometheusService|Common metrics')
+ = gl_badge_tag 0, nil, class: 'js-monitored-count'
+ - c.body do
+ .loading-metrics.js-loading-metrics
+ %p.m-3
+ = gl_loading_icon(inline: true, css_class: 'metrics-load-spinner')
+ = s_('PrometheusService|Finding and configuring metrics...')
+ .empty-metrics.hidden.js-empty-metrics
+ %p.text-tertiary.m-3
+ = s_('PrometheusService|Waiting for your first deployment to an environment to find common metrics')
+ %ul.list-unstyled.metrics-list.hidden.js-metrics-list
- .card.hidden.js-panel-missing-env-vars
- .card-header
+ = render Pajamas::CardComponent.new(body_options: { class: 'hidden gl-p-0' }, card_options: { class: 'hidden js-panel-missing-env-vars' }) do |c|
+ - c.header do
= sprite_icon('chevron-lg-right', css_class: 'panel-toggle js-panel-toggle-right')
= sprite_icon('chevron-lg-down', css_class: 'panel-toggle js-panel-toggle-down hidden')
= s_('PrometheusService|Missing environment variable')
= gl_badge_tag 0, nil, class: 'js-env-var-count'
- .card-body.hidden
+ - c.body do
.flash-container
.flash-notice
.flash-text
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 72940b64801..95c5f51c339 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -162,6 +162,14 @@
%li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
%button.gl-button.btn.btn-link{ type: 'button' }
= _('No')
+ #js-dropdown-approved.filtered-search-input-dropdown-menu.dropdown-menu
+ %ul.filter-dropdown{ data: { dropdown: true } }
+ %li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
+ %button.gl-button.btn.btn-link{ type: 'button' }
+ = _('Yes')
+ %li.filter-dropdown-item{ data: { value: 'no', capitalize: true } }
+ %button.gl-button.btn.btn-link{ type: 'button' }
+ = _('No')
#js-dropdown-confidential.filtered-search-input-dropdown-menu.dropdown-menu
%ul.filter-dropdown{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'yes', capitalize: true } }
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index c27086ded6f..3543d5c4336 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -50,6 +50,7 @@
.avatar-holder
= link_to avatar_icon_for_user(@user, 400, current_user: current_user), target: '_blank', rel: 'noopener noreferrer' do
= render Pajamas::AvatarComponent.new(@user, alt: "", size: 96, avatar_options: { itemprop: "image" })
+ #js-user-achievements{ data: { root_url: root_url, user_id: @user.id } }
.gl-display-inline-block.gl-vertical-align-top.gl-text-left
- if @user.blocked? || !@user.confirmed?
.user-info