Commit c2bdc29e authored by Nick Thomas's avatar Nick Thomas

Merge branch 'ph/225849/repositoryGraphQLWebPath' into 'master'

Use webPath in repository GraphQL responses

Closes #225849

See merge request gitlab-org/gitlab!35976
parents a14ff6ec 11c53b94
......@@ -4,9 +4,9 @@ import { joinPaths, escapeFileUrl } from '~/lib/utils/url_utility';
import { __ } from '../../locale';
import Icon from '../../vue_shared/components/icon.vue';
import getRefMixin from '../mixins/get_ref';
import getProjectShortPath from '../queries/getProjectShortPath.query.graphql';
import getProjectPath from '../queries/getProjectPath.query.graphql';
import getPermissions from '../queries/getPermissions.query.graphql';
import projectShortPathQuery from '../queries/project_short_path.query.graphql';
import projetPathQuery from '../queries/project_path.query.graphql';
import permissionsQuery from '../queries/permissions.query.graphql';
const ROW_TYPES = {
header: 'header',
......@@ -23,13 +23,13 @@ export default {
},
apollo: {
projectShortPath: {
query: getProjectShortPath,
query: projectShortPathQuery,
},
projectPath: {
query: getProjectPath,
query: projetPathQuery,
},
userPermissions: {
query: getPermissions,
query: permissionsQuery,
variables() {
return {
projectPath: this.projectPath,
......
......@@ -8,8 +8,8 @@ import TimeagoTooltip from '../../vue_shared/components/time_ago_tooltip.vue';
import CiIcon from '../../vue_shared/components/ci_icon.vue';
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
import getRefMixin from '../mixins/get_ref';
import getProjectPath from '../queries/getProjectPath.query.graphql';
import pathLastCommit from '../queries/pathLastCommit.query.graphql';
import projectPathQuery from '../queries/project_path.query.graphql';
import pathLastCommitQuery from '../queries/path_last_commit.query.graphql';
export default {
components: {
......@@ -28,10 +28,10 @@ export default {
mixins: [getRefMixin],
apollo: {
projectPath: {
query: getProjectPath,
query: projectPathQuery,
},
commit: {
query: pathLastCommit,
query: pathLastCommitQuery,
variables() {
return {
projectPath: this.projectPath,
......@@ -102,7 +102,7 @@ export default {
<template v-else-if="commit">
<user-avatar-link
v-if="commit.author"
:link-href="commit.author.webUrl"
:link-href="commit.author.webPath"
:img-src="commit.author.avatarUrl"
:img-size="40"
class="avatar-cell"
......@@ -118,7 +118,7 @@ export default {
<div class="commit-detail flex-list">
<div class="commit-content qa-commit-content">
<gl-link
:href="commit.webUrl"
:href="commit.webPath"
:class="{ 'font-italic': !commit.message }"
class="commit-row-message item-title"
v-html="commit.titleHtml"
......@@ -135,7 +135,7 @@ export default {
<div class="committer">
<gl-link
v-if="commit.author"
:href="commit.author.webUrl"
:href="commit.author.webPath"
class="commit-author-link js-user-link"
>
{{ commit.author.name }}
......
......@@ -3,15 +3,15 @@ import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
import { GlLink, GlLoadingIcon } from '@gitlab/ui';
import { handleLocationHash } from '~/lib/utils/common_utils';
import getReadmeQuery from '../../queries/getReadme.query.graphql';
import readmeQery from '../../queries/readme.query.graphql';
export default {
apollo: {
readme: {
query: getReadmeQuery,
query: readmeQery,
variables() {
return {
url: this.blob.webUrl,
url: this.blob.webPath,
};
},
loadingKey: 'loading',
......@@ -51,7 +51,7 @@ export default {
<div class="js-file-title file-title-flex-parent">
<div class="file-header-content">
<i aria-hidden="true" class="fa fa-file-text-o fa-fw"></i>
<gl-link :href="blob.webUrl">
<gl-link :href="blob.webPath">
<strong>{{ blob.name }}</strong>
</gl-link>
</div>
......
......@@ -2,7 +2,7 @@
import { GlSkeletonLoading } from '@gitlab/ui';
import { sprintf, __ } from '../../../locale';
import getRefMixin from '../../mixins/get_ref';
import getProjectPath from '../../queries/getProjectPath.query.graphql';
import projectPathQuery from '../../queries/project_path.query.graphql';
import TableHeader from './header.vue';
import TableRow from './row.vue';
import ParentRow from './parent_row.vue';
......@@ -17,7 +17,7 @@ export default {
mixins: [getRefMixin],
apollo: {
projectPath: {
query: getProjectPath,
query: projectPathQuery,
},
},
props: {
......@@ -96,7 +96,7 @@ export default {
:name="entry.name"
:path="entry.flatPath"
:type="entry.type"
:url="entry.webUrl"
:url="entry.webUrl || entry.webPath"
:submodule-tree-url="entry.treeUrl"
:lfs-oid="entry.lfsOid"
:loading-path="loadingPath"
......
......@@ -12,7 +12,7 @@ import { escapeFileUrl } from '~/lib/utils/url_utility';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import getRefMixin from '../../mixins/get_ref';
import getCommit from '../../queries/getCommit.query.graphql';
import commitQuery from '../../queries/commit.query.graphql';
export default {
components: {
......@@ -29,7 +29,7 @@ export default {
},
apollo: {
commit: {
query: getCommit,
query: commitQuery,
variables() {
return {
fileName: this.name,
......
......@@ -3,9 +3,9 @@ import createFlash from '~/flash';
import { __ } from '../../locale';
import FileTable from './table/index.vue';
import getRefMixin from '../mixins/get_ref';
import getFiles from '../queries/getFiles.query.graphql';
import getProjectPath from '../queries/getProjectPath.query.graphql';
import getVueFileListLfsBadge from '../queries/getVueFileListLfsBadge.query.graphql';
import filesQuery from '../queries/files.query.graphql';
import projectPathQuery from '../queries/project_path.query.graphql';
import vueFileListLfsBadgeQuery from '../queries/vue_file_list_lfs_badge.query.graphql';
import FilePreview from './preview/index.vue';
import { readmeFile } from '../utils/readme';
......@@ -19,10 +19,10 @@ export default {
mixins: [getRefMixin],
apollo: {
projectPath: {
query: getProjectPath,
query: projectPathQuery,
},
vueFileListLfsBadge: {
query: getVueFileListLfsBadge,
query: vueFileListLfsBadgeQuery,
},
},
props: {
......@@ -75,7 +75,7 @@ export default {
return this.$apollo
.query({
query: getFiles,
query: filesQuery,
variables: {
projectPath: this.projectPath,
ref: this.ref,
......
import { normalizeData } from 'ee_else_ce/repository/utils/commit';
import axios from '~/lib/utils/axios_utils';
import getCommits from './queries/getCommits.query.graphql';
import getProjectPath from './queries/getProjectPath.query.graphql';
import getRef from './queries/getRef.query.graphql';
import commitsQuery from './queries/commits.query.graphql';
import projectPathQuery from './queries/project_path.query.graphql';
import refQuery from './queries/ref.query.graphql';
let fetchpromise;
let resolvers = [];
......@@ -22,8 +22,8 @@ export function fetchLogsTree(client, path, offset, resolver = null) {
if (fetchpromise) return fetchpromise;
const { projectPath } = client.readQuery({ query: getProjectPath });
const { escapedRef } = client.readQuery({ query: getRef });
const { projectPath } = client.readQuery({ query: projectPathQuery });
const { escapedRef } = client.readQuery({ query: refQuery });
fetchpromise = axios
.get(
......@@ -36,10 +36,10 @@ export function fetchLogsTree(client, path, offset, resolver = null) {
)
.then(({ data, headers }) => {
const headerLogsOffset = headers['more-logs-offset'];
const { commits } = client.readQuery({ query: getCommits });
const { commits } = client.readQuery({ query: commitsQuery });
const newCommitData = [...commits, ...normalizeData(data, path)];
client.writeQuery({
query: getCommits,
query: commitsQuery,
data: { commits: newCommitData },
});
......
import getRef from '../queries/getRef.query.graphql';
import refQuery from '../queries/ref.query.graphql';
export default {
apollo: {
ref: {
query: getRef,
query: refQuery,
manual: true,
result({ data, loading }) {
if (!loading) {
......
import getFiles from '../queries/getFiles.query.graphql';
import filesQuery from '../queries/files.query.graphql';
import getRefMixin from './get_ref';
import getProjectPath from '../queries/getProjectPath.query.graphql';
import projectPathQuery from '../queries/project_path.query.graphql';
export default {
mixins: [getRefMixin],
apollo: {
projectPath: {
query: getProjectPath,
query: projectPathQuery,
},
},
data() {
......@@ -21,7 +21,7 @@ export default {
return this.$apollo
.query({
query: getFiles,
query: filesQuery,
variables: {
projectPath: this.projectPath,
ref: this.ref,
......
#import "ee_else_ce/repository/queries/commit.fragment.graphql"
query getCommit($fileName: String!, $type: String!, $path: String!) {
query Commit($fileName: String!, $type: String!, $path: String!) {
commit(path: $path, fileName: $fileName, type: $type) @client {
...TreeEntryCommit
}
......
#import "ee_else_ce/repository/queries/commit.fragment.graphql"
query getCommits {
query Commits {
commits @client {
...TreeEntryCommit
}
......
......@@ -8,7 +8,7 @@ fragment TreeEntry on Entry {
type
}
query getFiles(
query Files(
$projectPath: ID!
$path: String
$ref: String!
......@@ -23,7 +23,7 @@ query getFiles(
edges {
node {
...TreeEntry
webUrl
webPath
}
}
pageInfo {
......@@ -46,7 +46,7 @@ query getFiles(
edges {
node {
...TreeEntry
webUrl
webPath
lfsOid @include(if: $vueLfsEnabled)
}
}
......
query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
query PathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
project(fullPath: $projectPath) {
repository {
tree(path: $path, ref: $ref) {
......@@ -8,14 +8,14 @@ query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
titleHtml
description
message
webUrl
webPath
authoredDate
authorName
authorGravatar
author {
name
avatarUrl
webUrl
webPath
}
signatureHtml
pipelines(ref: $ref, first: 1) {
......
query getPermissions($projectPath: ID!) {
query Permissions($projectPath: ID!) {
project(fullPath: $projectPath) {
userPermissions {
pushCode
......
query getReadme($url: String!) {
query Readme($url: String!) {
readme(url: $url) @client {
html
}
......
......@@ -23,6 +23,8 @@ module Types
description: 'Timestamp of when the commit was authored'
field :web_url, type: GraphQL::STRING_TYPE, null: false,
description: 'Web URL of the commit'
field :web_path, type: GraphQL::STRING_TYPE, null: false,
description: 'Web path of the commit'
field :signature_html, type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true,
description: 'Rendered HTML of the commit signature'
field :author_name, type: GraphQL::STRING_TYPE, null: true,
......
......@@ -12,6 +12,8 @@ module Types
field :web_url, GraphQL::STRING_TYPE, null: true,
description: 'Web URL of the blob'
field :web_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path of the blob'
field :lfs_oid, GraphQL::STRING_TYPE, null: true,
description: 'LFS ID of the blob',
resolve: -> (blob, args, ctx) do
......
......@@ -13,6 +13,8 @@ module Types
field :web_url, GraphQL::STRING_TYPE, null: true,
description: 'Web URL for the tree entry (directory)'
field :web_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path for the tree entry (directory)'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......
......@@ -22,6 +22,8 @@ module Types
description: "URL of the user's avatar"
field :web_url, GraphQL::STRING_TYPE, null: false,
description: 'Web URL of the user'
field :web_path, GraphQL::STRING_TYPE, null: false,
description: 'Web path of the user'
field :todos, Types::TodoType.connection_type, null: false,
resolver: Resolvers::TodoResolver,
description: 'Todos of the user'
......
......@@ -18,6 +18,10 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
Gitlab::Routing.url_helpers.project_blob_url(blob.repository.project, File.join(blob.commit_id, blob.path))
end
def web_path
Gitlab::Routing.url_helpers.project_blob_path(blob.repository.project, File.join(blob.commit_id, blob.path))
end
private
def load_all_blob_data
......
......@@ -21,6 +21,10 @@ class CommitPresenter < Gitlab::View::Presenter::Delegated
url_builder.build(commit)
end
def web_path
url_builder.build(commit, only_path: true)
end
def signature_html
return unless commit.has_signature?
......
......@@ -6,4 +6,8 @@ class TreeEntryPresenter < Gitlab::View::Presenter::Delegated
def web_url
Gitlab::Routing.url_helpers.project_tree_url(tree.repository.project, File.join(tree.commit_id, tree.path))
end
def web_path
Gitlab::Routing.url_helpers.project_tree_path(tree.repository.project, File.join(tree.commit_id, tree.path))
end
end
......@@ -6,4 +6,8 @@ class UserPresenter < Gitlab::View::Presenter::Delegated
def web_url
Gitlab::Routing.url_helpers.user_url(user)
end
def web_path
Gitlab::Routing.url_helpers.user_path(user)
end
end
......@@ -813,6 +813,11 @@ type Blob implements Entry {
"""
type: EntryType!
"""
Web path of the blob
"""
webPath: String
"""
Web URL of the blob
"""
......@@ -1216,6 +1221,11 @@ type Commit {
"""
titleHtml: String
"""
Web path of the commit
"""
webPath: String!
"""
Web URL of the commit
"""
......@@ -13367,6 +13377,11 @@ type TreeEntry implements Entry {
"""
type: EntryType!
"""
Web path for the tree entry (directory)
"""
webPath: String
"""
Web URL for the tree entry (directory)
"""
......@@ -14268,6 +14283,11 @@ type User {
"""
username: String!
"""
Web path of the user
"""
webPath: String!
"""
Web URL of the user
"""
......
......@@ -2128,6 +2128,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webPath",
"description": "Web path of the blob",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webUrl",
"description": "Web URL of the blob",
......@@ -3290,6 +3304,24 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webPath",
"description": "Web path of the commit",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webUrl",
"description": "Web URL of the commit",
......@@ -39466,6 +39498,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webPath",
"description": "Web path for the tree entry (directory)",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webUrl",
"description": "Web URL for the tree entry (directory)",
......@@ -41883,6 +41929,24 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webPath",
"description": "Web path of the user",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "webUrl",
"description": "Web URL of the user",
......@@ -164,6 +164,7 @@ Autogenerated return type of AwardEmojiToggle
| `path` | String! | Path of the entry |
| `sha` | String! | Last commit sha for the entry |
| `type` | EntryType! | Type of tree entry |
| `webPath` | String | Web path of the blob |
| `webUrl` | String | Web URL of the blob |
## Board
......@@ -227,6 +228,7 @@ Autogenerated return type of BoardListUpdateLimitMetrics
| `signatureHtml` | String | Rendered HTML of the commit signature |
| `title` | String | Title of the commit message |
| `titleHtml` | String | The GitLab Flavored Markdown rendering of `title` |
| `webPath` | String! | Web path of the commit |
| `webUrl` | String! | Web URL of the commit |
## CommitCreatePayload
......@@ -2017,6 +2019,7 @@ Represents a directory
| `path` | String! | Path of the entry |
| `sha` | String! | Last commit sha for the entry |
| `type` | EntryType! | Type of tree entry |
| `webPath` | String | Web path for the tree entry (directory) |
| `webUrl` | String | Web URL for the tree entry (directory) |
## UpdateAlertStatusPayload
......@@ -2120,6 +2123,7 @@ Autogenerated return type of UpdateSnippet
| `state` | UserState! | State of the user |
| `userPermissions` | UserPermissions! | Permissions for the current user on the resource |
| `username` | String! | Username of the user. Unique within this instance of GitLab |
| `webPath` | String! | Web path of the user |
| `webUrl` | String! | Web URL of the user |
## UserPermissions
......
......@@ -10,7 +10,7 @@ exports[`Repository last commit component renders commit widget 1`] = `
imgcssclasses=""
imgsize="40"
imgsrc="https://test.com"
linkhref="https://test.com/test"
linkhref="/test"
tooltipplacement="top"
tooltiptext=""
username=""
......@@ -24,7 +24,7 @@ exports[`Repository last commit component renders commit widget 1`] = `
>
<gl-link-stub
class="commit-row-message item-title"
href="https://test.com/commit/123"
href="/commit/123"
>
Commit title
</gl-link-stub>
......@@ -36,7 +36,7 @@ exports[`Repository last commit component renders commit widget 1`] = `
>
<gl-link-stub
class="commit-author-link js-user-link"
href="https://test.com/test"
href="/test"
>
Test
......@@ -110,7 +110,7 @@ exports[`Repository last commit component renders the signature HTML as returned
imgcssclasses=""
imgsize="40"
imgsrc="https://test.com"
linkhref="https://test.com/test"
linkhref="/test"
tooltipplacement="top"
tooltiptext=""
username=""
......@@ -124,7 +124,7 @@ exports[`Repository last commit component renders the signature HTML as returned
>
<gl-link-stub
class="commit-row-message item-title"
href="https://test.com/commit/123"
href="/commit/123"
>
Commit title
</gl-link-stub>
......@@ -136,7 +136,7 @@ exports[`Repository last commit component renders the signature HTML as returned
>
<gl-link-stub
class="commit-author-link js-user-link"
href="https://test.com/test"
href="/test"
>
Test
......
......@@ -12,11 +12,13 @@ function createCommitData(data = {}) {
titleHtml: 'Commit title',
message: 'Commit message',
webUrl: 'https://test.com/commit/123',
webPath: '/commit/123',
authoredDate: '2019-01-01',
author: {
name: 'Test',
avatarUrl: 'https://test.com',
webUrl: 'https://test.com/test',
webPath: '/test',
},
pipeline: {
detailedStatus: {
......
......@@ -16,7 +16,7 @@ exports[`Repository file preview component renders file HTML 1`] = `
/>
<gl-link-stub
href="http://test.com"
href="/test.md"
>
<strong>
README.md
......
......@@ -31,6 +31,7 @@ describe('Repository file preview component', () => {
it('renders file HTML', () => {
factory({
webUrl: 'http://test.com',
webPath: '/test.md',
name: 'README.md',
});
......@@ -44,6 +45,7 @@ describe('Repository file preview component', () => {
it('handles hash after render', () => {
factory({
webUrl: 'http://test.com',
webPath: '/test.md',
name: 'README.md',
});
......@@ -60,6 +62,7 @@ describe('Repository file preview component', () => {
it('renders loading icon', () => {
factory({
webUrl: 'http://test.com',
webPath: '/test.md',
name: 'README.md',
});
......
......@@ -10,7 +10,7 @@ RSpec.describe GitlabSchema.types['Commit'] do
it 'contains attributes related to commit' do
expect(described_class).to have_graphql_fields(
:id, :sha, :title, :description, :message, :title_html, :authored_date,
:author_name, :author_gravatar, :author, :web_url, :latest_pipeline,
:author_name, :author_gravatar, :author, :web_path, :web_url, :latest_pipeline,
:pipelines, :signature_html
)
end
......
......@@ -5,5 +5,5 @@ require 'spec_helper'
RSpec.describe Types::Tree::BlobType do
specify { expect(described_class.graphql_name).to eq('Blob') }
specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url, :lfs_oid) }
specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_path, :web_url, :lfs_oid) }
end
......@@ -5,5 +5,5 @@ require 'spec_helper'
RSpec.describe Types::Tree::TreeEntryType do
specify { expect(described_class.graphql_name).to eq('TreeEntry') }
specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url) }
specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_path, :web_url) }
end
......@@ -16,6 +16,7 @@ RSpec.describe GitlabSchema.types['User'] do
username
avatarUrl
webUrl
webPath
todos
state
authoredMergeRequests
......
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