diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/manual_ordering.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/tracking.js | 67 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/common.scss | 1 | ||||
-rw-r--r-- | app/controllers/groups_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/projects/issues_controller.rb | 4 | ||||
-rw-r--r-- | app/models/application_setting_implementation.rb | 11 | ||||
-rw-r--r-- | app/models/environment.rb | 2 | ||||
-rw-r--r-- | app/models/note.rb | 4 | ||||
-rw-r--r-- | app/services/application_settings/update_service.rb | 9 | ||||
-rw-r--r-- | app/services/self_monitoring/project/create_service.rb | 32 | ||||
-rw-r--r-- | app/views/projects/mirrors/_instructions.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/settings/ci_cd/_form.html.haml | 2 | ||||
-rw-r--r-- | app/views/shared/issuable/_search_bar.html.haml | 5 | ||||
-rw-r--r-- | app/views/shared/issuable/_sort_dropdown.html.haml | 2 | ||||
-rw-r--r-- | app/views/u2f/_register.html.haml | 2 |
15 files changed, 127 insertions, 22 deletions
diff --git a/app/assets/javascripts/manual_ordering.js b/app/assets/javascripts/manual_ordering.js index 012d1e70410..29a0e5a904a 100644 --- a/app/assets/javascripts/manual_ordering.js +++ b/app/assets/javascripts/manual_ordering.js @@ -21,7 +21,7 @@ const updateIssue = (url, issueList, { move_before_id, move_after_id }) => const initManualOrdering = () => { const issueList = document.querySelector('.manual-ordering'); - if (!issueList || !(gon.features && gon.features.manualSorting) || !(gon.current_user_id > 0)) { + if (!issueList || !(gon.current_user_id > 0)) { return; } diff --git a/app/assets/javascripts/tracking.js b/app/assets/javascripts/tracking.js new file mode 100644 index 00000000000..2d0b099cf0b --- /dev/null +++ b/app/assets/javascripts/tracking.js @@ -0,0 +1,67 @@ +import $ from 'jquery'; + +const extractData = (el, opts = {}) => { + const { trackEvent, trackLabel = '', trackProperty = '' } = el.dataset; + let trackValue = el.dataset.trackValue || el.value || ''; + if (el.type === 'checkbox' && !el.checked) trackValue = false; + return [ + trackEvent + (opts.suffix || ''), + { + label: trackLabel, + property: trackProperty, + value: trackValue, + }, + ]; +}; + +export default class Tracking { + static enabled() { + return typeof window.snowplow === 'function'; + } + + static event(category = document.body.dataset.page, event = 'generic', data = {}) { + if (!this.enabled()) return false; + // eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings + if (!category) throw new Error('Tracking: no category provided for tracking.'); + + return window.snowplow( + 'trackStructEvent', + category, + event, + Object.assign({}, { label: '', property: '', value: '' }, data), + ); + } + + constructor(category = document.body.dataset.page) { + this.category = category; + } + + bind(container = document) { + if (!this.constructor.enabled()) return; + container.querySelectorAll(`[data-track-event]`).forEach(el => { + if (this.customHandlingFor(el)) return; + // jquery is required for select2, so we use it always + // see: https://github.com/select2/select2/issues/4686 + $(el).on('click', this.eventHandler(this.category)); + }); + } + + customHandlingFor(el) { + const classes = el.classList; + + // bootstrap dropdowns + if (classes.contains('dropdown')) { + $(el).on('show.bs.dropdown', this.eventHandler(this.category, { suffix: '_show' })); + $(el).on('hide.bs.dropdown', this.eventHandler(this.category, { suffix: '_hide' })); + return true; + } + + return false; + } + + eventHandler(category = null, opts = {}) { + return e => { + this.constructor.event(category || this.category, ...extractData(e.currentTarget, opts)); + }; + } +} diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 6b44834cc52..f384a49e0ae 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -435,6 +435,7 @@ img.emoji { /** COMMON SIZING CLASSES **/ .w-0 { width: 0; } .w-8em { width: 8em; } +.w-3rem { width: 3rem; } .h-12em { height: 12em; } diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index dda321bac79..5472ef05d7c 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -7,10 +7,6 @@ class GroupsController < Groups::ApplicationController include PreviewMarkdown include RecordUserLastActivity - before_action do - push_frontend_feature_flag(:manual_sorting, default_enabled: true) - end - respond_to :html prepend_before_action(only: [:show, :issues]) { authenticate_sessionless_user!(:rss) } diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index db7ca7ef0d7..bc9166b9df3 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -10,10 +10,6 @@ class Projects::IssuesController < Projects::ApplicationController include SpammableActions include RecordUserLastActivity - before_action do - push_frontend_feature_flag(:manual_sorting, default_enabled: true) - end - def issue_except_actions %i[index calendar new create bulk_update import_csv] end diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index 6efd07a6008..4bb09bf3b53 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -158,9 +158,20 @@ module ApplicationSettingImplementation end def outbound_local_requests_whitelist_raw=(values) + clear_memoization(:outbound_local_requests_whitelist_arrays) + self.outbound_local_requests_whitelist = domain_strings_to_array(values) end + def add_to_outbound_local_requests_whitelist(values_array) + clear_memoization(:outbound_local_requests_whitelist_arrays) + + self.outbound_local_requests_whitelist ||= [] + self.outbound_local_requests_whitelist += values_array + + self.outbound_local_requests_whitelist.uniq! + end + def outbound_local_requests_whitelist_arrays strong_memoize(:outbound_local_requests_whitelist_arrays) do next [[], []] unless self.outbound_local_requests_whitelist diff --git a/app/models/environment.rb b/app/models/environment.rb index 392481ea0cc..513427ac2c5 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -204,7 +204,7 @@ class Environment < ApplicationRecord public_path = project.public_path_for_source_path(path, commit_sha) return unless public_path - [external_url, public_path].join('/') + [external_url.delete_suffix('/'), public_path.delete_prefix('/')].join('/') end def expire_etag_cache diff --git a/app/models/note.rb b/app/models/note.rb index 3f182c1f099..a12d1eb7243 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -27,6 +27,10 @@ class Note < ApplicationRecord def values constants.map {|const| self.const_get(const)} end + + def value?(val) + values.include?(val) + end end end diff --git a/app/services/application_settings/update_service.rb b/app/services/application_settings/update_service.rb index 7eeaf8aade1..471df6e2d0c 100644 --- a/app/services/application_settings/update_service.rb +++ b/app/services/application_settings/update_service.rb @@ -15,6 +15,8 @@ module ApplicationSettings update_terms(@params.delete(:terms)) + add_to_outbound_local_requests_whitelist(@params.delete(:add_to_outbound_local_requests_whitelist)) + if params.key?(:performance_bar_allowed_group_path) params[:performance_bar_allowed_group_id] = performance_bar_allowed_group_id end @@ -32,6 +34,13 @@ module ApplicationSettings params.key?(:usage_ping_enabled) || params.key?(:version_check_enabled) end + def add_to_outbound_local_requests_whitelist(values) + values_array = Array(values).reject(&:empty?) + return if values_array.empty? + + @application_setting.add_to_outbound_local_requests_whitelist(values_array) + end + def update_terms(terms) return unless terms.present? diff --git a/app/services/self_monitoring/project/create_service.rb b/app/services/self_monitoring/project/create_service.rb index e5ef8c15456..8ffd22de127 100644 --- a/app/services/self_monitoring/project/create_service.rb +++ b/app/services/self_monitoring/project/create_service.rb @@ -14,6 +14,7 @@ module SelfMonitoring steps :validate_admins, :create_project, :add_project_members, + :add_to_whitelist, :add_prometheus_manual_configuration def initialize @@ -59,15 +60,29 @@ module SelfMonitoring end end - def add_prometheus_manual_configuration + def add_to_whitelist return success unless prometheus_enabled? return success unless prometheus_listen_address.present? - # TODO: Currently, adding the internal prometheus server as a manual configuration - # is only possible if the setting to allow webhooks and services to connect - # to local network is on. - # https://gitlab.com/gitlab-org/gitlab-ce/issues/44496 will add - # a whitelist that will allow connections to certain ips on the local network. + uri = parse_url(internal_prometheus_listen_address_uri) + return error(_('Prometheus listen_address is not a valid URI')) unless uri + + result = ApplicationSettings::UpdateService.new( + Gitlab::CurrentSettings.current_application_settings, + project_owner, + outbound_local_requests_whitelist: [uri.normalized_host] + ).execute + + if result + success + else + error(_('Could not add prometheus URL to whitelist')) + end + end + + def add_prometheus_manual_configuration + return success unless prometheus_enabled? + return success unless prometheus_listen_address.present? service = project.find_or_initialize_service('prometheus') @@ -79,6 +94,11 @@ module SelfMonitoring success end + def parse_url(uri_string) + Addressable::URI.parse(uri_string) + rescue Addressable::URI::InvalidURIError, TypeError + end + def prometheus_enabled? Gitlab.config.prometheus.enable rescue Settingslogic::MissingSetting diff --git a/app/views/projects/mirrors/_instructions.html.haml b/app/views/projects/mirrors/_instructions.html.haml index 33e5a6e67c3..1a163cc4a54 100644 --- a/app/views/projects/mirrors/_instructions.html.haml +++ b/app/views/projects/mirrors/_instructions.html.haml @@ -2,7 +2,7 @@ %ul %li = _('The repository must be accessible over <code>http://</code>, - <code>https://</code>, <code>ssh://</code> and <code>git://</code>.').html_safe + <code>https://</code>, <code>ssh://</code> or <code>git://</code>.').html_safe %li= _('Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>.').html_safe %li - minutes = Gitlab.config.gitlab_shell.git_timeout / 60 diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml index 2d108a1cba5..498a9744783 100644 --- a/app/views/projects/settings/ci_cd/_form.html.haml +++ b/app/views/projects/settings/ci_cd/_form.html.haml @@ -99,7 +99,7 @@ %code \(\d+.\d+\%\) covered %li pytest-cov (Python) - - %code ^TOTAL\s+\d+\s+\d+\s+(\d+\%)$ + %code ^TOTAL.+?(\d+\%)$ %li phpunit --coverage-text --colors=never (PHP) - %code ^\s*Lines:\s*\d+.\d+\% diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index e253413929a..c9458475aa5 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -1,6 +1,7 @@ - type = local_assigns.fetch(:type) - board = local_assigns.fetch(:board, nil) -- block_css_class = type != :boards_modal ? 'row-content-block second-block' : '' +- is_not_boards_modal_or_productivity_analytics = type != :boards_modal && type != :productivity_analytics +- block_css_class = is_not_boards_modal_or_productivity_analytics ? 'row-content-block second-block' : '' - user_can_admin_list = board && can?(current_user, :admin_list, board.parent) .issues-filters{ class: ("w-100" if type == :boards_modal) } @@ -155,5 +156,5 @@ - if @project #js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } } #js-toggle-focus-btn - - elsif type != :boards_modal + - elsif is_not_boards_modal_or_productivity_analytics = render 'shared/issuable/sort_dropdown' diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml index df0523595f5..8260915c2ab 100644 --- a/app/views/shared/issuable/_sort_dropdown.html.haml +++ b/app/views/shared/issuable/_sort_dropdown.html.haml @@ -1,7 +1,7 @@ - sort_value = @sort - sort_title = issuable_sort_option_title(sort_value) - viewing_issues = controller.controller_name == 'issues' || controller.action_name == 'issues' -- manual_sorting = viewing_issues && controller.controller_name != 'dashboard' && Feature.enabled?(:manual_sorting, default_enabled: true) +- manual_sorting = viewing_issues && controller.controller_name != 'dashboard' .dropdown.inline.prepend-left-10.issue-sort-dropdown .btn-group{ role: 'group' } diff --git a/app/views/u2f/_register.html.haml b/app/views/u2f/_register.html.haml index f6724f72307..ef3835332a7 100644 --- a/app/views/u2f/_register.html.haml +++ b/app/views/u2f/_register.html.haml @@ -16,7 +16,7 @@ .col-md-4 %button#js-setup-u2f-device.btn.btn-info.btn-block{ disabled: true }= _("Set up new U2F device") .col-md-8 - %p.text-warning= _("You need to register a two-factor authentication app before you can set up a U2F device.") + %p= _("You need to register a two-factor authentication app before you can set up a U2F device.") %script#js-register-u2f-in-progress{ type: "text/template" } %p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.") |