summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/components/board_filtered_search.vue17
-rw-r--r--app/assets/javascripts/boards/constants.js1
-rw-r--r--app/assets/javascripts/cycle_analytics/components/path_navigation.vue2
-rw-r--r--app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue4
-rw-r--r--app/assets/javascripts/experimental_flags.js15
-rw-r--r--app/assets/javascripts/jobs/bridge/components/sidebar.vue23
-rw-r--r--app/assets/javascripts/pages/admin/runners/edit/index.js4
-rw-r--r--app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue (renamed from app/assets/javascripts/runner/runner_details/runner_details_app.vue)2
-rw-r--r--app/assets/javascripts/runner/admin_runner_edit/index.js (renamed from app/assets/javascripts/runner/runner_details/index.js)6
-rw-r--r--app/assets/javascripts/runner/components/cells/runner_actions_cell.vue4
-rw-r--r--app/assets/javascripts/runner/components/runner_update_form.vue2
-rw-r--r--app/assets/javascripts/runner/graphql/get_runners.query.graphql1
-rw-r--r--app/assets/javascripts/runner/runner_update_form_utils.js (renamed from app/assets/javascripts/runner/runner_details/runner_update_form_utils.js)0
-rw-r--r--app/assets/javascripts/tree.js64
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue4
-rw-r--r--app/controllers/admin/runners_controller.rb2
-rw-r--r--app/controllers/projects/security/configuration_controller.rb31
-rw-r--r--app/models/concerns/routable.rb5
-rw-r--r--app/models/email.rb8
-rw-r--r--app/models/namespace.rb2
-rw-r--r--app/views/admin/runners/edit.html.haml15
-rw-r--r--app/views/admin/runners/show.html.haml8
-rw-r--r--app/workers/email_receiver_worker.rb33
23 files changed, 113 insertions, 140 deletions
diff --git a/app/assets/javascripts/boards/components/board_filtered_search.vue b/app/assets/javascripts/boards/components/board_filtered_search.vue
index 09ec385bbba..2599d1c80b8 100644
--- a/app/assets/javascripts/boards/components/board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/board_filtered_search.vue
@@ -6,6 +6,7 @@ import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
+import { AssigneeFilterType } from '~/boards/constants';
export default {
i18n: {
@@ -37,6 +38,7 @@ export default {
authorUsername,
labelName,
assigneeUsername,
+ assigneeId,
search,
milestoneTitle,
iterationId,
@@ -63,6 +65,13 @@ export default {
});
}
+ if (assigneeId) {
+ filteredSearchValue.push({
+ type: 'assignee',
+ value: { data: assigneeId, operator: '=' },
+ });
+ }
+
if (types) {
filteredSearchValue.push({
type: 'type',
@@ -211,6 +220,7 @@ export default {
authorUsername,
labelName,
assigneeUsername,
+ assigneeId,
search,
milestoneTitle,
types,
@@ -246,6 +256,7 @@ export default {
author_username: authorUsername,
'label_name[]': labelName,
assignee_username: assigneeUsername,
+ assignee_id: assigneeId,
milestone_title: milestoneTitle,
iteration_id: iterationId,
search,
@@ -295,7 +306,11 @@ export default {
filterParams.authorUsername = filter.value.data;
break;
case 'assignee':
- filterParams.assigneeUsername = filter.value.data;
+ if (Object.values(AssigneeFilterType).includes(filter.value.data)) {
+ filterParams.assigneeId = filter.value.data;
+ } else {
+ filterParams.assigneeUsername = filter.value.data;
+ }
break;
case 'type':
filterParams.types = filter.value.data;
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index 80559795cf0..e0eea761b31 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -120,6 +120,7 @@ export const FilterFields = {
/* eslint-disable @gitlab/require-i18n-strings */
export const AssigneeFilterType = {
any: 'Any',
+ none: 'None',
};
export const MilestoneFilterType = {
diff --git a/app/assets/javascripts/cycle_analytics/components/path_navigation.vue b/app/assets/javascripts/cycle_analytics/components/path_navigation.vue
index f8f89772fd6..af7334ecf2e 100644
--- a/app/assets/javascripts/cycle_analytics/components/path_navigation.vue
+++ b/app/assets/javascripts/cycle_analytics/components/path_navigation.vue
@@ -57,7 +57,7 @@ export default {
};
</script>
<template>
- <gl-skeleton-loading v-if="loading" :lines="2" class="h-auto pt-2 pb-1" />
+ <gl-skeleton-loading v-if="loading" :lines="2" />
<gl-path v-else :key="selectedStage.id" :items="stages" @selected="onSelectStage">
<template #default="{ pathItem, pathId }">
<gl-popover
diff --git a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
index 8610dfc2b03..64461797c46 100644
--- a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
+++ b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
@@ -59,7 +59,9 @@ export default {
};
</script>
<template>
- <div class="gl-mt-3 gl-py-2 gl-px-3 bg-gray-light border-top border-bottom">
+ <div
+ class="gl-mt-3 gl-py-2 gl-px-3 gl-bg-gray-10 gl-border-b-1 gl-border-b-solid gl-border-t-1 gl-border-t-solid gl-border-gray-100"
+ >
<filter-bar
data-testid="vsa-filter-bar"
class="filtered-search-box gl-display-flex gl-mb-2 gl-mr-3 gl-border-none"
diff --git a/app/assets/javascripts/experimental_flags.js b/app/assets/javascripts/experimental_flags.js
deleted file mode 100644
index 1d60847147b..00000000000
--- a/app/assets/javascripts/experimental_flags.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import $ from 'jquery';
-import Cookies from 'js-cookie';
-
-export default () => {
- $('.js-experiment-feature-toggle').on('change', (e) => {
- const el = e.target;
-
- Cookies.set(el.name, el.value, {
- expires: 365 * 10,
- });
-
- document.body.scrollTop = 0;
- window.location.reload();
- });
-};
diff --git a/app/assets/javascripts/jobs/bridge/components/sidebar.vue b/app/assets/javascripts/jobs/bridge/components/sidebar.vue
index 34cefb0d0e2..3ba07cf55d1 100644
--- a/app/assets/javascripts/jobs/bridge/components/sidebar.vue
+++ b/app/assets/javascripts/jobs/bridge/components/sidebar.vue
@@ -8,7 +8,6 @@ import CommitBlock from '../../components/commit_block.vue';
export default {
styles: {
- top: '75px',
width: '290px',
},
name: 'BridgeSidebar',
@@ -37,17 +36,37 @@ export default {
required: true,
},
},
+ data() {
+ return {
+ topPosition: 0,
+ };
+ },
+ computed: {
+ rootStyle() {
+ return { ...this.$options.styles, top: `${this.topPosition}px` };
+ },
+ },
+ mounted() {
+ this.setTopPosition();
+ },
methods: {
onSidebarButtonClick() {
this.$emit('toggleSidebar');
},
+ setTopPosition() {
+ const navbarEl = document.querySelector('.js-navbar');
+
+ if (navbarEl) {
+ this.topPosition = navbarEl.getBoundingClientRect().bottom;
+ }
+ },
},
};
</script>
<template>
<aside
class="gl-fixed gl-right-0 gl-px-5 gl-bg-gray-10 gl-h-full gl-border-l-solid gl-border-1 gl-border-gray-100 gl-z-index-200 gl-overflow-hidden"
- :style="this.$options.styles"
+ :style="rootStyle"
>
<div class="gl-py-5 gl-display-flex gl-align-items-center">
<tooltip-on-truncate :title="bridgeJob.name" truncate-target="child"
diff --git a/app/assets/javascripts/pages/admin/runners/edit/index.js b/app/assets/javascripts/pages/admin/runners/edit/index.js
index d1853772fda..ddf135a2732 100644
--- a/app/assets/javascripts/pages/admin/runners/edit/index.js
+++ b/app/assets/javascripts/pages/admin/runners/edit/index.js
@@ -1,3 +1,3 @@
-import { initRunnerDetail } from '~/runner/runner_details';
+import { initAdminRunnerEdit } from '~/runner/admin_runner_edit';
-initRunnerDetail();
+initAdminRunnerEdit();
diff --git a/app/assets/javascripts/runner/runner_details/runner_details_app.vue b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
index f0a1d781a3a..4d2ca9b0c58 100644
--- a/app/assets/javascripts/runner/runner_details/runner_details_app.vue
+++ b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
@@ -9,7 +9,7 @@ import getRunnerQuery from '../graphql/get_runner.query.graphql';
import { captureException } from '../sentry_utils';
export default {
- name: 'RunnerDetailsApp',
+ name: 'AdminRunnerEditApp',
components: {
RunnerHeader,
RunnerUpdateForm,
diff --git a/app/assets/javascripts/runner/runner_details/index.js b/app/assets/javascripts/runner/admin_runner_edit/index.js
index db8f239a3c3..adb420f9963 100644
--- a/app/assets/javascripts/runner/runner_details/index.js
+++ b/app/assets/javascripts/runner/admin_runner_edit/index.js
@@ -1,11 +1,11 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import RunnerDetailsApp from './runner_details_app.vue';
+import AdminRunnerEditApp from './admin_runner_edit_app.vue';
Vue.use(VueApollo);
-export const initRunnerDetail = (selector = '#js-runner-details') => {
+export const initAdminRunnerEdit = (selector = '#js-admin-runner-edit') => {
const el = document.querySelector(selector);
if (!el) {
@@ -22,7 +22,7 @@ export const initRunnerDetail = (selector = '#js-runner-details') => {
el,
apolloProvider,
render(h) {
- return h(RunnerDetailsApp, {
+ return h(AdminRunnerEditApp, {
props: {
runnerId,
},
diff --git a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
index 82ee41d6def..0934508c87f 100644
--- a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
+++ b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
@@ -162,9 +162,9 @@ export default {
See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
-->
<gl-button
- v-if="canUpdate && runner.adminUrl"
+ v-if="canUpdate && runner.editAdminUrl"
v-gl-tooltip.hover.viewport="$options.I18N_EDIT"
- :href="runner.adminUrl"
+ :href="runner.editAdminUrl"
:aria-label="$options.I18N_EDIT"
icon="pencil"
data-testid="edit-runner"
diff --git a/app/assets/javascripts/runner/components/runner_update_form.vue b/app/assets/javascripts/runner/components/runner_update_form.vue
index aeb5869bcce..e3deb94236e 100644
--- a/app/assets/javascripts/runner/components/runner_update_form.vue
+++ b/app/assets/javascripts/runner/components/runner_update_form.vue
@@ -10,7 +10,7 @@ import {
import {
modelToUpdateMutationVariables,
runnerToModel,
-} from 'ee_else_ce/runner/runner_details/runner_update_form_utils';
+} from 'ee_else_ce/runner/runner_update_form_utils';
import { createAlert, VARIANT_SUCCESS } from '~/flash';
import { __ } from '~/locale';
import { captureException } from '~/runner/sentry_utils';
diff --git a/app/assets/javascripts/runner/graphql/get_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
index 51a91b9eb96..05df399fa6a 100644
--- a/app/assets/javascripts/runner/graphql/get_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
@@ -26,6 +26,7 @@ query getRunners(
nodes {
...RunnerNode
adminUrl
+ editAdminUrl
}
pageInfo {
...PageInfo
diff --git a/app/assets/javascripts/runner/runner_details/runner_update_form_utils.js b/app/assets/javascripts/runner/runner_update_form_utils.js
index 3b519fa7d71..3b519fa7d71 100644
--- a/app/assets/javascripts/runner/runner_details/runner_update_form_utils.js
+++ b/app/assets/javascripts/runner/runner_update_form_utils.js
diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js
deleted file mode 100644
index 58bff370fa5..00000000000
--- a/app/assets/javascripts/tree.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* eslint-disable func-names, consistent-return, one-var, class-methods-use-this */
-
-import $ from 'jquery';
-import { visitUrl } from './lib/utils/url_utility';
-
-export default class TreeView {
- constructor() {
- this.initKeyNav();
- // Code browser tree slider
- // Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
- $('.tree-content-holder .tree-item').on('click', function (e) {
- const $clickedEl = $(e.target);
- const path = $('.tree-item-file-name a', this).attr('href');
- if (!$clickedEl.is('a') && !$clickedEl.is('.str-truncated')) {
- if (e.metaKey || e.which === 2) {
- e.preventDefault();
- return window.open(path, '_blank');
- }
- return visitUrl(path);
- }
- });
- // Show the "Loading commit data" for only the first element
- $('span.log_loading').first().removeClass('hide');
- }
-
- initKeyNav() {
- const li = $('tr.tree-item');
- let liSelected = null;
- return $('body').keydown((e) => {
- let next, path;
- if ($('input:focus').length > 0 && (e.which === 38 || e.which === 40)) {
- return false;
- }
- if (e.which === 40) {
- if (liSelected) {
- next = liSelected.next();
- if (next.length > 0) {
- liSelected.removeClass('selected');
- liSelected = next.addClass('selected');
- }
- } else {
- liSelected = li.eq(0).addClass('selected');
- }
- return $(liSelected).focus();
- } else if (e.which === 38) {
- if (liSelected) {
- next = liSelected.prev();
- if (next.length > 0) {
- liSelected.removeClass('selected');
- liSelected = next.addClass('selected');
- }
- } else {
- liSelected = li.last().addClass('selected');
- }
- return $(liSelected).focus();
- } else if (e.which === 13) {
- path = $('.tree-item.selected .tree-item-file-name a').attr('href');
- if (path) {
- return visitUrl(path);
- }
- }
- });
- }
-}
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
index 06478a89721..b70317b2ec4 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/author_token.vue
@@ -4,7 +4,7 @@ import { compact } from 'lodash';
import createFlash from '~/flash';
import { __ } from '~/locale';
-import { DEFAULT_LABEL_ANY } from '../constants';
+import { DEFAULT_NONE_ANY } from '../constants';
import BaseToken from './base_token.vue';
@@ -36,7 +36,7 @@ export default {
},
computed: {
defaultAuthors() {
- return this.config.defaultAuthors || [DEFAULT_LABEL_ANY];
+ return this.config.defaultAuthors || DEFAULT_NONE_ANY;
},
preloadedAuthors() {
return this.config.preloadedAuthors || [];
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 43d74603407..16657612050 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -15,7 +15,7 @@ class Admin::RunnersController < Admin::ApplicationController
# future iterations. For now, this route will have a
# redirect until this new view is developed. See more:
# https://gitlab.com/gitlab-org/gitlab/-/issues/347856
- redirect_to edit_admin_runner_path(runner)
+ redirect_to edit_admin_runner_path(runner) unless Feature.enabled?(:runner_read_only_admin_view, default_enabled: :yaml)
end
def edit
diff --git a/app/controllers/projects/security/configuration_controller.rb b/app/controllers/projects/security/configuration_controller.rb
index 444f4783a19..14f765814e6 100644
--- a/app/controllers/projects/security/configuration_controller.rb
+++ b/app/controllers/projects/security/configuration_controller.rb
@@ -9,6 +9,37 @@ module Projects
def show
render_403 unless can?(current_user, :read_security_configuration, project)
+
+ respond_to do |format|
+ format.html
+ format.json do
+ render status: :ok, json: configuration.to_h
+ end
+ end
+ end
+
+ private
+
+ def configuration
+ if unify_configuration_enabled?
+ configuration_presenter
+ else
+ {}
+ end
+ end
+
+ def configuration_presenter
+ ::Projects::Security::ConfigurationPresenter.new(project,
+ **presenter_attributes,
+ current_user: current_user)
+ end
+
+ def presenter_attributes
+ {}
+ end
+
+ def unify_configuration_enabled?
+ Feature.enabled?(:unify_security_configuration, project, default_enabled: :yaml)
end
end
end
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb
index f382b3624ed..2cf95ac0dae 100644
--- a/app/models/concerns/routable.rb
+++ b/app/models/concerns/routable.rb
@@ -190,5 +190,10 @@ module Routable
route || build_route(source: self)
route.path = build_full_path
route.name = build_full_name
+ route.namespace = if is_a?(Namespace)
+ self
+ elsif is_a?(Project)
+ self.project_namespace
+ end
end
end
diff --git a/app/models/email.rb b/app/models/email.rb
index cda46c5e523..3896dfd5d22 100644
--- a/app/models/email.rb
+++ b/app/models/email.rb
@@ -6,8 +6,8 @@ class Email < ApplicationRecord
belongs_to :user, optional: false
- validates :email, presence: true, uniqueness: true
- validate :validate_email_format
+ validates :email, presence: true, uniqueness: true, devise_email: true
+
validate :unique_email, if: ->(email) { email.email_changed? }
scope :confirmed, -> { where.not(confirmed_at: nil) }
@@ -33,10 +33,6 @@ class Email < ApplicationRecord
self.errors.add(:email, 'has already been taken') if primary_email_of_another_user?
end
- def validate_email_format
- self.errors.add(:email, I18n.t(:invalid, scope: 'valid_email.validations.email')) unless ValidateEmail.valid?(self.email)
- end
-
# once email is confirmed, update the gpg signatures
def update_invalid_gpg_signatures
user.update_invalid_gpg_signatures if confirmed?
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index adf42acdd2b..1e7f0f10aa6 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -43,7 +43,7 @@ class Namespace < ApplicationRecord
has_many :projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :project_statistics
has_one :namespace_settings, inverse_of: :namespace, class_name: 'NamespaceSetting', autosave: true
- has_one :namespace_route, foreign_key: :namespace_id, autosave: true, inverse_of: :namespace, class_name: 'Route'
+ has_one :namespace_route, foreign_key: :namespace_id, autosave: false, inverse_of: :namespace, class_name: 'Route'
has_many :runner_namespaces, inverse_of: :namespace, class_name: 'Ci::RunnerNamespace'
has_many :runners, through: :runner_namespaces, source: :runner, class_name: 'Ci::Runner'
diff --git a/app/views/admin/runners/edit.html.haml b/app/views/admin/runners/edit.html.haml
index 12d0f6a9d18..3f5c868d768 100644
--- a/app/views/admin/runners/edit.html.haml
+++ b/app/views/admin/runners/edit.html.haml
@@ -1,11 +1,16 @@
- add_page_specific_style 'page_bundles/ci_status'
-- title = "##{@runner.id} (#{@runner.short_sha})"
-- breadcrumb_title title
-- page_title title
-- add_to_breadcrumbs _('Runners'), admin_runners_path
+- runner_name = "##{@runner.id} (#{@runner.short_sha})"
+- if Feature.enabled?(:runner_read_only_admin_view)
+ - breadcrumb_title _('Edit')
+ - page_title _('Edit'), runner_name
+ - add_to_breadcrumbs _('Runners'), admin_runners_path
+ - add_to_breadcrumbs runner_name, admin_runner_path(@runner)
+- else
+ - breadcrumb_title runner_name
+ - page_title runner_name
-#js-runner-details{ data: {runner_id: @runner.id} }
+#js-admin-runner-edit{ data: {runner_id: @runner.id} }
.row
.col-md-6
diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml
new file mode 100644
index 00000000000..7b4390ae463
--- /dev/null
+++ b/app/views/admin/runners/show.html.haml
@@ -0,0 +1,8 @@
+- add_page_specific_style 'page_bundles/ci_status'
+
+- title = "##{@runner.id} (#{@runner.short_sha})"
+- breadcrumb_title title
+- page_title title
+- add_to_breadcrumbs _('Runners'), admin_runners_path
+
+-# Empty view in development behind feature flag runner_read_only_admin_view
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index 321d492f0f3..54689df4d7b 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -90,37 +90,6 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
def handle_failure(error)
return unless raw.present?
- can_retry = false
- reason =
- case error
- when Gitlab::Email::UnknownIncomingEmail
- s_("EmailError|We couldn't figure out what the email is for. Please create your issue or comment through the web interface.")
- when Gitlab::Email::SentNotificationNotFoundError
- s_("EmailError|We couldn't figure out what the email is in reply to. Please create your comment through the web interface.")
- when Gitlab::Email::ProjectNotFound
- s_("EmailError|We couldn't find the project. Please check if there's any typo.")
- when Gitlab::Email::EmptyEmailError
- can_retry = true
- s_("EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies.")
- when Gitlab::Email::UserNotFoundError
- s_("EmailError|We couldn't figure out what user corresponds to the email. Please create your comment through the web interface.")
- when Gitlab::Email::UserBlockedError
- s_("EmailError|Your account has been blocked. If you believe this is in error, contact a staff member.")
- when Gitlab::Email::UserNotAuthorizedError
- s_("EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member.")
- when Gitlab::Email::NoteableNotFoundError
- s_("EmailError|The thread you are replying to no longer exists, perhaps it was deleted? If you believe this is in error, contact a staff member.")
- when Gitlab::Email::InvalidAttachment
- error.message
- when Gitlab::Email::InvalidRecordError
- can_retry = true
- error.message
- end
-
- if reason
- receiver.mail.body = nil
-
- EmailRejectionMailer.rejection(reason, receiver.mail.encoded, can_retry).deliver_later
- end
+ Gitlab::Email::FailureHandler.handle(receiver, error)
end
end