summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriel Santiago <adriel@gitlab.com>2019-05-28 17:39:37 -0400
committerAdriel Santiago <adriel@gitlab.com>2019-06-01 06:12:13 -0400
commit9bee567fea1422631e6f4b4ae1607c7d9a61e6b3 (patch)
tree237670b9271a9efa65acf0298e58558f627ba2de
parent9bd7d5abe653e2a5231919c5bee8b1689faa1e7d (diff)
downloadgitlab-ce-fe-61453-helpers.tar.gz
Use vuex for external dashboard settingsfe-61453-helpers
Avoid ajax calls within the external dashboard component
-rw-r--r--app/assets/javascripts/operation_settings/components/external_dashboard.vue58
-rw-r--r--app/assets/javascripts/operation_settings/index.js9
-rw-r--r--app/assets/javascripts/operation_settings/store/actions.js38
-rw-r--r--app/assets/javascripts/operation_settings/store/index.js16
-rw-r--r--app/assets/javascripts/operation_settings/store/mutation_types.js3
-rw-r--r--app/assets/javascripts/operation_settings/store/mutations.js7
-rw-r--r--app/assets/javascripts/operation_settings/store/state.js5
-rw-r--r--spec/frontend/operation_settings/components/external_dashboard_spec.js23
-rw-r--r--spec/frontend/operation_settings/store/mutations_spec.js19
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);
+ });
+ });
+});