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

Add latest changes from gitlab-org/gitlab@master

parent 55693cc1
No related branches found
No related tags found
No related merge requests found
Showing
with 128 additions and 208 deletions
Loading
Loading
@@ -26,7 +26,7 @@ export default {
<ci-icon :status="job.status" :borderless="true" :size="24" class="d-flex" />
<span class="prepend-left-8">
{{ job.name }}
<a :href="job.path" target="_blank" class="ide-external-link">
<a :href="job.path" target="_blank" class="ide-external-link position-relative">
{{ jobId }} <icon :size="12" name="external-link" />
</a>
</span>
Loading
Loading
Loading
Loading
@@ -71,7 +71,7 @@ export default {
v-tooltip="showTooltip"
:title="showTooltip ? stage.name : null"
data-container="body"
class="prepend-left-8 ide-stage-title"
class="prepend-left-8 text-truncate"
>
{{ stage.name }}
</strong>
Loading
Loading
@@ -80,7 +80,7 @@ export default {
</div>
<icon :name="collapseIcon" class="ide-stage-collapse-icon" />
</div>
<div v-show="!stage.isCollapsed" ref="jobList" class="card-body">
<div v-show="!stage.isCollapsed" ref="jobList" class="card-body p-0">
<gl-loading-icon v-if="showLoadingIcon" />
<template v-else>
<item v-for="job in stage.jobs" :key="job.id" :job="job" @clickViewLog="clickViewLog" />
Loading
Loading
Loading
Loading
@@ -51,7 +51,7 @@ export default {
</script>
 
<template>
<div class="ide-new-btn">
<div class="ide-new-btn d-none">
<div
:class="{
show: isOpen,
Loading
Loading
Loading
Loading
@@ -43,21 +43,28 @@ export default {
},
createFile(target, file) {
const { name } = file;
let { result } = target;
const encodedContent = result.split('base64,')[1];
const encodedContent = target.result.split('base64,')[1];
const rawContent = encodedContent ? atob(encodedContent) : '';
const isText = this.isText(rawContent, file.type);
 
result = isText ? rawContent : encodedContent;
const emitCreateEvent = content =>
this.$emit('create', {
name: `${this.path ? `${this.path}/` : ''}${name}`,
type: 'blob',
content,
base64: !isText,
binary: !isText,
rawPath: !isText ? target.result : '',
});
 
this.$emit('create', {
name: `${this.path ? `${this.path}/` : ''}${name}`,
type: 'blob',
content: result,
base64: !isText,
binary: !isText,
rawPath: !isText ? target.result : '',
});
if (isText) {
const reader = new FileReader();
reader.addEventListener('load', e => emitCreateEvent(e.target.result), { once: true });
reader.readAsText(file);
} else {
emitCreateEvent(encodedContent);
}
},
readFile(file) {
const reader = new FileReader();
Loading
Loading
Loading
Loading
@@ -62,7 +62,11 @@ export default {
<ci-icon :status="latestPipeline.details.status" :size="24" />
<span class="prepend-left-8">
<strong> {{ __('Pipeline') }} </strong>
<a :href="latestPipeline.path" target="_blank" class="ide-external-link">
<a
:href="latestPipeline.path"
target="_blank"
class="ide-external-link position-relative"
>
#{{ latestPipeline.id }} <icon :size="12" name="external-link" />
</a>
</span>
Loading
Loading
Loading
Loading
@@ -274,7 +274,7 @@ export default {
<template>
<div id="ide" class="blob-viewer-container blob-editor-container">
<div class="ide-mode-tabs clearfix">
<ul v-if="!shouldHideEditor && isEditModeActive" class="nav-links float-left">
<ul v-if="!shouldHideEditor && isEditModeActive" class="nav-links float-left border-bottom-0">
<li :class="editTabCSS">
<a
href="javascript:void(0);"
Loading
Loading
Loading
Loading
@@ -14,9 +14,10 @@ export default {
iid: mergeRequest.iid,
title: mergeRequest.title,
projectId: mergeRequest.project_id,
projectPathWithNamespace: mergeRequest.web_url
.replace(`${gon.gitlab_url}/`, '')
.replace(`/merge_requests/${mergeRequest.iid}`, ''),
projectPathWithNamespace: mergeRequest.references.full.replace(
mergeRequest.references.short,
'',
),
}));
},
[types.RESET_MERGE_REQUESTS](state) {
Loading
Loading
Loading
Loading
@@ -13,6 +13,11 @@ export default {
type: String,
required: true,
},
filePath: {
type: String,
required: false,
default: '',
},
fileSize: {
type: Number,
required: false,
Loading
Loading
@@ -24,7 +29,8 @@ export default {
return numberToHumanSize(this.fileSize);
},
fileName() {
return this.path.split('/').pop();
// path could be a base64 uri too, so check if filePath was passed additionally
return (this.filePath || this.path).split('/').pop();
},
},
};
Loading
Loading
@@ -39,7 +45,13 @@ export default {
({{ fileSizeReadable }})
</template>
</p>
<gl-link :href="path" class="btn btn-default" rel="nofollow" download target="_blank">
<gl-link
:href="path"
class="btn btn-default"
rel="nofollow"
:download="fileName"
target="_blank"
>
<icon :size="16" name="download" class="float-left append-right-8" />
{{ __('Download') }}
</gl-link>
Loading
Loading
Loading
Loading
@@ -25,10 +25,6 @@ $ide-commit-header-height: 48px;
@include str-truncated(250px);
}
 
.editable-mode {
display: inline-block;
}
.ide-view {
position: relative;
margin-top: 0;
Loading
Loading
@@ -332,23 +328,6 @@ $ide-commit-header-height: 48px;
padding: $gl-padding;
max-width: 100%;
max-height: 100%;
img {
max-width: 90%;
}
.isZoomable {
cursor: pointer;
cursor: zoom-in;
&.isZoomed {
cursor: pointer;
cursor: zoom-out;
max-width: none;
max-height: none;
margin-right: $gl-padding;
}
}
}
 
.file-info {
Loading
Loading
@@ -361,13 +340,9 @@ $ide-commit-header-height: 48px;
.ide-mode-tabs {
border-bottom: 1px solid $white-dark;
 
.nav-links {
border-bottom: 0;
li a {
padding: $gl-padding-8 $gl-padding;
line-height: $gl-btn-line-height;
}
li a {
padding: $gl-padding-8 $gl-padding;
line-height: $gl-btn-line-height;
}
}
 
Loading
Loading
@@ -564,12 +539,6 @@ $ide-commit-header-height: 48px;
background: $gray-100;
 
outline: 0;
.multi-file-discard-btn {
> .btn {
display: flex;
}
}
}
 
&:active {
Loading
Loading
@@ -596,18 +565,6 @@ $ide-commit-header-height: 48px;
}
}
 
.multi-file-discard-btn {
> .btn {
display: none;
width: $ide-commit-row-height;
height: $ide-commit-row-height;
}
svg {
top: 0;
}
}
.multi-file-commit-form {
position: relative;
background-color: $white-light;
Loading
Loading
@@ -1060,8 +1017,6 @@ $ide-commit-header-height: 48px;
}
 
.ide-external-link {
position: relative;
svg {
display: none;
position: absolute;
Loading
Loading
@@ -1164,22 +1119,12 @@ $ide-commit-header-height: 48px;
align-items: center;
}
}
.card-body {
padding: 0;
}
}
 
.ide-stage-collapse-icon {
margin: auto 0 auto auto;
}
 
.ide-stage-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ide-job-header {
min-height: 60px;
}
Loading
Loading
@@ -1279,8 +1224,6 @@ $ide-commit-header-height: 48px;
}
 
.ide-new-btn {
display: none;
.btn {
padding: 2px 5px;
}
Loading
Loading
Loading
Loading
@@ -21,6 +21,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action only: [:show] do
push_frontend_feature_flag(:diffs_batch_load, @project)
push_frontend_feature_flag(:single_mr_diff_view, @project)
push_frontend_feature_flag(:suggest_pipeline) if experiment_enabled?(:suggest_pipeline)
end
 
before_action do
Loading
Loading
Loading
Loading
@@ -40,6 +40,10 @@ module Types
field :rich_viewer, type: Types::Snippets::BlobViewerType,
description: 'Blob content rich viewer',
null: true
field :mode, type: GraphQL::STRING_TYPE,
description: 'Blob mode',
null: true
end
# rubocop: enable Graphql/AuthorizeTypes
end
Loading
Loading
Loading
Loading
@@ -41,8 +41,8 @@ class Repository
CACHED_METHODS = %i(size commit_count rendered_readme readme_path contribution_guide
changelog license_blob license_key gitignore
gitlab_ci_yml branch_names tag_names branch_count
tag_count avatar exists? root_ref has_visible_content?
issue_template_names merge_request_template_names
tag_count avatar exists? root_ref merged_branch_names
has_visible_content? issue_template_names merge_request_template_names
metrics_dashboard_paths xcode_project?).freeze
 
# Methods that use cache_method but only memoize the value
Loading
Loading
@@ -65,6 +65,8 @@ class Repository
xcode_config: :xcode_project?
}.freeze
 
MERGED_BRANCH_NAMES_CACHE_DURATION = 10.minutes
def initialize(full_path, project, disk_path: nil, repo_type: Gitlab::GlRepository::PROJECT)
@full_path = full_path
@disk_path = disk_path || full_path
Loading
Loading
@@ -296,7 +298,7 @@ class Repository
end
 
def expire_branches_cache
expire_method_caches(%i(branch_names branch_count has_visible_content?))
expire_method_caches(%i(branch_names merged_branch_names branch_count has_visible_content?))
@local_branches = nil
@branch_exists_memo = nil
end
Loading
Loading
@@ -916,7 +918,39 @@ class Repository
@root_ref_sha ||= commit(root_ref).sha
end
 
delegate :merged_branch_names, to: :raw_repository
def merged_branch_names(branch_names = [])
# Currently we should skip caching if requesting all branch names
# This is only used in a few places, notably app/services/branches/delete_merged_service.rb,
# and it could potentially result in a very large cache/performance issues with the current
# implementation.
skip_cache = branch_names.empty? || Feature.disabled?(:merged_branch_names_redis_caching)
return raw_repository.merged_branch_names(branch_names) if skip_cache
cached_branch_names = cache.read(:merged_branch_names)
merged_branch_names_hash = cached_branch_names || {}
missing_branch_names = branch_names.select { |bn| !merged_branch_names_hash.key?(bn) }
# Track some metrics here whilst feature flag is enabled
if cached_branch_names.present?
counter = Gitlab::Metrics.counter(
:gitlab_repository_merged_branch_names_cache_hit,
"Count of cache hits for Repository#merged_branch_names"
)
counter.increment(full_hit: missing_branch_names.empty?)
end
if missing_branch_names.any?
merged = raw_repository.merged_branch_names(missing_branch_names)
missing_branch_names.each do |bn|
merged_branch_names_hash[bn] = merged.include?(bn)
end
cache.write(:merged_branch_names, merged_branch_names_hash, expires_in: MERGED_BRANCH_NAMES_CACHE_DURATION)
end
Set.new(merged_branch_names_hash.select { |_, v| v }.keys)
end
 
def merge_base(*commits_or_ids)
commit_ids = commits_or_ids.map do |commit_or_id|
Loading
Loading
---
title: Fix some of the file encoding issues when uploading in the Web IDE
merge_request: 23761
author:
type: fixed
---
title: Add mode field to snippet blob in GraphQL
merge_request: 24157
author:
type: changed
---
title: Separate issue entities into own class files
merge_request: 24226
author: Rajendra Kadam
type: added
Loading
Loading
@@ -6641,6 +6641,11 @@ type SnippetBlob {
"""
highlightedData: String
 
"""
Blob mode
"""
mode: String
"""
Blob name
"""
Loading
Loading
Loading
Loading
@@ -7171,6 +7171,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "mode",
"description": "Blob mode",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "name",
"description": "Blob name",
Loading
Loading
Loading
Loading
@@ -1063,6 +1063,7 @@ Represents the snippet blob
| --- | ---- | ---------- |
| `binary` | Boolean! | Shows whether the blob is binary |
| `highlightedData` | String | Blob highlighted data |
| `mode` | String | Blob mode |
| `name` | String | Blob name |
| `path` | String | Blob path |
| `rawPath` | String! | Blob raw content endpoint path |
Loading
Loading
Loading
Loading
@@ -19,7 +19,7 @@ for a good example):
 
- `desc` for the method summary. You should pass it a block for additional
details such as:
- The GitLab version when the endpoint was added
- The GitLab version when the endpoint was added. If it is behind a feature flag, mention that instead: _This feature is gated by the :feature\_flag\_symbol feature flag._
- If the endpoint is deprecated, and if so, when will it be removed
 
- `params` for the method params. This acts as description,
Loading
Loading
Loading
Loading
@@ -128,127 +128,6 @@ module API
end
end
 
class Milestone < Grape::Entity
expose :id, :iid
expose :project_id, if: -> (entity, options) { entity&.project_id }
expose :group_id, if: -> (entity, options) { entity&.group_id }
expose :title, :description
expose :state, :created_at, :updated_at
expose :due_date
expose :start_date
expose :web_url do |milestone, _options|
Gitlab::UrlBuilder.build(milestone)
end
end
class IssueBasic < IssuableEntity
expose :closed_at
expose :closed_by, using: Entities::UserBasic
expose :labels do |issue, options|
if options[:with_labels_details]
::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title))
else
issue.labels.map(&:title).sort
end
end
expose :milestone, using: Entities::Milestone
expose :assignees, :author, using: Entities::UserBasic
expose :assignee, using: ::API::Entities::UserBasic do |issue|
issue.assignees.first
end
expose(:user_notes_count) { |issue, options| issuable_metadata(issue, options, :user_notes_count) }
expose(:merge_requests_count) { |issue, options| issuable_metadata(issue, options, :merge_requests_count, options[:current_user]) }
expose(:upvotes) { |issue, options| issuable_metadata(issue, options, :upvotes) }
expose(:downvotes) { |issue, options| issuable_metadata(issue, options, :downvotes) }
expose :due_date
expose :confidential
expose :discussion_locked
expose :web_url do |issue|
Gitlab::UrlBuilder.build(issue)
end
expose :time_stats, using: 'API::Entities::IssuableTimeStats' do |issue|
issue
end
expose :task_completion_status
end
class Issue < IssueBasic
include ::API::Helpers::RelatedResourcesHelpers
expose(:has_tasks) do |issue, _|
!issue.task_list_items.empty?
end
expose :task_status, if: -> (issue, _) do
!issue.task_list_items.empty?
end
expose :_links do
expose :self do |issue|
expose_url(api_v4_project_issue_path(id: issue.project_id, issue_iid: issue.iid))
end
expose :notes do |issue|
expose_url(api_v4_projects_issues_notes_path(id: issue.project_id, noteable_id: issue.iid))
end
expose :award_emoji do |issue|
expose_url(api_v4_projects_issues_award_emoji_path(id: issue.project_id, issue_iid: issue.iid))
end
expose :project do |issue|
expose_url(api_v4_projects_path(id: issue.project_id))
end
end
expose :references, with: IssuableReferences do |issue|
issue
end
# Calculating the value of subscribed field triggers Markdown
# processing. We can't do that for multiple issues / merge
# requests in a single API request.
expose :subscribed, if: -> (_, options) { options.fetch(:include_subscribed, true) } do |issue, options|
issue.subscribed?(options[:current_user], options[:project] || issue.project)
end
expose :moved_to_id
end
class IssuableTimeStats < Grape::Entity
format_with(:time_tracking_formatter) do |time_spent|
Gitlab::TimeTrackingFormatter.output(time_spent)
end
expose :time_estimate
expose :total_time_spent
expose :human_time_estimate
with_options(format_with: :time_tracking_formatter) do
expose :total_time_spent, as: :human_total_time_spent
end
# rubocop: disable CodeReuse/ActiveRecord
def total_time_spent
# Avoids an N+1 query since timelogs are preloaded
object.timelogs.map(&:time_spent).sum
end
# rubocop: enable CodeReuse/ActiveRecord
end
class ExternalIssue < Grape::Entity
expose :title
expose :id
end
class PipelineBasic < Grape::Entity
expose :id, :sha, :ref, :status
expose :created_at, :updated_at
Loading
Loading
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