Skip to content
Snippets Groups Projects
Commit 0a6ffb54 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent a0482614
No related branches found
No related tags found
No related merge requests found
Showing
with 177 additions and 238 deletions
Loading
Loading
@@ -101,7 +101,7 @@ gem 'hashie-forbidden_attributes'
gem 'kaminari', '~> 1.0'
 
# HAML
gem 'hamlit', '~> 2.8.8'
gem 'hamlit', '~> 2.10.0'
 
# Files attachments
gem 'carrierwave', '~> 1.3'
Loading
Loading
@@ -135,7 +135,7 @@ gem 'aws-sdk'
gem 'faraday_middleware-aws-signers-v4'
 
# Markdown and HTML processing
gem 'html-pipeline', '~> 2.8'
gem 'html-pipeline', '~> 2.12'
gem 'deckar01-task_list', '2.2.1'
gem 'gitlab-markup', '~> 1.7.0'
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
Loading
Loading
@@ -373,7 +373,7 @@ group :development, :test do
gem 'rubocop-rspec', '~> 1.22.1'
 
gem 'scss_lint', '~> 0.56.0', require: false
gem 'haml_lint', '~> 0.31.0', require: false
gem 'haml_lint', '~> 0.34.0', require: false
gem 'simplecov', '~> 0.16.1', require: false
gem 'bundler-audit', '~> 0.5.0', require: false
 
Loading
Loading
Loading
Loading
@@ -460,17 +460,16 @@ GEM
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
haml (5.0.4)
haml (5.1.2)
temple (>= 0.8.0)
tilt
haml_lint (0.31.0)
haml (>= 4.0, < 5.1)
haml_lint (0.34.0)
haml (>= 4.0, < 5.2)
rainbow
rake (>= 10, < 13)
rubocop (>= 0.50.0)
sysexits (~> 1.1)
hamlit (2.8.8)
temple (>= 0.8.0)
hamlit (2.10.0)
temple (>= 0.8.2)
thor
tilt
hangouts-chat (0.0.5)
Loading
Loading
@@ -484,7 +483,7 @@ GEM
hipchat (1.5.2)
httparty
mimemagic
html-pipeline (2.8.4)
html-pipeline (2.12.2)
activesupport (>= 2)
nokogiri (>= 1.4)
html2text (0.2.0)
Loading
Loading
@@ -1017,7 +1016,7 @@ GEM
sys-filesystem (1.1.6)
ffi
sysexits (1.2.0)
temple (0.8.1)
temple (0.8.2)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
test-prof (0.10.0)
Loading
Loading
@@ -1219,13 +1218,13 @@ DEPENDENCIES
grpc (~> 1.24.0)
gssapi
guard-rspec
haml_lint (~> 0.31.0)
hamlit (~> 2.8.8)
haml_lint (~> 0.34.0)
hamlit (~> 2.10.0)
hangouts-chat (~> 0.0.5)
hashie-forbidden_attributes
health_check (~> 2.6.0)
hipchat (~> 1.5.0)
html-pipeline (~> 2.8)
html-pipeline (~> 2.12)
html2text
httparty (~> 0.16.4)
icalendar
Loading
Loading
/* eslint-disable func-names, no-underscore-dangle, no-var, one-var, vars-on-top, no-cond-assign, no-return-assign, no-else-return, camelcase, no-lonely-if, guard-for-in, no-restricted-syntax, consistent-return, no-param-reassign, no-loop-func */
/* eslint-disable func-names, no-underscore-dangle, one-var, no-cond-assign, no-return-assign, no-else-return, camelcase, no-lonely-if, guard-for-in, no-restricted-syntax, consistent-return, no-param-reassign, no-loop-func */
 
import $ from 'jquery';
import _ from 'underscore';
Loading
Loading
@@ -33,13 +33,12 @@ const FILTER_INPUT = '.dropdown-input .dropdown-input-field:not(.dropdown-no-fil
const NO_FILTER_INPUT = '.dropdown-input .dropdown-input-field.dropdown-no-filter';
 
