diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-06-28 12:21:58 +0300 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-06-28 12:21:58 +0300 |
commit | 6412850942992c26cc6de0864149b7877f98afb5 (patch) | |
tree | 9e029d405f230c92b5e20b8e6951d771509cb680 /app/assets | |
parent | 4473b685d6a64263eca6f87567fd2a0529802071 (diff) | |
parent | 5d5579b3f5e7394ee7158a5cc462980b9a966b63 (diff) |
Merge branch 'ide-improve-error-messages' into 'master'
Improve branch 404 error in Web IDE
See merge request gitlab-org/gitlab-ce!19861
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/api.js | 9 | ||||
-rw-r--r-- | app/assets/javascripts/ide/components/error_message.vue | 69 | ||||
-rw-r--r-- | app/assets/javascripts/ide/components/ide.vue | 7 | ||||
-rw-r--r-- | app/assets/javascripts/ide/ide_router.js | 8 | ||||
-rw-r--r-- | app/assets/javascripts/ide/services/index.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/actions.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/actions/project.js | 66 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/actions/tree.js | 25 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/mutation_types.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/mutations.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/ide/stores/state.js | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/flash.scss | 2 |
12 files changed, 172 insertions, 30 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 000938e475f..d62fae99c6b 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -243,6 +243,15 @@ const Api = { }); }, + createBranch(id, { ref, branch }) { + const url = Api.buildUrl(this.createBranchPath).replace(':id', encodeURIComponent(id)); + + return axios.post(url, { + ref, + branch, + }); + }, + buildUrl(url) { let urlRoot = ''; if (gon.relative_url_root != null) { diff --git a/app/assets/javascripts/ide/components/error_message.vue b/app/assets/javascripts/ide/components/error_message.vue new file mode 100644 index 00000000000..e7408264c80 --- /dev/null +++ b/app/assets/javascripts/ide/components/error_message.vue @@ -0,0 +1,69 @@ +<script> +import { mapActions } from 'vuex'; +import LoadingIcon from '../../vue_shared/components/loading_icon.vue'; + +export default { + components: { + LoadingIcon, + }, + props: { + message: { + type: Object, + required: true, + }, + }, + data() { + return { + isLoading: false, + }; + }, + methods: { + ...mapActions(['setErrorMessage']), + clickAction() { + if (this.isLoading) return; + + this.isLoading = true; + + this.$store + .dispatch(this.message.action, this.message.actionPayload) + .then(() => { + this.isLoading = false; + }) + .catch(() => { + this.isLoading = false; + }); + }, + clickFlash() { + if (!this.message.action) { + this.setErrorMessage(null); + } + }, + }, +}; +</script> + +<template> + <div + class="flash-container flash-container-page" + @click="clickFlash" + > + <div class="flash-alert"> + <span + v-html="message.text" + > + </span> + <button + v-if="message.action" + type="button" + class="flash-action text-white p-0 border-top-0 border-right-0 border-left-0 bg-transparent" + @click.stop.prevent="clickAction" + > + {{ message.actionText }} + <loading-icon + v-show="isLoading" + inline + /> + </button> + </div> + </div> +</template> diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue index f5f7f967a92..9f016e0338f 100644 --- a/app/assets/javascripts/ide/components/ide.vue +++ b/app/assets/javascripts/ide/components/ide.vue @@ -7,6 +7,7 @@ import IdeStatusBar from './ide_status_bar.vue'; import RepoEditor from './repo_editor.vue'; import FindFile from './file_finder/index.vue'; import RightPane from './panes/right.vue'; +import ErrorMessage from './error_message.vue'; const originalStopCallback = Mousetrap.stopCallback; @@ -18,6 +19,7 @@ export default { RepoEditor, FindFile, RightPane, + ErrorMessage, }, computed: { ...mapState([ @@ -28,6 +30,7 @@ export default { 'fileFindVisible', 'emptyStateSvgPath', 'currentProjectId', + 'errorMessage', ]), ...mapGetters(['activeFile', 'hasChanges']), }, @@ -72,6 +75,10 @@ export default { <template> <article class="ide"> + <error-message + v-if="errorMessage" + :message="errorMessage" + /> <div class="ide-view" > diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js index b52618f4fde..cc8dbb942d8 100644 --- a/app/assets/javascripts/ide/ide_router.js +++ b/app/assets/javascripts/ide/ide_router.js @@ -95,14 +95,6 @@ router.beforeEach((to, from, next) => { } }) .catch(e => { - flash( - 'Error while loading the branch files. Please try again.', - 'alert', - document, - null, - false, - true, - ); throw e; }); } else if (to.params.mrid) { diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js index da9de25302a..5e642067141 100644 --- a/app/assets/javascripts/ide/services/index.js +++ b/app/assets/javascripts/ide/services/index.js @@ -1,5 +1,6 @@ import Vue from 'vue'; import VueResource from 'vue-resource'; +import axios from '~/lib/utils/axios_utils'; import Api from '~/api'; Vue.use(VueResource); @@ -69,11 +70,7 @@ export default { }, getFiles(projectUrl, branchId) { const url = `${projectUrl}/files/${branchId}`; - return Vue.http.get(url, { - params: { - format: 'json', - }, - }); + return axios.get(url, { params: { format: 'json' } }); }, lastCommitPipelines({ getters }) { const commitSha = getters.lastCommit.id; diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js index 3dc365eaead..5e91fa915ff 100644 --- a/app/assets/javascripts/ide/stores/actions.js +++ b/app/assets/javascripts/ide/stores/actions.js @@ -175,6 +175,9 @@ export const setRightPane = ({ commit }, view) => { export const setLinks = ({ commit }, links) => commit(types.SET_LINKS, links); +export const setErrorMessage = ({ commit }, errorMessage) => + commit(types.SET_ERROR_MESSAGE, errorMessage); + export * from './actions/tree'; export * from './actions/file'; export * from './actions/project'; diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js index 0b99bce4a8e..ab5cd8e4742 100644 --- a/app/assets/javascripts/ide/stores/actions/project.js +++ b/app/assets/javascripts/ide/stores/actions/project.js @@ -1,7 +1,10 @@ +import _ from 'underscore'; import flash from '~/flash'; -import { __ } from '~/locale'; +import { __, sprintf } from '~/locale'; import service from '../../services'; +import api from '../../../api'; import * as types from '../mutation_types'; +import router from '../../ide_router'; export const getProjectData = ({ commit, state }, { namespace, projectId, force = false } = {}) => new Promise((resolve, reject) => { @@ -32,7 +35,10 @@ export const getProjectData = ({ commit, state }, { namespace, projectId, force } }); -export const getBranchData = ({ commit, state }, { projectId, branchId, force = false } = {}) => +export const getBranchData = ( + { commit, dispatch, state }, + { projectId, branchId, force = false } = {}, +) => new Promise((resolve, reject) => { if ( typeof state.projects[`${projectId}`] === 'undefined' || @@ -51,15 +57,19 @@ export const getBranchData = ({ commit, state }, { projectId, branchId, force = commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id }); resolve(data); }) - .catch(() => { - flash( - __('Error loading branch data. Please try again.'), - 'alert', - document, - null, - false, - true, - ); + .catch(e => { + if (e.response.status === 404) { + dispatch('showBranchNotFoundError', branchId); + } else { + flash( + __('Error loading branch data. Please try again.'), + 'alert', + document, + null, + false, + true, + ); + } reject(new Error(`Branch not loaded - ${projectId}/${branchId}`)); }); } else { @@ -80,3 +90,37 @@ export const refreshLastCommitData = ({ commit }, { projectId, branchId } = {}) .catch(() => { flash(__('Error loading last commit.'), 'alert', document, null, false, true); }); + +export const createNewBranchFromDefault = ({ state, dispatch, getters }, branch) => + api + .createBranch(state.currentProjectId, { + ref: getters.currentProject.default_branch, + branch, + }) + .then(() => { + dispatch('setErrorMessage', null); + router.push(`${router.currentRoute.path}?${Date.now()}`); + }) + .catch(() => { + dispatch('setErrorMessage', { + text: __('An error occured creating the new branch.'), + action: 'createNewBranchFromDefault', + actionText: __('Please try again'), + actionPayload: branch, + }); + }); + +export const showBranchNotFoundError = ({ dispatch }, branchId) => { + dispatch('setErrorMessage', { + text: sprintf( + __("Branch %{branchName} was not found in this project's repository."), + { + branchName: `<strong>${_.escape(branchId)}</strong>`, + }, + false, + ), + action: 'createNewBranchFromDefault', + actionText: __('Create branch'), + actionPayload: branchId, + }); +}; diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js index 2fbc9990fa2..dcdd900fc7e 100644 --- a/app/assets/javascripts/ide/stores/actions/tree.js +++ b/app/assets/javascripts/ide/stores/actions/tree.js @@ -1,5 +1,6 @@ import { normalizeHeaders } from '~/lib/utils/common_utils'; import flash from '~/flash'; +import { __ } from '../../../locale'; import service from '../../services'; import * as types from '../mutation_types'; import { findEntry } from '../utils'; @@ -62,16 +63,19 @@ export const getLastCommitData = ({ state, commit, dispatch }, tree = state) => .catch(() => flash('Error fetching log data.', 'alert', document, null, false, true)); }; -export const getFiles = ({ state, commit }, { projectId, branchId } = {}) => +export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = {}) => new Promise((resolve, reject) => { - if (!state.trees[`${projectId}/${branchId}`]) { + if ( + !state.trees[`${projectId}/${branchId}`] || + (state.trees[`${projectId}/${branchId}`].tree && + state.trees[`${projectId}/${branchId}`].tree.length === 0) + ) { const selectedProject = state.projects[projectId]; commit(types.CREATE_TREE, { treePath: `${projectId}/${branchId}` }); service .getFiles(selectedProject.web_url, branchId) - .then(res => res.json()) - .then(data => { + .then(({ data }) => { const worker = new FilesDecoratorWorker(); worker.addEventListener('message', e => { const { entries, treeList } = e.data; @@ -99,7 +103,18 @@ export const getFiles = ({ state, commit }, { projectId, branchId } = {}) => }); }) .catch(e => { - flash('Error loading tree data. Please try again.', 'alert', document, null, false, true); + if (e.response.status === 404) { + dispatch('showBranchNotFoundError', branchId); + } else { + flash( + __('Error loading tree data. Please try again.'), + 'alert', + document, + null, + false, + true, + ); + } reject(e); }); } else { diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js index fda606dbf01..555802e1811 100644 --- a/app/assets/javascripts/ide/stores/mutation_types.js +++ b/app/assets/javascripts/ide/stores/mutation_types.js @@ -72,3 +72,5 @@ export const SET_RIGHT_PANE = 'SET_RIGHT_PANE'; export const CLEAR_PROJECTS = 'CLEAR_PROJECTS'; export const RESET_OPEN_FILES = 'RESET_OPEN_FILES'; + +export const SET_ERROR_MESSAGE = 'SET_ERROR_MESSAGE'; diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js index 48f1da4eccf..702be2140e2 100644 --- a/app/assets/javascripts/ide/stores/mutations.js +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -163,6 +163,9 @@ export default { [types.RESET_OPEN_FILES](state) { Object.assign(state, { openFiles: [] }); }, + [types.SET_ERROR_MESSAGE](state, errorMessage) { + Object.assign(state, { errorMessage }); + }, ...projectMutations, ...mergeRequestMutation, ...fileMutations, diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js index 4aac4696075..be229b2c723 100644 --- a/app/assets/javascripts/ide/stores/state.js +++ b/app/assets/javascripts/ide/stores/state.js @@ -25,4 +25,5 @@ export default () => ({ fileFindVisible: false, rightPane: null, links: {}, + errorMessage: null, }); diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss index a6e324036ae..e4bcb92876d 100644 --- a/app/assets/stylesheets/framework/flash.scss +++ b/app/assets/stylesheets/framework/flash.scss @@ -42,7 +42,7 @@ display: inline-block; } - a.flash-action { + .flash-action { margin-left: 5px; text-decoration: none; font-weight: $gl-font-weight-normal; |