Truncate tree to max 1,000 items and display notice to users
Rendering ten thousands of tree items consumes a lot of server time and can cause timeouts in extreme cases. Realistically, displaying more than 1,000 files is probably not useful so truncate and show the user a notice instead. 'Find files' can be used to locate specific files beyond the 1,000 limit.
This commit is contained in:
parent
a4072db019
commit
03b1bcbb68
5 changed files with 59 additions and 7 deletions
|
@ -125,7 +125,7 @@
|
|||
color: $white-normal;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover:not(.tree-truncated-warning) {
|
||||
td {
|
||||
background-color: $row-hover;
|
||||
border-top: 1px solid $row-hover-border;
|
||||
|
@ -198,6 +198,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tree-truncated-warning {
|
||||
color: $orange-600;
|
||||
background-color: $orange-100;
|
||||
}
|
||||
|
||||
.tree-time-ago {
|
||||
min-width: 135px;
|
||||
color: $gl-text-color-secondary;
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
module TreeHelper
|
||||
FILE_LIMIT = 1_000
|
||||
|
||||
# Sorts a repository's tree so that folders are before files and renders
|
||||
# their corresponding partials
|
||||
#
|
||||
# contents - A Grit::Tree object for the current tree
|
||||
# tree - A `Tree` object for the current tree
|
||||
def render_tree(tree)
|
||||
# Sort submodules and folders together by name ahead of files
|
||||
folders, files, submodules = tree.trees, tree.blobs, tree.submodules
|
||||
tree = ""
|
||||
tree = ''
|
||||
items = (folders + submodules).sort_by(&:name) + files
|
||||
tree << render(partial: "projects/tree/tree_row", collection: items) if items.present?
|
||||
|
||||
if items.size > FILE_LIMIT
|
||||
tree << render(partial: 'projects/tree/truncated_notice_tree_row',
|
||||
locals: { limit: FILE_LIMIT, total: items.size })
|
||||
items = items.take(FILE_LIMIT)
|
||||
end
|
||||
|
||||
tree << render(partial: 'projects/tree/tree_row', collection: items) if items.present?
|
||||
tree.html_safe
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
%tr.tree-truncated-warning
|
||||
%td{ colspan: '3' }
|
||||
= icon('exclamation-triangle fw')
|
||||
%span
|
||||
Too many items to show. To preserve performance only
|
||||
%strong #{number_with_delimiter(limit)} of #{number_with_delimiter(total)}
|
||||
items are displayed.
|
5
changelogs/unreleased/tree_item_limit.yml
Normal file
5
changelogs/unreleased/tree_item_limit.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Truncate tree to max 1,000 items and display notice to users
|
||||
merge_request:
|
||||
author:
|
||||
type: performance
|
|
@ -1,10 +1,36 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe TreeHelper do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:repository) { project.repository }
|
||||
let(:sha) { 'ce369011c189f62c815f5971d096b26759bab0d1' }
|
||||
|
||||
describe '.render_tree' do
|
||||
before do
|
||||
@id = sha
|
||||
@project = project
|
||||
end
|
||||
|
||||
it 'displays all entries without a warning' do
|
||||
tree = repository.tree(sha, 'files')
|
||||
|
||||
html = render_tree(tree)
|
||||
|
||||
expect(html).not_to have_selector('.tree-truncated-warning')
|
||||
end
|
||||
|
||||
it 'truncates entries and adds a warning' do
|
||||
stub_const('TreeHelper::FILE_LIMIT', 1)
|
||||
tree = repository.tree(sha, 'files')
|
||||
|
||||
html = render_tree(tree)
|
||||
|
||||
expect(html).to have_selector('.tree-truncated-warning', count: 1)
|
||||
expect(html).to have_selector('.tree-item-file-name', count: 1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'flatten_tree' do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:repository) { project.repository }
|
||||
let(:sha) { 'ce369011c189f62c815f5971d096b26759bab0d1' }
|
||||
let(:tree) { repository.tree(sha, 'files') }
|
||||
let(:root_path) { 'files' }
|
||||
let(:tree_item) { tree.entries.find { |entry| entry.path == path } }
|
||||
|
|
Loading…
Reference in a new issue