<script> /* global Flash */ import Visibility from 'visibilityjs'; import Poll from '../../lib/utils/poll'; import eventHub from '../event_hub'; import Service from '../services/index'; 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: { endpoint: { required: true, type: String, }, canMove: { required: true, type: Boolean, }, canUpdate: { required: true, type: Boolean, }, canDestroy: { required: true, type: Boolean, }, issuableRef: { type: String, required: true, }, initialTitleHtml: { type: String, required: true, }, initialTitleText: { type: String, required: true, }, initialDescriptionHtml: { type: String, required: false, default: '', }, initialDescriptionText: { type: String, required: false, default: '', }, issuableTemplates: { type: Array, required: false, default: () => [], }, isConfidential: { type: Boolean, required: true, }, markdownPreviewUrl: { type: String, required: true, }, markdownDocs: { type: String, required: true, }, projectPath: { type: String, required: true, }, projectNamespace: { type: String, required: true, }, projectsAutocompleteUrl: { type: String, required: true, }, }, data() { const store = new Store({ titleHtml: this.initialTitleHtml, titleText: this.initialTitleText, descriptionHtml: this.initialDescriptionHtml, descriptionText: this.initialDescriptionText, }); return { store, state: store.state, showForm: false, }; }, computed: { formState() { return this.store.formState; }, }, components: { descriptionComponent, titleComponent, formComponent, }, methods: { openForm() { if (!this.showForm) { this.showForm = true; this.store.setFormState({ title: this.state.titleText, confidential: this.isConfidential, description: this.state.descriptionText, lockedWarningVisible: false, move_to_project_id: 0, updateLoading: false, }); } }, closeForm() { this.showForm = false; }, updateIssuable() { const canPostUpdate = this.store.formState.move_to_project_id !== 0 ? confirm('Are you sure you want to move this issue to another project?') : true; // eslint-disable-line no-alert if (!canPostUpdate) { this.store.setFormState({ updateLoading: false, }); return; } this.service.updateIssuable(this.store.formState) .then(res => res.json()) .then((data) => { if (location.pathname !== data.web_url) { gl.utils.visitUrl(data.web_url); } else if (data.confidential !== this.isConfidential) { gl.utils.visitUrl(location.pathname); } return this.service.getData(); }) .then(res => res.json()) .then((data) => { this.store.updateState(data); eventHub.$emit('close.form'); }) .catch(() => { eventHub.$emit('close.form'); return new Flash('Error updating issue'); }); }, deleteIssuable() { this.service.deleteIssuable() .then(res => res.json()) .then((data) => { // Stop the poll so we don't get 404's with the issue not existing this.poll.stop(); gl.utils.visitUrl(data.web_url); }) .catch(() => { eventHub.$emit('close.form'); return new Flash('Error deleting issue'); }); }, }, created() { this.service = new Service(this.endpoint); this.poll = new Poll({ resource: this.service, method: 'getData', successCallback: (res) => { const data = res.json(); const shouldUpdate = this.store.stateShouldUpdate(data); this.store.updateState(data); if (this.showForm && (shouldUpdate.title || shouldUpdate.description)) { this.store.formState.lockedWarningVisible = true; } }, errorCallback(err) { throw new Error(err); }, }); if (!Visibility.hidden()) { this.poll.makeRequest(); } Visibility.change(() => { if (!Visibility.hidden()) { this.poll.restart(); } else { this.poll.stop(); } }); eventHub.$on('delete.issuable', this.deleteIssuable); eventHub.$on('update.issuable', this.updateIssuable); eventHub.$on('close.form', this.closeForm); eventHub.$on('open.form', this.openForm); }, beforeDestroy() { eventHub.$off('delete.issuable', this.deleteIssuable); eventHub.$off('update.issuable', this.updateIssuable); eventHub.$off('close.form', this.closeForm); eventHub.$off('open.form', this.openForm); }, }; </script> <template> <div> <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" :projects-autocomplete-url="projectsAutocompleteUrl" /> <div v-else> <title-component :issuable-ref="issuableRef" :title-html="state.titleHtml" :title-text="state.titleText" /> <description-component v-if="state.descriptionHtml" :can-update="canUpdate" :description-html="state.descriptionHtml" :description-text="state.descriptionText" :updated-at="state.updatedAt" :task-status="state.taskStatus" /> </div> </div> </template>