Commit edd4710c authored by David O'Regan's avatar David O'Regan

Alert Settings Apollo

A small refractor for the alert
settings form to use apollo
cache instead of props
parent c22d72d1
......@@ -13,6 +13,7 @@ import {
import { s__, __ } from '~/locale';
import Tracking from '~/tracking';
import { trackAlertIntegrationsViewsOptions, integrationToDeleteDefault } from '../constants';
import getCurrentIntegrationQuery from '../graphql/queries/get_current_integration.query.graphql';
export const i18n = {
title: s__('AlertsIntegrations|Current integrations'),
......@@ -58,11 +59,6 @@ export default {
required: false,
default: false,
},
currentIntegration: {
type: Object,
required: false,
default: null,
},
},
fields: [
{
......@@ -82,9 +78,15 @@ export default {
label: __('Actions'),
},
],
apollo: {
currentIntegration: {
query: getCurrentIntegrationQuery,
},
},
data() {
return {
integrationToDelete: integrationToDeleteDefault,
currentIntegration: null,
};
},
mounted() {
......@@ -101,11 +103,11 @@ export default {
const { category, action } = trackAlertIntegrationsViewsOptions;
Tracking.event(category, action);
},
intergrationToDelete({ name, id }) {
setIntegrationToDelete({ name, id }) {
this.integrationToDelete.id = id;
this.integrationToDelete.name = name;
},
deleteIntergration() {
deleteIntegration() {
this.$emit('delete-integration', { id: this.integrationToDelete.id });
this.integrationToDelete = { ...integrationToDeleteDefault };
},
......@@ -153,7 +155,7 @@ export default {
<gl-button
v-gl-modal.deleteIntegration
icon="remove"
@click="intergrationToDelete(item)"
@click="setIntegrationToDelete(item)"
/>
</gl-button-group>
</template>
......@@ -175,7 +177,7 @@ export default {
:title="__('Are you sure?')"
:ok-title="s__('AlertSettings|Delete integration')"
ok-variant="danger"
@ok="deleteIntergration"
@ok="deleteIntegration"
>
<gl-sprintf
:message="
......
......@@ -12,11 +12,12 @@ import {
GlModalDirective,
GlToggle,
} from '@gitlab/ui';
import MappingBuilder from './alert_mapping_builder.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import MappingBuilder from './alert_mapping_builder.vue';
import AlertSettingsFormHelpBlock from './alert_settings_form_help_block.vue';
import getCurrentIntegrationQuery from '../graphql/queries/get_current_integration.query.graphql';
import service from '../services';
import {
integrationTypesNew,
......@@ -117,16 +118,16 @@ export default {
type: Boolean,
required: true,
},
currentIntegration: {
type: Object,
required: false,
default: null,
},
canAddIntegration: {
type: Boolean,
required: true,
},
},
apollo: {
currentIntegration: {
query: getCurrentIntegrationQuery,
},
},
data() {
return {
selectedIntegration: integrationTypesNew[0].value,
......@@ -140,6 +141,7 @@ export default {
resetSamplePayloadConfirmed: false,
customMapping: null,
parsingPayload: false,
currentIntegration: null,
};
},
computed: {
......
......@@ -4,6 +4,7 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { fetchPolicies } from '~/lib/graphql';
import createFlash, { FLASH_TYPES } from '~/flash';
import getIntegrationsQuery from '../graphql/queries/get_integrations.query.graphql';
import getCurrentIntegrationQuery from '../graphql/queries/get_current_integration.query.graphql';
import createHttpIntegrationMutation from '../graphql/mutations/create_http_integration.mutation.graphql';
import createPrometheusIntegrationMutation from '../graphql/mutations/create_prometheus_integration.mutation.graphql';
import updateHttpIntegrationMutation from '../graphql/mutations/update_http_integration.mutation.graphql';
......@@ -11,6 +12,7 @@ import updatePrometheusIntegrationMutation from '../graphql/mutations/update_pro
import destroyHttpIntegrationMutation from '../graphql/mutations/destroy_http_integration.mutation.graphql';
import resetHttpTokenMutation from '../graphql/mutations/reset_http_token.mutation.graphql';
import resetPrometheusTokenMutation from '../graphql/mutations/reset_prometheus_token.mutation.graphql';
import updateCurrentIntergrationMutation from '../graphql/mutations/update_current_intergration.mutation.graphql';
import IntegrationsList from './alerts_integrations_list.vue';
import SettingsFormOld from './alerts_settings_form_old.vue';
import SettingsFormNew from './alerts_settings_form_new.vue';
......@@ -75,6 +77,9 @@ export default {
createFlash({ message: err });
},
},
currentIntegration: {
query: getCurrentIntegrationQuery,
},
},
data() {
return {
......@@ -87,7 +92,7 @@ export default {
loading() {
return this.$apollo.queries.integrations.loading;
},
intergrationsOptionsOld() {
integrationsOptionsOld() {
return [
{
name: s__('AlertSettings|HTTP endpoint'),
......@@ -208,7 +213,19 @@ export default {
});
},
editIntegration({ id }) {
this.currentIntegration = this.integrations.list.find(integration => integration.id === id);
const currentIntegration = this.integrations.list.find(integration => integration.id === id);
this.$apollo.mutate({
mutation: updateCurrentIntergrationMutation,
variables: {
id: currentIntegration.id,
name: currentIntegration.name,
active: currentIntegration.active,
token: currentIntegration.token,
type: currentIntegration.type,
url: currentIntegration.url,
apiUrl: currentIntegration.apiUrl,
},
});
},
deleteIntegration({ id }) {
const { projectPath } = this;
......@@ -229,7 +246,7 @@ export default {
if (error) {
return createFlash({ message: error });
}
this.currentIntegration = null;
this.clearCurrentIntegration();
return createFlash({
message: this.$options.i18n.integrationRemoved,
type: FLASH_TYPES.SUCCESS,
......@@ -243,7 +260,10 @@ export default {
});
},
clearCurrentIntegration() {
this.currentIntegration = null;
this.$apollo.mutate({
mutation: updateCurrentIntergrationMutation,
variables: {},
});
},
testPayloadFailure() {
createFlash({ message: INTEGRATION_PAYLOAD_TEST_ERROR });
......@@ -255,16 +275,14 @@ export default {
<template>
<div>
<integrations-list
:integrations="glFeatures.httpIntegrationsList ? integrations.list : intergrationsOptionsOld"
:integrations="glFeatures.httpIntegrationsList ? integrations.list : integrationsOptionsOld"
:loading="loading"
:current-integration="currentIntegration"
@edit-integration="editIntegration"
@delete-integration="deleteIntegration"
/>
<settings-form-new
v-if="glFeatures.httpIntegrationsList"
:loading="isUpdating"
:current-integration="currentIntegration"
:can-add-integration="canAddIntegration"
@create-new-integration="createNewIntegration"
@update-integration="updateIntegration"
......
import Vue from 'vue';
import produce from 'immer';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import getCurrentIntegrationQuery from './graphql/queries/get_current_integration.query.graphql';
Vue.use(VueApollo);
const resolvers = {
Mutation: {
updateCurrentIntegration: (
_,
{ id = null, name, active, token, type, url, apiUrl },
{ cache },
) => {
const sourceData = cache.readQuery({ query: getCurrentIntegrationQuery });
const data = produce(sourceData, draftData => {
if (id === null) {
// eslint-disable-next-line no-param-reassign
draftData.currentIntegration = null;
} else {
// eslint-disable-next-line no-param-reassign
draftData.currentIntegration = {
id,
name,
active,
token,
type,
url,
apiUrl,
};
}
});
cache.writeQuery({ query: getCurrentIntegrationQuery, data });
},
},
};
export default new VueApollo({
defaultClient: createDefaultClient(resolvers, {
cacheConfig: {},
assumeImmutableResults: true,
}),
});
mutation updateCurrentIntegration(
$id: String
$name: String
$active: Boolean
$token: String
$type: String
$url: String
$apiUrl: String
) {
updateCurrentIntegration(
id: $id
name: $name
active: $active
token: $token
type: $type
url: $url
apiUrl: $apiUrl
) @client
}
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import AlertSettingsWrapper from './components/alerts_settings_wrapper.vue';
import apolloProvider from './graphql';
Vue.use(VueApollo);
apolloProvider.clients.defaultClient.cache.writeData({
data: {
currentIntegration: null,
},
});
export default el => {
if (!el) {
......@@ -32,15 +35,6 @@ export default el => {
multiIntegrations,
} = el.dataset;
const resolvers = {};
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(resolvers, {
cacheConfig: {},
assumeImmutableResults: true,
}),
});
return new Vue({
el,
provide: {
......
......@@ -24,11 +24,14 @@ const mockIntegrations = [
describe('AlertIntegrationsList', () => {
let wrapper;
function mountComponent(propsData = {}) {
function mountComponent({ data = {}, props = {} } = {}) {
wrapper = mount(AlertIntegrationsList, {
data() {
return { ...data };
},
propsData: {
integrations: mockIntegrations,
...propsData,
...props,
},
stubs: {
GlIcon: true,
......@@ -57,7 +60,7 @@ describe('AlertIntegrationsList', () => {
});
it('renders an empty state when no integrations provided', () => {
mountComponent({ integrations: [] });
mountComponent({ props: { integrations: [] } });
expect(findTableComponent().text()).toContain(i18n.emptyState);
});
......@@ -66,7 +69,7 @@ describe('AlertIntegrationsList', () => {
});
it('renders an highlighted row when a current integration is selected to edit', () => {
mountComponent({ currentIntegration: { id: '1' } });
mountComponent({ data: { currentIntegration: { id: '1' } } });
expect(
findTableComponentRows()
.at(0)
......
......@@ -152,9 +152,9 @@ describe('AlertsSettingsFormNew', () => {
createComponent({
data: {
selectedIntegration: typeSet.http,
currentIntegration: { id: '1', name: 'Test integration pre' },
},
props: {
currentIntegration: { id: '1', name: 'Test integration pre' },
loading: false,
},
});
......@@ -183,9 +183,9 @@ describe('AlertsSettingsFormNew', () => {
createComponent({
data: {
selectedIntegration: typeSet.prometheus,
currentIntegration: { id: '1', apiUrl: 'https://test-pre.com' },
},
props: {
currentIntegration: { id: '1', apiUrl: 'https://test-pre.com' },
loading: false,
},
});
......@@ -219,10 +219,10 @@ describe('AlertsSettingsFormNew', () => {
createComponent({
data: {
selectedIntegration: typeSet.http,
currentIntegration: { id: '1', name: 'Test' },
active: true,
},
props: {
currentIntegration: { id: '1', name: 'Test' },
loading: false,
},
});
......
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