Commit f1a01bab authored by Phil Hughes's avatar Phil Hughes

make error messages a first class citizen in Web IDE

This is to reduce the dependancy on the flash module which just modifies
the DOM, whereas this now correcly uses the vDOM
parent b5f2adf1
<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>
<a
v-if="message.action"
href="#"
class="flash-action"
@click.stop.prevent="clickAction"
>
{{ message.actionText }}
<loading-icon
v-show="isLoading"
inline
/>
</a>
</div>
</div>
</template>
<style scoped>
.flash-action {
color: #fff;
}
</style>
......@@ -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"
>
......
......@@ -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';
......
import _ from 'underscore';
import flash from '~/flash';
import { __, sprintf } from '~/locale';
import service from '../../services';
......@@ -89,7 +90,7 @@ export const refreshLastCommitData = ({ commit }, { projectId, branchId } = {})
flash(__('Error loading last commit.'), 'alert', document, null, false, true);
});
export const createNewBranchFromDefault = ({ state, getters }, branch) => {
export const createNewBranchFromDefault = ({ state, getters }, branch) =>
api
.createBranch(state.currentProjectId, {
ref: getters.currentProject.default_branch,
......@@ -97,27 +98,23 @@ export const createNewBranchFromDefault = ({ state, getters }, branch) => {
})
.then(() => {
location.reload();
// this forces the loading icon to spin whilst the page is reloading
return new Promise(() => {});
})
.catch(() => {});
};
export const showBranchNotFoundError = ({ dispatch }, branchId) => {
flash(
sprintf(__('Branch %{branchName} was not found in project.'), {
branchName: branchId,
}),
'alert',
document,
{
href: '#',
title: 'Create branch',
clickHandler(e) {
e.stopPropagation();
e.preventDefault();
dispatch('createNewBranchFromDefault', branchId);
dispatch('setErrorMessage', {
text: sprintf(
__('Branch %{branchName} was not found in project.'),
{
branchName: `<strong>${_.escape(branchId)}</strong>`,
},
},
false,
true,
);
false,
),
action: 'createNewBranchFromDefault',
actionText: 'Create branch',
actionPayload: branchId,
});
};
......@@ -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';
......@@ -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,
......
......@@ -25,4 +25,5 @@ export default () => ({
fileFindVisible: false,
rightPane: null,
links: {},
errorMessage: null,
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment