Commit 327c7d5a authored by Nick Thomas's avatar Nick Thomas

Merge branch 'graphql-file-entry-url' into 'master'

Add web_url to tree entry in GraphQL API

See merge request gitlab-org/gitlab-ce!28646
parents 86ff32da 4644a2da
...@@ -134,6 +134,7 @@ export default { ...@@ -134,6 +134,7 @@ export default {
:current-path="path" :current-path="path"
:path="entry.flatPath" :path="entry.flatPath"
:type="entry.type" :type="entry.type"
:url="entry.webUrl"
/> />
</template> </template>
</tbody> </tbody>
......
...@@ -21,6 +21,11 @@ export default { ...@@ -21,6 +21,11 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
url: {
type: String,
required: false,
default: null,
},
}, },
computed: { computed: {
routerLinkTo() { routerLinkTo() {
...@@ -59,7 +64,7 @@ export default { ...@@ -59,7 +64,7 @@ export default {
<tr v-once :class="`file_${id}`" class="tree-item" @click="openRow"> <tr v-once :class="`file_${id}`" class="tree-item" @click="openRow">
<td class="tree-item-file-name"> <td class="tree-item-file-name">
<i :aria-label="type" role="img" :class="iconName" class="fa fa-fw"></i> <i :aria-label="type" role="img" :class="iconName" class="fa fa-fw"></i>
<component :is="linkComponent" :to="routerLinkTo" class="str-truncated"> <component :is="linkComponent" :to="routerLinkTo" :href="url" class="str-truncated">
{{ fullPath }} {{ fullPath }}
</component> </component>
<template v-if="isSubmodule"> <template v-if="isSubmodule">
......
...@@ -23,6 +23,7 @@ query getFiles( ...@@ -23,6 +23,7 @@ query getFiles(
edges { edges {
node { node {
...TreeEntry ...TreeEntry
webUrl
} }
} }
pageInfo { pageInfo {
...@@ -43,6 +44,7 @@ query getFiles( ...@@ -43,6 +44,7 @@ query getFiles(
edges { edges {
node { node {
...TreeEntry ...TreeEntry
webUrl
} }
} }
pageInfo { pageInfo {
......
...@@ -4,7 +4,11 @@ module Types ...@@ -4,7 +4,11 @@ module Types
class BlobType < BaseObject class BlobType < BaseObject
implements Types::Tree::EntryType implements Types::Tree::EntryType
present_using BlobPresenter
graphql_name 'Blob' graphql_name 'Blob'
field :web_url, GraphQL::STRING_TYPE, null: true
end end
end end
end end
...@@ -4,8 +4,12 @@ module Types ...@@ -4,8 +4,12 @@ module Types
class TreeEntryType < BaseObject class TreeEntryType < BaseObject
implements Types::Tree::EntryType implements Types::Tree::EntryType
present_using TreeEntryPresenter
graphql_name 'TreeEntry' graphql_name 'TreeEntry'
description 'Represents a directory' description 'Represents a directory'
field :web_url, GraphQL::STRING_TYPE, null: true
end end
end end
end end
...@@ -4,9 +4,15 @@ module Types ...@@ -4,9 +4,15 @@ module Types
class TreeType < BaseObject class TreeType < BaseObject
graphql_name 'Tree' graphql_name 'Tree'
field :trees, Types::Tree::TreeEntryType.connection_type, null: false field :trees, Types::Tree::TreeEntryType.connection_type, null: false, resolve: -> (obj, args, ctx) do
Gitlab::Graphql::Representation::TreeEntry.decorate(obj.trees, obj.repository)
end
field :submodules, Types::Tree::SubmoduleType.connection_type, null: false field :submodules, Types::Tree::SubmoduleType.connection_type, null: false
field :blobs, Types::Tree::BlobType.connection_type, null: false
field :blobs, Types::Tree::BlobType.connection_type, null: false, resolve: -> (obj, args, ctx) do
Gitlab::Graphql::Representation::TreeEntry.decorate(obj.blobs, obj.repository)
end
end end
end end
end end
...@@ -13,4 +13,8 @@ class BlobPresenter < Gitlab::View::Presenter::Simple ...@@ -13,4 +13,8 @@ class BlobPresenter < Gitlab::View::Presenter::Simple
plain: plain plain: plain
) )
end end
def web_url
Gitlab::Routing.url_helpers.project_blob_url(blob.repository.project, File.join(blob.commit_id, blob.path))
end
end end
# frozen_string_literal: true
class TreeEntryPresenter < Gitlab::View::Presenter::Delegated
presents :tree
def web_url
Gitlab::Routing.url_helpers.project_tree_url(tree.repository.project, File.join(tree.commit_id, tree.path))
end
end
# frozen_string_literal: true
module Gitlab
module Graphql
module Representation
class TreeEntry < SimpleDelegator
class << self
def decorate(entries, repository)
return if entries.nil?
entries.map do |entry|
if entry.is_a?(TreeEntry)
entry
else
self.new(entry, repository)
end
end
end
end
attr_accessor :repository
def initialize(raw_entry, repository)
@repository = repository
super(raw_entry)
end
end
end
end
end
...@@ -86,4 +86,16 @@ describe('Repository table row component', () => { ...@@ -86,4 +86,16 @@ describe('Repository table row component', () => {
expect(vm.find('.commit-sha').text()).toContain('1'); expect(vm.find('.commit-sha').text()).toContain('1');
}); });
it('renders link with href', () => {
factory({
id: '1',
path: 'test',
type: 'blob',
url: 'https://test.com',
currentPath: '/',
});
expect(vm.find('a').attributes('href')).toEqual('https://test.com');
});
}); });
...@@ -5,5 +5,5 @@ require 'spec_helper' ...@@ -5,5 +5,5 @@ require 'spec_helper'
describe Types::Tree::BlobType do describe Types::Tree::BlobType do
it { expect(described_class.graphql_name).to eq('Blob') } it { expect(described_class.graphql_name).to eq('Blob') }
it { expect(described_class).to have_graphql_fields(:id, :name, :type, :path, :flat_path) } it { expect(described_class).to have_graphql_fields(:id, :name, :type, :path, :flat_path, :web_url) }
end end
...@@ -5,5 +5,5 @@ require 'spec_helper' ...@@ -5,5 +5,5 @@ require 'spec_helper'
describe Types::Tree::TreeEntryType do describe Types::Tree::TreeEntryType do
it { expect(described_class.graphql_name).to eq('TreeEntry') } it { expect(described_class.graphql_name).to eq('TreeEntry') }
it { expect(described_class).to have_graphql_fields(:id, :name, :type, :path, :flat_path) } it { expect(described_class).to have_graphql_fields(:id, :name, :type, :path, :flat_path, :web_url) }
end end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Graphql::Representation::TreeEntry do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
describe '.decorate' do
it 'returns NilClass when given nil' do
expect(described_class.decorate(nil, repository)).to be_nil
end
it 'returns array of TreeEntry' do
entries = described_class.decorate(repository.tree.blobs, repository)
expect(entries.first).to be_a(described_class)
end
end
end
...@@ -14,6 +14,16 @@ describe BlobPresenter, :seed_helper do ...@@ -14,6 +14,16 @@ describe BlobPresenter, :seed_helper do
end end
let(:blob) { Blob.new(git_blob) } let(:blob) { Blob.new(git_blob) }
describe '.web_url' do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:blob) { Gitlab::Graphql::Representation::TreeEntry.new(repository.tree.blobs.first, repository) }
subject { described_class.new(blob) }
it { expect(subject.web_url).to eq("http://localhost/#{project.full_path}/blob/#{blob.commit_id}/#{blob.path}") }
end
describe '#highlight' do describe '#highlight' do
subject { described_class.new(blob) } subject { described_class.new(blob) }
......
# frozen_string_literal: true
require 'spec_helper'
describe TreeEntryPresenter do
include Gitlab::Routing.url_helpers
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:tree) { Gitlab::Graphql::Representation::TreeEntry.new(repository.tree.trees.first, repository) }
let(:presenter) { described_class.new(tree) }
describe '.web_url' do
it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/tree/#{tree.commit_id}/#{tree.path}") }
end
end
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