summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Schatz <jschatz@gitlab.com>2017-08-15 18:16:43 +0000
committerJacob Schatz <jschatz@gitlab.com>2017-08-15 18:16:43 +0000
commite6d87021f31839395fdbdedc36613a57fb771375 (patch)
tree7d777e0fe017dc38d7cc6084b3f17a6388356b3f
parentf82d8a22189aed685db8e7d9501dd798bf495f4a (diff)
parent855199775375d6c319e3dd969d9c4f68313f5ac8 (diff)
downloadgitlab-ce-test-trigger-build.tar.gz
Merge branch 'bpj-repo-editor-fixes' into 'master'test-trigger-build
Repo Editor Fixes See merge request !13468
-rw-r--r--app/assets/javascripts/project.js2
-rw-r--r--app/assets/javascripts/repo/components/repo_commit_section.vue4
-rw-r--r--app/assets/javascripts/repo/components/repo_edit_button.vue18
-rw-r--r--app/assets/javascripts/repo/components/repo_editor.vue35
-rw-r--r--app/assets/javascripts/repo/components/repo_sidebar.vue6
-rw-r--r--app/assets/javascripts/repo/components/repo_tab.vue6
-rw-r--r--app/assets/javascripts/repo/components/repo_tabs.vue15
-rw-r--r--app/assets/javascripts/repo/helpers/repo_helper.js4
-rw-r--r--app/assets/javascripts/repo/index.js3
-rw-r--r--app/assets/javascripts/repo/services/repo_service.js10
-rw-r--r--app/assets/javascripts/repo/stores/repo_store.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/popup_dialog.vue69
-rw-r--r--app/assets/stylesheets/pages/repo.scss8
-rw-r--r--app/views/shared/repo/_repo.html.haml1
-rw-r--r--spec/javascripts/repo/components/repo_edit_button_spec.js2
-rw-r--r--spec/javascripts/repo/components/repo_editor_spec.js51
-rw-r--r--spec/javascripts/repo/components/repo_file_buttons_spec.js1
-rw-r--r--spec/javascripts/repo/components/repo_tab_spec.js14
-rw-r--r--spec/javascripts/repo/components/repo_tabs_spec.js4
19 files changed, 141 insertions, 114 deletions
diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js
index 1c2100a1c25..272e8e8c218 100644
--- a/app/assets/javascripts/project.js
+++ b/app/assets/javascripts/project.js
@@ -130,7 +130,7 @@ import Cookies from 'js-cookie';
var action = $form.attr('action');
var divider = action.indexOf('?') === -1 ? '?' : '&';
if (shouldVisit) {
- gl.utils.visitUrl(action + '' + divider + '' + $form.serialize());
+ gl.utils.visitUrl(`${action}${divider}${$form.serialize()}`);
}
}
}
diff --git a/app/assets/javascripts/repo/components/repo_commit_section.vue b/app/assets/javascripts/repo/components/repo_commit_section.vue
index bd83f80c928..344d40be131 100644
--- a/app/assets/javascripts/repo/components/repo_commit_section.vue
+++ b/app/assets/javascripts/repo/components/repo_commit_section.vue
@@ -5,7 +5,7 @@ import RepoMixin from '../mixins/repo_mixin';
import Helper from '../helpers/repo_helper';
import Service from '../services/repo_service';
-const RepoCommitSection = {
+export default {
data: () => Store,
mixins: [RepoMixin],
@@ -54,8 +54,6 @@ const RepoCommitSection = {
},
},
};
-
-export default RepoCommitSection;
</script>
<template>
diff --git a/app/assets/javascripts/repo/components/repo_edit_button.vue b/app/assets/javascripts/repo/components/repo_edit_button.vue
index f47b6c33fa2..e3820f7688b 100644
--- a/app/assets/javascripts/repo/components/repo_edit_button.vue
+++ b/app/assets/javascripts/repo/components/repo_edit_button.vue
@@ -23,19 +23,21 @@ export default {
this.editMode = !this.editMode;
Store.toggleBlobView();
},
- },
-
- watch: {
- editMode() {
+ toggleProjectRefsForm() {
if (this.editMode) {
- $('.project-refs-form').addClass('disabled');
- $('.js-tree-ref-target-holder').show();
+ $('.project-refs-form').addClass('disabled-content');
+ $('.project-refs-target-form').show();
} else {
- $('.project-refs-form').removeClass('disabled');
- $('.js-tree-ref-target-holder').hide();
+ $('.project-refs-form').removeClass('disabled-content');
+ $('.project-refs-target-form').hide();
}
},
},
+ watch: {
+ editMode() {
+ this.toggleProjectRefsForm();
+ },
+ },
};
</script>
diff --git a/app/assets/javascripts/repo/components/repo_editor.vue b/app/assets/javascripts/repo/components/repo_editor.vue
index fd1a21e15b4..55a3af7aabb 100644
--- a/app/assets/javascripts/repo/components/repo_editor.vue
+++ b/app/assets/javascripts/repo/components/repo_editor.vue
@@ -32,7 +32,6 @@ const RepoEditor = {
const languages = this.monaco.languages.getLanguages();
const languageID = Helper.getLanguageIDForFile(this.activeFile, languages);
- this.showHide();
const newModel = this.monaco.editor.createModel(this.blobRaw, languageID);
this.monacoInstance.setModel(newModel);
@@ -40,14 +39,6 @@ const RepoEditor = {
},
methods: {
- showHide() {
- if (!this.openedFiles.length || (this.binary && !this.activeFile.raw)) {
- this.$el.style.display = 'none';
- } else {
- this.$el.style.display = 'inline-block';
- }
- },
-
addMonacoEvents() {
this.monacoInstance.onMouseUp(this.onMonacoEditorMouseUp);
this.monacoInstance.onKeyUp(this.onMonacoEditorKeysPressed.bind(this));
@@ -73,11 +64,6 @@ const RepoEditor = {
column: 1,
});
},
-
- activeFileLabel() {
- this.showHide();
- },
-
dialog: {
handler(obj) {
const newObj = obj;
@@ -99,21 +85,7 @@ const RepoEditor = {
deep: true,
},
- isTree() {
- this.showHide();
- },
-
- openedFiles() {
- this.showHide();
- },
-
- binary() {
- this.showHide();
- },
-
blobRaw() {
- this.showHide();
-
if (this.isTree) return;
this.monacoInstance.setModel(null);
@@ -125,11 +97,16 @@ const RepoEditor = {
this.monacoInstance.setModel(newModel);
},
},
+ computed: {
+ shouldHideEditor() {
+ return !this.openedFiles.length || (this.binary && !this.activeFile.raw);
+ },
+ },
};
export default RepoEditor;
</script>
<template>
-<div id="ide"></div>
+<div id="ide" v-if='!shouldHideEditor'></div>
</template>
diff --git a/app/assets/javascripts/repo/components/repo_sidebar.vue b/app/assets/javascripts/repo/components/repo_sidebar.vue
index 0d4f8c6635e..8e9499adf88 100644
--- a/app/assets/javascripts/repo/components/repo_sidebar.vue
+++ b/app/assets/javascripts/repo/components/repo_sidebar.vue
@@ -8,7 +8,7 @@ import RepoFile from './repo_file.vue';
import RepoLoadingFile from './repo_loading_file.vue';
import RepoMixin from '../mixins/repo_mixin';
-const RepoSidebar = {
+export default {
mixins: [RepoMixin],
components: {
'repo-file-options': RepoFileOptions,
@@ -59,12 +59,10 @@ const RepoSidebar = {
},
},
};
-
-export default RepoSidebar;
</script>
<template>
-<div id="sidebar" :class="{'sidebar-mini' : isMini}" v-cloak>
+<div id="sidebar" :class="{'sidebar-mini' : isMini}">
<table class="table">
<thead v-if="!isMini">
<tr>
diff --git a/app/assets/javascripts/repo/components/repo_tab.vue b/app/assets/javascripts/repo/components/repo_tab.vue
index fc66a8ea953..caabf5d4b1b 100644
--- a/app/assets/javascripts/repo/components/repo_tab.vue
+++ b/app/assets/javascripts/repo/components/repo_tab.vue
@@ -28,9 +28,9 @@ const RepoTab = {
methods: {
tabClicked: Store.setActiveFiles,
- xClicked(file) {
+ closeTab(file) {
if (file.changed) return;
- this.$emit('xclicked', file);
+ this.$emit('tabclosed', file);
},
},
};
@@ -43,7 +43,7 @@ export default RepoTab;
<a
href="#0"
class="close"
- @click.prevent="xClicked(tab)"
+ @click.prevent="closeTab(tab)"
:aria-label="closeLabel">
<i
class="fa"
diff --git a/app/assets/javascripts/repo/components/repo_tabs.vue b/app/assets/javascripts/repo/components/repo_tabs.vue
index bbd60d9d793..841aa689594 100644
--- a/app/assets/javascripts/repo/components/repo_tabs.vue
+++ b/app/assets/javascripts/repo/components/repo_tabs.vue
@@ -13,7 +13,7 @@ const RepoTabs = {
data: () => Store,
methods: {
- xClicked(file) {
+ tabClosed(file) {
Store.removeFromOpenedFiles(file);
},
},
@@ -23,10 +23,15 @@ export default RepoTabs;
</script>
<template>
-<ul
- v-if="isMini"
- id="tabs">
- <repo-tab v-for="tab in openedFiles" :key="tab.id" :tab="tab" :class="{'active' : tab.active}" @xclicked="xClicked"/>
+<ul id="tabs"
+ v-if="isMini">
+ <repo-tab
+ v-for="tab in openedFiles"
+ :key="tab.id"
+ :tab="tab"
+ :class="{'active' : tab.active}"
+ @tabclosed="tabClosed"
+ />
<li class="tabs-divider" />
</ul>
</template>
diff --git a/app/assets/javascripts/repo/helpers/repo_helper.js b/app/assets/javascripts/repo/helpers/repo_helper.js
index 17aaa0e1584..03d5e69af0f 100644
--- a/app/assets/javascripts/repo/helpers/repo_helper.js
+++ b/app/assets/javascripts/repo/helpers/repo_helper.js
@@ -62,7 +62,7 @@ const RepoHelper = {
file.opened = true;
file.icon = 'fa-folder-open';
- RepoHelper.toURL(file.url, file.name);
+ RepoHelper.updateHistoryEntry(file.url, file.name);
return file;
},
@@ -276,7 +276,7 @@ const RepoHelper = {
RepoHelper.key = key;
},
- toURL(url, title) {
+ updateHistoryEntry(url, title) {
const history = window.history;
RepoHelper.key = RepoHelper.genKey();
diff --git a/app/assets/javascripts/repo/index.js b/app/assets/javascripts/repo/index.js
index 3e37da1726e..530aec3021a 100644
--- a/app/assets/javascripts/repo/index.js
+++ b/app/assets/javascripts/repo/index.js
@@ -43,6 +43,9 @@ function initRepo(el) {
components: {
repo: Repo,
},
+ render(createElement) {
+ return createElement('repo');
+ },
});
}
diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js
index 17578f3bbf3..fbc24062140 100644
--- a/app/assets/javascripts/repo/services/repo_service.js
+++ b/app/assets/javascripts/repo/services/repo_service.js
@@ -15,10 +15,12 @@ const RepoService = {
checkCurrentBranchIsCommitable() {
const url = Store.service.refsUrl;
- return axios.get(url, { params: {
- ref: Store.currentBranch,
- search: Store.currentBranch,
- } });
+ return axios.get(url, {
+ params: {
+ ref: Store.currentBranch,
+ search: Store.currentBranch,
+ },
+ });
},
getRaw(url) {
diff --git a/app/assets/javascripts/repo/stores/repo_store.js b/app/assets/javascripts/repo/stores/repo_store.js
index bb605540aad..73b4e1b3c14 100644
--- a/app/assets/javascripts/repo/stores/repo_store.js
+++ b/app/assets/javascripts/repo/stores/repo_store.js
@@ -90,7 +90,7 @@ const RepoStore = {
}).catch(Helper.loadingError);
}
- if (!file.loading) Helper.toURL(file.url, file.name);
+ if (!file.loading) Helper.updateHistoryEntry(file.url, file.name);
RepoStore.binary = file.binary;
},
diff --git a/app/assets/javascripts/vue_shared/components/popup_dialog.vue b/app/assets/javascripts/vue_shared/components/popup_dialog.vue
index 7d339c0e753..87ae8d0c9f1 100644
--- a/app/assets/javascripts/vue_shared/components/popup_dialog.vue
+++ b/app/assets/javascripts/vue_shared/components/popup_dialog.vue
@@ -1,31 +1,41 @@
<script>
-const PopupDialog = {
+export default {
name: 'popup-dialog',
props: {
- open: Boolean,
- title: String,
- body: String,
+ open: {
+ type: Boolean,
+ required: true,
+ },
+ title: {
+ type: String,
+ required: true,
+ },
+ body: {
+ type: String,
+ required: true,
+ },
kind: {
type: String,
+ required: false,
default: 'primary',
},
closeButtonLabel: {
type: String,
+ required: false,
default: 'Cancel',
},
primaryButtonLabel: {
type: String,
- default: 'Save changes',
+ required: true,
},
},
computed: {
- typeOfClass() {
- const className = `btn-${this.kind}`;
- const returnObj = {};
- returnObj[className] = true;
- return returnObj;
+ btnKindClass() {
+ return {
+ [`btn-${this.kind}`]: true,
+ };
},
},
@@ -33,33 +43,46 @@ const PopupDialog = {
close() {
this.$emit('toggle', false);
},
-
- yesClick() {
- this.$emit('submit', true);
- },
-
- noClick() {
- this.$emit('submit', false);
+ emitSubmit(status) {
+ this.$emit('submit', status);
},
},
};
-
-export default PopupDialog;
</script>
+
<template>
-<div class="modal popup-dialog" tabindex="-1" v-show="open" role="dialog">
+<div
+ class="modal popup-dialog"
+ v-if="open"
+ role="dialog"
+ tabindex="-1">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
- <button type="button" class="close" @click="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <button type="button"
+ class="close"
+ @click="close"
+ aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
<h4 class="modal-title">{{this.title}}</h4>
</div>
<div class="modal-body">
<p>{{this.body}}</p>
</div>
<div class="modal-footer">
- <button type="button" class="btn btn-default" data-dismiss="modal" @click="noClick">{{closeButtonLabel}}</button>
- <button type="button" class="btn" :class="typeOfClass" @click="yesClick">{{primaryButtonLabel}}</button>
+ <button
+ type="button"
+ class="btn btn-default"
+ @click="emitSubmit(false)">
+ {{closeButtonLabel}}
+ </button>
+ <button type="button"
+ class="btn"
+ :class="btnKindClass"
+ @click="emitSubmit(true)">
+ {{primaryButtonLabel}}
+ </button>
</div>
</div>
</div>
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index ad17078c98a..5ffd5a08216 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -28,11 +28,6 @@
.project-refs-form,
.project-refs-target-form {
display: inline-block;
-
- &.disabled {
- opacity: 0.5;
- pointer-events: none;
- }
}
.fade-enter,
@@ -133,7 +128,6 @@
a {
@include str-truncated(100px);
color: $black;
- display: inline-block;
width: 100px;
text-align: center;
vertical-align: middle;
@@ -298,7 +292,7 @@
}
.fa {
- font-size: $code_font_size;
+ font-size: 12px;
margin-right: 5px;
}
}
diff --git a/app/views/shared/repo/_repo.html.haml b/app/views/shared/repo/_repo.html.haml
index 0fc40cf0801..051a5783516 100644
--- a/app/views/shared/repo/_repo.html.haml
+++ b/app/views/shared/repo/_repo.html.haml
@@ -1,2 +1 @@
#repo{ data: { url: content_url, project_name: project.name, refs_url: refs_project_path(project, format: :json), project_url: project_path(project), project_id: project.id, can_commit: (!!can_push_branch?(project, @ref)).to_s } }
- %repo
diff --git a/spec/javascripts/repo/components/repo_edit_button_spec.js b/spec/javascripts/repo/components/repo_edit_button_spec.js
index df2f9697acc..2e0406cae34 100644
--- a/spec/javascripts/repo/components/repo_edit_button_spec.js
+++ b/spec/javascripts/repo/components/repo_edit_button_spec.js
@@ -19,11 +19,13 @@ describe('RepoEditButton', () => {
expect(vm.$el.textContent).toMatch('Edit');
spyOn(vm, 'editClicked').and.callThrough();
+ spyOn(vm, 'toggleProjectRefsForm');
vm.$el.click();
Vue.nextTick(() => {
expect(vm.editClicked).toHaveBeenCalled();
+ expect(vm.toggleProjectRefsForm).toHaveBeenCalled();
expect(vm.$el.textContent).toMatch('Cancel edit');
done();
});
diff --git a/spec/javascripts/repo/components/repo_editor_spec.js b/spec/javascripts/repo/components/repo_editor_spec.js
index 35e0c995163..85d55d171f9 100644
--- a/spec/javascripts/repo/components/repo_editor_spec.js
+++ b/spec/javascripts/repo/components/repo_editor_spec.js
@@ -1,26 +1,49 @@
import Vue from 'vue';
import repoEditor from '~/repo/components/repo_editor.vue';
-import RepoStore from '~/repo/stores/repo_store';
describe('RepoEditor', () => {
- function createComponent() {
+ beforeEach(() => {
const RepoEditor = Vue.extend(repoEditor);
- return new RepoEditor().$mount();
- }
+ this.vm = new RepoEditor().$mount();
+ });
+
+ it('renders an ide container', (done) => {
+ this.vm.openedFiles = ['idiidid'];
+ this.vm.binary = false;
- it('renders an ide container', () => {
- const monacoInstance = jasmine.createSpyObj('monacoInstance', ['onMouseUp', 'onKeyUp', 'setModel', 'updateOptions']);
- const monaco = {
- editor: jasmine.createSpyObj('editor', ['create']),
- };
- RepoStore.monaco = monaco;
+ Vue.nextTick(() => {
+ expect(this.vm.shouldHideEditor).toBe(false);
+ expect(this.vm.$el.id).toEqual('ide');
+ expect(this.vm.$el.tagName).toBe('DIV');
+ done();
+ });
+ });
- monaco.editor.create.and.returnValue(monacoInstance);
- spyOn(repoEditor.watch, 'blobRaw');
+ describe('when there are no open files', () => {
+ it('does not render the ide', (done) => {
+ this.vm.openedFiles = [];
+
+ Vue.nextTick(() => {
+ expect(this.vm.shouldHideEditor).toBe(true);
+ expect(this.vm.$el.tagName).not.toBeDefined();
+ done();
+ });
+ });
+ });
- const vm = createComponent();
+ describe('when open file is binary and not raw', () => {
+ it('does not render the IDE', (done) => {
+ this.vm.binary = true;
+ this.vm.activeFile = {
+ raw: false,
+ };
- expect(vm.$el.id).toEqual('ide');
+ Vue.nextTick(() => {
+ expect(this.vm.shouldHideEditor).toBe(true);
+ expect(this.vm.$el.tagName).not.toBeDefined();
+ done();
+ });
+ });
});
});
diff --git a/spec/javascripts/repo/components/repo_file_buttons_spec.js b/spec/javascripts/repo/components/repo_file_buttons_spec.js
index e1f25e4485f..d15c3e33459 100644
--- a/spec/javascripts/repo/components/repo_file_buttons_spec.js
+++ b/spec/javascripts/repo/components/repo_file_buttons_spec.js
@@ -23,6 +23,7 @@ describe('RepoFileButtons', () => {
RepoStore.activeFile = activeFile;
RepoStore.activeFileLabel = activeFileLabel;
RepoStore.editMode = true;
+ RepoStore.binary = false;
const vm = createComponent();
const raw = vm.$el.querySelector('.raw');
diff --git a/spec/javascripts/repo/components/repo_tab_spec.js b/spec/javascripts/repo/components/repo_tab_spec.js
index a3b2d5dea82..d2a790ad73a 100644
--- a/spec/javascripts/repo/components/repo_tab_spec.js
+++ b/spec/javascripts/repo/components/repo_tab_spec.js
@@ -21,7 +21,7 @@ describe('RepoTab', () => {
const close = vm.$el.querySelector('.close');
const name = vm.$el.querySelector(`a[title="${tab.url}"]`);
- spyOn(vm, 'xClicked');
+ spyOn(vm, 'closeTab');
spyOn(vm, 'tabClicked');
expect(close.querySelector('.fa-times')).toBeTruthy();
@@ -30,7 +30,7 @@ describe('RepoTab', () => {
close.click();
name.click();
- expect(vm.xClicked).toHaveBeenCalledWith(tab);
+ expect(vm.closeTab).toHaveBeenCalledWith(tab);
expect(vm.tabClicked).toHaveBeenCalledWith(tab);
});
@@ -48,22 +48,22 @@ describe('RepoTab', () => {
});
describe('methods', () => {
- describe('xClicked', () => {
+ describe('closeTab', () => {
const vm = jasmine.createSpyObj('vm', ['$emit']);
it('returns undefined and does not $emit if file is changed', () => {
const file = { changed: true };
- const returnVal = repoTab.methods.xClicked.call(vm, file);
+ const returnVal = repoTab.methods.closeTab.call(vm, file);
expect(returnVal).toBeUndefined();
expect(vm.$emit).not.toHaveBeenCalled();
});
- it('$emits xclicked event with file obj', () => {
+ it('$emits tabclosed event with file obj', () => {
const file = { changed: false };
- repoTab.methods.xClicked.call(vm, file);
+ repoTab.methods.closeTab.call(vm, file);
- expect(vm.$emit).toHaveBeenCalledWith('xclicked', file);
+ expect(vm.$emit).toHaveBeenCalledWith('tabclosed', file);
});
});
});
diff --git a/spec/javascripts/repo/components/repo_tabs_spec.js b/spec/javascripts/repo/components/repo_tabs_spec.js
index 60459e90c48..306af735dee 100644
--- a/spec/javascripts/repo/components/repo_tabs_spec.js
+++ b/spec/javascripts/repo/components/repo_tabs_spec.js
@@ -38,13 +38,13 @@ describe('RepoTabs', () => {
});
describe('methods', () => {
- describe('xClicked', () => {
+ describe('tabClosed', () => {
it('calls removeFromOpenedFiles with file obj', () => {
const file = {};
spyOn(RepoStore, 'removeFromOpenedFiles');
- repoTabs.methods.xClicked(file);
+ repoTabs.methods.tabClosed(file);
expect(RepoStore.removeFromOpenedFiles).toHaveBeenCalledWith(file);
});