Commit ed265429 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 082c051b2db8
......@@ -11,18 +11,19 @@ import {
GlModalDirective,
GlTooltipDirective,
} from '@gitlab/ui';
import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue';
import { s__ } from '~/locale';
import createFlash from '~/flash';
import Icon from '~/vue_shared/components/icon.vue';
import { getParameterValues, mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
import invalidUrl from '~/lib/utils/invalid_url';
import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue';
import DateTimePicker from './date_time_picker/date_time_picker.vue';
import MonitorTimeSeriesChart from './charts/time_series.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue';
import { getTimeDiff, isValidDate } from '../utils';
import TrackEventDirective from '~/vue_shared/directives/track_event';
import { getTimeDiff, isValidDate, getAddMetricTrackingOptions } from '../utils';
export default {
components: {
......@@ -43,6 +44,7 @@ export default {
directives: {
GlModal: GlModalDirective,
GlTooltip: GlTooltipDirective,
TrackEvent: TrackEventDirective,
},
props: {
externalDashboardUrl: {
......@@ -298,6 +300,7 @@ export default {
onDateTimePickerApply(timeWindowUrlParams) {
return redirectTo(mergeUrlParams(timeWindowUrlParams, window.location.href));
},
getAddMetricTrackingOptions,
},
addMetric: {
title: s__('Metrics|Add metric'),
......@@ -389,9 +392,10 @@ export default {
</gl-button>
<gl-button
v-if="addingMetricsAvailable"
ref="addMetricBtn"
v-gl-modal="$options.addMetric.modalId"
variant="outline-success"
class="mr-2 mt-1 js-add-metric-button"
class="mr-2 mt-1"
>
{{ $options.addMetric.title }}
</gl-button>
......@@ -411,6 +415,8 @@ export default {
<div slot="modal-footer">
<gl-button @click="hideAddMetricModal">{{ __('Cancel') }}</gl-button>
<gl-button
ref="submitCustomMetricsFormBtn"
v-track-event="getAddMetricTrackingOptions()"
:disabled="!formIsValid"
variant="success"
@click="submitCustomMetricsForm"
......
......@@ -115,6 +115,7 @@ export const generateLinkToChartOptions = chartLink => {
/**
* Tracks snowplow event when user downloads CSV of cluster metric
* @param {String} chart title that will be sent as a property for the event
* @return {Object} config object for event tracking
*/
export const downloadCSVOptions = title => {
const isCLusterHealthBoard = isClusterHealthBoard();
......@@ -129,6 +130,18 @@ export const downloadCSVOptions = title => {
return { category, action, label: 'Chart title', property: title };
};
/**
* Generate options for snowplow to track adding a new metric via the dashboard
* custom metric modal
* @return {Object} config object for event tracking
*/
export const getAddMetricTrackingOptions = () => ({
category: document.body.dataset.page,
action: 'click_button',
label: 'add_new_metric',
property: 'modal',
});
/**
* This function validates the graph data contains exactly 3 metrics plus
* value validations from graphDataValidatorForValues.
......
......@@ -15,7 +15,6 @@
}
.tree-controls {
display: flex;
text-align: right;
.btn {
......
......@@ -55,6 +55,7 @@ def render_index_json
render json: {
errors: serialize_errors(result[:issues]),
pagination: result[:pagination],
external_url: service.external_url
}
end
......@@ -111,7 +112,7 @@ def handle_errors(result)
end
def list_issues_params
params.permit([:search_term, :sort])
params.permit(:search_term, :sort, :cursor)
end
def list_projects_params
......
......@@ -301,7 +301,8 @@ def visible_attributes
:snowplow_iglu_registry_url,
:push_event_hooks_limit,
:push_event_activities_limit,
:custom_http_clone_url_root
:custom_http_clone_url_root,
:snippet_size_limit
]
end
......
......@@ -226,6 +226,8 @@ class ApplicationSetting < ApplicationRecord
validates :push_event_activities_limit,
numericality: { greater_than_or_equal_to: 0 }
validates :snippet_size_limit, numericality: { only_integer: true, greater_than: 0 }
SUPPORTED_KEY_TYPES.each do |type|
validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type }
end
......
......@@ -26,7 +26,8 @@ module ApplicationSettingImplementation
'/users',
'/users/confirmation',
'/unsubscribes/',
'/import/github/personal_access_token'
'/import/github/personal_access_token',
'/admin/session'
].freeze
class_methods do
......@@ -139,7 +140,8 @@ def defaults
snowplow_app_id: nil,
snowplow_iglu_registry_url: nil,
custom_http_clone_url_root: nil,
productivity_analytics_start_date: Time.now
productivity_analytics_start_date: Time.now,
snippet_size_limit: 50.megabytes
}
end
......
......@@ -104,7 +104,7 @@ def issue_latest_event(opts = {})
def calculate_reactive_cache(request, opts)
case request
when 'list_issues'
{ issues: sentry_client.list_issues(**opts.symbolize_keys) }
sentry_client.list_issues(**opts.symbolize_keys)
when 'issue_details'
{
issue: sentry_client.issue_details(**opts.symbolize_keys)
......
......@@ -170,6 +170,7 @@ class Project < ApplicationRecord
has_one :microsoft_teams_service
has_one :packagist_service
has_one :hangouts_chat_service
has_one :unify_circuit_service
has_one :root_of_fork_network,
foreign_key: 'root_project_id',
......
# frozen_string_literal: true
class UnifyCircuitService < ChatNotificationService
def title
'Unify Circuit'
end
def description
'Receive event notifications in Unify Circuit'
end
def self.to_param
'unify_circuit'
end
def help
'This service sends notifications about projects events to a Unify Circuit conversation.<br />
To set up this service:
<ol>
<li><a href="https://www.circuit.com/unifyportalfaqdetail?articleId=164448">Set up an incoming webhook for your conversation</a>. All notifications will come to this conversation.</li>
<li>Paste the <strong>Webhook URL</strong> into the field below.</li>
<li>Select events below to enable notifications.</li>
</ol>'
end
def event_field(event)
end
def default_channel_placeholder
end
def self.supported_events
%w[push issue confidential_issue merge_request note confidential_note tag_push
pipeline wiki_page]
end
def default_fields
[
{ type: 'text', name: 'webhook', placeholder: "e.g. https://circuit.com/rest/v2/webhooks/incoming/…", required: true },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
{ type: 'select', name: 'branches_to_be_notified', choices: BRANCH_CHOICES }
]
end
private
def notify(message, opts)
response = Gitlab::HTTP.post(webhook, body: {
subject: message.project_name,
text: message.pretext,
markdown: true
}.to_json)
response if response.success?
end
def custom_data(data)
super(data).merge(markdown: true)
end
end
......@@ -289,6 +289,7 @@ def self.available_services_names
slack
teamcity
microsoft_teams
unify_circuit
]
if Rails.env.development?
......
......@@ -46,6 +46,18 @@ def content_html_invalidated?
length: { maximum: 255 }
validates :content, presence: true
validates :content,
length: {
maximum: ->(_) { Gitlab::CurrentSettings.snippet_size_limit },
message: -> (_, data) do
current_value = ActiveSupport::NumberHelper.number_to_human_size(data[:value].size)
max_size = ActiveSupport::NumberHelper.number_to_human_size(Gitlab::CurrentSettings.snippet_size_limit)
_("is too long (%{current_value}). The maximum size is %{max_size}.") % { current_value: current_value, max_size: max_size }
end
},
if: :content_changed?
validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values }
# Scopes
......
......@@ -6,37 +6,24 @@ class ListIssuesService < ErrorTracking::BaseService
DEFAULT_LIMIT = 20
DEFAULT_SORT = 'last_seen'
def execute
return error('Error Tracking is not enabled') unless enabled?
return error('Access denied', :unauthorized) unless can_read?
result = project_error_tracking_setting.list_sentry_issues(
issue_status: issue_status,
limit: limit,
search_term: search_term,
sort: sort
)
# our results are not yet ready
unless result
return error('Not ready. Try again later', :no_content)
end
if result[:error].present?
return error(result[:error], http_status_for(result[:error_type]))
end
success(issues: result[:issues])
end
def external_url
project_error_tracking_setting&.sentry_external_url
end
private
def fetch
project_error_tracking_setting.list_sentry_issues(
issue_status: issue_status,
limit: limit,
search_term: params[:search_term].presence,
sort: sort,
cursor: params[:cursor].presence
)
end
def parse_response(response)
{ issues: response[:issues] }
response.slice(:issues, :pagination)
end
def issue_status
......@@ -47,18 +34,6 @@ def limit
params[:limit] || DEFAULT_LIMIT
end
def search_term
params[:search_term].presence
end
def enabled?
project_error_tracking_setting&.enabled?
end
def can_read?
can?(current_user, :read_sentry_issue, project)
end
def sort
params[:sort] || DEFAULT_SORT
end
......
......@@ -15,7 +15,7 @@
%li.breadcrumb-item
= link_to truncate(title, length: 40), browse_project_job_artifacts_path(@project, @build, path)
.tree-controls
.tree-controls<
= link_to download_project_job_artifacts_path(@project, @build),
rel: 'nofollow', download: '', class: 'btn btn-default download' do
= sprite_icon('download')
......
......@@ -17,21 +17,19 @@
- else
= link_to title, project_tree_path(@project, tree_join(@ref, path))
.tree-controls
.tree-controls<
= render 'projects/find_file_link'
-# only show normal/blame view links for text files
- if blob.readable_text?
- if blame
= link_to 'Normal view', project_blob_path(@project, @id),
class: 'btn'
- else
= link_to 'Blame', project_blame_path(@project, @id),
class: 'btn js-blob-blame-link' unless blob.empty?
.btn-group{ role: "group" }<
-# only show normal/blame view links for text files
- if blob.readable_text?
- if blame
= link_to 'Normal view', project_blob_path(@project, @id),
class: 'btn'
- else
= link_to 'Blame', project_blame_path(@project, @id),
class: 'btn js-blob-blame-link' unless blob.empty?
= link_to 'History', project_commits_path(@project, @id),
class: 'btn'
= link_to 'History', project_commits_path(@project, @id),
class: 'btn'
= link_to 'Permalink', project_blob_path(@project,
tree_join(@commit.sha, @path)), class: 'btn js-data-file-blob-permalink-url'
= link_to 'Permalink', project_blob_path(@project,
tree_join(@commit.sha, @path)), class: 'btn js-data-file-blob-permalink-url'
......@@ -7,7 +7,7 @@
- show_menu = can_create_issue || can_create_project_snippet || can_push_code || create_mr_from_new_fork || merge_project
- if show_menu
.project-action-button.dropdown.inline
.project-action-button.dropdown.inline<
%a.btn.dropdown-toggle.has-tooltip.qa-create-new-dropdown{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...'), 'data-display' => 'static' }
= icon('plus')
= icon("caret-down")
......
......@@ -13,7 +13,7 @@
%ul.breadcrumb.repo-breadcrumb
= commits_breadcrumbs
.tree-controls.d-none.d-sm-none.d-md-block
.tree-controls.d-none.d-sm-none.d-md-block<
- if @merge_request.present?
.control
= link_to _("View open merge request"), project_merge_request_path(@project, @merge_request), class: 'btn'
......
......@@ -75,7 +75,7 @@
= link_to new_project_tag_path(@project) do
#{ _('New tag') }
.tree-controls
.tree-controls<
= render_if_exists 'projects/tree/lock_link'
- if vue_file_list_enabled?
#js-tree-history-link.d-inline-block{ data: { history_link: project_commits_path(@project, @ref) } }
......@@ -85,20 +85,19 @@
= render 'projects/find_file_link'
- if can_create_mr_from_fork
= succeed " " do
- if can_collaborate || current_user&.already_forked?(@project)
- if vue_file_list_enabled?
#js-tree-web-ide-link.d-inline-block
- else
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
= _('Web IDE')
- if can_collaborate || current_user&.already_forked?(@project)
- if vue_file_list_enabled?
#js-tree-web-ide-link.d-inline-block
- else
= link_to '#modal-confirm-fork', class: 'btn btn-default qa-web-ide-button', data: { target: '#modal-confirm-fork', toggle: 'modal'} do
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
= _('Web IDE')
= render 'shared/confirm_fork_modal', fork_path: ide_fork_and_edit_path(@project, @ref, @path)
- else
= link_to '#modal-confirm-fork', class: 'btn btn-default qa-web-ide-button', data: { target: '#modal-confirm-fork', toggle: 'modal'} do
= _('Web IDE')
= render 'shared/confirm_fork_modal', fork_path: ide_fork_and_edit_path(@project, @ref, @path)
- if show_xcode_link?(@project)
.project-action-button.project-xcode.inline
.project-action-button.project-xcode.inline<
= render "projects/buttons/xcode_link"
= render 'projects/buttons/download', project: @project, ref: @ref
---
title: Track adding metric via monitoring dashboard
merge_request: 20818
author:
type: added
---
title: Remove whitespaces between tree-controls elements
merge_request: 20952
author:
type: other
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment