diff options
author | Adriel Santiago <adriel@gitlab.com> | 2019-05-28 17:39:37 -0400 |
---|---|---|
committer | Adriel Santiago <adriel@gitlab.com> | 2019-06-01 06:12:13 -0400 |
commit | 9bee567fea1422631e6f4b4ae1607c7d9a61e6b3 (patch) | |
tree | 237670b9271a9efa65acf0298e58558f627ba2de | |
parent | 9bd7d5abe653e2a5231919c5bee8b1689faa1e7d (diff) | |
download | gitlab-ce-fe-61453-helpers.tar.gz |
Use vuex for external dashboard settingsfe-61453-helpers
Avoid ajax calls within the external dashboard component
9 files changed, 123 insertions, 55 deletions
diff --git a/app/assets/javascripts/operation_settings/components/external_dashboard.vue b/app/assets/javascripts/operation_settings/components/external_dashboard.vue index 805a7f93c58..6d11d0c72aa 100644 --- a/app/assets/javascripts/operation_settings/components/external_dashboard.vue +++ b/app/assets/javascripts/operation_settings/components/external_dashboard.vue @@ -1,9 +1,6 @@ <script> +import { mapState, mapActions } from 'vuex'; import { GlButton, GlFormGroup, GlFormInput, GlLink } from '@gitlab/ui'; -import { __ } from '~/locale'; -import axios from '~/lib/utils/axios_utils'; -import createFlash from '~/flash'; -import { refreshCurrentPage } from '~/lib/utils/url_utility'; export default { components: { @@ -12,44 +9,23 @@ export default { GlFormInput, GlLink, }, - props: { - operationsSettingsEndpoint: { - type: String, - required: true, + computed: { + ...mapState([ + 'externalDashboardHelpPagePath', + 'externalDashboardUrl', + 'operationsSettingsEndpoint', + ]), + userDashboardUrl: { + get() { + return this.externalDashboardUrl; + }, + set(url) { + this.setExternalDashboardUrl(url); + }, }, - externalDashboardUrl: { - type: String, - required: false, - default: '', - }, - externalDashboardHelpPagePath: { - type: String, - required: true, - }, - }, - data() { - return { - userDashboardUrl: this.externalDashboardUrl, - }; }, methods: { - submitForm() { - axios - .patch(this.operationsSettingsEndpoint, { - project: { - metrics_setting_attributes: { - external_dashboard_url: this.userDashboardUrl, - }, - }, - }) - .then(() => refreshCurrentPage()) - .catch(error => { - const { response } = error; - const message = response.data && response.data.message ? response.data.message : ''; - - createFlash(`${__('There was an error saving your changes.')} ${message}`, 'alert'); - }); - }, + ...mapActions(['setExternalDashboardUrl', 'updateExternalDashboardUrl']), }, }; </script> @@ -78,10 +54,10 @@ export default { <gl-form-input v-model="userDashboardUrl" placeholder="https://my-org.gitlab.io/my-dashboards" - @keydown.enter.native.prevent="submitForm" + @keydown.enter.native.prevent="updateExternalDashboardUrl" /> </gl-form-group> - <gl-button variant="success" @click="submitForm"> + <gl-button variant="success" @click="updateExternalDashboardUrl"> {{ __('Save Changes') }} </gl-button> </form> diff --git a/app/assets/javascripts/operation_settings/index.js b/app/assets/javascripts/operation_settings/index.js index 1171f3ece9f..6946578e6d2 100644 --- a/app/assets/javascripts/operation_settings/index.js +++ b/app/assets/javascripts/operation_settings/index.js @@ -1,4 +1,5 @@ import Vue from 'vue'; +import store from './store'; import ExternalDashboardForm from './components/external_dashboard.vue'; export default () => { @@ -14,13 +15,9 @@ export default () => { return new Vue({ el, + store: store(el.dataset), render(createElement) { - return createElement(ExternalDashboardForm, { - props: { - ...el.dataset, - expanded: false, - }, - }); + return createElement(ExternalDashboardForm); }, }); }; diff --git a/app/assets/javascripts/operation_settings/store/actions.js b/app/assets/javascripts/operation_settings/store/actions.js new file mode 100644 index 00000000000..ec05b0c76cf --- /dev/null +++ b/app/assets/javascripts/operation_settings/store/actions.js @@ -0,0 +1,38 @@ +import axios from '~/lib/utils/axios_utils'; +import { __ } from '~/locale'; +import createFlash from '~/flash'; +import { refreshCurrentPage } from '~/lib/utils/url_utility'; +import * as mutationTypes from './mutation_types'; + +export const setExternalDashboardUrl = ({ commit }, url) => + commit(mutationTypes.SET_EXTERNAL_DASHBOARD_URL, url); + +export const updateExternalDashboardUrl = ({ state, dispatch }) => + axios + .patch(state.operationsSettingsEndpoint, { + project: { + metrics_setting_attributes: { + external_dashboard_url: state.externalDashboardUrl, + }, + }, + }) + .then(() => dispatch('receiveExternalDashboardUpdateSuccess')) + .catch(error => dispatch('receiveExternalDashboardUpdateError', error)); + +export const receiveExternalDashboardUpdateSuccess = () => { + /** + * The operations_controller currently handles successful requests + * by creating a flash banner messsage to notify the user. + */ + refreshCurrentPage(); +}; + +export const receiveExternalDashboardUpdateError = (_, error) => { + const { response } = error; + const message = response.data && response.data.message ? response.data.message : ''; + + createFlash(`${__('There was an error saving your changes.')} ${message}`, 'alert'); +}; + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/operation_settings/store/index.js b/app/assets/javascripts/operation_settings/store/index.js new file mode 100644 index 00000000000..e96bb1e8aad --- /dev/null +++ b/app/assets/javascripts/operation_settings/store/index.js @@ -0,0 +1,16 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import createState from './state'; +import * as actions from './actions'; +import mutations from './mutations'; + +Vue.use(Vuex); + +export const createStore = initialState => + new Vuex.Store({ + state: createState(initialState), + actions, + mutations, + }); + +export default createStore; diff --git a/app/assets/javascripts/operation_settings/store/mutation_types.js b/app/assets/javascripts/operation_settings/store/mutation_types.js new file mode 100644 index 00000000000..237d2b6122f --- /dev/null +++ b/app/assets/javascripts/operation_settings/store/mutation_types.js @@ -0,0 +1,3 @@ +/* eslint-disable import/prefer-default-export */ + +export const SET_EXTERNAL_DASHBOARD_URL = 'SET_EXTERNAL_DASHBOARD_URL'; diff --git a/app/assets/javascripts/operation_settings/store/mutations.js b/app/assets/javascripts/operation_settings/store/mutations.js new file mode 100644 index 00000000000..64bb33bb89f --- /dev/null +++ b/app/assets/javascripts/operation_settings/store/mutations.js @@ -0,0 +1,7 @@ +import * as types from './mutation_types'; + +export default { + [types.SET_EXTERNAL_DASHBOARD_URL](state, url) { + state.externalDashboardUrl = url; + }, +}; diff --git a/app/assets/javascripts/operation_settings/store/state.js b/app/assets/javascripts/operation_settings/store/state.js new file mode 100644 index 00000000000..72167141c48 --- /dev/null +++ b/app/assets/javascripts/operation_settings/store/state.js @@ -0,0 +1,5 @@ +export default (initialState = {}) => ({ + externalDashboardUrl: initialState.externalDashboardUrl || '', + operationsSettingsEndpoint: initialState.operationsSettingsEndpoint, + externalDashboardHelpPagePath: initialState.externalDashboardHelpPagePath, +}); diff --git a/spec/frontend/operation_settings/components/external_dashboard_spec.js b/spec/frontend/operation_settings/components/external_dashboard_spec.js index 5b33bb9adcc..c629574e332 100644 --- a/spec/frontend/operation_settings/components/external_dashboard_spec.js +++ b/spec/frontend/operation_settings/components/external_dashboard_spec.js @@ -1,6 +1,7 @@ -import { mount, shallowMount } from '@vue/test-utils'; +import { mount, shallowMount, createLocalVue } from '@vue/test-utils'; import { GlButton, GlLink, GlFormGroup, GlFormInput } from '@gitlab/ui'; import ExternalDashboard from '~/operation_settings/components/external_dashboard.vue'; +import store from '~/operation_settings/store'; import axios from '~/lib/utils/axios_utils'; import { refreshCurrentPage } from '~/lib/utils/url_utility'; import createFlash from '~/flash'; @@ -15,13 +16,19 @@ describe('operation settings external dashboard component', () => { const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`; const externalDashboardUrl = `http://mock-external-domain.com/external/dashboard/url`; const externalDashboardHelpPagePath = `${TEST_HOST}/help/page/path`; - const propsData = { - operationsSettingsEndpoint, - externalDashboardUrl, - externalDashboardHelpPagePath, - }; + const localVue = createLocalVue(); const mountComponent = (shallow = true) => { - const config = [ExternalDashboard, { propsData }]; + const config = [ + ExternalDashboard, + { + localVue, + store: store({ + operationsSettingsEndpoint, + externalDashboardUrl, + externalDashboardHelpPagePath, + }), + }, + ]; wrapper = shallow ? shallowMount(...config) : mount(...config); }; @@ -89,7 +96,7 @@ describe('operation settings external dashboard component', () => { input = wrapper.find(GlFormInput); }); - it('defaults to externalDashboardUrl prop', () => { + it('defaults to externalDashboardUrl', () => { expect(input.attributes().value).toBe(externalDashboardUrl); }); diff --git a/spec/frontend/operation_settings/store/mutations_spec.js b/spec/frontend/operation_settings/store/mutations_spec.js new file mode 100644 index 00000000000..1854142c89a --- /dev/null +++ b/spec/frontend/operation_settings/store/mutations_spec.js @@ -0,0 +1,19 @@ +import mutations from '~/operation_settings/store/mutations'; +import createState from '~/operation_settings/store/state'; + +describe('operation settings mutations', () => { + let localState; + + beforeEach(() => { + localState = createState(); + }); + + describe('SET_EXTERNAL_DASHBOARD_URL', () => { + it('sets externalDashboardUrl', () => { + const mockUrl = 'mockUrl'; + mutations.SET_EXTERNAL_DASHBOARD_URL(localState, mockUrl); + + expect(localState.externalDashboardUrl).toBe(mockUrl); + }); + }); +}); |