function GitLabDropdownInput(input, options) {
var $inputContainer, $clearButton;
var _this = this;
const _this = this;
this.input = input;
this.options = options;
this.fieldName = this.options.fieldName || 'field-name';
$inputContainer = this.input.parent();
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
const $inputContainer = this.input.parent();
const $clearButton = $inputContainer.find('.js-dropdown-input-clear');
$clearButton.on('click', e => {
// Clear click
e.preventDefault();
Loading
Loading
@@ -52,13 +51,13 @@ function GitLabDropdownInput(input, options) {
 
this.input
.on('keydown', e => {
var keyCode = e.which;
const keyCode = e.which;
if (keyCode === 13 && !options.elIsInput) {
e.preventDefault();
}
})
.on('input', e => {
var val = e.currentTarget.value || _this.options.inputFieldName;
let val = e.currentTarget.value || _this.options.inputFieldName;
val = val
.split(' ')
.join('-') // replaces space with dash
Loading
Loading
@@ -78,12 +77,12 @@ GitLabDropdownInput.prototype.onInput = function(cb) {
};
 
function GitLabDropdownFilter(input, options) {
var $clearButton, $inputContainer, ref, timeout;
let ref, timeout;
this.input = input;
this.options = options;
this.filterInputBlur = (ref = this.options.filterInputBlur) != null ? ref : true;
$inputContainer = this.input.parent();
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
const $inputContainer = this.input.parent();
const $clearButton = $inputContainer.find('.js-dropdown-input-clear');
$clearButton.on('click', e => {
// Clear click
e.preventDefault();
Loading
Loading
@@ -97,7 +96,7 @@ function GitLabDropdownFilter(input, options) {
timeout = '';
this.input
.on('keydown', e => {
var keyCode = e.which;
const keyCode = e.which;
if (keyCode === 13 && !options.elIsInput) {
e.preventDefault();
}
Loading
Loading
@@ -130,11 +129,11 @@ GitLabDropdownFilter.prototype.shouldBlur = function(keyCode) {
};
 
GitLabDropdownFilter.prototype.filter = function(search_text) {
var data, elements, group, key, results, tmp;
let elements, group, key, results, tmp;
if (this.options.onFilter) {
this.options.onFilter(search_text);
}
data = this.options.data();
const data = this.options.data();
if (data != null && !this.options.filterByText) {
results = data;
if (search_text !== '') {
Loading
Loading
@@ -178,9 +177,8 @@ GitLabDropdownFilter.prototype.filter = function(search_text) {
elements = this.options.elements();
if (search_text) {
elements.each(function() {
var $el, matches;
$el = $(this);
matches = fuzzaldrinPlus.match($el.text().trim(), search_text);
const $el = $(this);
const matches = fuzzaldrinPlus.match($el.text().trim(), search_text);
if (!$el.is('.dropdown-header')) {
if (matches.length) {
return $el.show().removeClass('option-hidden');
Loading
Loading
@@ -238,7 +236,7 @@ GitLabDropdownRemote.prototype.fetchData = function() {
};
 
function GitLabDropdown(el1, options) {
var searchFields, selector, self;
let selector, self;
this.el = el1;
this.options = options;
this.updateLabel = this.updateLabel.bind(this);
Loading
Loading
@@ -260,7 +258,7 @@ function GitLabDropdown(el1, options) {
if (_.isString(this.filterInput)) {
this.filterInput = this.getElement(this.filterInput);
}
searchFields = this.options.search ? this.options.search.fields : [];
const searchFields = this.options.search ? this.options.search.fields : [];
if (this.options.data) {
// If we provided data
// data could be an array of objects or a group of arrays
Loading
Loading
@@ -350,7 +348,7 @@ function GitLabDropdown(el1, options) {
}
});
this.dropdown.on('blur', 'a', e => {
var $dropdownMenu, $relatedTarget;
let $dropdownMenu, $relatedTarget;
if (e.relatedTarget != null) {
$relatedTarget = $(e.relatedTarget);
$dropdownMenu = $relatedTarget.closest('.dropdown-menu');
Loading
Loading
@@ -372,11 +370,10 @@ function GitLabDropdown(el1, options) {
selector = '.dropdown-page-one .dropdown-content a';
}
this.dropdown.on('click', selector, e => {
var $el, selected, selectedObj, isMarking;
$el = $(e.currentTarget);
selected = self.rowClicked($el);
selectedObj = selected ? selected[0] : null;
isMarking = selected ? selected[1] : null;
const $el = $(e.currentTarget);
const selected = self.rowClicked($el);
const selectedObj = selected ? selected[0] : null;
const isMarking = selected ? selected[1] : null;
if (this.options.clicked) {
this.options.clicked.call(this, {
selectedObj,
Loading
Loading
@@ -406,8 +403,7 @@ GitLabDropdown.prototype.toggleLoading = function() {
};
 
GitLabDropdown.prototype.togglePage = function() {
var menu;
menu = $('.dropdown-menu', this.dropdown);
const menu = $('.dropdown-menu', this.dropdown);
if (menu.hasClass(PAGE_TWO_CLASS)) {
if (this.remote) {
this.remote.execute();
Loading
Loading
@@ -419,7 +415,7 @@ GitLabDropdown.prototype.togglePage = function() {
};
 
GitLabDropdown.prototype.parseData = function(data) {
var full_html, groupData, html, name;
let groupData, html, name;
this.renderedData = data;
if (this.options.filterable && data.length === 0) {
// render no matching results
Loading
Loading
@@ -447,7 +443,7 @@ GitLabDropdown.prototype.parseData = function(data) {
}
}
// Render the full menu
full_html = this.renderMenu(html);
const full_html = this.renderMenu(html);
return this.appendMenu(full_html);
};
 
Loading
Loading
@@ -456,7 +452,7 @@ GitLabDropdown.prototype.renderData = function(data, group) {
};
 
GitLabDropdown.prototype.shouldPropagate = function(e) {
var $target;
let $target;
if (this.options.multiSelect || this.options.shouldPropagate === false) {
$target = $(e.target);
if (
Loading
Loading
@@ -487,7 +483,6 @@ GitLabDropdown.prototype.filteredFullData = function() {
};
 
GitLabDropdown.prototype.opened = function(e) {
var contentHtml;
this.resetRows();
this.addArrowKeyEvent();
 
Loading
Loading
@@ -513,7 +508,7 @@ GitLabDropdown.prototype.opened = function(e) {
);
}
 
contentHtml = $('.dropdown-content', this.dropdown).html();
const contentHtml = $('.dropdown-content', this.dropdown).html();
if (this.remote && contentHtml === '') {
this.remote.execute();
} else {
Loading
Loading
@@ -536,7 +531,7 @@ GitLabDropdown.prototype.opened = function(e) {
};
 
GitLabDropdown.prototype.positionMenuAbove = function() {
var $menu = this.dropdown.find('.dropdown-menu');
const $menu = this.dropdown.find('.dropdown-menu');
 
$menu.addClass('dropdown-open-top');
$menu.css('top', 'initial');
Loading
Loading
@@ -544,10 +539,9 @@ GitLabDropdown.prototype.positionMenuAbove = function() {
};
 
GitLabDropdown.prototype.hidden = function(e) {
var $input;
this.resetRows();
this.removeArrowKeyEvent();
$input = this.dropdown.find('.dropdown-input-field');
const $input = this.dropdown.find('.dropdown-input-field');
if (this.options.filterable) {
$input.blur();
}
Loading
Loading
@@ -575,7 +569,7 @@ GitLabDropdown.prototype.appendMenu = function(html) {
};
 
GitLabDropdown.prototype.clearMenu = function() {
var selector;
let selector;
selector = '.dropdown-content';
if (this.dropdown.find('.dropdown-toggle-page').length) {
if (this.options.containerSelector) {
Loading
Loading
@@ -635,10 +629,9 @@ GitLabDropdown.prototype.noResults = function() {
};
 
GitLabDropdown.prototype.rowClicked = function(el) {
var field, groupName, isInput, selectedIndex, selectedObject, value, isMarking;
let field, groupName, selectedIndex, selectedObject, isMarking;
const { fieldName } = this.options;
isInput = $(this.el).is('input');
const isInput = $(this.el).is('input');
if (this.renderedData) {
groupName = el.data('group');
if (groupName) {
Loading
Loading
@@ -662,7 +655,7 @@ GitLabDropdown.prototype.rowClicked = function(el) {
}
 
field = [];
value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id;
const value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id;
if (isInput) {
field = $(this.el);
} else if (value != null) {
Loading
Loading
@@ -734,13 +727,12 @@ GitLabDropdown.prototype.focusTextInput = function() {
};
 
GitLabDropdown.prototype.addInput = function(fieldName, value, selectedObject, single) {
var $input;
// Create hidden input for form
if (single) {
$(`input[name="${fieldName}"]`).remove();
}
 
$input = $('<input>')
const $input = $('<input>')
.attr('type', 'hidden')
.attr('name', fieldName)
.val(value);
Loading
Loading
@@ -762,7 +754,7 @@ GitLabDropdown.prototype.addInput = function(fieldName, value, selectedObject, s
};
 
GitLabDropdown.prototype.selectRowAtIndex = function(index) {
var $el, selector;
let selector;
// If we pass an option index
if (typeof index !== 'undefined') {
selector = `${SELECTABLE_CLASSES}:eq(${index}) a`;
Loading
Loading
@@ -773,9 +765,9 @@ GitLabDropdown.prototype.selectRowAtIndex = function(index) {
selector = `.dropdown-page-one ${selector}`;
}
// simulate a click on the first link
$el = $(selector, this.dropdown);
const $el = $(selector, this.dropdown);
if ($el.length) {
var href = $el.attr('href');
const href = $el.attr('href');
if (href && href !== '#') {
visitUrl(href);
} else {
Loading
Loading
@@ -785,15 +777,15 @@ GitLabDropdown.prototype.selectRowAtIndex = function(index) {
};
 
GitLabDropdown.prototype.addArrowKeyEvent = function() {
var ARROW_KEY_CODES, selector;
ARROW_KEY_CODES = [38, 40];
let selector;
const ARROW_KEY_CODES = [38, 40];
selector = SELECTABLE_CLASSES;
if (this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`;
}
return $('body').on('keydown', e => {
var $listItems, PREV_INDEX, currentKeyCode;
currentKeyCode = e.which;
let $listItems, PREV_INDEX;
const currentKeyCode = e.which;
if (ARROW_KEY_CODES.indexOf(currentKeyCode) !== -1) {
e.preventDefault();
e.stopImmediatePropagation();
Loading
Loading
@@ -834,16 +826,6 @@ GitLabDropdown.prototype.resetRows = function resetRows() {
};
 
GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
var $dropdownContent,
$listItem,
dropdownContentBottom,
dropdownContentHeight,
dropdownContentTop,
dropdownScrollTop,
listItemBottom,
listItemHeight,
listItemTop;
if (!$listItems) {
$listItems = $(SELECTABLE_CLASSES, this.dropdown);
}
Loading
Loading
@@ -851,18 +833,18 @@ GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
// Remove the class for the previously focused row
$('.is-focused', this.dropdown).removeClass('is-focused');
// Update the class for the row at the specific index
$listItem = $listItems.eq(index);
const $listItem = $listItems.eq(index);
$listItem.find('a:first-child').addClass('is-focused');
// Dropdown content scroll area
$dropdownContent = $listItem.closest('.dropdown-content');
dropdownScrollTop = $dropdownContent.scrollTop();
dropdownContentHeight = $dropdownContent.outerHeight();
dropdownContentTop = $dropdownContent.prop('offsetTop');
dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
const $dropdownContent = $listItem.closest('.dropdown-content');
const dropdownScrollTop = $dropdownContent.scrollTop();
const dropdownContentHeight = $dropdownContent.outerHeight();
const dropdownContentTop = $dropdownContent.prop('offsetTop');
const dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
// Get the offset bottom of the list item
listItemHeight = $listItem.outerHeight();
listItemTop = $listItem.prop('offsetTop');
listItemBottom = listItemTop + listItemHeight;
const listItemHeight = $listItem.outerHeight();
const listItemTop = $listItem.prop('offsetTop');
const listItemBottom = listItemTop + listItemHeight;
if (!index) {
// Scroll the dropdown content to the top
$dropdownContent.scrollTop(0);
Loading
Loading
Loading
Loading
@@ -169,12 +169,6 @@ export default {
<p v-if="shouldShowMetricsUnavailable" class="usage-info js-usage-info usage-info-unavailable">
{{ s__('mrWidget|Deployment statistics are not available currently') }}
</p>
<memory-graph
v-if="shouldShowMemoryGraph"
:metrics="memoryMetrics"
:deployment-time="deploymentTime"
height="25"
width="100"
/>
<memory-graph v-if="shouldShowMemoryGraph" :metrics="memoryMetrics" :height="25" :width="110" />
</div>
</template>
<script>
import { __, sprintf } from '~/locale';
import { getTimeago } from '../../lib/utils/datetime_utility';
import { formatDate, secondsToMilliseconds } from '~/lib/utils/datetime_utility';
import { GlSparklineChart } from '@gitlab/ui/dist/charts';
 
export default {
name: 'MemoryGraph',
components: {
GlSparklineChart,
},
props: {
metrics: { type: Array, required: true },
deploymentTime: { type: Number, required: true },
width: { type: String, required: true },
height: { type: String, required: true },
},
data() {
return {
pathD: '',
pathViewBox: '',
dotX: '',
dotY: '',
};
width: { type: Number, required: true },
height: { type: Number, required: true },
},
computed: {
getFormattedMedian() {
const deployedSince = getTimeago().format(this.deploymentTime * 1000);
return sprintf(__('Deployed %{deployedSince}'), { deployedSince });
chartData() {
return this.metrics.map(([x, y]) => [
this.getFormattedDeploymentTime(x),
this.getMemoryUsage(y),
]);
},
},
mounted() {
this.renderGraph(this.deploymentTime, this.metrics);
},
methods: {
/**
* Returns metric value index in metrics array
* with timestamp closest to matching median
*/
getMedianMetricIndex(median, metrics) {
let matchIndex = 0;
let timestampDiff = 0;
let smallestDiff = 0;
const metricTimestamps = metrics.map(v => v[0]);
// Find metric timestamp which is closest to deploymentTime
timestampDiff = Math.abs(metricTimestamps[0] - median);
metricTimestamps.forEach((timestamp, index) => {
if (index === 0) {
// Skip first element
return;
}
smallestDiff = Math.abs(timestamp - median);
if (smallestDiff < timestampDiff) {
matchIndex = index;
timestampDiff = smallestDiff;
}
});
return matchIndex;
getFormattedDeploymentTime(timestamp) {
return formatDate(new Date(secondsToMilliseconds(timestamp)), 'mmm dd yyyy HH:MM:s');
},
/**
* Get Graph Plotting values to render Line and Dot
*/
getGraphPlotValues(median, metrics) {
const renderData = metrics.map(v => v[1]);
const medianMetricIndex = this.getMedianMetricIndex(median, metrics);
let cx = 0;
let cy = 0;
// Find Maximum and Minimum values from `renderData` array
const maxMemory = Math.max.apply(null, renderData);
const minMemory = Math.min.apply(null, renderData);
// Find difference between extreme ends
const diff = maxMemory - minMemory;
const lineWidth = renderData.length;
// Iterate over metrics values and perform following
// 1. Find x & y co-ords for deploymentTime's memory value
// 2. Return line path against maxMemory
const linePath = renderData.map((y, x) => {
if (medianMetricIndex === x) {
cx = x;
cy = maxMemory - y;
}
return `${x} ${maxMemory - y}`;
});
return {
pathD: linePath,
pathViewBox: {
lineWidth,
diff,
},
dotX: cx,
dotY: cy,
};
},
/**
* Render Graph based on provided median and metrics values
*/
renderGraph(median, metrics) {
const { pathD, pathViewBox, dotX, dotY } = this.getGraphPlotValues(median, metrics);
// Set props and update graph on UI.
this.pathD = `M ${pathD}`;
this.pathViewBox = `0 0 ${pathViewBox.lineWidth} ${pathViewBox.diff}`;
this.dotX = dotX;
this.dotY = dotY;
getMemoryUsage(MBs) {
return Number(MBs).toFixed(2);
},
},
};
</script>
 
<template>
<div class="memory-graph-container">
<svg
:title="getFormattedMedian"
:width="width"
<div class="memory-graph-container p-1" :style="{ width: `${width}px` }">
<gl-sparkline-chart
:height="height"
class="has-tooltip"
xmlns="http://www.w3.org/2000/svg"
>
<path :d="pathD" :viewBox="pathViewBox" />
<circle :cx="dotX" :cy="dotY" r="1.5" transform="translate(0 -1)" />
</svg>
:tooltip-label="__('MB')"
:show-last-y-value="false"
:data="chartData"
/>
</div>
</template>
.memory-graph-container {
svg {
background: $white-light;
border: 1px solid $gray-200;
}
path {
fill: none;
stroke: $blue-500;
stroke-width: 2px;
}
circle {
stroke: $blue-700;
fill: $blue-700;
stroke-width: 4px;
}
background: $white-light;
border: 1px solid $gray-200;
}
Loading
Loading
@@ -949,7 +949,6 @@
.deployment-info {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 100px;
 
Loading
Loading
Loading
Loading
@@ -111,7 +111,7 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
end
 
def list_issues_params
params.permit(:search_term)
params.permit([:search_term, :sort])
end
 
def list_projects_params
Loading
Loading
# frozen_string_literal: true
module Mutations
module Todos
class Restore < ::Mutations::Todos::Base
graphql_name 'TodoRestore'
authorize :update_todo
argument :id,
GraphQL::ID_TYPE,
required: true,
description: 'The global id of the todo to restore'
field :todo, Types::TodoType,
null: false,
description: 'The requested todo'
def resolve(id:)
todo = authorized_find!(id: id)
restore(todo.id) if todo.done?
{
todo: todo.reset,
errors: errors_on_object(todo)
}
end
private
def restore(id)
TodoService.new.mark_todos_as_pending_by_ids([id], current_user)
end
end
end
end
Loading
Loading
@@ -21,6 +21,7 @@ module Types
mount_mutation Mutations::Notes::Update
mount_mutation Mutations::Notes::Destroy
mount_mutation Mutations::Todos::MarkDone
mount_mutation Mutations::Todos::Restore
end
end
 
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ module Clusters
REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts'
METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml'
FETCH_IP_ADDRESS_DELAY = 30.seconds
API_RESOURCES_PATH = 'config/knative/api_resources.yml'
API_GROUPS_PATH = 'config/knative/api_groups.yml'
 
self.table_name = 'clusters_applications_knative'
 
Loading
Loading
@@ -109,15 +109,15 @@ module Clusters
end
 
def delete_knative_and_istio_crds
api_resources.map do |crd|
Gitlab::Kubernetes::KubectlCmd.delete("--ignore-not-found", "crd", "#{crd}")
api_groups.map do |group|
Gitlab::Kubernetes::KubectlCmd.delete_crds_from_group(group)
end
end
 
# returns an array of CRDs to be postdelete since helm does not
# manage the CRDs it creates.
def api_resources
@api_resources ||= YAML.safe_load(File.read(Rails.root.join(API_RESOURCES_PATH)))
def api_groups
@api_groups ||= YAML.safe_load(File.read(Rails.root.join(API_GROUPS_PATH)))
end
 
def install_knative_metrics
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@ module ErrorTracking
include Gitlab::Utils::StrongMemoize
include ReactiveCaching
 
SENTRY_API_ERROR_TYPE_BAD_REQUEST = 'bad_request_for_sentry_api'
SENTRY_API_ERROR_TYPE_MISSING_KEYS = 'missing_keys_in_sentry_response'
SENTRY_API_ERROR_TYPE_NON_20X_RESPONSE = 'non_20x_response_from_sentry'
SENTRY_API_ERROR_INVALID_SIZE = 'invalid_size_of_sentry_response'
Loading
Loading
@@ -119,6 +120,8 @@ module ErrorTracking
{ error: e.message, error_type: SENTRY_API_ERROR_TYPE_MISSING_KEYS }
rescue Sentry::Client::ResponseInvalidSizeError => e
{ error: e.message, error_type: SENTRY_API_ERROR_INVALID_SIZE }
rescue Sentry::Client::BadRequestError => e
{ error: e.message, error_type: SENTRY_API_ERROR_TYPE_BAD_REQUEST }
end
 
# http://HOST/api/0/projects/ORG/PROJECT
Loading
Loading
Loading
Loading
@@ -4,6 +4,7 @@ module ErrorTracking
class ListIssuesService < ErrorTracking::BaseService
DEFAULT_ISSUE_STATUS = 'unresolved'
DEFAULT_LIMIT = 20
DEFAULT_SORT = 'last_seen'
 
def execute
return error('Error Tracking is not enabled') unless enabled?
Loading
Loading
@@ -12,7 +13,8 @@ module ErrorTracking
result = project_error_tracking_setting.list_sentry_issues(
issue_status: issue_status,
limit: limit,
search_term: search_term
search_term: search_term,
sort: sort
)
 
# our results are not yet ready
Loading
Loading
@@ -33,10 +35,6 @@ module ErrorTracking
 
private
 
def fetch
project_error_tracking_setting.list_sentry_issues(issue_status: issue_status, limit: limit)
end
def parse_response(response)
{ issues: response[:issues] }
end
Loading
Loading
@@ -60,5 +58,9 @@ module ErrorTracking
def can_read?
can?(current_user, :read_sentry_issue, project)
end
def sort
params[:sort] || DEFAULT_SORT
end
end
end
---
title: Improve sparkline chart in MR widget deployment
merge_request: 20085
author:
type: other
---
title: Add GraphQL mutation to restore a Todo
merge_request: 20261
author:
type: added
---
title: Add sort param to error tracking issue index
merge_request: 20101
author:
type: changed
---
title: Drop deprecated column from projects table
merge_request: 18914
author:
type: deprecated
---
title: replace var gl_dropdown.js
merge_request: 20166
author: nuwe1
type: other
module Hamlit
class TemplateHandler
def call(template)
Engine.new(
generator: Temple::Generators::RailsOutputBuffer,
attr_quote: '"'
).call(template.source)
end
end
end
ActionView::Template.register_template_handler(
:haml,
Hamlit::TemplateHandler.new
)
Hamlit::RailsTemplate.set_options(attr_quote: '"')
 
Hamlit::Filters.remove_filter('coffee')
Hamlit::Filters.remove_filter('coffeescript')
---
- networking.istio.io
- rbac.istio.io
- authentication.istio.io
- config.istio.io
- networking.internal.knative.dev
- serving.knative.dev
- caching.internal.knative.dev
- autoscaling.internal.knative.dev
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment