Commit 0a805493 authored by Mike Greiling's avatar Mike Greiling

Merge branch '31411-add-loading-indicator-when-connecting-to-error-tracking-server' into 'master'

Resolve "Add loading indicator when connecting to error tracking server"

See merge request gitlab-org/gitlab!19539
parents 10d8e6ce 39f9c85b
<script> <script>
import { mapActions, mapState } from 'vuex'; import { mapActions, mapState } from 'vuex';
import { GlButton, GlFormInput } from '@gitlab/ui'; import { GlFormInput } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
export default { export default {
components: { GlButton, GlFormInput, Icon }, components: { GlFormInput, Icon, LoadingButton },
computed: { computed: {
...mapState(['apiHost', 'connectError', 'connectSuccessful', 'token']), ...mapState(['apiHost', 'connectError', 'connectSuccessful', 'isLoadingProjects', 'token']),
tokenInputState() { tokenInputState() {
return this.connectError ? false : null; return this.connectError ? false : null;
}, },
...@@ -27,6 +28,7 @@ export default { ...@@ -27,6 +28,7 @@ export default {
<gl-form-input <gl-form-input
id="error-tracking-api-host" id="error-tracking-api-host"
:value="apiHost" :value="apiHost"
:disabled="isLoadingProjects"
placeholder="https://mysentryserver.com" placeholder="https://mysentryserver.com"
@input="updateApiHost" @input="updateApiHost"
/> />
...@@ -47,13 +49,17 @@ export default { ...@@ -47,13 +49,17 @@ export default {
id="error-tracking-token" id="error-tracking-token"
:value="token" :value="token"
:state="tokenInputState" :state="tokenInputState"
:disabled="isLoadingProjects"
@input="updateToken" @input="updateToken"
/> />
</div> </div>
<div class="col-4 col-md-3 gl-pl-0"> <div class="col-4 col-md-3 gl-pl-0">
<gl-button class="js-error-tracking-connect prepend-left-5" @click="fetchProjects">{{ <loading-button
__('Connect') class="js-error-tracking-connect prepend-left-5 d-inline-flex"
}}</gl-button> :label="isLoadingProjects ? __('Connecting') : __('Connect')"
:loading="isLoadingProjects"
@click="fetchProjects"
/>
<icon <icon
v-show="connectSuccessful" v-show="connectSuccessful"
class="js-error-tracking-connect-success prepend-left-5 text-success align-middle" class="js-error-tracking-connect-success prepend-left-5 text-success align-middle"
......
...@@ -6,17 +6,20 @@ import { transformFrontendSettings } from '../utils'; ...@@ -6,17 +6,20 @@ import { transformFrontendSettings } from '../utils';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const requestProjects = ({ commit }) => { export const requestProjects = ({ commit }) => {
commit(types.SET_PROJECTS_LOADING, true);
commit(types.RESET_CONNECT); commit(types.RESET_CONNECT);
}; };
export const receiveProjectsSuccess = ({ commit }, projects) => { export const receiveProjectsSuccess = ({ commit }, projects) => {
commit(types.UPDATE_CONNECT_SUCCESS); commit(types.UPDATE_CONNECT_SUCCESS);
commit(types.RECEIVE_PROJECTS, projects); commit(types.RECEIVE_PROJECTS, projects);
commit(types.SET_PROJECTS_LOADING, false);
}; };
export const receiveProjectsError = ({ commit }) => { export const receiveProjectsError = ({ commit }) => {
commit(types.UPDATE_CONNECT_ERROR); commit(types.UPDATE_CONNECT_ERROR);
commit(types.CLEAR_PROJECTS); commit(types.CLEAR_PROJECTS);
commit(types.SET_PROJECTS_LOADING, false);
}; };
export const fetchProjects = ({ dispatch, state }) => { export const fetchProjects = ({ dispatch, state }) => {
......
...@@ -9,3 +9,4 @@ export const UPDATE_ENABLED = 'UPDATE_ENABLED'; ...@@ -9,3 +9,4 @@ export const UPDATE_ENABLED = 'UPDATE_ENABLED';
export const UPDATE_SELECTED_PROJECT = 'UPDATE_SELECTED_PROJECT'; export const UPDATE_SELECTED_PROJECT = 'UPDATE_SELECTED_PROJECT';
export const UPDATE_SETTINGS_LOADING = 'UPDATE_SETTINGS_LOADING'; export const UPDATE_SETTINGS_LOADING = 'UPDATE_SETTINGS_LOADING';
export const UPDATE_TOKEN = 'UPDATE_TOKEN'; export const UPDATE_TOKEN = 'UPDATE_TOKEN';
export const SET_PROJECTS_LOADING = 'SET_PROJECTS_LOADING';
...@@ -58,4 +58,7 @@ export default { ...@@ -58,4 +58,7 @@ export default {
state.connectSuccessful = false; state.connectSuccessful = false;
state.connectError = true; state.connectError = true;
}, },
[types.SET_PROJECTS_LOADING](state, loading) {
state.isLoadingProjects = loading;
},
}; };
...@@ -3,6 +3,7 @@ export default () => ({ ...@@ -3,6 +3,7 @@ export default () => ({
enabled: false, enabled: false,
token: '', token: '',
projects: [], projects: [],
isLoadingProjects: false,
selectedProject: null, selectedProject: null,
settingsLoading: false, settingsLoading: false,
connectSuccessful: false, connectSuccessful: false,
......
---
title: Add loading icon to error tracking settings page
merge_request: 19539
author:
type: changed
...@@ -4452,6 +4452,9 @@ msgstr "" ...@@ -4452,6 +4452,9 @@ msgstr ""
msgid "Connect your external repositories, and CI/CD pipelines will run for new commits. A GitLab project will be created with only CI/CD features enabled." msgid "Connect your external repositories, and CI/CD pipelines will run for new commits. A GitLab project will be created with only CI/CD features enabled."
msgstr "" msgstr ""
msgid "Connecting"
msgstr ""
msgid "Connecting to terminal sync service" msgid "Connecting to terminal sync service"
msgstr "" msgstr ""
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import { GlButton, GlFormInput } from '@gitlab/ui'; import { GlFormInput } from '@gitlab/ui';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
import ErrorTrackingForm from '~/error_tracking_settings/components/error_tracking_form.vue'; import ErrorTrackingForm from '~/error_tracking_settings/components/error_tracking_form.vue';
import createStore from '~/error_tracking_settings/store'; import createStore from '~/error_tracking_settings/store';
import { defaultProps } from '../mock'; import { defaultProps } from '../mock';
...@@ -42,7 +43,7 @@ describe('error tracking settings form', () => { ...@@ -42,7 +43,7 @@ describe('error tracking settings form', () => {
.attributes('id'), .attributes('id'),
).toBe('error-tracking-token'); ).toBe('error-tracking-token');
expect(wrapper.findAll(GlButton).exists()).toBe(true); expect(wrapper.findAll(LoadingButton).exists()).toBe(true);
}); });
it('is rendered with labels and placeholders', () => { it('is rendered with labels and placeholders', () => {
...@@ -63,6 +64,18 @@ describe('error tracking settings form', () => { ...@@ -63,6 +64,18 @@ describe('error tracking settings form', () => {
}); });
}); });
describe('loading projects', () => {
beforeEach(() => {
store.state.isLoadingProjects = true;
});
it('shows loading spinner', () => {
const { label, loading } = wrapper.find(LoadingButton).props();
expect(loading).toBe(true);
expect(label).toBe('Connecting');
});
});
describe('after a successful connection', () => { describe('after a successful connection', () => {
beforeEach(() => { beforeEach(() => {
store.state.connectSuccessful = true; store.state.connectSuccessful = true;
......
...@@ -69,7 +69,14 @@ describe('error tracking settings actions', () => { ...@@ -69,7 +69,14 @@ describe('error tracking settings actions', () => {
}); });
it('should request projects correctly', done => { it('should request projects correctly', done => {
testAction(actions.requestProjects, null, state, [{ type: types.RESET_CONNECT }], [], done); testAction(
actions.requestProjects,
null,
state,
[{ type: types.SET_PROJECTS_LOADING, payload: true }, { type: types.RESET_CONNECT }],
[],
done,
);
}); });
it('should receive projects correctly', done => { it('should receive projects correctly', done => {
...@@ -81,6 +88,7 @@ describe('error tracking settings actions', () => { ...@@ -81,6 +88,7 @@ describe('error tracking settings actions', () => {
[ [
{ type: types.UPDATE_CONNECT_SUCCESS }, { type: types.UPDATE_CONNECT_SUCCESS },
{ type: types.RECEIVE_PROJECTS, payload: testPayload }, { type: types.RECEIVE_PROJECTS, payload: testPayload },
{ type: types.SET_PROJECTS_LOADING, payload: false },
], ],
[], [],
done, done,
...@@ -93,7 +101,11 @@ describe('error tracking settings actions', () => { ...@@ -93,7 +101,11 @@ describe('error tracking settings actions', () => {
actions.receiveProjectsError, actions.receiveProjectsError,
testPayload, testPayload,
state, state,
[{ type: types.UPDATE_CONNECT_ERROR }, { type: types.CLEAR_PROJECTS }], [
{ type: types.UPDATE_CONNECT_ERROR },
{ type: types.CLEAR_PROJECTS },
{ type: types.SET_PROJECTS_LOADING, payload: false },
],
[], [],
done, done,
); );
......
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