summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-05-22 08:59:37 +0100
committerPhil Hughes <me@iamphill.com>2017-05-22 08:59:37 +0100
commit7a21e26f4b1243a48e6e31f2b9af6e525ae8ca30 (patch)
tree15f730d427826f884aa5f84827da6810255cd080 /app/assets
parent4f0849f2fd1427b21bd6a043223f49d0c77fa3a3 (diff)
parent3c3b17a5a4b4f85f3f81f918a7e0c3a57f469eb7 (diff)
downloadgitlab-ce-7a21e26f4b1243a48e6e31f2b9af6e525ae8ca30.tar.gz
Merge branch 'issue-edit-inline' into issue-edit-inline-description-template
[ci skip]
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/issue_show/components/app.vue40
-rw-r--r--app/assets/javascripts/issue_show/components/fields/description.vue5
-rw-r--r--app/assets/javascripts/issue_show/components/fields/project_move.vue83
-rw-r--r--app/assets/javascripts/issue_show/components/form.vue17
-rw-r--r--app/assets/javascripts/issue_show/index.js6
-rw-r--r--app/assets/javascripts/issue_show/services/index.js2
-rw-r--r--app/assets/javascripts/issue_show/stores/index.js1
7 files changed, 140 insertions, 14 deletions
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue
index 9cd454e9f73..d9bfc29130f 100644
--- a/app/assets/javascripts/issue_show/components/app.vue
+++ b/app/assets/javascripts/issue_show/components/app.vue
@@ -8,6 +8,7 @@ import Store from '../stores';
import titleComponent from './title.vue';
import descriptionComponent from './description.vue';
import formComponent from './form.vue';
+import '../../lib/utils/url_utility';
export default {
props: {
@@ -15,6 +16,10 @@ export default {
required: true,
type: String,
},
+ canMove: {
+ required: true,
+ type: Boolean,
+ },
canUpdate: {
required: true,
type: Boolean,
@@ -66,6 +71,10 @@ export default {
type: String,
required: true,
},
+ projectsAutocompleteUrl: {
+ type: String,
+ required: true,
+ },
},
data() {
const store = new Store({
@@ -92,23 +101,27 @@ export default {
},
methods: {
openForm() {
- this.showForm = true;
- this.store.formState = {
- title: this.state.titleText,
- confidential: this.isConfidential,
- description: this.state.descriptionText,
- };
+ if (!this.showForm) {
+ this.showForm = true;
+ this.store.formState = {
+ title: this.state.titleText,
+ confidential: this.isConfidential,
+ description: this.state.descriptionText,
+ move_to_project_id: 0,
+ };
+ }
},
closeForm() {
this.showForm = false;
},
updateIssuable() {
this.service.updateIssuable(this.store.formState)
- .then((res) => {
- const data = res.json();
-
- if (data.confidential !== this.isConfidential) {
- location.reload();
+ .then(res => res.json())
+ .then((data) => {
+ if (location.pathname !== data.path) {
+ gl.utils.visitUrl(data.path);
+ } else if (data.confidential !== this.isConfidential) {
+ gl.utils.visitUrl(location.pathname);
}
eventHub.$emit('close.form');
@@ -177,12 +190,15 @@ export default {
<form-component
v-if="canUpdate && showForm"
:form-state="formState"
+ :can-move="canMove"
:can-destroy="canDestroy"
:issuable-templates="issuableTemplates"
:markdown-docs="markdownDocs"
:markdown-preview-url="markdownPreviewUrl"
:project-path="projectPath"
- :project-namespace="projectNamespace" />
+ :project-namespace="projectNamespace"
+ :projects-autocomplete-url="projectsAutocompleteUrl"
+ />
<div v-else>
<title-component
:issuable-ref="issuableRef"
diff --git a/app/assets/javascripts/issue_show/components/fields/description.vue b/app/assets/javascripts/issue_show/components/fields/description.vue
index b4c31811a0b..35b1ea6ff2b 100644
--- a/app/assets/javascripts/issue_show/components/fields/description.vue
+++ b/app/assets/javascripts/issue_show/components/fields/description.vue
@@ -20,6 +20,9 @@
components: {
markdownField,
},
+ mounted() {
+ this.$refs.textarea.focus();
+ },
};
</script>
@@ -39,7 +42,7 @@
data-supports-slash-commands="false"
aria-label="Description"
v-model="formState.description"
- ref="textatea"
+ ref="textarea"
slot="textarea">
</textarea>
</markdown-field>
diff --git a/app/assets/javascripts/issue_show/components/fields/project_move.vue b/app/assets/javascripts/issue_show/components/fields/project_move.vue
new file mode 100644
index 00000000000..f811fb0de24
--- /dev/null
+++ b/app/assets/javascripts/issue_show/components/fields/project_move.vue
@@ -0,0 +1,83 @@
+<script>
+ import tooltipMixin from '../../../vue_shared/mixins/tooltip';
+
+ export default {
+ mixins: [
+ tooltipMixin,
+ ],
+ props: {
+ formState: {
+ type: Object,
+ required: true,
+ },
+ projectsAutocompleteUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ mounted() {
+ const $moveDropdown = $(this.$refs['move-dropdown']);
+
+ $moveDropdown.select2({
+ ajax: {
+ url: this.projectsAutocompleteUrl,
+ quietMillis: 125,
+ data(term, page, context) {
+ return {
+ search: term,
+ offset_id: context,
+ };
+ },
+ results(data) {
+ const more = data.length >= 50;
+ const context = data[data.length - 1] ? data[data.length - 1].id : null;
+
+ return {
+ results: data,
+ more,
+ context,
+ };
+ },
+ },
+ formatResult(project) {
+ return project.name_with_namespace;
+ },
+ formatSelection(project) {
+ return project.name_with_namespace;
+ },
+ })
+ .on('change', (e) => {
+ this.formState.move_to_project_id = parseInt(e.target.value, 10);
+ });
+ },
+ beforeDestroy() {
+ $(this.$refs['move-dropdown']).select2('destroy');
+ },
+ };
+</script>
+
+<template>
+ <fieldset>
+ <label
+ for="issuable-move"
+ class="sr-only">
+ Move
+ </label>
+ <div class="issuable-form-select-holder append-right-5">
+ <input
+ ref="move-dropdown"
+ type="hidden"
+ id="issuable-move"
+ data-placeholder="Move to a different project" />
+ </div>
+ <span
+ data-placement="auto top"
+ title="Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location."
+ ref="tooltip">
+ <i
+ class="fa fa-question-circle"
+ aria-hidden="true">
+ </i>
+ </span>
+ </fieldset>
+</template>
diff --git a/app/assets/javascripts/issue_show/components/form.vue b/app/assets/javascripts/issue_show/components/form.vue
index facdca4072d..0c8c972ff31 100644
--- a/app/assets/javascripts/issue_show/components/form.vue
+++ b/app/assets/javascripts/issue_show/components/form.vue
@@ -2,11 +2,19 @@
import titleField from './fields/title.vue';
import descriptionField from './fields/description.vue';
import editActions from './edit_actions.vue';
+<<<<<<< HEAD
import descriptionTemplate from './fields/description_template.vue';
+=======
+ import projectMove from './fields/project_move.vue';
+>>>>>>> issue-edit-inline
import confidentialCheckbox from './fields/confidential_checkbox.vue';
export default {
props: {
+ canMove: {
+ type: Boolean,
+ required: true,
+ },
canDestroy: {
type: Boolean,
required: true,
@@ -36,12 +44,17 @@
type: String,
required: true,
},
+ projectsAutocompleteUrl: {
+ type: String,
+ required: true,
+ },
},
components: {
titleField,
descriptionField,
descriptionTemplate,
editActions,
+ projectMove,
confidentialCheckbox,
},
computed: {
@@ -80,6 +93,10 @@
:markdown-docs="markdownDocs" />
<confidential-checkbox
:form-state="formState" />
+ <project-move
+ v-if="canMove"
+ :form-state="formState"
+ :projects-autocomplete-url="projectsAutocompleteUrl" />
<edit-actions
:form-state="formState"
:can-destroy="canDestroy" />
diff --git a/app/assets/javascripts/issue_show/index.js b/app/assets/javascripts/issue_show/index.js
index f368dd5902c..3b4e5c5488c 100644
--- a/app/assets/javascripts/issue_show/index.js
+++ b/app/assets/javascripts/issue_show/index.js
@@ -25,16 +25,19 @@ document.addEventListener('DOMContentLoaded', () => {
const {
canUpdate,
canDestroy,
+ canMove,
endpoint,
issuableRef,
isConfidential,
markdownPreviewUrl,
markdownDocs,
+ projectsAutocompleteUrl,
} = issuableElement.dataset;
return {
canUpdate: gl.utils.convertPermissionToBoolean(canUpdate),
canDestroy: gl.utils.convertPermissionToBoolean(canDestroy),
+ canMove: gl.utils.convertPermissionToBoolean(canMove),
endpoint,
issuableRef,
initialTitle: issuableTitleElement.innerHTML,
@@ -45,6 +48,7 @@ document.addEventListener('DOMContentLoaded', () => {
markdownDocs,
projectPath: initialData.project_path,
projectNamespace: initialData.namespace_path,
+ projectsAutocompleteUrl,
};
},
render(createElement) {
@@ -52,6 +56,7 @@ document.addEventListener('DOMContentLoaded', () => {
props: {
canUpdate: this.canUpdate,
canDestroy: this.canDestroy,
+ canMove: this.canMove,
endpoint: this.endpoint,
issuableRef: this.issuableRef,
initialTitle: this.initialTitle,
@@ -63,6 +68,7 @@ document.addEventListener('DOMContentLoaded', () => {
markdownDocs: this.markdownDocs,
projectPath: this.projectPath,
projectNamespace: this.projectNamespace,
+ projectsAutocompleteUrl: this.projectsAutocompleteUrl,
},
});
},
diff --git a/app/assets/javascripts/issue_show/services/index.js b/app/assets/javascripts/issue_show/services/index.js
index 0ceff34cf8b..6f0fd0b1768 100644
--- a/app/assets/javascripts/issue_show/services/index.js
+++ b/app/assets/javascripts/issue_show/services/index.js
@@ -7,7 +7,7 @@ export default class Service {
constructor(endpoint) {
this.endpoint = endpoint;
- this.resource = Vue.resource(this.endpoint, {}, {
+ this.resource = Vue.resource(`${this.endpoint}.json`, {}, {
realtimeChanges: {
method: 'GET',
url: `${this.endpoint}/realtime_changes`,
diff --git a/app/assets/javascripts/issue_show/stores/index.js b/app/assets/javascripts/issue_show/stores/index.js
index d90716bef80..1135bc0bfb5 100644
--- a/app/assets/javascripts/issue_show/stores/index.js
+++ b/app/assets/javascripts/issue_show/stores/index.js
@@ -16,6 +16,7 @@ export default class Store {
title: '',
confidential: false,
description: '',
+ move_to_project_id: 0,
};
}