diff options
author | Robert Speicher <robert@gitlab.com> | 2018-10-05 17:40:32 +0000 |
---|---|---|
committer | Robert Speicher <robert@gitlab.com> | 2018-10-05 17:40:32 +0000 |
commit | b407061a281607e0c4bf22d2b7e94a068768ccac (patch) | |
tree | 7bfb1d7ffbde4d9aa40f3a05c1bbfb829732c807 /app/assets/javascripts | |
parent | 2c9c7d72383c6e7232077b4949b98bb71c90e521 (diff) | |
parent | 25bd49e4f57fe15f9d61dc9376a5b7dc35b30f64 (diff) | |
download | gitlab-ce-b407061a281607e0c4bf22d2b7e94a068768ccac.tar.gz |
Merge branch 'ce-5987-project-templates-api' into 'master'
Add a new project-specific templates API endpoint
See merge request gitlab-org/gitlab-ce!22118
Diffstat (limited to 'app/assets/javascripts')
10 files changed, 67 insertions, 84 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index ecc2440c7e6..3f7a1ef1bfc 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -15,12 +15,9 @@ const Api = { mergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes', mergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions', groupLabelsPath: '/groups/:namespace_path/-/labels', - templatesPath: '/api/:version/templates/:key', - licensePath: '/api/:version/templates/licenses/:key', - gitignorePath: '/api/:version/templates/gitignores/:key', - gitlabCiYmlPath: '/api/:version/templates/gitlab_ci_ymls/:key', - dockerfilePath: '/api/:version/templates/dockerfiles/:key', issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key', + projectTemplatePath: '/api/:version/projects/:id/templates/:type/:key', + projectTemplatesPath: '/api/:version/projects/:id/templates/:type', usersPath: '/api/:version/users.json', userStatusPath: '/api/:version/user/status', commitPath: '/api/:version/projects/:id/repository/commits', @@ -196,29 +193,29 @@ const Api = { return axios.get(url); }, - // Return text for a specific license - licenseText(key, data, callback) { - const url = Api.buildUrl(Api.licensePath).replace(':key', key); - return axios - .get(url, { - params: data, - }) - .then(res => callback(res.data)); - }, + projectTemplate(id, type, key, options, callback) { + const url = Api.buildUrl(this.projectTemplatePath) + .replace(':id', encodeURIComponent(id)) + .replace(':type', type) + .replace(':key', encodeURIComponent(key)); - gitignoreText(key, callback) { - const url = Api.buildUrl(Api.gitignorePath).replace(':key', key); - return axios.get(url).then(({ data }) => callback(data)); - }, + return axios.get(url, { params: options }).then(res => { + if (callback) callback(res.data); - gitlabCiYml(key, callback) { - const url = Api.buildUrl(Api.gitlabCiYmlPath).replace(':key', key); - return axios.get(url).then(({ data }) => callback(data)); + return res; + }); }, - dockerfileYml(key, callback) { - const url = Api.buildUrl(Api.dockerfilePath).replace(':key', key); - return axios.get(url).then(({ data }) => callback(data)); + projectTemplates(id, type, params = {}, callback) { + const url = Api.buildUrl(this.projectTemplatesPath) + .replace(':id', encodeURIComponent(id)) + .replace(':type', type); + + return axios.get(url, { params }).then(res => { + if (callback) callback(res.data); + + return res; + }); }, issueTemplate(namespacePath, projectPath, key, type, callback) { @@ -276,12 +273,6 @@ const Api = { }); }, - templates(key, params = {}) { - const url = Api.buildUrl(this.templatesPath).replace(':key', key); - - return axios.get(url, { params }); - }, - buildUrl(url) { let urlRoot = ''; if (gon.relative_url_root != null) { diff --git a/app/assets/javascripts/blob/file_template_mediator.js b/app/assets/javascripts/blob/file_template_mediator.js index ff1cbcad145..addacf29f1e 100644 --- a/app/assets/javascripts/blob/file_template_mediator.js +++ b/app/assets/javascripts/blob/file_template_mediator.js @@ -1,4 +1,4 @@ -/* eslint-disable class-methods-use-this */ +import Api from '~/api'; import $ from 'jquery'; import Flash from '../flash'; @@ -9,9 +9,10 @@ import GitignoreSelector from './template_selectors/gitignore_selector'; import LicenseSelector from './template_selectors/license_selector'; export default class FileTemplateMediator { - constructor({ editor, currentAction }) { + constructor({ editor, currentAction, projectId }) { this.editor = editor; this.currentAction = currentAction; + this.projectId = projectId; this.initTemplateSelectors(); this.initTemplateTypeSelector(); @@ -33,15 +34,14 @@ export default class FileTemplateMediator { initTemplateTypeSelector() { this.typeSelector = new FileTemplateTypeSelector({ mediator: this, - dropdownData: this.templateSelectors - .map((templateSelector) => { - const cfg = templateSelector.config; - - return { - name: cfg.name, - key: cfg.key, - }; - }), + dropdownData: this.templateSelectors.map(templateSelector => { + const cfg = templateSelector.config; + + return { + name: cfg.name, + key: cfg.key, + }; + }), }); } @@ -89,7 +89,7 @@ export default class FileTemplateMediator { } listenForPreviewMode() { - this.$navLinks.on('click', 'a', (e) => { + this.$navLinks.on('click', 'a', e => { const urlPieces = e.target.href.split('#'); const hash = urlPieces[1]; if (hash === 'preview') { @@ -105,7 +105,7 @@ export default class FileTemplateMediator { e.preventDefault(); } - this.templateSelectors.forEach((selector) => { + this.templateSelectors.forEach(selector => { if (selector.config.key === item.key) { selector.show(); } else { @@ -126,8 +126,8 @@ export default class FileTemplateMediator { selector.renderLoading(); // in case undo menu is already already there this.destroyUndoMenu(); - this.fetchFileTemplate(selector.config.endpoint, query, data) - .then((file) => { + this.fetchFileTemplate(selector.config.type, query, data) + .then(file => { this.showUndoMenu(); this.setEditorContent(file); this.setFilename(selector.config.name); @@ -138,7 +138,7 @@ export default class FileTemplateMediator { displayMatchedTemplateSelector() { const currentInput = this.getFilename(); - this.templateSelectors.forEach((selector) => { + this.templateSelectors.forEach(selector => { const match = selector.config.pattern.test(currentInput); if (match) { @@ -149,15 +149,11 @@ export default class FileTemplateMediator { }); } - fetchFileTemplate(apiCall, query, data) { - return new Promise((resolve) => { + fetchFileTemplate(type, query, data = {}) { + return new Promise(resolve => { const resolveFile = file => resolve(file); - if (!data) { - apiCall(query, resolveFile); - } else { - apiCall(query, data, resolveFile); - } + Api.projectTemplate(this.projectId, type, query, data, resolveFile); }); } diff --git a/app/assets/javascripts/blob/template_selector.js b/app/assets/javascripts/blob/template_selector.js index 9dfdb06007d..9db1fa70ffb 100644 --- a/app/assets/javascripts/blob/template_selector.js +++ b/app/assets/javascripts/blob/template_selector.js @@ -66,9 +66,6 @@ export default class TemplateSelector { // be added by all subclasses. } - // To be implemented on the extending class - // e.g. Api.gitlabCiYml(query.name, file => this.setEditorContent(file)); - setEditorContent(file, { skipFocus } = {}) { if (!file) return; diff --git a/app/assets/javascripts/blob/template_selectors/ci_yaml_selector.js b/app/assets/javascripts/blob/template_selectors/ci_yaml_selector.js index 9c41e429c8d..43f7aead8b9 100644 --- a/app/assets/javascripts/blob/template_selectors/ci_yaml_selector.js +++ b/app/assets/javascripts/blob/template_selectors/ci_yaml_selector.js @@ -1,5 +1,3 @@ -import Api from '../../api'; - import FileTemplateSelector from '../file_template_selector'; export default class BlobCiYamlSelector extends FileTemplateSelector { @@ -9,7 +7,7 @@ export default class BlobCiYamlSelector extends FileTemplateSelector { key: 'gitlab-ci-yaml', name: '.gitlab-ci.yml', pattern: /(.gitlab-ci.yml)/, - endpoint: Api.gitlabCiYml, + type: 'gitlab_ci_ymls', dropdown: '.js-gitlab-ci-yml-selector', wrapper: '.js-gitlab-ci-yml-selector-wrap', }; diff --git a/app/assets/javascripts/blob/template_selectors/dockerfile_selector.js b/app/assets/javascripts/blob/template_selectors/dockerfile_selector.js index 45fb614fe00..4718b642617 100644 --- a/app/assets/javascripts/blob/template_selectors/dockerfile_selector.js +++ b/app/assets/javascripts/blob/template_selectors/dockerfile_selector.js @@ -1,5 +1,3 @@ -import Api from '../../api'; - import FileTemplateSelector from '../file_template_selector'; export default class DockerfileSelector extends FileTemplateSelector { @@ -9,7 +7,7 @@ export default class DockerfileSelector extends FileTemplateSelector { key: 'dockerfile', name: 'Dockerfile', pattern: /(Dockerfile)/, - endpoint: Api.dockerfileYml, + type: 'dockerfiles', dropdown: '.js-dockerfile-selector', wrapper: '.js-dockerfile-selector-wrap', }; diff --git a/app/assets/javascripts/blob/template_selectors/gitignore_selector.js b/app/assets/javascripts/blob/template_selectors/gitignore_selector.js index a894953cc86..a8067ec5c84 100644 --- a/app/assets/javascripts/blob/template_selectors/gitignore_selector.js +++ b/app/assets/javascripts/blob/template_selectors/gitignore_selector.js @@ -1,5 +1,3 @@ -import Api from '../../api'; - import FileTemplateSelector from '../file_template_selector'; export default class BlobGitignoreSelector extends FileTemplateSelector { @@ -9,7 +7,7 @@ export default class BlobGitignoreSelector extends FileTemplateSelector { key: 'gitignore', name: '.gitignore', pattern: /(.gitignore)/, - endpoint: Api.gitignoreText, + type: 'gitignores', dropdown: '.js-gitignore-selector', wrapper: '.js-gitignore-selector-wrap', }; diff --git a/app/assets/javascripts/blob/template_selectors/license_selector.js b/app/assets/javascripts/blob/template_selectors/license_selector.js index b7c4da0f62e..ac1fe95eee5 100644 --- a/app/assets/javascripts/blob/template_selectors/license_selector.js +++ b/app/assets/javascripts/blob/template_selectors/license_selector.js @@ -1,5 +1,3 @@ -import Api from '../../api'; - import FileTemplateSelector from '../file_template_selector'; export default class BlobLicenseSelector extends FileTemplateSelector { @@ -9,7 +7,7 @@ export default class BlobLicenseSelector extends FileTemplateSelector { key: 'license', name: 'LICENSE', pattern: /^(.+\/)?(licen[sc]e|copying)($|\.)/i, - endpoint: Api.licenseText, + type: 'licenses', dropdown: '.js-license-selector', wrapper: '.js-license-selector-wrap', }; diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index a603d89b84a..4e4598870fa 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -15,8 +15,9 @@ export default () => { const assetsPath = editBlobForm.data('assetsPrefix'); const blobLanguage = editBlobForm.data('blobLanguage'); const currentAction = $('.js-file-title').data('currentAction'); + const projectId = editBlobForm.data('project-id'); - new EditBlob(`${urlRoot}${assetsPath}`, blobLanguage, currentAction); + new EditBlob(`${urlRoot}${assetsPath}`, blobLanguage, currentAction, projectId); new NewCommitForm(editBlobForm); } diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index 82a3d494b67..ec2b130ab7d 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -7,11 +7,11 @@ import { __ } from '~/locale'; import TemplateSelectorMediator from '../blob/file_template_mediator'; export default class EditBlob { - constructor(assetsPath, aceMode, currentAction) { + constructor(assetsPath, aceMode, currentAction, projectId) { this.configureAceEditor(aceMode, assetsPath); this.initModePanesAndLinks(); this.initSoftWrap(); - this.initFileSelectors(currentAction); + this.initFileSelectors(currentAction, projectId); } configureAceEditor(aceMode, assetsPath) { @@ -30,10 +30,11 @@ export default class EditBlob { } } - initFileSelectors(currentAction) { + initFileSelectors(currentAction, projectId) { this.fileTemplateMediator = new TemplateSelectorMediator({ currentAction, editor: this.editor, + projectId, }); } @@ -60,14 +61,15 @@ export default class EditBlob { if (paneId === '#preview') { this.$toggleButton.hide(); - axios.post(currentLink.data('previewUrl'), { - content: this.editor.getValue(), - }) - .then(({ data }) => { - currentPane.empty().append(data); - currentPane.renderGFM(); - }) - .catch(() => createFlash(__('An error occurred previewing the blob'))); + axios + .post(currentLink.data('previewUrl'), { + content: this.editor.getValue(), + }) + .then(({ data }) => { + currentPane.empty().append(data); + currentPane.renderGFM(); + }) + .catch(() => createFlash(__('An error occurred previewing the blob'))); } this.$toggleButton.show(); diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js index cc9f6c8638c..b7090e09daf 100644 --- a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js +++ b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js @@ -23,12 +23,12 @@ export const receiveTemplateTypesError = ({ commit, dispatch }) => { export const receiveTemplateTypesSuccess = ({ commit }, templates) => commit(types.RECEIVE_TEMPLATE_TYPES_SUCCESS, templates); -export const fetchTemplateTypes = ({ dispatch, state }, page = 1) => { +export const fetchTemplateTypes = ({ dispatch, state, rootState }, page = 1) => { if (!Object.keys(state.selectedTemplateType).length) return Promise.reject(); dispatch('requestTemplateTypes'); - return Api.templates(state.selectedTemplateType.key, { page }) + return Api.projectTemplates(rootState.currentProjectId, state.selectedTemplateType.key, { page }) .then(({ data, headers }) => { const nextPage = parseInt(normalizeHeaders(headers)['X-NEXT-PAGE'], 10); @@ -74,12 +74,16 @@ export const receiveTemplateError = ({ dispatch }, template) => { ); }; -export const fetchTemplate = ({ dispatch, state }, template) => { +export const fetchTemplate = ({ dispatch, state, rootState }, template) => { if (template.content) { return dispatch('setFileTemplate', template); } - return Api.templates(`${state.selectedTemplateType.key}/${template.key || template.name}`) + return Api.projectTemplate( + rootState.currentProjectId, + state.selectedTemplateType.key, + template.key || template.name, + ) .then(({ data }) => { dispatch('setFileTemplate', data); }) |