summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-10-23 14:01:22 +0100
committerPhil Hughes <me@iamphill.com>2017-10-23 14:01:22 +0100
commitc147bccc45dc1a47b17a18d14169606470833d02 (patch)
tree8641047561219255d76d422f0e8b02ac7eb29e57 /app
parent133e66d22d7b4ea26af17eb50a69e09f4210f737 (diff)
parent9931ef4a8a9fa9544729fe39cb3572d278819c8d (diff)
downloadgitlab-ce-c147bccc45dc1a47b17a18d14169606470833d02.tar.gz
Merge branch 'master' into ph-multi-file-editor-new-file-folder-dropdownph-multi-file-editor-new-file-folder-dropdown
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/notes.js8
-rw-r--r--app/assets/javascripts/repo/components/new_branch_form.vue115
-rw-r--r--app/assets/javascripts/repo/components/repo.vue32
-rw-r--r--app/assets/javascripts/repo/index.js22
-rw-r--r--app/assets/javascripts/repo/services/repo_service.js10
-rw-r--r--app/assets/javascripts/repo/stores/repo_store.js1
-rw-r--r--app/views/peek/views/_gitaly.html.haml7
-rw-r--r--app/views/projects/tree/_tree_header.html.haml2
-rw-r--r--app/views/shared/_ref_switcher.html.haml23
9 files changed, 208 insertions, 12 deletions
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 9c008da1a5d..5a6868be444 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -1280,10 +1280,12 @@ export default class Notes {
* Get data from Form attributes to use for saving/submitting comment.
*/
getFormData($form) {
+ const content = $form.find('.js-note-text').val();
return {
formData: $form.serialize(),
- formContent: _.escape($form.find('.js-note-text').val()),
+ formContent: _.escape(content),
formAction: $form.attr('action'),
+ formContentOriginal: content,
};
}
@@ -1415,7 +1417,7 @@ export default class Notes {
const isMainForm = $form.hasClass('js-main-target-form');
const isDiscussionForm = $form.hasClass('js-discussion-note-form');
const isDiscussionResolve = $submitBtn.hasClass('js-comment-resolve-button');
- const { formData, formContent, formAction } = this.getFormData($form);
+ const { formData, formContent, formAction, formContentOriginal } = this.getFormData($form);
let noteUniqueId;
let systemNoteUniqueId;
let hasQuickActions = false;
@@ -1574,7 +1576,7 @@ export default class Notes {
$form = $notesContainer.parent().find('form');
}
- $form.find('.js-note-text').val(formContent);
+ $form.find('.js-note-text').val(formContentOriginal);
this.reenableTargetFormSubmitButton(e);
this.addNoteError($form);
});
diff --git a/app/assets/javascripts/repo/components/new_branch_form.vue b/app/assets/javascripts/repo/components/new_branch_form.vue
new file mode 100644
index 00000000000..eac43e692b0
--- /dev/null
+++ b/app/assets/javascripts/repo/components/new_branch_form.vue
@@ -0,0 +1,115 @@
+<script>
+ import flash, { hideFlash } from '../../flash';
+ import loadingIcon from '../../vue_shared/components/loading_icon.vue';
+ import eventHub from '../event_hub';
+
+ export default {
+ components: {
+ loadingIcon,
+ },
+ props: {
+ currentBranch: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ branchName: '',
+ loading: false,
+ };
+ },
+ computed: {
+ btnDisabled() {
+ return this.loading || this.branchName === '';
+ },
+ },
+ methods: {
+ toggleDropdown() {
+ this.$dropdown.dropdown('toggle');
+ },
+ submitNewBranch() {
+ // need to query as the element is appended outside of Vue
+ const flashEl = this.$refs.flashContainer.querySelector('.flash-alert');
+
+ this.loading = true;
+
+ if (flashEl) {
+ hideFlash(flashEl, false);
+ }
+
+ eventHub.$emit('createNewBranch', this.branchName);
+ },
+ showErrorMessage(message) {
+ this.loading = false;
+ flash(message, 'alert', this.$el);
+ },
+ createdNewBranch(newBranchName) {
+ this.loading = false;
+ this.branchName = '';
+
+ if (this.dropdownText) {
+ this.dropdownText.textContent = newBranchName;
+ }
+ },
+ },
+ created() {
+ // Dropdown is outside of Vue instance & is controlled by Bootstrap
+ this.$dropdown = $('.git-revision-dropdown');
+
+ // text element is outside Vue app
+ this.dropdownText = document.querySelector('.project-refs-form .dropdown-toggle-text');
+
+ eventHub.$on('createNewBranchSuccess', this.createdNewBranch);
+ eventHub.$on('createNewBranchError', this.showErrorMessage);
+ eventHub.$on('toggleNewBranchDropdown', this.toggleDropdown);
+ },
+ destroyed() {
+ eventHub.$off('createNewBranchSuccess', this.createdNewBranch);
+ eventHub.$off('toggleNewBranchDropdown', this.toggleDropdown);
+ eventHub.$off('createNewBranchError', this.showErrorMessage);
+ },
+ };
+</script>
+
+<template>
+ <div>
+ <div
+ class="flash-container"
+ ref="flashContainer"
+ >
+ </div>
+ <p>
+ Create from:
+ <code>{{ currentBranch }}</code>
+ </p>
+ <input
+ class="form-control js-new-branch-name"
+ type="text"
+ placeholder="Name new branch"
+ v-model="branchName"
+ @keyup.enter.stop.prevent="submitNewBranch"
+ />
+ <div class="prepend-top-default clearfix">
+ <button
+ type="button"
+ class="btn btn-primary pull-left"
+ :disabled="btnDisabled"
+ @click.stop.prevent="submitNewBranch"
+ >
+ <loading-icon
+ v-if="loading"
+ :inline="true"
+ />
+ <span>Create</span>
+ </button>
+ <button
+ type="button"
+ class="btn btn-default pull-right"
+ @click.stop.prevent="toggleDropdown"
+ >
+ Cancel
+ </button>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/repo/components/repo.vue b/app/assets/javascripts/repo/components/repo.vue
index 6ab98a33d15..788976a9804 100644
--- a/app/assets/javascripts/repo/components/repo.vue
+++ b/app/assets/javascripts/repo/components/repo.vue
@@ -8,7 +8,9 @@ import RepoMixin from '../mixins/repo_mixin';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue';
import Store from '../stores/repo_store';
import Helper from '../helpers/repo_helper';
+import Service from '../services/repo_service';
import MonacoLoaderHelper from '../helpers/monaco_loader_helper';
+import eventHub from '../event_hub';
export default {
data() {
@@ -24,12 +26,19 @@ export default {
PopupDialog,
RepoPreview,
},
-
+ created() {
+ eventHub.$on('createNewBranch', this.createNewBranch);
+ },
mounted() {
Helper.getContent().catch(Helper.loadingError);
},
-
+ destroyed() {
+ eventHub.$off('createNewBranch', this.createNewBranch);
+ },
methods: {
+ getCurrentLocation() {
+ return location.href;
+ },
toggleDialogOpen(toggle) {
this.dialog.open = toggle;
},
@@ -42,8 +51,25 @@ export default {
Helper.removeAllTmpFiles('openedFiles');
Helper.removeAllTmpFiles('files');
},
-
toggleBlobView: Store.toggleBlobView,
+ createNewBranch(branch) {
+ Service.createBranch({
+ branch,
+ ref: Store.currentBranch,
+ }).then((res) => {
+ const newBranchName = res.data.name;
+ const newUrl = this.getCurrentLocation().replace(Store.currentBranch, newBranchName);
+
+ Store.currentBranch = newBranchName;
+
+ history.pushState({ key: Helper.key }, '', newUrl);
+
+ eventHub.$emit('createNewBranchSuccess', newBranchName);
+ eventHub.$emit('toggleNewBranchDropdown');
+ }).catch((err) => {
+ eventHub.$emit('createNewBranchError', err.response.data.message);
+ });
+ },
},
};
</script>
diff --git a/app/assets/javascripts/repo/index.js b/app/assets/javascripts/repo/index.js
index 3586b5fea67..72fc5a70648 100644
--- a/app/assets/javascripts/repo/index.js
+++ b/app/assets/javascripts/repo/index.js
@@ -5,6 +5,7 @@ import Service from './services/repo_service';
import Store from './stores/repo_store';
import Repo from './components/repo.vue';
import RepoEditButton from './components/repo_edit_button.vue';
+import newBranchForm from './components/new_branch_form.vue';
import newDropdown from './components/new_dropdown/index.vue';
import Translate from '../vue_shared/translate';
@@ -76,6 +77,26 @@ function initNewDropdown(el) {
});
}
+function initNewBranchForm() {
+ const el = document.querySelector('.js-new-branch-dropdown');
+
+ if (!el) return null;
+
+ return new Vue({
+ el,
+ components: {
+ newBranchForm,
+ },
+ render(createElement) {
+ return createElement('new-branch-form', {
+ props: {
+ currentBranch: Store.currentBranch,
+ },
+ });
+ },
+ });
+}
+
function initRepoBundle() {
const repo = document.getElementById('repo');
const editButton = document.querySelector('.editable-mode');
@@ -88,6 +109,7 @@ function initRepoBundle() {
initRepo(repo);
initRepoEditButton(editButton);
+ initNewBranchForm();
initNewDropdown(newDropdownHolder);
}
diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js
index de8a2ecaa1d..c9fa5cc8bf8 100644
--- a/app/assets/javascripts/repo/services/repo_service.js
+++ b/app/assets/javascripts/repo/services/repo_service.js
@@ -1,8 +1,11 @@
import axios from 'axios';
+import csrf from '../../lib/utils/csrf';
import Store from '../stores/repo_store';
import Api from '../../api';
import Helper from '../helpers/repo_helper';
+axios.defaults.headers.common[csrf.headerKey] = csrf.token;
+
const RepoService = {
url: '',
options: {
@@ -10,6 +13,7 @@ const RepoService = {
format: 'json',
},
},
+ createBranchPath: '/api/:version/projects/:id/repository/branches',
richExtensionRegExp: /md/,
getRaw(file) {
@@ -79,6 +83,12 @@ const RepoService = {
.then(this.commitFlash);
},
+ createBranch(payload) {
+ const url = Api.buildUrl(this.createBranchPath)
+ .replace(':id', Store.projectId);
+ return axios.post(url, payload);
+ },
+
commitFlash(data) {
if (data.short_id && data.stats) {
window.Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
diff --git a/app/assets/javascripts/repo/stores/repo_store.js b/app/assets/javascripts/repo/stores/repo_store.js
index 1214419f553..38df1e3e0d2 100644
--- a/app/assets/javascripts/repo/stores/repo_store.js
+++ b/app/assets/javascripts/repo/stores/repo_store.js
@@ -13,6 +13,7 @@ const RepoStore = {
projectId: '',
projectName: '',
projectUrl: '',
+ branchUrl: '',
blobRaw: '',
currentBlobView: 'repo-preview',
openedFiles: [],
diff --git a/app/views/peek/views/_gitaly.html.haml b/app/views/peek/views/_gitaly.html.haml
new file mode 100644
index 00000000000..a7d040d6821
--- /dev/null
+++ b/app/views/peek/views/_gitaly.html.haml
@@ -0,0 +1,7 @@
+- local_assigns.fetch(:view)
+
+%strong
+ %span{ data: { defer_to: "#{view.defer_key}-duration" } } ...
+ \/
+ %span{ data: { defer_to: "#{view.defer_key}-calls" } } ...
+ Gitaly
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index df58e257a4e..7ea19e6c828 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -1,6 +1,6 @@
.tree-ref-container
.tree-ref-holder
- = render 'shared/ref_switcher', destination: 'tree', path: @path
+ = render 'shared/ref_switcher', destination: 'tree', path: @path, show_create: true
- if show_new_repo?
.js-new-dropdown
diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml
index 7ad743b3b81..6d7c9633913 100644
--- a/app/views/shared/_ref_switcher.html.haml
+++ b/app/views/shared/_ref_switcher.html.haml
@@ -1,3 +1,4 @@
+- show_new_branch_form = show_new_repo? && show_create && can?(current_user, :push_code, @project)
- dropdown_toggle_text = @ref || @project.default_branch
= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do
= hidden_field_tag :destination, destination
@@ -7,8 +8,20 @@
= hidden_field_tag key, value, id: nil
.dropdown
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project), field_name: 'ref', submit_form_on_click: true, visit: true }, { toggle_class: "js-project-refs-dropdown" }
- .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
- = dropdown_title _("Switch branch/tag")
- = dropdown_filter _("Search branches and tags")
- = dropdown_content
- = dropdown_loading
+ .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
+ .dropdown-page-one
+ = dropdown_title _("Switch branch/tag")
+ = dropdown_filter _("Search branches and tags")
+ = dropdown_content
+ = dropdown_loading
+ - if show_new_branch_form
+ = dropdown_footer do
+ %ul.dropdown-footer-list
+ %li
+ %a.dropdown-toggle-page{ href: "#" }
+ Create new branch
+ - if show_new_branch_form
+ .dropdown-page-two
+ = dropdown_title("Create new branch", options: { back: true })
+ = dropdown_content do
+ .js-new-branch-dropdown