Commit a797ca35 authored by John Hope's avatar John Hope Committed by Natalia Tepluhina

Change shared query location

Let's use app/graphql/queries for shared queries and teach jest and
webpack about it as well with a `shared_queries` alias.
parent 6cf719ee
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* eslint-disable vue/no-v-html */ /* eslint-disable vue/no-v-html */
import { GlTooltipDirective, GlLink, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui'; import { GlTooltipDirective, GlLink, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import defaultAvatarUrl from 'images/no_avatar.png'; import defaultAvatarUrl from 'images/no_avatar.png';
import pathLastCommitQuery from 'shared_queries/repository/path_last_commit.query.graphql';
import { sprintf, s__ } from '~/locale'; import { sprintf, s__ } from '~/locale';
import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import TimeagoTooltip from '../../vue_shared/components/time_ago_tooltip.vue'; import TimeagoTooltip from '../../vue_shared/components/time_ago_tooltip.vue';
...@@ -9,7 +10,6 @@ import CiIcon from '../../vue_shared/components/ci_icon.vue'; ...@@ -9,7 +10,6 @@ import CiIcon from '../../vue_shared/components/ci_icon.vue';
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue'; import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
import getRefMixin from '../mixins/get_ref'; import getRefMixin from '../mixins/get_ref';
import projectPathQuery from '../queries/project_path.query.graphql'; import projectPathQuery from '../queries/project_path.query.graphql';
import pathLastCommitQuery from '../queries/path_last_commit.query.graphql';
export default { export default {
components: { components: {
......
import Vue from 'vue'; import Vue from 'vue';
import PathLastCommitQuery from 'shared_queries/repository/path_last_commit.query.graphql';
import { escapeFileUrl, joinPaths, webIDEUrl } from '../lib/utils/url_utility'; import { escapeFileUrl, joinPaths, webIDEUrl } from '../lib/utils/url_utility';
import createRouter from './router'; import createRouter from './router';
import App from './components/app.vue'; import App from './components/app.vue';
...@@ -18,6 +19,10 @@ export default function setupVueRepositoryList() { ...@@ -18,6 +19,10 @@ export default function setupVueRepositoryList() {
const { dataset } = el; const { dataset } = el;
const { projectPath, projectShortPath, ref, escapedRef, fullName } = dataset; const { projectPath, projectShortPath, ref, escapedRef, fullName } = dataset;
const router = createRouter(projectPath, escapedRef); const router = createRouter(projectPath, escapedRef);
const pathRegex = /-\/tree\/[^/]+\/(.+$)/;
const matches = window.location.href.match(pathRegex);
const currentRoutePath = matches ? matches[1] : '';
apolloProvider.clients.defaultClient.cache.writeData({ apolloProvider.clients.defaultClient.cache.writeData({
data: { data: {
...@@ -29,6 +34,43 @@ export default function setupVueRepositoryList() { ...@@ -29,6 +34,43 @@ export default function setupVueRepositoryList() {
}, },
}); });
const initLastCommitApp = () =>
new Vue({
el: document.getElementById('js-last-commit'),
router,
apolloProvider,
render(h) {
return h(LastCommit, {
props: {
currentPath: this.$route.params.path,
},
});
},
});
if (window.gl.startup_graphql_calls) {
const query = window.gl.startup_graphql_calls.find(
call => call.operationName === 'pathLastCommit',
);
query.fetchCall
.then(res => res.json())
.then(res => {
apolloProvider.clients.defaultClient.writeQuery({
query: PathLastCommitQuery,
data: res.data,
variables: {
projectPath,
ref,
path: currentRoutePath,
},
});
})
.catch(() => {})
.finally(() => initLastCommitApp());
} else {
initLastCommitApp();
}
router.afterEach(({ params: { path } }) => { router.afterEach(({ params: { path } }) => {
setTitle(path, ref, fullName); setTitle(path, ref, fullName);
}); });
...@@ -77,20 +119,6 @@ export default function setupVueRepositoryList() { ...@@ -77,20 +119,6 @@ export default function setupVueRepositoryList() {
}); });
} }
// eslint-disable-next-line no-new
new Vue({
el: document.getElementById('js-last-commit'),
router,
apolloProvider,
render(h) {
return h(LastCommit, {
props: {
currentPath: this.$route.params.path,
},
});
},
});
const treeHistoryLinkEl = document.getElementById('js-tree-history-link'); const treeHistoryLinkEl = document.getElementById('js-tree-history-link');
const { historyLink } = treeHistoryLinkEl.dataset; const { historyLink } = treeHistoryLinkEl.dataset;
......
query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) { query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
__typename
repository { repository {
__typename
tree(path: $path, ref: $ref) { tree(path: $path, ref: $ref) {
__typename
lastCommit { lastCommit {
__typename
sha sha
title title
titleHtml titleHtml
...@@ -13,15 +17,20 @@ query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) { ...@@ -13,15 +17,20 @@ query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
authorName authorName
authorGravatar authorGravatar
author { author {
__typename
name name
avatarUrl avatarUrl
webPath webPath
} }
signatureHtml signatureHtml
pipelines(ref: $ref, first: 1) { pipelines(ref: $ref, first: 1) {
__typename
edges { edges {
__typename
node { node {
__typename
detailedStatus { detailedStatus {
__typename
detailsPath detailsPath
icon icon
tooltip tooltip
......
# frozen_string_literal: true
module StartupjsHelper
def page_startup_graphql_calls
@graphql_startup_calls
end
def add_page_startup_graphql_call(query, variables = {})
@graphql_startup_calls ||= []
file_location = File.join(Rails.root, "app/graphql/queries/#{query}.query.graphql")
return unless File.exist?(file_location)
query_str = File.read(file_location)
@graphql_startup_calls << { query: query_str, variables: variables }
end
end
- return unless page_startup_api_calls.present? - return unless page_startup_api_calls.present? || page_startup_graphql_calls.present?
= javascript_tag nonce: true do = javascript_tag nonce: true do
:plain :plain
var gl = window.gl || {}; var gl = window.gl || {};
gl.startup_calls = #{page_startup_api_calls.to_json}; gl.startup_calls = #{page_startup_api_calls.to_json};
gl.startup_graphql_calls = #{page_startup_graphql_calls.to_json};
if (gl.startup_calls && window.fetch) { if (gl.startup_calls && window.fetch) {
Object.keys(gl.startup_calls).forEach(apiCall => { Object.keys(gl.startup_calls).forEach(apiCall => {
// fetch won’t send cookies in older browsers, unless you set the credentials init option. // fetch won’t send cookies in older browsers, unless you set the credentials init option.
...@@ -14,3 +16,21 @@ ...@@ -14,3 +16,21 @@
}; };
}); });
} }
if (gl.startup_graphql_calls && window.fetch) {
const url = `#{api_graphql_url}`
const opts = {
method: "POST",
headers: { "Content-Type": "application/json", 'X-CSRF-Token': "#{form_authenticity_token}" },
};
gl.startup_graphql_calls = gl.startup_graphql_calls.map(call => ({
operationName: call.query.match(/^query (.+)\(/)[1],
fetchCall: fetch(url, {
...opts,
credentials: 'same-origin',
body: JSON.stringify(call)
})
}))
}
- current_route_path = request.fullpath.match(/-\/tree\/[^\/]+\/(.+$)/).to_a[1]
- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, currentRoutePath: current_route_path })
- breadcrumb_title _("Repository") - breadcrumb_title _("Repository")
- @content_class = "limit-container-width" unless fluid_layout - @content_class = "limit-container-width" unless fluid_layout
......
...@@ -96,6 +96,7 @@ const alias = { ...@@ -96,6 +96,7 @@ const alias = {
vue$: 'vue/dist/vue.esm.js', vue$: 'vue/dist/vue.esm.js',
spec: path.join(ROOT_PATH, 'spec/javascripts'), spec: path.join(ROOT_PATH, 'spec/javascripts'),
jest: path.join(ROOT_PATH, 'spec/frontend'), jest: path.join(ROOT_PATH, 'spec/frontend'),
shared_queries: path.join(ROOT_PATH, 'app/graphql/queries'),
// the following resolves files which are different between CE and EE // the following resolves files which are different between CE and EE
ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'), ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'),
......
...@@ -33,6 +33,7 @@ module.exports = path => { ...@@ -33,6 +33,7 @@ module.exports = path => {
'^~(/.*)$': '<rootDir>/app/assets/javascripts$1', '^~(/.*)$': '<rootDir>/app/assets/javascripts$1',
'^ee_component(/.*)$': '^ee_component(/.*)$':
'<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js', '<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js',
'^shared_queries(/.*)$': '<rootDir>/app/graphql/queries$1',
'^ee_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1', '^ee_else_ce(/.*)$': '<rootDir>/app/assets/javascripts$1',
'^helpers(/.*)$': '<rootDir>/spec/frontend/helpers$1', '^helpers(/.*)$': '<rootDir>/spec/frontend/helpers$1',
'^vendor(/.*)$': '<rootDir>/vendor/assets/javascripts$1', '^vendor(/.*)$': '<rootDir>/vendor/assets/javascripts$1',
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe StartupjsHelper do
describe '#page_startup_graphql_calls' do
let(:query_location) { 'repository/path_last_commit' }
let(:query_content) do
File.read(File.join(Rails.root, 'app/graphql/queries', "#{query_location}.query.graphql"))
end
it 'returns an array containing GraphQL Page Startup Calls' do
helper.add_page_startup_graphql_call(query_location, { ref: 'foo' })
startup_graphql_calls = helper.page_startup_graphql_calls
expect(startup_graphql_calls).to include({ query: query_content, variables: { ref: 'foo' } })
end
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